Author: desruisseaux Date: Mon Oct 15 08:51:37 2012 New Revision: 1398219 URL: http://svn.apache.org/viewvc?rev=1398219&view=rev Log: Merge from the JDK7 branch.
Added: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Decorator.java - copied unchanged from r1398215, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Decorator.java Removed: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/SynchronizedIterator.java Modified: sis/branches/JDK6/ (props changed) sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedArrayList.java sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashMap.java sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashSet.java Propchange: sis/branches/JDK6/ ------------------------------------------------------------------------------ Merged /sis/branches/JDK7:r1397415-1398215 Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedArrayList.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedArrayList.java?rev=1398219&r1=1398218&r2=1398219&view=diff ============================================================================== --- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedArrayList.java (original) +++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedArrayList.java Mon Oct 15 08:51:37 2012 @@ -18,10 +18,12 @@ package org.apache.sis.util.collection; import java.util.List; import java.util.Iterator; +import java.util.ListIterator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import net.jcip.annotations.ThreadSafe; +import org.apache.sis.util.Decorator; import org.apache.sis.util.resources.Errors; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; @@ -166,20 +168,69 @@ public class CheckedArrayList<E> extends } /** + * A synchronized iterator with a check for write permission prior element removal. + */ + @ThreadSafe + @Decorator(Iterator.class) + private class Iter<E,I extends Iterator<E>> implements Iterator<E> { + final I iterator; + Iter(final I iterator) {this.iterator = iterator;} + @Override public final boolean hasNext() {synchronized (getLock()) {return iterator.hasNext();}} + @Override public final E next() {synchronized (getLock()) {return iterator.next();}} + @Override public final void remove() {synchronized (getLock()) {checkWritePermission(); iterator.remove();}} + } + + /** + * A synchronized list iterator with a check for write permission prior element removal. + */ + @Decorator(ListIterator.class) + private class ListIter<E> extends Iter<E,ListIterator<E>> implements ListIterator<E> { + ListIter(final ListIterator<E> iterator) {super(iterator);} + @Override public int nextIndex() {synchronized (getLock()) {return iterator.nextIndex();}} + @Override public int previousIndex() {synchronized (getLock()) {return iterator.previousIndex();}} + @Override public boolean hasPrevious() {synchronized (getLock()) {return iterator.hasPrevious();}} + @Override public E previous() {synchronized (getLock()) {return iterator.previous();}} + @Override public void set(final E e) {synchronized (getLock()) {checkWritePermission(); iterator.set(e);}} + @Override public void add(final E e) {synchronized (getLock()) {checkWritePermission(); iterator.add(e);}} + } + + /** * Returns an iterator over the elements in this list. + * The returned iterator will support {@linkplain Iterator#remove() element removal} + * only if the {@link #checkWritePermission()} method does not throw exception. */ @Override public Iterator<E> iterator() { - final Object lock = getLock(); - synchronized (lock) { - return new SynchronizedIterator<E>(super.iterator(), lock); + synchronized (getLock()) { + return new Iter<E,Iterator<E>>(super.iterator()); + } + } + + /** + * Returns an iterator over the elements in this list. + * The returned iterator will support {@linkplain ListIterator#remove() element removal}, + * {@linkplain ListIterator#add(Object) addition} or {@linkplain ListIterator#set(Object) + * modification} only if the {@link #checkWritePermission()} method does not throw exception. + */ + @Override + public ListIterator<E> listIterator() { + synchronized (getLock()) { + return new ListIter<E>(super.listIterator()); } } - // Note: providing a synchronized iterator is a little bit of paranoia because the ArrayList - // implementation inherits the default AbstractList implementation, which delegate its work - // to the public List methods. All the later are already synchronized. We do not override - // ListIterator for this reason and because it is less used. + /** + * Returns an iterator over the elements in this list, starting at the given index. + * The returned iterator will support {@linkplain ListIterator#remove() element removal}, + * {@linkplain ListIterator#add(Object) addition} or {@linkplain ListIterator#set(Object) + * modification} only if the {@link #checkWritePermission()} method does not throw exception. + */ + @Override + public ListIterator<E> listIterator(final int index) { + synchronized (getLock()) { + return new ListIter<E>(super.listIterator(index)); + } + } /** * Returns the number of elements in this list. Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashMap.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashMap.java?rev=1398219&r1=1398218&r2=1398219&view=diff ============================================================================== --- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashMap.java (original) +++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashMap.java Mon Oct 15 08:51:37 2012 @@ -17,9 +17,13 @@ package org.apache.sis.util.collection; import java.util.Map; +import java.util.Set; +import java.util.Iterator; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import net.jcip.annotations.ThreadSafe; +import org.apache.sis.util.Decorator; import org.apache.sis.util.resources.Errors; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; @@ -48,9 +52,6 @@ import static org.apache.sis.util.Argume * {@note The above is the reason why the name of this class emphases the <cite>checked</cite> * aspect rather than the <cite>synchronized</cite> aspect of the map.} * - * @todo Current implementation do not synchronize the {@linkplain #entrySet entry set}, - * {@linkplain #keySet key set} and {@linkplain #values values} collection. - * * @param <K> The type of keys in the map. * @param <V> The type of values in the map. * @@ -257,6 +258,48 @@ public class CheckedHashMap<K,V> extends } /** + * Returns a view of the keys in the map. + * The returned set will support {@linkplain Set#remove(Object) element removal} + * only if the {@link #checkWritePermission()} method does not throw exception. + * + * @return A synchronized view of the keys in the map. + */ + @Override + public Set<K> keySet() { + synchronized (getLock()) { + return new SyncSet<K>(super.keySet()); + } + } + + /** + * Returns a view of the values in the map. + * The returned collection will support {@linkplain Collection#remove(Object) element removal} + * only if the {@link #checkWritePermission()} method does not throw exception. + * + * @return A synchronized view of the values in the map. + */ + @Override + public Collection<V> values() { + synchronized (getLock()) { + return new Sync<V>(super.values()); + } + } + + /** + * Returns a view of the entries in the map. + * The returned set will support {@linkplain Set#remove(Object) element removal} + * only if the {@link #checkWritePermission()} method does not throw exception. + * + * @return A synchronized view of the keys in the map. + */ + @Override + public Set<Map.Entry<K,V>> entrySet() { + synchronized (getLock()) { + return new SyncSet<Map.Entry<K,V>>(super.entrySet()); + } + } + + /** * Returns a string representation of this map. */ @Override @@ -298,4 +341,69 @@ public class CheckedHashMap<K,V> extends return (CheckedHashMap<K,V>) super.clone(); } } + + /** + * A synchronized iterator with a check for write permission prior element removal. + */ + @ThreadSafe + @Decorator(Iterator.class) + private final class Iter<E> implements Iterator<E> { + final Iterator<E> iterator; + Iter(final Iterator<E> iterator) {this.iterator = iterator;} + @Override public boolean hasNext() {synchronized (getLock()) {return iterator.hasNext();}} + @Override public E next() {synchronized (getLock()) {return iterator.next();}} + @Override public void remove() {synchronized (getLock()) {checkWritePermission(); iterator.remove();}} + } + + /** + * A collection or a set synchronized on the enclosing map {@linkplain #getLock() lock}. + * This is used directly for wrapping {@link Map#values()}, or indirectly for wrapping + * {@link Map#keySet()} or {@link Map#entrySet()} views. + */ + @ThreadSafe + @Decorator(Collection.class) + private class Sync<E> implements Collection<E> { + /** + * The {@link Map#keySet()}, {@link Map#values()} or {@link Map#entrySet()} view. + */ + private final Collection<E> view; + + /** + * Create a new synchronized wrapper for the given view. + */ + Sync(final Collection<E> view) { + this.view = view; + } + + @Override public final void clear() {synchronized (getLock()) { view.clear ( );}} + @Override public final int size() {synchronized (getLock()) { return view.size ( );}} + @Override public final boolean isEmpty() {synchronized (getLock()) { return view.isEmpty ( );}} + @Override public final boolean contains(Object o) {synchronized (getLock()) { return view.contains (o);}} + @Override public final boolean containsAll(Collection<?> c) {synchronized (getLock()) { return view.containsAll(c);}} + @Override public final boolean add(E e) {synchronized (getLock()) {checkWritePermission(); return view.add (e);}} + @Override public final boolean addAll(Collection<? extends E> c) {synchronized (getLock()) {checkWritePermission(); return view.addAll (c);}} + @Override public final boolean remove(Object o) {synchronized (getLock()) {checkWritePermission(); return view.remove (o);}} + @Override public final boolean removeAll(Collection<?> c) {synchronized (getLock()) {checkWritePermission(); return view.removeAll (c);}} + @Override public final boolean retainAll(Collection<?> c) {synchronized (getLock()) {checkWritePermission(); return view.retainAll (c);}} + @Override public final Object[] toArray() {synchronized (getLock()) { return view.toArray ( );}} + @Override public final <T> T[] toArray(T[] a) {synchronized (getLock()) { return view.toArray (a);}} + @Override public final String toString() {synchronized (getLock()) { return view.toString ( );}} + @Override public final boolean equals(Object o) {synchronized (getLock()) { return view.equals (o);}} + @Override public final int hashCode() {synchronized (getLock()) { return view.hashCode ( );}} + @Override public final Iterator<E> iterator() {synchronized (getLock()) {return new Iter<E>(view.iterator());}} + } + + /** + * A set synchronized on the enclosing map {@linkplain #getLock() lock}. + * This is used for wrapping {@link Map#keySet()} or {@link Map#entrySet()} views. + */ + @Decorator(Set.class) + private final class SyncSet<E> extends Sync<E> implements Set<E> { + /** + * Create a new synchronized wrapper for the given view. + */ + SyncSet(final Set<E> set) { + super(set); + } + } } Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashSet.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashSet.java?rev=1398219&r1=1398218&r2=1398219&view=diff ============================================================================== --- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashSet.java (original) +++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/collection/CheckedHashSet.java Mon Oct 15 08:51:37 2012 @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import net.jcip.annotations.ThreadSafe; +import org.apache.sis.util.Decorator; import org.apache.sis.util.resources.Errors; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; @@ -166,13 +167,27 @@ public class CheckedHashSet<E> extends L } /** + * A synchronized iterator with a check for write permission prior element removal. + */ + @ThreadSafe + @Decorator(Iterator.class) + private final class Iter<E> implements Iterator<E> { + final Iterator<E> iterator; + Iter(final Iterator<E> iterator) {this.iterator = iterator;} + @Override public boolean hasNext() {synchronized (getLock()) {return iterator.hasNext();}} + @Override public E next() {synchronized (getLock()) {return iterator.next();}} + @Override public void remove() {synchronized (getLock()) {checkWritePermission(); iterator.remove();}} + } + + /** * Returns an iterator over the elements in this set. + * The returned iterator will support {@linkplain Iterator#remove() element removal} + * only if the {@link #checkWritePermission()} method does not throw exception. */ @Override public Iterator<E> iterator() { - final Object lock = getLock(); - synchronized (lock) { - return new SynchronizedIterator<E>(super.iterator(), lock); + synchronized (getLock()) { + return new Iter<E>(super.iterator()); } }