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     */
017    package org.apache.activemq.command;
018    
019    import java.util.concurrent.atomic.AtomicReference;
020    
021    /**
022     * @openwire:marshaller code="110"
023     * 
024     */
025    public class MessageId implements DataStructure, Comparable<MessageId> {
026    
027        public static final byte DATA_STRUCTURE_TYPE = CommandTypes.MESSAGE_ID;
028    
029        protected ProducerId producerId;
030        protected long producerSequenceId;
031        protected long brokerSequenceId;
032    
033        private transient String key;
034        private transient int hashCode;
035    
036        private transient AtomicReference<Object> dataLocator = new AtomicReference<Object>();
037        private transient Object entryLocator;
038        private transient Object plistLocator;
039    
040        public MessageId() {
041            this.producerId = new ProducerId();
042        }
043    
044        public MessageId(ProducerInfo producerInfo, long producerSequenceId) {
045            this.producerId = producerInfo.getProducerId();
046            this.producerSequenceId = producerSequenceId;
047        }
048    
049        public MessageId(String messageKey) {
050            setValue(messageKey);
051        }
052    
053        public MessageId(String producerId, long producerSequenceId) {
054            this(new ProducerId(producerId), producerSequenceId);
055        }
056    
057        public MessageId(ProducerId producerId, long producerSequenceId) {
058            this.producerId = producerId;
059            this.producerSequenceId = producerSequenceId;
060        }
061    
062        /**
063         * Sets the value as a String
064         */
065        public void setValue(String messageKey) {
066            key = messageKey;
067            // Parse off the sequenceId
068            int p = messageKey.lastIndexOf(":");
069            if (p >= 0) {
070                producerSequenceId = Long.parseLong(messageKey.substring(p + 1));
071                messageKey = messageKey.substring(0, p);
072            }
073            producerId = new ProducerId(messageKey);
074        }
075    
076        /**
077         * Sets the transient text view of the message which will be ignored if the
078         * message is marshaled on a transport; so is only for in-JVM changes to
079         * accommodate foreign JMS message IDs
080         */
081        public void setTextView(String key) {
082            this.key = key;
083        }
084    
085        public byte getDataStructureType() {
086            return DATA_STRUCTURE_TYPE;
087        }
088    
089        public boolean equals(Object o) {
090            if (this == o) {
091                return true;
092            }
093            if (o == null || o.getClass() != getClass()) {
094                return false;
095            }
096    
097            MessageId id = (MessageId)o;
098            return producerSequenceId == id.producerSequenceId && producerId.equals(id.producerId);
099        }
100    
101        public int hashCode() {
102            if (hashCode == 0) {
103                hashCode = producerId.hashCode() ^ (int)producerSequenceId;
104            }
105            return hashCode;
106        }
107    
108        public String toString() {
109            if (key == null) {
110                key = producerId.toString() + ":" + producerSequenceId;
111            }
112            return key;
113        }
114    
115        /**
116         * @openwire:property version=1 cache=true
117         */
118        public ProducerId getProducerId() {
119            return producerId;
120        }
121    
122        public void setProducerId(ProducerId producerId) {
123            this.producerId = producerId;
124        }
125    
126        /**
127         * @openwire:property version=1
128         */
129        public long getProducerSequenceId() {
130            return producerSequenceId;
131        }
132    
133        public void setProducerSequenceId(long producerSequenceId) {
134            this.producerSequenceId = producerSequenceId;
135        }
136    
137        /**
138         * @openwire:property version=1
139         */
140        public long getBrokerSequenceId() {
141            return brokerSequenceId;
142        }
143    
144        public void setBrokerSequenceId(long brokerSequenceId) {
145            this.brokerSequenceId = brokerSequenceId;
146        }
147    
148        public boolean isMarshallAware() {
149            return false;
150        }
151    
152        public MessageId copy() {
153            MessageId copy = new MessageId(producerId, producerSequenceId);
154            copy.key = key;
155            copy.brokerSequenceId = brokerSequenceId;
156            copy.dataLocator = new AtomicReference<Object>(dataLocator != null ? dataLocator.get() : null);
157            copy.entryLocator = entryLocator;
158            copy.plistLocator = plistLocator;
159            return copy;
160        }
161    
162        /**
163         * @param
164         * @return
165         * @see java.lang.Comparable#compareTo(java.lang.Object)
166         */
167        public int compareTo(MessageId other) {
168            int result = -1;
169            if (other != null) {
170                result = this.toString().compareTo(other.toString());
171            }
172            return result;
173        }
174    
175        /**
176         * @return a locator which aids a message store in loading a message faster.  Only used
177         * by the message stores.
178         */
179        public Object getDataLocator() {
180            return dataLocator.get();
181        }
182    
183        /**
184         * Sets a locator which aids a message store in loading a message faster.  Only used
185         * by the message stores.
186         */
187        public void setDataLocator(Object value) {
188            this.dataLocator.set(value);
189        }
190    
191        public Object getEntryLocator() {
192            return entryLocator;
193        }
194    
195        public void setEntryLocator(Object entryLocator) {
196            this.entryLocator = entryLocator;
197        }
198    
199        public Object getPlistLocator() {
200            return plistLocator;
201        }
202    
203        public void setPlistLocator(Object plistLocator) {
204            this.plistLocator = plistLocator;
205        }
206    }