/**
*
*/
package vnet.sms.gateway.nettytest.embedded;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.CopyOnWriteArrayList;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ExceptionEvent;
import com.google.common.base.Predicate;
/**
* @author obergner
*
*/
class FilteredChannelEventQueue<T extends ChannelEvent> implements
ChannelListener<T>, Queue<T> {
// ------------------------------------------------------------------------
// Fields
// ------------------------------------------------------------------------
private final Queue<T> channelEvents;
private final List<ChannelEventSink<T>> filters = new CopyOnWriteArrayList<ChannelEventSink<T>>();
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
FilteredChannelEventQueue() {
this(new LinkedList<T>());
}
/**
* EXPOSED FOR TESTING PURPOSES.
*/
FilteredChannelEventQueue(final Queue<T> channelEvents) {
this.channelEvents = channelEvents;
}
// ------------------------------------------------------------------------
// Adding filters
// ------------------------------------------------------------------------
FilteringChannelEventFuture<T> addFilter(final Predicate<T> filter) {
final FilteringChannelEventFuture<T> filterFuture = new FilteringChannelEventFuture<T>(
filter);
for (final T e : this.channelEvents) {
if (filterFuture.acceptsChannelEvent(e)) {
this.channelEvents.remove(e);
return filterFuture;
}
}
this.filters.add(filterFuture);
return filterFuture;
}
TimedFilteringChannelEventFuture<T> addTimedFilter(final Predicate<T> filter) {
final TimedFilteringChannelEventFuture<T> filterFuture = new TimedFilteringChannelEventFuture<T>(
filter);
for (final T e : this.channelEvents) {
if (filterFuture.acceptsChannelEvent(e)) {
this.channelEvents.remove(e);
return filterFuture;
}
}
this.filters.add(filterFuture);
return filterFuture;
}
// ------------------------------------------------------------------------
// ChannelListener
// ------------------------------------------------------------------------
@Override
public void onEvent(final T e) {
for (final ChannelEventSink<T> filterFuture : this.filters) {
if (filterFuture.acceptsChannelEvent(e)) {
this.channelEvents.remove(e);
this.filters.remove(filterFuture);
break;
}
}
this.channelEvents.add(e);
}
@Override
public void onExceptionEvent(final ExceptionEvent e) {
for (final ChannelEventSink<T> filterFuture : this.filters) {
if (filterFuture.acceptsExceptionEvent(e)) {
this.filters.remove(filterFuture);
}
}
}
// ------------------------------------------------------------------------
// Queue
// ------------------------------------------------------------------------
/**
* @param e
* @return
* @see java.util.Queue#add(java.lang.Object)
*/
@Override
public boolean add(final T e) {
throw new UnsupportedOperationException();
}
/**
* @param c
* @return
* @see java.util.Collection#addAll(java.util.Collection)
*/
@Override
public boolean addAll(final Collection<? extends T> c) {
throw new UnsupportedOperationException();
}
/**
*
* @see java.util.Collection#clear()
*/
@Override
public void clear() {
throw new UnsupportedOperationException();
}
/**
* @param o
* @return
* @see java.util.Collection#contains(java.lang.Object)
*/
@Override
public boolean contains(final Object o) {
return this.channelEvents.contains(o);
}
/**
* @param c
* @return
* @see java.util.Collection#containsAll(java.util.Collection)
*/
@Override
public boolean containsAll(final Collection<?> c) {
return this.channelEvents.containsAll(c);
}
/**
* @return
* @see java.util.Queue#element()
*/
@Override
public T element() {
return this.channelEvents.element();
}
/**
* @return
* @see java.util.Collection#isEmpty()
*/
@Override
public boolean isEmpty() {
return this.channelEvents.isEmpty();
}
/**
* @return
* @see java.util.Collection#iterator()
*/
@Override
public Iterator<T> iterator() {
return this.channelEvents.iterator();
}
/**
* @param e
* @return
* @see java.util.Queue#offer(java.lang.Object)
*/
@Override
public boolean offer(final ChannelEvent e) {
throw new UnsupportedOperationException();
}
/**
* @return
* @see java.util.Queue#peek()
*/
@Override
public T peek() {
return this.channelEvents.peek();
}
/**
* @return
* @see java.util.Queue#poll()
*/
@Override
public T poll() {
return this.channelEvents.poll();
}
/**
* @return
* @see java.util.Queue#remove()
*/
@Override
public T remove() {
throw new UnsupportedOperationException();
}
/**
* @param o
* @return
* @see java.util.Collection#remove(java.lang.Object)
*/
@Override
public boolean remove(final Object o) {
return this.channelEvents.remove(o);
}
/**
* @param c
* @return
* @see java.util.Collection#removeAll(java.util.Collection)
*/
@Override
public boolean removeAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
/**
* @param c
* @return
* @see java.util.Collection#retainAll(java.util.Collection)
*/
@Override
public boolean retainAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
/**
* @return
* @see java.util.Collection#size()
*/
@Override
public int size() {
return this.channelEvents.size();
}
/**
* @return
* @see java.util.Collection#toArray()
*/
@Override
public Object[] toArray() {
return this.channelEvents.toArray();
}
/**
* @param <S>
* @param a
* @return
* @see java.util.Collection#toArray(S[])
*/
@Override
public <S> S[] toArray(final S[] a) {
return this.channelEvents.toArray(a);
}
}