1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.collection
package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import WrapAsScala._
import WrapAsJava._
/** Don't put the implementations in the same scope as the implicits
* which utilize them, or they will stow away into every scope which
* extends one of those implementations. See SI-5580.
*/
private[collection] trait Wrappers {
trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] {
val underlying: Iterable[A]
def size = underlying.size
override def iterator = IteratorWrapper(underlying.iterator)
override def isEmpty = underlying.isEmpty
}
case class IteratorWrapper[A](underlying: Iterator[A]) extends ju.Iterator[A] with ju.Enumeration[A] {
def hasNext = underlying.hasNext
def next() = underlying.next
def hasMoreElements = underlying.hasNext
def nextElement() = underlying.next
def remove() = throw new UnsupportedOperationException
}
class ToIteratorWrapper[A](underlying : Iterator[A]) {
def asJava = new IteratorWrapper(underlying)
}
case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] {
def hasNext = underlying.hasNext
def next() = underlying.next
}
case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] {
def hasNext = underlying.hasMoreElements
def next() = underlying.nextElement
}
case class IterableWrapper[A](underlying: Iterable[A]) extends ju.AbstractCollection[A] with IterableWrapperTrait[A] { }
case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends AbstractIterable[A] with Iterable[A] {
def iterator = underlying.iterator
def newBuilder[B] = new mutable.ArrayBuffer[B]
}
case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends AbstractIterable[A] with Iterable[A] {
def iterator = underlying.iterator
override def size = underlying.size
override def isEmpty = underlying.isEmpty
def newBuilder[B] = new mutable.ArrayBuffer[B]
}
case class SeqWrapper[A](underlying: Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
def get(i: Int) = underlying(i)
}
case class MutableSeqWrapper[A](underlying: mutable.Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
def get(i: Int) = underlying(i)
override def set(i: Int, elem: A) = {
val p = underlying(i)
underlying(i) = elem
p
}
}
case class MutableBufferWrapper[A](underlying: mutable.Buffer[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
def get(i: Int) = underlying(i)
override def set(i: Int, elem: A) = { val p = underlying(i); underlying(i) = elem; p }
override def add(elem: A) = { underlying append elem; true }
override def remove(i: Int) = underlying remove i
}
case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.AbstractBuffer[A] with mutable.Buffer[A] {
def length = underlying.size
override def isEmpty = underlying.isEmpty
override def iterator: Iterator[A] = underlying.iterator
def apply(i: Int) = underlying.get(i)
def update(i: Int, elem: A) = underlying.set(i, elem)
def +=:(elem: A) = { underlying.subList(0, 0) add elem; this }
def +=(elem: A): this.type = { underlying add elem; this }
def insertAll(i: Int, elems: Traversable[A]) = {
val ins = underlying.subList(0, i)
elems.seq.foreach(ins.add(_))
}
def remove(i: Int) = underlying.remove(i)
def clear() = underlying.clear()
def result = this
}
class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] {
self =>
def size = underlying.size
def iterator = new ju.Iterator[A] {
val ui = underlying.iterator
var prev: Option[A] = None
def hasNext = ui.hasNext
def next = { val e = ui.next; prev = Some(e); e }
def remove = prev match {
case Some(e) =>
underlying match {
case ms: mutable.Set[a] =>
ms remove e
prev = None
case _ =>
throw new UnsupportedOperationException("remove")
}
case _ =>
throw new IllegalStateException("next must be called at least once before remove")
}
}
}
case class MutableSetWrapper[A](underlying: mutable.Set[A]) extends SetWrapper[A](underlying) {
override def add(elem: A) = {
val sz = underlying.size
underlying += elem
sz < underlying.size
}
override def remove(elem: AnyRef) =
try underlying remove elem.asInstanceOf[A]
catch { case ex: ClassCastException => false }
override def clear() = underlying.clear()
}
case class JSetWrapper[A](underlying: ju.Set[A]) extends mutable.AbstractSet[A] with mutable.Set[A] with mutable.SetLike[A, JSetWrapper[A]] {
override def size = underlying.size
def iterator = underlying.iterator
def contains(elem: A): Boolean = underlying.contains(elem)
def +=(elem: A): this.type = { underlying add elem; this }
def -=(elem: A): this.type = { underlying remove elem; this }
override def add(elem: A): Boolean = underlying add elem
override def remove(elem: A): Boolean = underlying remove elem
override def clear() = underlying.clear()
override def empty = JSetWrapper(new ju.HashSet[A])
}
class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] { self =>
override def size = underlying.size
override def get(key: AnyRef): B = try {
underlying get key.asInstanceOf[A] match {
case None => null.asInstanceOf[B]
case Some(v) => v
}
} catch {
case ex: ClassCastException => null.asInstanceOf[B]
}
override def entrySet: ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] {
def size = self.size
def iterator = new ju.Iterator[ju.Map.Entry[A, B]] {
val ui = underlying.iterator
var prev : Option[A] = None
def hasNext = ui.hasNext
def improve(hc: Int) = {
var i = hc * 0x9e3775cd
i = java.lang.Integer.reverseBytes(i)
i * 0x9e3775c
}
def next() = {
val (k, v) = ui.next
prev = Some(k)
new ju.Map.Entry[A, B] {
def getKey = k
def getValue = v
def setValue(v1 : B) = self.put(k, v1)
override def hashCode = improve(k.hashCode) + (improve(v.hashCode) << 16)
override def equals(other: Any) = other match {
case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue
case _ => false
}
}
}
def remove() {
prev match {
case Some(k) =>
underlying match {
case mm: mutable.Map[a, _] =>
mm remove k
prev = None
case _ =>
throw new UnsupportedOperationException("remove")
}
case _ =>
throw new IllegalStateException("next must be called at least once before remove")
}
}
}
}
}
case class MutableMapWrapper[A, B](underlying: mutable.Map[A, B]) extends MapWrapper[A, B](underlying) {
override def put(k: A, v: B) = underlying.put(k, v) match {
case Some(v1) => v1
case None => null.asInstanceOf[B]
}
override def remove(k: AnyRef): B = try {
underlying remove k.asInstanceOf[A] match {
case None => null.asInstanceOf[B]
case Some(v) => v
}
} catch {
case ex: ClassCastException => null.asInstanceOf[B]
}
override def clear() = underlying.clear()
}
trait JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]] extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] {
def underlying: ju.Map[A, B]
override def size = underlying.size
def get(k: A) = {
val v = underlying get k
if (v != null)
Some(v)
else if (underlying containsKey k)
Some(null.asInstanceOf[B])
else
None
}
def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
def -=(key: A): this.type = { underlying remove key; this }
override def put(k: A, v: B): Option[B] = {
val r = underlying.put(k, v)
if (r != null) Some(r) else None
}
override def update(k: A, v: B) { underlying.put(k, v) }
override def remove(k: A): Option[B] = {
val r = underlying remove k
if (r != null) Some(r) else None
}
def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] {
val ui = underlying.entrySet.iterator
def hasNext = ui.hasNext
def next() = { val e = ui.next(); (e.getKey, e.getValue) }
}
override def clear() = underlying.clear()
override def empty: Repr = null.asInstanceOf[Repr]
}
case class JMapWrapper[A, B](val underlying : ju.Map[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JMapWrapper[A, B]] {
override def empty = JMapWrapper(new ju.HashMap[A, B])
}
class ConcurrentMapDeprecatedWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
case Some(v) => v
case None => null.asInstanceOf[B]
}
def remove(k: AnyRef, v: AnyRef) = try {
underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B])
} catch {
case ex: ClassCastException =>
false
}
def replace(k: A, v: B): B = underlying.replace(k, v) match {
case Some(v) => v
case None => null.asInstanceOf[B]
}
def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
}
class ConcurrentMapWrapper[A, B](override val underlying: concurrent.Map[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
case Some(v) => v
case None => null.asInstanceOf[B]
}
def remove(k: AnyRef, v: AnyRef) = try {
underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B])
} catch {
case ex: ClassCastException =>
false
}
def replace(k: A, v: B): B = underlying.replace(k, v) match {
case Some(v) => v
case None => null.asInstanceOf[B]
}
def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
}
case class JConcurrentMapDeprecatedWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapDeprecatedWrapper[A, B]] with mutable.ConcurrentMap[A, B] {
override def get(k: A) = {
val v = underlying get k
if (v != null) Some(v)
else None
}
override def empty = new JConcurrentMapDeprecatedWrapper(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 JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with concurrent.Map[A, B] {
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 DictionaryWrapper[A, B](underlying: mutable.Map[A, B]) extends ju.Dictionary[A, B] {
def size: Int = underlying.size
def isEmpty: Boolean = underlying.isEmpty
def keys: ju.Enumeration[A] = asJavaEnumeration(underlying.keysIterator)
def elements: ju.Enumeration[B] = asJavaEnumeration(underlying.valuesIterator)
def get(key: AnyRef) = try {
underlying get key.asInstanceOf[A] match {
case None => null.asInstanceOf[B]
case Some(v) => v
}
} catch {
case ex: ClassCastException => null.asInstanceOf[B]
}
def put(key: A, value: B): B = underlying.put(key, value) match {
case Some(v) => v
case None => null.asInstanceOf[B]
}
override def remove(key: AnyRef) = try {
underlying remove key.asInstanceOf[A] match {
case None => null.asInstanceOf[B]
case Some(v) => v
}
} catch {
case ex: ClassCastException => null.asInstanceOf[B]
}
}
case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B]) extends mutable.AbstractMap[A, B] with mutable.Map[A, B] {
override def size: Int = underlying.size
def get(k: A) = {
val v = underlying get k
if (v != null) Some(v) else None
}
def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
def -=(key: A): this.type = { underlying remove key; this }
override def put(k: A, v: B): Option[B] = {
val r = underlying.put(k, v)
if (r != null) Some(r) else None
}
override def update(k: A, v: B) { underlying.put(k, v) }
override def remove(k: A): Option[B] = {
val r = underlying remove k
if (r != null) Some(r) else None
}
def iterator = enumerationAsScalaIterator(underlying.keys) map (k => (k, underlying get k))
override def clear() = underlying.clear()
}
case class JPropertiesWrapper(underlying: ju.Properties) extends mutable.AbstractMap[String, String]
with 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: Iterator[(String, String)] = new AbstractIterator[(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)
}
}
object Wrappers extends Wrappers
|