From 7da59277e59a7a6fdf559e422aa07bb89af97404 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Mon, 15 Jul 2013 08:54:44 -0600 Subject: [PATCH] This solves a class cast exception from a call to .values() from an UnmodifiableMap. It also solves an issue where you can modify an unmodifiable collection through the Iterator or ListIterator (depending on the structure type). --- classpath/java/util/Collections.java | 138 ++++++++++++++++++++------- 1 file changed, 105 insertions(+), 33 deletions(-) diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index 788e083f5e..4a950e3b11 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -168,7 +168,7 @@ public class Collections { } public Iterator iterator() { - return new SynchronizedIterator(lock, collection.iterator()); + return new SynchronizedIterator(lock, collection.iterator()); } public boolean containsAll(Collection c) { @@ -355,7 +355,7 @@ public class Collections { } public Iterator iterator() { - return inner.iterator(); + return new UnmodifiableIterator(inner.iterator()); } public int indexOf(Object value) { @@ -371,11 +371,11 @@ public class Collections { } public ListIterator listIterator(int index) { - return inner.listIterator(index); + return new UnmodifiableListIterator(inner.listIterator(index)); } public ListIterator listIterator() { - return inner.listIterator(); + return new UnmodifiableListIterator(inner.listIterator()); } public int size() { @@ -471,64 +471,136 @@ public class Collections { } public Collection values() { - return unmodifiableSet((Set)inner.values()); + return unmodifiableCollection(inner.values()); } } - - static class UnmodifiableSet implements Set { - private Set inner; - - UnmodifiableSet(Set inner) { + + static class UnmodifiableIterator implements Iterator { + private static final String EXCEPTION_MESSAGE = "not supported in unmodifiable collection"; + + private final Iterator inner; + + UnmodifiableIterator(Iterator inner) { this.inner = inner; } - - public boolean add(T element) { - throw new UnsupportedOperationException("not supported"); + + @Override + public T next() { + return inner.next(); } - public boolean addAll(Collection collection) { - throw new UnsupportedOperationException("not supported"); + @Override + public boolean hasNext() { + return inner.hasNext(); } - public void clear() { - throw new UnsupportedOperationException("not supported"); + @Override + public void remove() { + throw new UnsupportedOperationException(EXCEPTION_MESSAGE); + } + } + + + static class UnmodifiableListIterator extends UnmodifiableIterator + implements ListIterator { + private final ListIterator innerListIterator; + + UnmodifiableListIterator(ListIterator listIterator) { + super(listIterator); + + this.innerListIterator = listIterator; } - public boolean contains(Object element) { - return inner.contains(element); + @Override + public boolean hasPrevious() { + return innerListIterator.hasPrevious(); } - public boolean isEmpty() { - return inner.isEmpty(); + @Override + public T previous() { + return innerListIterator.previous(); } - + } + + static class UnmodifiableCollection implements Collection { + private static final String EXCEPTION_MESSAGE = "not supported in unmodifiable collection"; + + private final Collection inner; + + UnmodifiableCollection(Collection inner) { + this.inner = inner; + } + + @Override public Iterator iterator() { - return inner.iterator(); - } - - public boolean remove(Object element) { - throw new UnsupportedOperationException("not supported"); + return new UnmodifiableIterator(inner.iterator()); } + @Override public int size() { return inner.size(); } - public Object[] toArray() { - return toArray(new Object[size()]); + @Override + public boolean isEmpty() { + return inner.isEmpty(); } - public S[] toArray(S[] array) { - return inner.toArray(array); + @Override + public boolean contains(Object element) { + return inner.contains(element); } + @Override public boolean containsAll(Collection c) { return inner.containsAll(c); } + @Override + public boolean add(T element) { + throw new UnsupportedOperationException(EXCEPTION_MESSAGE); + } + + @Override + public boolean addAll(Collection collection) { + throw new UnsupportedOperationException(EXCEPTION_MESSAGE); + } + + @Override + public boolean remove(Object element) { + throw new UnsupportedOperationException(EXCEPTION_MESSAGE); + } + + @Override public boolean removeAll(Collection c) { - throw new UnsupportedOperationException("not supported"); - } + throw new UnsupportedOperationException(EXCEPTION_MESSAGE); + } + + @Override + public Object[] toArray() { + return inner.toArray(); + } + + @Override + public S[] toArray(S[] array) { + return inner.toArray(array); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(EXCEPTION_MESSAGE); + } + } + + public static UnmodifiableCollection unmodifiableCollection(Collection collection) { + return new UnmodifiableCollection(collection); + } + + static class UnmodifiableSet extends UnmodifiableCollection + implements Set { + UnmodifiableSet(Set inner) { + super(inner); + } } public static Set unmodifiableSet(Set hs) {