1 /* 2 * Copyright 2002-2018 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 module hunt.stomp.support.GenericMessage; 18 19 import hunt.stomp.Message; 20 import hunt.stomp.MessageHeaders; 21 22 import hunt.collection.Map; 23 import hunt.text.Common; 24 import hunt.text.StringBuilder; 25 import hunt.util.ObjectUtils; 26 27 28 /** 29 * An implementation of {@link Message} with a generic payload. 30 * Once created, a GenericMessage is immutable. 31 * 32 * @author Mark Fisher 33 * @since 4.0 34 * @param (T) the payload type 35 * @see MessageBuilder 36 */ 37 class GenericMessage(T) : Message!(T) { 38 39 private T payload; 40 41 private MessageHeaders headers; 42 43 44 /** 45 * Create a new message with the given payload. 46 * @param payload the message payload (never {@code null}) 47 */ 48 this(T payload) { 49 this(payload, new MessageHeaders(null)); 50 } 51 52 /** 53 * Create a new message with the given payload and headers. 54 * The content of the given header map is copied. 55 * @param payload the message payload (never {@code null}) 56 * @param headers message headers to use for initialization 57 */ 58 this(T payload, Map!(string, Object) headers) { 59 this(payload, new MessageHeaders(headers)); 60 } 61 62 /** 63 * A constructor with the {@link MessageHeaders} instance to use. 64 * <p><strong>Note:</strong> the given {@code MessageHeaders} instance is used 65 * directly in the new message, i.e. it is not copied. 66 * @param payload the message payload (never {@code null}) 67 * @param headers message headers 68 */ 69 this(T payload, MessageHeaders headers) { 70 // assert(payload, "Payload must not be null"); 71 assert(headers, "MessageHeaders must not be null"); 72 this.payload = payload; 73 this.headers = headers; 74 } 75 76 TypeInfo payloadType() { 77 return typeid(T); 78 } 79 80 T getPayload() { 81 return this.payload; 82 } 83 84 MessageHeaders getHeaders() { 85 return this.headers; 86 } 87 88 override bool opEquals(Object other) { 89 if (this is other) { 90 return true; 91 } 92 93 GenericMessage!T otherMsg = cast(GenericMessage!T) other; 94 if (otherMsg is null) { 95 return false; 96 } 97 return this.payload == otherMsg.payload && this.headers == otherMsg.headers; 98 } 99 100 override size_t toHash() @trusted nothrow { 101 // Using nullSafeHashCode for proper array toHash handling 102 return hashOf(this.payload) * 23 + this.headers.toHash(); 103 } 104 105 override string toString() { 106 StringBuilder sb = new StringBuilder(typeid(this).name); 107 sb.append(" [payload="); 108 static if(is(T == class)) { 109 sb.append(this.payload.toString()); 110 } else static if(is(T == interface)) { 111 sb.append((cast(Object)this.payload).toString()); 112 } else { 113 sb.append("byte[").append((cast(byte[]) this.payload).length).append("]"); 114 } 115 // static if(is(T == byte[])) { 116 // sb.append("byte[").append((cast(byte[]) this.payload).length).append("]"); 117 // } else { 118 // sb.append(this.payload.toString()); 119 // } 120 sb.append(", headers=").append(this.headers.toString()).append("]"); 121 return sb.toString(); 122 } 123 124 }