package uk.ac.rhul.cs.utils;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
/**
* Adapts a BlockingQueue to conform to the {@link Collection} interface with
* a different behaviour.
*
* By default, {@link BlockingQueue.add} adds an item to the queue only if
* is not full and throws an exception otherwise. This class modifies the
* default behaviour: calling {@link BlockingQueueAdapter.add} will forward
* the call to {@link BlockingQueue.put} instead, which blocks the current
* thread until more space becomes available in the queue.
*
* @author ntamas
*
*/
public class BlockingQueueAdapter<E> implements Collection<E> {
private BlockingQueue<E> queue;
/**
* Creates an adapter that adapts the given blocking queue.
*
* @param queue the queue to be adapted
*/
public BlockingQueueAdapter(BlockingQueue<E> queue) {
this.queue = queue;
}
/**
* Returns the number of elements in the queue.
*/
public int size() {
return this.queue.size();
}
/**
* Returns whether the queue is empty
*/
public boolean isEmpty() {
return this.queue.isEmpty();
}
/**
* Checks whether the queue contains the given object
*/
public boolean contains(Object o) {
return this.queue.contains(o);
}
/**
* Returns an iterator over the queue
*/
public Iterator<E> iterator() {
return this.queue.iterator();
}
/**
* Converts the contents of the queue to an array
*/
public Object[] toArray() {
return this.queue.toArray();
}
/**
* Converts the contents of the queue to an array
*/
public <T> T[] toArray(T[] a) {
return this.queue.toArray(a);
}
/**
* Adds the given element to the queue, blocking the current thread if
* there is not enough space available.
*
* @return true if the element was added successfully, false if the thread
* has been interrupted while waiting for space to become available.
*/
public boolean add(E e) {
try {
this.queue.put(e);
} catch (InterruptedException ex) {
return false;
}
return true;
}
/**
* Removes the given object from the queue.
*/
public boolean remove(Object o) {
return this.queue.remove(o);
}
/**
* Returns true if the queue contains all the elements of the given collection
*/
public boolean containsAll(Collection<?> c) {
return this.queue.containsAll(c);
}
/**
* Adds all the elements in the given collection to the queue, blocking the
* current thread if there is not enough space available.
*
* @return true if the element was added successfully, false if the thread
* has been interrupted while waiting for space to become available.
*/
public boolean addAll(Collection<? extends E> c) {
for (E elem: c)
if (!this.queue.add(elem))
return false;
return true;
}
/**
* Removes all the elements in the given collection from the queue.
*/
public boolean removeAll(Collection<?> c) {
return this.queue.removeAll(c);
}
/**
* Removes all but the elements in the given collection from the queue.
*/
public boolean retainAll(Collection<?> c) {
return this.queue.retainAll(c);
}
/**
* Clears the queue.
*/
public void clear() {
this.queue.clear();
}
}