diff --git a/kotlin-spark-api/2.4/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Conversions.kt b/kotlin-spark-api/2.4/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Conversions.kt
new file mode 100644
index 00000000..81cb1761
--- /dev/null
+++ b/kotlin-spark-api/2.4/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Conversions.kt
@@ -0,0 +1,139 @@
+@file:Suppress("NOTHING_TO_INLINE", "RemoveExplicitTypeArguments")
+
+package org.jetbrains.kotlinx.spark.api
+
+import scala.collection.JavaConversions
+import java.util.*
+import java.util.concurrent.ConcurrentMap
+import scala.collection.Iterable as ScalaIterable
+import scala.collection.Iterator as ScalaIterator
+import scala.collection.Map as ScalaMap
+import scala.collection.Seq as ScalaSeq
+import scala.collection.Set as ScalaSet
+import scala.collection.concurrent.Map as ScalaConcurrentMap
+import scala.collection.mutable.Buffer as ScalaMutableBuffer
+import scala.collection.mutable.Map as ScalaMutableMap
+import scala.collection.mutable.Seq as ScalaMutableSeq
+import scala.collection.mutable.Set as ScalaMutableSet
+
+/**
+ * @see JavaConversions.asScalaIterator for more information.
+ */
+fun Iterator.asScalaIterator(): ScalaIterator = JavaConversions.asScalaIterator(this)
+
+/**
+ * @see JavaConversions.enumerationAsScalaIterator for more information.
+ */
+fun Enumeration.asScalaIterator(): ScalaIterator = JavaConversions.enumerationAsScalaIterator(this)
+
+/**
+ * @see JavaConversions.iterableAsScalaIterable for more information.
+ */
+fun Iterable.asScalaIterable(): ScalaIterable = JavaConversions.iterableAsScalaIterable(this)
+
+/**
+ * @see JavaConversions.collectionAsScalaIterable for more information.
+ */
+fun Collection.asScalaIterable(): ScalaIterable = JavaConversions.collectionAsScalaIterable(this)
+
+/**
+ * @see JavaConversions.asScalaBuffer for more information.
+ */
+fun MutableList.asScalaMutableBuffer(): ScalaMutableBuffer = JavaConversions.asScalaBuffer(this)
+
+/**
+ * @see JavaConversions.asScalaSet for more information.
+ */
+fun MutableSet.asScalaMutableSet(): ScalaMutableSet = JavaConversions.asScalaSet(this)
+
+/**
+ * @see JavaConversions.mapAsScalaMap for more information.
+ */
+fun MutableMap.asScalaMutableMap(): ScalaMutableMap = JavaConversions.mapAsScalaMap(this)
+
+/**
+ * @see JavaConversions.dictionaryAsScalaMap for more information.
+ */
+fun Map.asScalaMap(): ScalaMap = JavaConversions.mapAsScalaMap(this)
+
+/**
+ * @see JavaConversions.mapAsScalaConcurrentMap for more information.
+ */
+fun ConcurrentMap.asScalaConcurrentMap(): ScalaConcurrentMap = JavaConversions.mapAsScalaConcurrentMap(this)
+
+/**
+ * @see JavaConversions.dictionaryAsScalaMap for more information.
+ */
+fun Dictionary.asScalaMap(): ScalaMutableMap = JavaConversions.dictionaryAsScalaMap(this)
+
+/**
+ * @see JavaConversions.propertiesAsScalaMap for more information.
+ */
+fun Properties.asScalaMap(): ScalaMutableMap = JavaConversions.propertiesAsScalaMap(this)
+
+
+/**
+ * @see JavaConversions.asJavaIterator for more information.
+ */
+fun ScalaIterator.asKotlinIterator(): Iterator = JavaConversions.asJavaIterator(this)
+
+/**
+ * @see JavaConversions.asJavaEnumeration for more information.
+ */
+fun ScalaIterator.asKotlinEnumeration(): Enumeration = JavaConversions.asJavaEnumeration(this)
+
+/**
+ * @see JavaConversions.asJavaIterable for more information.
+ */
+fun ScalaIterable.asKotlinIterable(): Iterable = JavaConversions.asJavaIterable(this)
+
+/**
+ * @see JavaConversions.asJavaCollection for more information.
+ */
+fun ScalaIterable.asKotlinCollection(): Collection = JavaConversions.asJavaCollection(this)
+
+/**
+ * @see JavaConversions.bufferAsJavaList for more information.
+ */
+fun ScalaMutableBuffer.asKotlinMutableList(): MutableList = JavaConversions.bufferAsJavaList(this)
+
+/**
+ * @see JavaConversions.mutableSeqAsJavaList for more information.
+ */
+fun ScalaMutableSeq.asKotlinMutableList(): MutableList = JavaConversions.mutableSeqAsJavaList(this)
+
+/**
+ * @see JavaConversions.seqAsJavaList for more information.
+ */
+fun ScalaSeq.asKotlinList(): List = JavaConversions.seqAsJavaList(this)
+
+/**
+ * @see JavaConversions.mutableSetAsJavaSet for more information.
+ */
+fun ScalaMutableSet.asKotlinMutableSet(): MutableSet = JavaConversions.mutableSetAsJavaSet(this)
+
+/**
+ * @see JavaConversions.setAsJavaSet for more information.
+ */
+fun ScalaSet.asKotlinSet(): Set = JavaConversions.setAsJavaSet(this)
+
+/**
+ * @see JavaConversions.mutableMapAsJavaMap for more information.
+ */
+fun ScalaMutableMap.asKotlinMutableMap(): MutableMap = JavaConversions.mutableMapAsJavaMap(this)
+
+/**
+ * @see JavaConversions.asJavaDictionary for more information.
+ */
+fun ScalaMutableMap.asKotlinDictionary(): Dictionary = JavaConversions.asJavaDictionary(this)
+
+/**
+ * @see JavaConversions.mapAsJavaMap for more information.
+ */
+fun ScalaMap.asKotlinMap(): Map = JavaConversions.mapAsJavaMap(this)
+
+/**
+ * @see JavaConversions.mapAsJavaConcurrentMap for more information.
+ */
+fun ScalaConcurrentMap.asKotlinConcurrentMap(): ConcurrentMap = JavaConversions.mapAsJavaConcurrentMap(this)
+
diff --git a/kotlin-spark-api/2.4/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt b/kotlin-spark-api/2.4/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt
index 0749bc59..36734d46 100644
--- a/kotlin-spark-api/2.4/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt
+++ b/kotlin-spark-api/2.4/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt
@@ -21,11 +21,16 @@ import ch.tutteli.atrium.api.fluent.en_GB.*
import ch.tutteli.atrium.domain.builders.migration.asExpect
import ch.tutteli.atrium.verbs.expect
import io.kotest.core.spec.style.ShouldSpec
+import io.kotest.matchers.shouldBe
+import scala.collection.Seq
import org.apache.spark.sql.Dataset
import java.io.Serializable
import java.sql.Date
import java.sql.Timestamp
import java.time.LocalDate
+import scala.collection.Iterator as ScalaIterator
+import scala.collection.Map as ScalaMap
+import scala.collection.mutable.Map as ScalaMutableMap
class ApiTest : ShouldSpec({
context("integration tests") {
@@ -159,6 +164,41 @@ class ApiTest : ShouldSpec({
expect(result).asExpect().contains.inOrder.only.values(3, 5, 7, 9, 11)
}
+ should("Handle JavaConversions in Kotlin") {
+ // Test the iterator conversion
+ val scalaIterator: ScalaIterator = listOf("test1", "test2").iterator().asScalaIterator()
+ scalaIterator.next() shouldBe "test1"
+
+ val kotlinIterator: Iterator = scalaIterator.asKotlinIterator()
+ kotlinIterator.next() shouldBe "test2"
+
+
+ val scalaMap: ScalaMap = mapOf(1 to "a", 2 to "b").asScalaMap()
+ scalaMap.get(1).get() shouldBe "a"
+ scalaMap.get(2).get() shouldBe "b"
+
+ val kotlinMap: Map = scalaMap.asKotlinMap()
+ kotlinMap[1] shouldBe "a"
+ kotlinMap[2] shouldBe "b"
+
+
+ val scalaMutableMap: ScalaMutableMap = mutableMapOf(1 to "a").asScalaMutableMap()
+ scalaMutableMap.get(1).get() shouldBe "a"
+
+ scalaMutableMap.put(2, "b")
+
+ val kotlinMutableMap: MutableMap = scalaMutableMap.asKotlinMutableMap()
+ kotlinMutableMap[1] shouldBe "a"
+ kotlinMutableMap[2] shouldBe "b"
+
+ val scalaSeq: Seq = listOf("a", "b").iterator().asScalaIterator().toSeq()
+ scalaSeq.take(1).toList().last() shouldBe "a"
+ scalaSeq.take(2).toList().last() shouldBe "b"
+
+ val kotlinList: List = scalaSeq.asKotlinList()
+ kotlinList.first() shouldBe "a"
+ kotlinList.last() shouldBe "b"
+ }
should("be able to serialize Date 2.4") { // uses knownDataTypes
val dataset: Dataset> = dsOf(Date.valueOf("2020-02-10") to 5)
dataset.show()
diff --git a/kotlin-spark-api/3.0/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Conversions.kt b/kotlin-spark-api/3.0/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Conversions.kt
new file mode 100644
index 00000000..00562001
--- /dev/null
+++ b/kotlin-spark-api/3.0/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Conversions.kt
@@ -0,0 +1,139 @@
+@file:Suppress("NOTHING_TO_INLINE", "RemoveExplicitTypeArguments")
+
+package org.jetbrains.kotlinx.spark.api
+
+import scala.collection.JavaConverters
+import java.util.*
+import java.util.concurrent.ConcurrentMap
+import scala.collection.Iterable as ScalaIterable
+import scala.collection.Iterator as ScalaIterator
+import scala.collection.Map as ScalaMap
+import scala.collection.Seq as ScalaSeq
+import scala.collection.Set as ScalaSet
+import scala.collection.concurrent.Map as ScalaConcurrentMap
+import scala.collection.mutable.Buffer as ScalaMutableBuffer
+import scala.collection.mutable.Map as ScalaMutableMap
+import scala.collection.mutable.Seq as ScalaMutableSeq
+import scala.collection.mutable.Set as ScalaMutableSet
+
+/**
+ * @see JavaConverters.asScalaIterator for more information.
+ */
+fun Iterator.asScalaIterator(): ScalaIterator = JavaConverters.asScalaIterator(this)
+
+/**
+ * @see JavaConverters.enumerationAsScalaIterator for more information.
+ */
+fun Enumeration.asScalaIterator(): ScalaIterator = JavaConverters.enumerationAsScalaIterator(this)
+
+/**
+ * @see JavaConverters.iterableAsScalaIterable for more information.
+ */
+fun Iterable.asScalaIterable(): ScalaIterable = JavaConverters.iterableAsScalaIterable(this)
+
+/**
+ * @see JavaConverters.collectionAsScalaIterable for more information.
+ */
+fun Collection.asScalaIterable(): ScalaIterable = JavaConverters.collectionAsScalaIterable(this)
+
+/**
+ * @see JavaConverters.asScalaBuffer for more information.
+ */
+fun MutableList.asScalaMutableBuffer(): ScalaMutableBuffer = JavaConverters.asScalaBuffer(this)
+
+/**
+ * @see JavaConverters.asScalaSet for more information.
+ */
+fun MutableSet.asScalaMutableSet(): ScalaMutableSet = JavaConverters.asScalaSet(this)
+
+/**
+ * @see JavaConverters.mapAsScalaMap for more information.
+ */
+fun MutableMap.asScalaMutableMap(): ScalaMutableMap = JavaConverters.mapAsScalaMap(this)
+
+/**
+ * @see JavaConverters.dictionaryAsScalaMap for more information.
+ */
+fun Map.asScalaMap(): ScalaMap = JavaConverters.mapAsScalaMap(this)
+
+/**
+ * @see JavaConverters.mapAsScalaConcurrentMap for more information.
+ */
+fun ConcurrentMap.asScalaConcurrentMap(): ScalaConcurrentMap = JavaConverters.mapAsScalaConcurrentMap(this)
+
+/**
+ * @see JavaConverters.dictionaryAsScalaMap for more information.
+ */
+fun Dictionary.asScalaMap(): ScalaMutableMap = JavaConverters.dictionaryAsScalaMap(this)
+
+/**
+ * @see JavaConverters.propertiesAsScalaMap for more information.
+ */
+fun Properties.asScalaMap(): ScalaMutableMap = JavaConverters.propertiesAsScalaMap(this)
+
+
+/**
+ * @see JavaConverters.asJavaIterator for more information.
+ */
+fun ScalaIterator.asKotlinIterator(): Iterator = JavaConverters.asJavaIterator(this)
+
+/**
+ * @see JavaConverters.asJavaEnumeration for more information.
+ */
+fun ScalaIterator.asKotlinEnumeration(): Enumeration = JavaConverters.asJavaEnumeration(this)
+
+/**
+ * @see JavaConverters.asJavaIterable for more information.
+ */
+fun ScalaIterable.asKotlinIterable(): Iterable = JavaConverters.asJavaIterable(this)
+
+/**
+ * @see JavaConverters.asJavaCollection for more information.
+ */
+fun ScalaIterable.asKotlinCollection(): Collection = JavaConverters.asJavaCollection(this)
+
+/**
+ * @see JavaConverters.bufferAsJavaList for more information.
+ */
+fun ScalaMutableBuffer.asKotlinMutableList(): MutableList = JavaConverters.bufferAsJavaList(this)
+
+/**
+ * @see JavaConverters.mutableSeqAsJavaList for more information.
+ */
+fun ScalaMutableSeq.asKotlinMutableList(): MutableList = JavaConverters.mutableSeqAsJavaList(this)
+
+/**
+ * @see JavaConverters.seqAsJavaList for more information.
+ */
+fun ScalaSeq.asKotlinList(): List = JavaConverters.seqAsJavaList(this)
+
+/**
+ * @see JavaConverters.mutableSetAsJavaSet for more information.
+ */
+fun ScalaMutableSet.asKotlinMutableSet(): MutableSet = JavaConverters.mutableSetAsJavaSet(this)
+
+/**
+ * @see JavaConverters.setAsJavaSet for more information.
+ */
+fun ScalaSet.asKotlinSet(): Set = JavaConverters.setAsJavaSet(this)
+
+/**
+ * @see JavaConverters.mutableMapAsJavaMap for more information.
+ */
+fun ScalaMutableMap.asKotlinMutableMap(): MutableMap = JavaConverters.mutableMapAsJavaMap(this)
+
+/**
+ * @see JavaConverters.asJavaDictionary for more information.
+ */
+fun ScalaMutableMap.asKotlinDictionary(): Dictionary = JavaConverters.asJavaDictionary(this)
+
+/**
+ * @see JavaConverters.mapAsJavaMap for more information.
+ */
+fun ScalaMap.asKotlinMap(): Map = JavaConverters.mapAsJavaMap(this)
+
+/**
+ * @see JavaConverters.mapAsJavaConcurrentMap for more information.
+ */
+fun ScalaConcurrentMap.asKotlinConcurrentMap(): ConcurrentMap = JavaConverters.mapAsJavaConcurrentMap(this)
+
diff --git a/kotlin-spark-api/3.0/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt b/kotlin-spark-api/3.0/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt
index fce75fb2..baaa6cf3 100644
--- a/kotlin-spark-api/3.0/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt
+++ b/kotlin-spark-api/3.0/src/test/kotlin/org/jetbrains/kotlinx/spark/api/ApiTest.kt
@@ -21,12 +21,17 @@ import ch.tutteli.atrium.api.fluent.en_GB.*
import ch.tutteli.atrium.domain.builders.migration.asExpect
import ch.tutteli.atrium.verbs.expect
import io.kotest.core.spec.style.ShouldSpec
+import io.kotest.matchers.shouldBe
+import scala.collection.Seq
import org.apache.spark.sql.Dataset
import java.io.Serializable
import java.sql.Date
import java.sql.Timestamp
import java.time.Instant
import java.time.LocalDate
+import scala.collection.Iterator as ScalaIterator
+import scala.collection.Map as ScalaMap
+import scala.collection.mutable.Map as ScalaMutableMap
class ApiTest : ShouldSpec({
context("integration tests") {
@@ -173,6 +178,41 @@ class ApiTest : ShouldSpec({
expect(result).asExpect().contains.inOrder.only.values(3, 5, 7, 9, 11)
}
+ should("Handle JavaConversions in Kotlin") {
+ // Test the iterator conversion
+ val scalaIterator: ScalaIterator = listOf("test1", "test2").iterator().asScalaIterator()
+ scalaIterator.next() shouldBe "test1"
+
+ val kotlinIterator: Iterator = scalaIterator.asKotlinIterator()
+ kotlinIterator.next() shouldBe "test2"
+
+
+ val scalaMap: ScalaMap = mapOf(1 to "a", 2 to "b").asScalaMap()
+ scalaMap.get(1).get() shouldBe "a"
+ scalaMap.get(2).get() shouldBe "b"
+
+ val kotlinMap: Map = scalaMap.asKotlinMap()
+ kotlinMap[1] shouldBe "a"
+ kotlinMap[2] shouldBe "b"
+
+
+ val scalaMutableMap: ScalaMutableMap = mutableMapOf(1 to "a").asScalaMutableMap()
+ scalaMutableMap.get(1).get() shouldBe "a"
+
+ scalaMutableMap.put(2, "b")
+
+ val kotlinMutableMap: MutableMap = scalaMutableMap.asKotlinMutableMap()
+ kotlinMutableMap[1] shouldBe "a"
+ kotlinMutableMap[2] shouldBe "b"
+
+ val scalaSeq: Seq = listOf("a", "b").iterator().asScalaIterator().toSeq()
+ scalaSeq.take(1).toList().last() shouldBe "a"
+ scalaSeq.take(2).toList().last() shouldBe "b"
+
+ val kotlinList: List = scalaSeq.asKotlinList()
+ kotlinList.first() shouldBe "a"
+ kotlinList.last() shouldBe "b"
+ }
should("handle LocalDate Datasets") { // uses encoder
val dataset: Dataset = dsOf(LocalDate.now(), LocalDate.now())
dataset.show()