You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2010/07/17 14:15:21 UTC

svn commit: r965065 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/util/CaseInsensitiveMap.java test/java/org/apache/camel/util/CaseInsensitiveMapTest.java

Author: davsclaus
Date: Sat Jul 17 12:15:20 2010
New Revision: 965065

URL: http://svn.apache.org/viewvc?rev=965065&view=rev
Log:
CAMEL-2958: CaseInsensitveMap is more thread safe when defensive copying during routing.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java?rev=965065&r1=965064&r2=965065&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java Sat Jul 17 12:15:20 2010
@@ -29,6 +29,9 @@ import java.util.Set;
  * <p/>
  * When copying from this map to a regular Map such as {@link java.util.HashMap} then the original keys are
  * copied over and you get the old behavior back using a regular Map with case sensitive keys.
+ * <p/>
+ * This map is <b>not</b> designed to be thread safe as concurrent access to it is not supposed to be performed
+ * by the Camel routing engine.
  *
  * @version $Revision$
  */
@@ -73,7 +76,7 @@ public class CaseInsensitiveMap extends 
     }
 
     @Override
-    public Object put(String key, Object value) {
+    public synchronized Object put(String key, Object value) {
         // invalidate views as we mutate
         entrySetView = null;
         String s = key.toLowerCase();
@@ -83,13 +86,19 @@ public class CaseInsensitiveMap extends 
 
     @Override
     public void putAll(Map<? extends String, ?> map) {
-        for (Map.Entry<? extends String, ?> entry : map.entrySet()) {
-            put(entry.getKey(), entry.getValue());
+        if (map != null && !map.isEmpty()) {
+            for (Map.Entry<? extends String, ?> entry : map.entrySet()) {
+                put(entry.getKey(), entry.getValue());
+            }
         }
     }
 
     @Override
-    public Object remove(Object key) {
+    public synchronized Object remove(Object key) {
+        if (key == null) {
+            return null;
+        }
+
         // invalidate views as we mutate
         entrySetView = null;
         String s = key.toString().toLowerCase();
@@ -98,7 +107,7 @@ public class CaseInsensitiveMap extends 
     }
 
     @Override
-    public void clear() {
+    public synchronized void clear() {
         // invalidate views as we mutate
         entrySetView = null;
         originalKeys.clear();
@@ -107,12 +116,16 @@ public class CaseInsensitiveMap extends 
 
     @Override
     public boolean containsKey(Object key) {
+        if (key == null) {
+            return false;
+        }
+
         String s = key.toString().toLowerCase();
         return super.containsKey(s);
     }
 
     @Override
-    public Set<Map.Entry<String, Object>> entrySet() {
+    public synchronized Set<Map.Entry<String, Object>> entrySet() {
         if (entrySetView == null) {
             // build the key set using the original keys so we retain their case
             // when for example we copy values to another map

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java?rev=965065&r1=965064&r2=965065&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java Sat Jul 17 12:15:20 2010
@@ -141,6 +141,37 @@ public class CaseInsensitiveMapTest exte
         Map<String, Object> map = new CaseInsensitiveMap();
         assertNull(map.get("foo"));
 
+        Map<String, Object> other = new CaseInsensitiveMap();
+        other.put("Foo", "cheese");
+        other.put("bar", 123);
+
+        map.putAll(other);
+
+        assertEquals("cheese", map.get("FOO"));
+        assertEquals("cheese", map.get("foo"));
+        assertEquals("cheese", map.get("Foo"));
+
+        assertEquals(123, map.get("BAR"));
+        assertEquals(123, map.get("bar"));
+        assertEquals(123, map.get("BaR"));
+
+        // key case should be preserved
+        Map<String, Object> keys = new HashMap<String, Object>();
+        keys.putAll(map);
+
+        assertEquals("cheese", keys.get("Foo"));
+        assertNull(keys.get("foo"));
+        assertNull(keys.get("FOO"));
+
+        assertEquals(123, keys.get("bar"));
+        assertNull(keys.get("Bar"));
+        assertNull(keys.get("BAR"));
+    }
+
+    public void testPutAllOther() {
+        Map<String, Object> map = new CaseInsensitiveMap();
+        assertNull(map.get("foo"));
+
         Map<String, Object> other = new HashMap<String, Object>();
         other.put("Foo", "cheese");
         other.put("bar", 123);
@@ -156,6 +187,20 @@ public class CaseInsensitiveMapTest exte
         assertEquals(123, map.get("BaR"));
     }
 
+    public void testPutAllEmpty() {
+        Map<String, Object> map = new CaseInsensitiveMap();
+        map.put("foo", "cheese");
+
+        Map<String, Object> other = new HashMap<String, Object>();
+        map.putAll(other);
+
+        assertEquals("cheese", map.get("FOO"));
+        assertEquals("cheese", map.get("foo"));
+        assertEquals("cheese", map.get("Foo"));
+
+        assertEquals(1, map.size());
+    }
+
     public void testConstructFromOther() {
         Map<String, Object> other = new HashMap<String, Object>();
         other.put("Foo", "cheese");