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()