/*
* Copyright to the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.rioproject.eventcollector.service;
import net.jini.core.event.RemoteEvent;
import org.rioproject.event.RemoteServiceEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
/**
* An {@code EventManager} that keeps an in-memory collection of events.
*
* @author Dennis Reedy
*/
public class TransientEventManager extends AbstractEventManager {
private final ConcurrentSkipListMap<EventKey, RemoteServiceEvent> eventLog = new ConcurrentSkipListMap<EventKey, RemoteServiceEvent>();
private static final Logger logger = LoggerFactory.getLogger(TransientEventManager.class.getName());
@Override
public void postNotify(final RemoteServiceEvent event) {
EventKey key = new EventKey(event);
if(eventLog.containsKey(key)) {
logger.warn("Already have {}", key);
return;
}
eventLog.put(key, event);
if(logger.isDebugEnabled())
logger.debug(String.format("Added key: %s, we have %d events", key, eventLog.size()));
}
@Override
public Collection<RemoteServiceEvent> getEvents() {
List<RemoteServiceEvent> events = new LinkedList<RemoteServiceEvent>();
events.addAll(eventLog.values());
return events;
}
@Override
public Date getLastRecordedDate() {
if(eventLog.isEmpty())
return null;
return eventLog.lastKey().date;
}
@Override
public Collection<RemoteServiceEvent> getEvents(final Date from) {
if(from==null)
return getEvents();
if(logger.isDebugEnabled()) {
DateFormat formatter = new SimpleDateFormat("HH:mm:ss,SSS");
logger.debug(String.format("Getting sublist from %s, to %s",
formatter.format(from), formatter.format(eventLog.lastKey())));
}
List<RemoteServiceEvent> events = new LinkedList<RemoteServiceEvent>();
events.addAll(eventLog.subMap(new EventKey(from), eventLog.lastKey()).values());
return events;
}
@Override
public int delete(Collection<RemoteServiceEvent> events) {
List<EventKey> removals = new ArrayList<EventKey>();
for(RemoteEvent event : events) {
for(Map.Entry<EventKey, RemoteServiceEvent> entry : eventLog.entrySet()) {
RemoteEvent remoteEvent = entry.getValue();
if(remoteEvent.getClass().getName().equals(event.getClass().getName()) &&
remoteEvent.getSequenceNumber()==event.getSequenceNumber()) {
removals.add(entry.getKey());
}
}
}
for(EventKey eventKey : removals) {
eventLog.remove(eventKey);
}
return removals.size();
}
protected void addRemoteEvents(Collection<RemoteServiceEvent> events) {
for(RemoteServiceEvent event : events) {
postNotify(event);
}
}
protected int getNumberOfCollectedEvents() {
return eventLog.size();
}
private class EventKey implements Comparable<EventKey> {
private Long sequenceNumber;
private final Date date;
private String name;
private EventKey(final RemoteServiceEvent event) {
sequenceNumber = event.getSequenceNumber();
date = event.getDate();
name = event.getClass().getName();
}
private EventKey(final Date date) {
this.date = date;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
EventKey eventKey = (EventKey) o;
return date.equals(eventKey.date) &&
!(name != null ? !name.equals(eventKey.name) : eventKey.name != null) &&
!(sequenceNumber != null ?
!sequenceNumber.equals(eventKey.sequenceNumber) :
eventKey.sequenceNumber != null);
}
@Override
public int hashCode() {
int result = sequenceNumber != null ? sequenceNumber.hashCode() : 0;
result = 31 * result + date.hashCode();
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public int compareTo(EventKey o) {
int result = date.compareTo(o.date);
if(result==0) {
if(name!=null && o.name!=null) {
result = name.compareTo(o.name);
}
}
if(result==0) {
if(sequenceNumber!=null && o.sequenceNumber!=null) {
result = sequenceNumber.compareTo(o.sequenceNumber);
}
}
return result;
}
@Override
public String toString() {
DateFormat dateFormatter = new SimpleDateFormat("yyyy.MM.dd-HH.mm.ss.SSS");
StringBuilder nameBuilder = new StringBuilder();
nameBuilder.append(sequenceNumber).append("-").append(name).append("-");
nameBuilder.append(dateFormatter.format(date));
return nameBuilder.toString();
}
}
}