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