You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2015/03/19 16:08:26 UTC
tapestry-5 git commit: TAP5-2452: prevent modifications to
CaseInsensitiveMap's key set
Repository: tapestry-5
Updated Branches:
refs/heads/master 65b9671c2 -> 0a1993457
TAP5-2452: prevent modifications to CaseInsensitiveMap's key set
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/0a199345
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/0a199345
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/0a199345
Branch: refs/heads/master
Commit: 0a19934571247b7642fb6b0a6899e2c368b1d0b9
Parents: 65b9671
Author: Jochen Kemnade <jo...@eddyson.de>
Authored: Wed Feb 18 10:08:32 2015 +0100
Committer: Jochen Kemnade <jo...@eddyson.de>
Committed: Thu Mar 19 16:06:08 2015 +0100
----------------------------------------------------------------------
.../tapestry5/ioc/util/CaseInsensitiveMap.java | 73 +++++++++++++++++---
.../ioc/specs/CaseInsensitiveMapSpec.groovy | 23 ++++++
2 files changed, 87 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/0a199345/commons/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java b/commons/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
index f5aff7e..7862f9f 100644
--- a/commons/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
+++ b/commons/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
@@ -29,7 +29,8 @@ import java.util.*;
*/
public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Serializable
{
- private static final long serialVersionUID = 3362718337611953298L;
+
+ private static final long serialVersionUID = -3162531976817110908L;
private static final int NULL_HASH = Integer.MIN_VALUE;
@@ -91,9 +92,17 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
{
return value == this.value || (value != null && value.equals(this.value));
}
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("CIMEntry [key=").append(key).append(", value=").append(value).append("]");
+ return builder.toString();
+ }
+
}
- private class EntrySetIterator implements Iterator
+ private class EntrySetIterator implements Iterator<Entry<String, V>>
{
int expectedModCount = modCount;
@@ -108,7 +117,7 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
}
@Override
- public Object next()
+ public Entry<String, V> next()
{
check();
@@ -135,13 +144,17 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
{
if (expectedModCount != modCount) throw new ConcurrentModificationException();
}
+
+ @Override
+ public String toString() {
+ return "EntrySetIterator, current key: "+entries[current].key;
+ }
}
- @SuppressWarnings("unchecked")
- private class EntrySet extends AbstractSet
+ private class EntrySet extends AbstractSet<Entry<String, V>>
{
@Override
- public Iterator iterator()
+ public Iterator<Entry<String, V>> iterator()
{
return new EntrySetIterator();
}
@@ -163,6 +176,7 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
{
if (!(o instanceof Map.Entry)) return false;
+ @SuppressWarnings("rawtypes")
Map.Entry e = (Map.Entry) o;
Position position = select(e.getKey());
@@ -175,6 +189,7 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
{
if (!(o instanceof Map.Entry)) return false;
+ @SuppressWarnings("rawtypes")
Map.Entry e = (Map.Entry) o;
Position position = select(e.getKey());
@@ -352,7 +367,6 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
return size;
}
- @SuppressWarnings("unchecked")
@Override
public V put(String key, V value)
{
@@ -379,7 +393,6 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
return select(key).remove();
}
- @SuppressWarnings("unchecked")
@Override
public Set<Map.Entry<String, V>> entrySet()
{
@@ -388,6 +401,48 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
return entrySet;
}
+ @Override
+ public Set<String> keySet() {
+
+ AbstractSet<String> set = new AbstractSet<String>() {
+
+ @Override
+ public Iterator<String> iterator() {
+
+ final Iterator<java.util.Map.Entry<String, V>> entrySetIterator = entrySet().iterator();
+
+ return new Iterator<String>() {
+ @Override
+ public boolean hasNext() {
+ return entrySetIterator.hasNext();
+ }
+ @Override
+ public String next() {
+ String nextKey = entrySetIterator.next().getKey();
+ return nextKey;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Modifications to the key set are not allowed.");
+ }
+ };
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return containsKey(o);
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+ };
+
+ return Collections.unmodifiableSet(set);
+ }
+
private Position select(Object key)
{
if (key == null || key instanceof String)
@@ -416,7 +471,7 @@ public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Ser
{
cursor = (low + high) >> 1;
- CIMEntry e = entries[cursor];
+ CIMEntry<V> e = entries[cursor];
if (e.hashCode < hashCode)
{
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/0a199345/tapestry-ioc/src/test/groovy/ioc/specs/CaseInsensitiveMapSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/CaseInsensitiveMapSpec.groovy b/tapestry-ioc/src/test/groovy/ioc/specs/CaseInsensitiveMapSpec.groovy
index c4e43f0..4813003 100644
--- a/tapestry-ioc/src/test/groovy/ioc/specs/CaseInsensitiveMapSpec.groovy
+++ b/tapestry-ioc/src/test/groovy/ioc/specs/CaseInsensitiveMapSpec.groovy
@@ -1,6 +1,8 @@
package ioc.specs
import org.apache.tapestry5.ioc.util.CaseInsensitiveMap
+
+import spock.lang.Issue;
import spock.lang.Specification
class CaseInsensitiveMapSpec extends Specification {
@@ -300,4 +302,25 @@ class CaseInsensitiveMapSpec extends Specification {
copy == map
}
+
+ @Issue('https://issues.apache.org/jira/browse/TAP5-2452')
+ def "Modifications to key set are not allowed"(){
+ setup:
+ def map = new CaseInsensitiveMap<String>()
+ map.put('1', '1')
+ map.put('2', '2')
+ map.put('3', '3')
+ def keysToRetain = ['3', '4', '5']
+ expect:
+ map.keySet().size() == 3
+ map.keySet() == ['1', '2', '3'] as Set
+ when:
+ map.keySet().retainAll(keysToRetain)
+ then:
+ thrown(UnsupportedOperationException)
+ when:
+ map.keySet().remove("Zaphod")
+ then:
+ thrown(UnsupportedOperationException)
+ }
}