diff options
author | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2010-01-13 23:42:33 +0000 |
---|---|---|
committer | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2010-01-13 23:42:33 +0000 |
commit | 34fe81a8a91aeb63f6316211ac9212899ec14116 (patch) | |
tree | d386b071a657b01e37f3e3450e0dcc8f38392db3 | |
parent | 1e828fdbf04402dc53e897f6a7201bad00388b70 (diff) | |
download | scala-34fe81a8a91aeb63f6316211ac9212899ec14116.tar.gz scala-34fe81a8a91aeb63f6316211ac9212899ec14116.tar.bz2 scala-34fe81a8a91aeb63f6316211ac9212899ec14116.zip |
Added ConcurrentMap and Properties conversion c...
Added ConcurrentMap and Properties conversion classes and test.
-rw-r--r-- | src/library/scala/collection/JavaConversions.scala | 95 | ||||
-rw-r--r-- | test/files/run/map_java_conversions.scala | 60 |
2 files changed, 153 insertions, 2 deletions
diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala index 15005f71ba..7d05227336 100644 --- a/src/library/scala/collection/JavaConversions.scala +++ b/src/library/scala/collection/JavaConversions.scala @@ -53,6 +53,7 @@ package scala.collection */ object JavaConversions { import java.{ lang => jl, util => ju } + import java.util.{ concurrent => juc } import scala.collection.{ generic, immutable, mutable, Traversable } import scala.reflect.ClassManifest @@ -304,7 +305,15 @@ object JavaConversions { */ implicit def asMap[A, B](m : ju.Map[A, B]) = m match { case MutableMapWrapper(wrapped) => wrapped - case _ =>new JMapWrapper(m) + case _ => new JMapWrapper(m) + } + + implicit def asConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]) = m match { + case _ => new JConcurrentMapWrapper(m) + } + + implicit def asMap(p: ju.Properties): mutable.Map[String, String] = p match { + case _ => new JPropertiesWrapper(p) } // Private implementations ... @@ -462,7 +471,9 @@ object JavaConversions { } } - case class JMapWrapper[A, B](underlying : ju.Map[A, B]) extends mutable.Map[A, B] with mutable.MapLike[A, B, JMapWrapper[A, B]] { + abstract class JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]] + (underlying: ju.Map[A, B]) + extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] { override def size = underlying.size def get(k : A) = { @@ -498,6 +509,86 @@ object JavaConversions { override def clear = underlying.clear + override def empty: Repr = null.asInstanceOf[Repr] + } + + case class JMapWrapper[A, B](underlying : ju.Map[A, B]) + extends JMapWrapperLike[A, B, JMapWrapper[A, B]](underlying) { override def empty = JMapWrapper(new ju.HashMap[A, B]) } + + case class JConcurrentMapWrapper[A, B](underlying: juc.ConcurrentMap[A, B]) + extends JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]](underlying) { + override def get(k: A) = { + val v = underlying.get(k) + if (v != null) Some(v) + else None + } + + override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B]) + + def putIfAbsent(k: A, v: B): Option[B] = { + val r = underlying.putIfAbsent(k, v) + if (r != null) Some(r) else None + } + + def remove(k: A, v: B): Boolean = underlying.remove(k, v) + + def replace(k: A, v: B): Option[B] = { + val prev = underlying.replace(k, v) + if (prev != null) Some(prev) else None + } + + def replace(k: A, oldvalue: B, newvalue: B): Boolean = underlying.replace(k, oldvalue, newvalue) + + } + + case class JPropertiesWrapper(underlying: ju.Properties) + extends mutable.Map[String, String] with mutable.MapLike[String, String, JPropertiesWrapper] { + override def size = underlying.size + + def get(k : String) = { + val v = underlying.get(k) + if (v != null) + Some(v.asInstanceOf[String]) + else + None + } + + def +=(kv: (String, String)): this.type = { underlying.put(kv._1, kv._2); this } + def -=(key: String): this.type = { underlying.remove(key); this } + + override def put(k : String, v : String): Option[String] = { + val r = underlying.put(k, v) + if (r != null) Some(r.asInstanceOf[String]) else None + } + + override def update(k : String, v : String) { underlying.put(k, v) } + + override def remove(k : String): Option[String] = { + val r = underlying.remove(k) + if (r != null) Some(r.asInstanceOf[String]) else None + } + + def iterator = new Iterator[(String, String)] { + val ui = underlying.entrySet.iterator + def hasNext = ui.hasNext + def next = { val e = ui.next ; (e.getKey.asInstanceOf[String], e.getValue.asInstanceOf[String]) } + } + + override def clear = underlying.clear + + override def empty = JPropertiesWrapper(new ju.Properties) + + def getProperty(key: String) = underlying.getProperty(key) + + def getProperty(key: String, defaultValue: String) = underlying.getProperty(key, defaultValue) + + def setProperty(key: String, value: String) = underlying.setProperty(key, value) + } + } + + + + diff --git a/test/files/run/map_java_conversions.scala b/test/files/run/map_java_conversions.scala new file mode 100644 index 0000000000..4f9f8a915a --- /dev/null +++ b/test/files/run/map_java_conversions.scala @@ -0,0 +1,60 @@ + + + + + +object Test { + + def main(args: Array[String]) { + import collection.JavaConversions._ + + test(new java.util.HashMap[String, String]) + test(new java.util.Properties) + testConcMap + } + + def testConcMap { + import collection.JavaConversions._ + + val concMap = new java.util.concurrent.ConcurrentHashMap[String, String] + + test(concMap) + val cmap = asConcurrentMap(concMap) + cmap.putIfAbsent("absentKey", "absentValue") + cmap.put("somekey", "somevalue") + assert(cmap.remove("somekey", "somevalue") == true) + assert(cmap.replace("absentKey", "newAbsentValue") == Some("absentValue")) + assert(cmap.replace("absentKey", "newAbsentValue", ".......") == true) + } + + def test(m: collection.mutable.Map[String, String]) { + m.clear + assert(m.size == 0) + + m.put("key", "value") + assert(m.size == 1) + + assert(m.put("key", "anotherValue") == Some("value")) + assert(m.put("key2", "value2") == None) + assert(m.size == 2) + + m += (("key3", "value3")) + assert(m.size == 3) + + m -= "key2" + assert(m.size == 2) + assert(m.nonEmpty) + assert(m.remove("key") == Some("anotherValue")) + + m.clear + for (i <- 0 until 10) m += (("key" + i, "value" + i)) + for ((k, v) <- m) assert(k.startsWith("key")) + } + +} + + + + + + |