001 /**
002 *
003 * Copyright 2004 Protique Ltd
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 **/
018
019 package org.activemq;
020
021 import java.util.LinkedHashMap;
022
023 import javax.jms.JMSException;
024 import javax.jms.Message;
025
026 import org.activemq.util.BitArrayBin;
027 import org.activemq.util.IdGenerator;
028 import org.activemq.util.LRUCache;
029
030 /**
031 * Provides basic audit functions for Messages
032 *
033 * @version $Revision: 1.1.1.1 $
034 */
035 public class ActiveMQMessageAudit {
036 private static final int DEFAULT_WINDOW_SIZE = 1024;
037 private static final int MAXIMUM_PRODUCER_COUNT = 128;
038 private int windowSize;
039 private LinkedHashMap map;
040
041 /**
042 * Default Constructor windowSize = 1024, maximumNumberOfProducersToTrack = 128
043 */
044 public ActiveMQMessageAudit() {
045 this(DEFAULT_WINDOW_SIZE, MAXIMUM_PRODUCER_COUNT);
046 }
047
048 /**
049 * Construct a MessageAudit
050 *
051 * @param windowSize range of ids to track
052 * @param maximumNumberOfProducersToTrack
053 * number of producers expected in the system
054 */
055 public ActiveMQMessageAudit(int windowSize, final int maximumNumberOfProducersToTrack) {
056 this.windowSize = windowSize;
057 map = new LRUCache(maximumNumberOfProducersToTrack);
058 }
059
060 /**
061 * Checks if this message has beeb seen before
062 *
063 * @param message
064 * @return true if the message is a duplicate
065 * @throws JMSException
066 */
067 public boolean isDuplicate(Message message) throws JMSException {
068 return isDuplicate(message.getJMSMessageID());
069 }
070
071
072 /**
073 * checks whether this messageId has been seen before and adds this messageId to the list
074 *
075 * @param id
076 * @return true if the message is a duplicate
077 */
078 public boolean isDuplicate(String id) {
079 boolean answer = false;
080 String seed = IdGenerator.getSeedFromId(id);
081 if (seed != null) {
082 BitArrayBin bab = (BitArrayBin) map.get(seed);
083 if (bab == null) {
084 bab = new BitArrayBin(windowSize);
085 map.put(seed, bab);
086 }
087 long index = IdGenerator.getCountFromId(id);
088 if (index >= 0) {
089 answer = bab.setBit(index, true);
090 }
091 }
092 return answer;
093 }
094 }