| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| using System; |
| using Apache.NMS.AMQP.Message.Facade; |
| using Apache.NMS.Util; |
| |
| namespace Apache.NMS.AMQP.Message |
| { |
| public class NmsMessage : IMessage |
| { |
| private MessagePropertyIntercepter properties; |
| private bool readOnlyProperties; |
| |
| public NmsMessage(INmsMessageFacade facade) |
| { |
| Facade = facade; |
| } |
| |
| public INmsMessageFacade Facade { get; } |
| |
| public IPrimitiveMap Properties => properties ?? |
| (properties = new MessagePropertyIntercepter(this, Facade.Properties, |
| IsReadOnlyProperties)); |
| |
| public string NMSCorrelationID |
| { |
| get => Facade.NMSCorrelationID; |
| set => Facade.NMSCorrelationID = value; |
| } |
| |
| public IDestination NMSDestination |
| { |
| get => Facade.NMSDestination; |
| set => Facade.NMSDestination = value; |
| } |
| |
| public TimeSpan NMSTimeToLive |
| { |
| get => Facade.NMSTimeToLive; |
| set => Facade.NMSTimeToLive = value; |
| } |
| |
| public string NMSMessageId |
| { |
| get => Facade.NMSMessageId; |
| set => Facade.NMSMessageId = value; |
| } |
| |
| public MsgDeliveryMode NMSDeliveryMode |
| { |
| get => Facade.IsPersistent ? MsgDeliveryMode.Persistent : MsgDeliveryMode.NonPersistent; |
| set |
| { |
| CheckReadOnly(); |
| switch (value) |
| { |
| case MsgDeliveryMode.Persistent: |
| Facade.IsPersistent = true; |
| break; |
| case MsgDeliveryMode.NonPersistent: |
| Facade.IsPersistent = false; |
| break; |
| default: |
| throw new NMSException($"Invalid DeliveryMode specified: {value}"); |
| } |
| } |
| } |
| |
| public MsgPriority NMSPriority |
| { |
| get => Facade.NMSPriority; |
| set => Facade.NMSPriority = value; |
| } |
| |
| public bool NMSRedelivered |
| { |
| get => Facade.NMSRedelivered; |
| set => Facade.NMSRedelivered = value; |
| } |
| |
| public IDestination NMSReplyTo |
| { |
| get => Facade.NMSReplyTo; |
| set => Facade.NMSReplyTo = value; |
| } |
| |
| public DateTime NMSTimestamp |
| { |
| get => Facade.NMSTimestamp; |
| set => Facade.NMSTimestamp = value; |
| } |
| |
| public string NMSType |
| { |
| get => Facade.NMSType; |
| set => Facade.NMSType = value; |
| } |
| |
| public DateTime NMSDeliveryTime |
| { |
| get => Facade.DeliveryTime; |
| set => Facade.DeliveryTime = value; |
| } |
| |
| public string NMSXGroupId |
| { |
| get => Facade.GroupId; |
| set => Facade.GroupId = value; |
| } |
| |
| public int NMSXGroupSeq |
| { |
| get => (int) Facade.GroupSequence; |
| set => Facade.GroupSequence = (uint) value; |
| } |
| |
| public NmsAcknowledgeCallback NmsAcknowledgeCallback { get; set; } |
| |
| public virtual bool IsReadOnly { get; set; } |
| |
| public bool IsReadOnlyBody { get; set; } |
| |
| public bool IsReadOnlyProperties |
| { |
| get => readOnlyProperties; |
| set |
| { |
| readOnlyProperties = value; |
| if (properties != null) |
| { |
| properties.ReadOnly = value; |
| } |
| } |
| } |
| |
| public void Acknowledge() |
| { |
| if (NmsAcknowledgeCallback != null) |
| { |
| try |
| { |
| NmsAcknowledgeCallback.Acknowledge(); |
| NmsAcknowledgeCallback = null; |
| } |
| catch (Exception e) |
| { |
| throw NMSExceptionSupport.Create(e); |
| } |
| } |
| } |
| |
| public virtual void ClearBody() |
| { |
| CheckReadOnly(); |
| IsReadOnlyBody = false; |
| Facade.ClearBody(); |
| } |
| |
| public void ClearProperties() |
| { |
| CheckReadOnly(); |
| IsReadOnlyProperties = false; |
| Properties.Clear(); |
| } |
| |
| public virtual void OnSend(TimeSpan producerTtl) |
| { |
| IsReadOnly = true; |
| Facade.OnSend(producerTtl); |
| } |
| |
| public void OnDispatch() |
| { |
| IsReadOnly = false; |
| IsReadOnlyBody = true; |
| IsReadOnlyProperties = true; |
| } |
| |
| public override string ToString() |
| { |
| return $"NmsMessage {{ {Facade} }}"; |
| } |
| |
| protected bool Equals(NmsMessage other) |
| { |
| if (other.NMSMessageId == null) |
| return false; |
| |
| return string.Equals(NMSMessageId, other.NMSMessageId); |
| } |
| |
| public override bool Equals(object obj) |
| { |
| if (ReferenceEquals(null, obj)) return false; |
| if (ReferenceEquals(this, obj)) return true; |
| if (obj.GetType() != this.GetType()) return false; |
| return Equals((NmsMessage) obj); |
| } |
| |
| public override int GetHashCode() |
| { |
| return (NMSMessageId != null ? NMSMessageId.GetHashCode() : base.GetHashCode()); |
| } |
| |
| //----- State validation methods -----------------------------------------// |
| |
| protected void CheckReadOnly() |
| { |
| if (IsReadOnly) |
| { |
| throw new MessageNotReadableException("Message is currently read-only"); |
| } |
| } |
| |
| protected void CheckWriteOnlyBody() |
| { |
| if (!IsReadOnlyBody) |
| { |
| throw new MessageNotReadableException("Message body is write-only"); |
| } |
| } |
| |
| protected void CheckReadOnlyBody() |
| { |
| if (IsReadOnly || IsReadOnlyBody) |
| { |
| throw new MessageNotWriteableException("Message body is read-only"); |
| } |
| } |
| |
| public bool IsExpired() |
| { |
| DateTime? expireTime = Facade.Expiration; |
| return expireTime != null && DateTime.UtcNow > expireTime; |
| } |
| |
| public virtual NmsMessage Copy() |
| { |
| NmsMessage copy = new NmsMessage(Facade.Copy()); |
| CopyInto(copy); |
| return copy; |
| } |
| |
| protected void CopyInto(NmsMessage target) |
| { |
| target.IsReadOnly = IsReadOnly; |
| target.IsReadOnlyBody = IsReadOnlyBody; |
| target.IsReadOnlyProperties = IsReadOnlyProperties; |
| target.NmsAcknowledgeCallback = NmsAcknowledgeCallback; |
| } |
| |
| public virtual bool IsBodyAssignableTo(Type type) |
| { |
| return true; |
| } |
| |
| public T Body<T>() |
| { |
| if (IsBodyAssignableTo(typeof(T))) |
| { |
| return DoGetBody<T>(); |
| } |
| |
| throw new MessageFormatException("Message body cannot be read as type: " + typeof(T)); |
| } |
| |
| protected virtual T DoGetBody<T>() |
| { |
| return default; |
| } |
| } |
| } |