001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.command; 018 019import java.util.concurrent.atomic.AtomicReference; 020 021/** 022 * @openwire:marshaller code="110" 023 * 024 */ 025public class MessageId implements DataStructure, Comparable<MessageId> { 026 027 public static final byte DATA_STRUCTURE_TYPE = CommandTypes.MESSAGE_ID; 028 029 protected String textView; 030 protected ProducerId producerId; 031 protected long producerSequenceId; 032 protected long brokerSequenceId; 033 034 private transient String key; 035 private transient int hashCode; 036 037 private transient AtomicReference<Object> dataLocator = new AtomicReference<Object>(); 038 private transient Object entryLocator; 039 private transient Object plistLocator; 040 private transient Object futureOrSequenceLong; 041 042 public MessageId() { 043 this.producerId = new ProducerId(); 044 } 045 046 public MessageId(ProducerInfo producerInfo, long producerSequenceId) { 047 this.producerId = producerInfo.getProducerId(); 048 this.producerSequenceId = producerSequenceId; 049 } 050 051 public MessageId(String messageKey) { 052 setValue(messageKey); 053 } 054 055 public MessageId(String producerId, long producerSequenceId) { 056 this(new ProducerId(producerId), producerSequenceId); 057 } 058 059 public MessageId(ProducerId producerId, long producerSequenceId) { 060 this.producerId = producerId; 061 this.producerSequenceId = producerSequenceId; 062 } 063 064 /** 065 * Sets the value as a String 066 */ 067 public void setValue(String messageKey) { 068 key = messageKey; 069 // Parse off the sequenceId 070 int p = messageKey.lastIndexOf(":"); 071 if (p >= 0) { 072 producerSequenceId = Long.parseLong(messageKey.substring(p + 1)); 073 messageKey = messageKey.substring(0, p); 074 } else { 075 throw new NumberFormatException(); 076 } 077 producerId = new ProducerId(messageKey); 078 } 079 080 /** 081 * Sets the transient text view of the message which will be ignored if the message is marshaled on a transport; so 082 * is only for in-JVM changes to accommodate foreign JMS message IDs 083 */ 084 public void setTextView(String key) { 085 this.textView = key; 086 } 087 088 /** 089 * @openwire:property version=10 090 * @return 091 */ 092 public String getTextView() { 093 return textView; 094 } 095 096 @Override 097 public byte getDataStructureType() { 098 return DATA_STRUCTURE_TYPE; 099 } 100 101 @Override 102 public boolean equals(Object o) { 103 if (this == o) { 104 return true; 105 } 106 if (o == null || o.getClass() != getClass()) { 107 return false; 108 } 109 110 MessageId id = (MessageId) o; 111 return producerSequenceId == id.producerSequenceId && producerId.equals(id.producerId); 112 } 113 114 @Override 115 public int hashCode() { 116 if (hashCode == 0) { 117 hashCode = producerId.hashCode() ^ (int) producerSequenceId; 118 } 119 return hashCode; 120 } 121 122 public String toProducerKey() { 123 if (textView == null) { 124 return toString(); 125 } else { 126 return producerId.toString() + ":" + producerSequenceId; 127 } 128 } 129 130 @Override 131 public String toString() { 132 if (key == null) { 133 if (textView != null) { 134 if (textView.startsWith("ID:")) { 135 key = textView; 136 } else { 137 key = "ID:" + textView; 138 } 139 } else { 140 key = producerId.toString() + ":" + producerSequenceId; 141 } 142 } 143 return key; 144 } 145 146 /** 147 * @openwire:property version=1 cache=true 148 */ 149 public ProducerId getProducerId() { 150 return producerId; 151 } 152 153 public void setProducerId(ProducerId producerId) { 154 this.producerId = producerId; 155 } 156 157 /** 158 * @openwire:property version=1 159 */ 160 public long getProducerSequenceId() { 161 return producerSequenceId; 162 } 163 164 public void setProducerSequenceId(long producerSequenceId) { 165 this.producerSequenceId = producerSequenceId; 166 } 167 168 /** 169 * @openwire:property version=1 170 */ 171 public long getBrokerSequenceId() { 172 return brokerSequenceId; 173 } 174 175 public void setBrokerSequenceId(long brokerSequenceId) { 176 this.brokerSequenceId = brokerSequenceId; 177 } 178 179 @Override 180 public boolean isMarshallAware() { 181 return false; 182 } 183 184 public MessageId copy() { 185 MessageId copy = new MessageId(producerId, producerSequenceId); 186 copy.key = key; 187 copy.brokerSequenceId = brokerSequenceId; 188 copy.dataLocator = dataLocator; 189 copy.entryLocator = entryLocator; 190 copy.futureOrSequenceLong = futureOrSequenceLong; 191 copy.plistLocator = plistLocator; 192 copy.textView = textView; 193 return copy; 194 } 195 196 /** 197 * @param 198 * @return 199 * @see java.lang.Comparable#compareTo(java.lang.Object) 200 */ 201 @Override 202 public int compareTo(MessageId other) { 203 int result = -1; 204 if (other != null) { 205 result = this.toString().compareTo(other.toString()); 206 } 207 return result; 208 } 209 210 /** 211 * @return a locator which aids a message store in loading a message faster. Only used by the message stores. 212 */ 213 public Object getDataLocator() { 214 return dataLocator.get(); 215 } 216 217 /** 218 * Sets a locator which aids a message store in loading a message faster. Only used by the message stores. 219 */ 220 public void setDataLocator(Object value) { 221 this.dataLocator.set(value); 222 } 223 224 public Object getFutureOrSequenceLong() { 225 return futureOrSequenceLong; 226 } 227 228 public void setFutureOrSequenceLong(Object futureOrSequenceLong) { 229 this.futureOrSequenceLong = futureOrSequenceLong; 230 } 231 232 public Object getEntryLocator() { 233 return entryLocator; 234 } 235 236 public void setEntryLocator(Object entryLocator) { 237 this.entryLocator = entryLocator; 238 } 239 240 public Object getPlistLocator() { 241 return plistLocator; 242 } 243 244 public void setPlistLocator(Object plistLocator) { 245 this.plistLocator = plistLocator; 246 } 247}