/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2012 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.util.internal.collection;
import java.util.Collection;
import java.util.Iterator;
import javolution.util.function.Consumer;
import javolution.util.function.Equality;
import javolution.util.internal.ReadWriteLockImpl;
import javolution.util.service.CollectionService;
/**
* A shared view over a collection (reads-write locks).
*/
public class SharedCollectionImpl<E> extends CollectionView<E> {
/** Thread-Safe Iterator. */
private class IteratorImpl implements Iterator<E> { // Thread-Safe.
private E next;
private final Iterator<E> targetIterator;
public IteratorImpl() {
lock.readLock.lock();
try {
targetIterator = cloneTarget().iterator(); // Copy.
} finally {
lock.readLock.unlock();
}
}
@Override
public boolean hasNext() {
return targetIterator.hasNext();
}
@Override
public E next() {
next = targetIterator.next();
return next;
}
@Override
public void remove() {
if (next == null) throw new IllegalStateException();
SharedCollectionImpl.this.remove(next);
next = null;
}
}
private static final long serialVersionUID = 0x600L; // Version.
protected ReadWriteLockImpl lock;
public SharedCollectionImpl(CollectionService<E> target) {
this(target, new ReadWriteLockImpl());
}
public SharedCollectionImpl(CollectionService<E> target,
ReadWriteLockImpl lock) {
super(target);
this.lock = lock;
}
@Override
public boolean add(E element) {
lock.writeLock.lock();
try {
return target().add(element);
} finally {
lock.writeLock.unlock();
}
}
@Override
public boolean addAll(Collection<? extends E> c) {
lock.writeLock.lock();
try {
return target().addAll(c);
} finally {
lock.writeLock.unlock();
}
}
@Override
public void clear() {
lock.writeLock.lock();
try {
target().clear();
} finally {
lock.writeLock.unlock();
}
}
@Override
public SharedCollectionImpl<E> clone() {
lock.readLock.lock();
try {
SharedCollectionImpl<E> copy = (SharedCollectionImpl<E>) super
.clone();
copy.lock = new ReadWriteLockImpl(); // No need to share the same lock.
return copy;
} finally {
lock.readLock.unlock();
}
}
@Override
public Equality<? super E> comparator() {
return target().comparator();
}
@Override
public boolean contains(Object o) {
lock.readLock.lock();
try {
return target().contains(o);
} finally {
lock.readLock.unlock();
}
}
@Override
public boolean containsAll(Collection<?> c) {
lock.readLock.lock();
try {
return target().containsAll(c);
} finally {
lock.readLock.unlock();
}
}
@Override
public boolean equals(Object o) {
lock.readLock.lock();
try {
return target().equals(o);
} finally {
lock.readLock.unlock();
}
}
@Override
public int hashCode() {
lock.readLock.lock();
try {
return target().hashCode();
} finally {
lock.readLock.unlock();
}
}
@Override
public boolean isEmpty() {
lock.readLock.lock();
try {
return target().isEmpty();
} finally {
lock.readLock.unlock();
}
}
@Override
public Iterator<E> iterator() {
return new IteratorImpl();
}
@Override
public void perform(Consumer<CollectionService<E>> action,
CollectionService<E> view) {
lock.readLock.lock();
try {
target().perform(action, view);
} finally {
lock.readLock.unlock();
}
}
@Override
public boolean remove(Object o) {
lock.writeLock.lock();
try {
return target().remove(o);
} finally {
lock.writeLock.unlock();
}
}
@Override
public boolean removeAll(Collection<?> c) {
lock.writeLock.lock();
try {
return target().removeAll(c);
} finally {
lock.writeLock.unlock();
}
}
@Override
public boolean retainAll(Collection<?> c) {
lock.writeLock.lock();
try {
return target().retainAll(c);
} finally {
lock.writeLock.unlock();
}
}
@Override
public int size() {
lock.readLock.lock();
try {
return target().size();
} finally {
lock.readLock.unlock();
}
}
@SuppressWarnings("unchecked")
@Override
public CollectionService<E>[] split(int n, boolean updateable) {
CollectionService<E>[] tmp;
lock.readLock.lock();
try {
tmp = target().split(n, updateable);
} finally {
lock.readLock.unlock();
}
CollectionService<E>[] result = new CollectionService[tmp.length];
for (int i = 0; i < tmp.length; i++) {
result[i] = new SharedCollectionImpl<E>(tmp[i], lock); // Shares the same locks.
}
return result;
}
@Override
public Object[] toArray() {
lock.readLock.lock();
try {
return target().toArray();
} finally {
lock.readLock.unlock();
}
}
@Override
public <T> T[] toArray(T[] a) {
lock.readLock.lock();
try {
return target().toArray(a);
} finally {
lock.readLock.unlock();
}
}
/** Returns a clone copy of target. */
protected CollectionService<E> cloneTarget() {
try {
return target().clone();
} catch (CloneNotSupportedException e) {
throw new Error("Cannot happen since target is Cloneable.");
}
}
}