package javax.slee.management;
import java.util.HashMap;
import java.util.Iterator;
import javax.management.Notification;
import javax.management.NotificationFilter;
/**
* A notification filter that suppresses equivalent {@link AlarmNotification}s
* that occur during a specified period of time. Only the first of a series of
* equivalent alarm notifications is allowed through this filter. When the
* specified period of time elapses after the first notification, the cycle restarts
* and a subsequent equivalent alarm notification is allowed through.
* <p>
* Alarm notification equivalence is tested using the {@link AlarmNotification#equals}
* method.
* <p>
* Notifications that are not instances of {@link AlarmNotification} are suppressed
* by this filter.
* <p>
* <i>Note:</i> This filter implementation does not use threads to clear stale timeouts.
* Instead, stale timeouts are cleared on each invocation of {@link #isNotificationEnabled
* isNotificationEnabled}. Methods in this class are also thread-safe.
*/
public class AlarmDuplicateFilter implements NotificationFilter {
/**
* Create an <code>AlarmDuplicateFilter</code>.
* @param period the period (measured in ms) during which duplicate alarm
* notifications will be discarded.
*/
public AlarmDuplicateFilter(long period) {
this.period = period;
}
/**
* Determine whether the specified notification should be delivered to notification
* listeners using this notification filter.
* @param notification the notification to be sent.
* @return <code>true</code> if the notification should be delivered to notification
* listeners, <code>false</code> otherwise. This method always returns
* <code>false</code> if <code>notification</code> is not an instance of
* {@link AlarmNotification}.
*/
public boolean isNotificationEnabled(Notification notification) {
if (!(notification instanceof AlarmNotification)) return false;
synchronized (knownAlarms) {
clearStaleTimeouts();
if (knownAlarms.containsKey(notification)) return false;
// we've not seen this alarm before, or the period has expired since
// the first notification
knownAlarms.put(notification, new Long(System.currentTimeMillis()));
return true;
}
}
// private
private void clearStaleTimeouts() {
Iterator iterator = knownAlarms.values().iterator();
long currentTime = System.currentTimeMillis();
while (iterator.hasNext()) {
Long firstSeenTime = (Long)iterator.next();
// if period has expired remove reference to the notification
if ((firstSeenTime.longValue() + period) < currentTime) {
iterator.remove();
}
}
}
private final long period;
private final HashMap knownAlarms = new HashMap();
}