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 }