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 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 = dataLocator;
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}