/*
* Copyright (c) 2014-2015 Janith Bandara, This source is a part of
* Audit4j - An open source auditing framework.
* http://audit4j.org
*
* 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.audit4j.core.util;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.RandomAccess;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArrayList;
import org.audit4j.core.util.annotation.ThreadSafe;
/**
* The Class CircularTimelyBufferedArrayList.
*
* @param <E>
* the element type
* @author <a href="mailto:janith3000@gmail.com">Janith Bandara</a>
*
* @since 2.3.0
*/
@ThreadSafe
public class ConcurrentTimelyBufferedArrayList<E> extends AbstractList<E> implements RandomAccess, Serializable,
Cloneable {
/** asdas. */
private static final long serialVersionUID = 8870953621895891238L;
/** The buff. */
private final List<E> buff = new CopyOnWriteArrayList<E>();
/** The listener. */
private final BufferedListener<E> listener;
/** The consumer. */
ScheduleConsumer consumer;
/** The time. */
Timer time;
/**
* Instantiates a new circular timely buffered array list.
*
* @param timeInMills
* the time in mills
* @param listener
* the listener
*/
public ConcurrentTimelyBufferedArrayList(final int timeInMills, final BufferedListener<E> listener) {
this.listener = listener;
time = new Timer();
consumer = new ScheduleConsumer();
time.schedule(consumer, 0, timeInMills);
}
/*
* (non-Javadoc)
*
* @see java.util.AbstractList#get(int)
*/
@Override
public E get(int index) {
return buff.get(index);
}
/*
* (non-Javadoc)
*
* @see java.util.AbstractList#add(java.lang.Object)
*/
@Override
public boolean add(E e) {
return buff.add(e);
}
/*
* (non-Javadoc)
*
* @see java.util.AbstractCollection#size()
*/
@Override
public int size() {
return buff.size();
}
/*
* (non-Javadoc)
*
* @see java.util.AbstractCollection#isEmpty()
*/
@Override
public boolean isEmpty() {
return buff.isEmpty();
}
/**
* Close.
*/
public void close() {
time.cancel();
consumer.cancel();
}
/* (non-Javadoc)
* @see java.util.AbstractList#clear()
*/
@Override
public void clear() {
buff.clear();
}
/**
* Gets the buffered.
*
* @return the buffered
*/
public List<E> getBuffered() {
List<E> temp = new ArrayList<>(buff);
clear();
return temp;
}
/**
* The Class ScheduleConsumer.
*
* @author <a href="mailto:janith3000@gmail.com">Janith Bandara</a>
*/
public class ScheduleConsumer extends TimerTask {
/*
* (non-Javadoc)
*
* @see java.util.TimerTask#run()
*/
@Override
public void run() {
if (!isEmpty()) {
listener.accept(getBuffered());
}
}
}
/**
* The listener interface for receiving buffered events. The class that is
* interested in processing a buffered event implements this interface, and
* the object created with that class is registered with a component using
* the component's addBufferedListener method. When the buffered event
* occurs, that object's appropriate method is invoked.
*
* @param <E> the element type
*/
public interface BufferedListener<E> {
/**
* Accept.
*
* @param buffered
* list
*/
void accept(List<E> buffered);
}
}