Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add javaapi collection forwarders for 2.12 and 2.11 #551

Merged
merged 2 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ lazy val compat = new MultiScalaCrossProject(
sharedSourceDir / "scala-2.11_2.12"
}
},
versionPolicyIntention := Compatibility.BinaryAndSourceCompatible,
versionPolicyIntention := Compatibility.BinaryCompatible,
mimaBinaryIssueFilters ++= {
import com.typesafe.tools.mima.core._
import com.typesafe.tools.mima.core.ProblemFilters._
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk.javaapi

import java.{lang => jl, util => ju}, java.util.{concurrent => juc}
import scala.collection.convert.{WrapAsJava, WrapAsScala}
import scala.collection._

/** This object contains methods that convert between Scala and Java collections.
*
* The explicit conversion methods defined here are intended to be used in Java code. For Scala
* code, it is recommended to use the extension methods defined in
* [[scala.jdk.CollectionConverters]].
*/
object CollectionConverters extends WrapAsJava with WrapAsScala {
def asJava[A](i: Iterator[A]): ju.Iterator[A] = asJavaIterator(i)

def asJava[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)

def asJava[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)

def asJava[A](s: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(s)

def asJava[A](s: Seq[A]): ju.List[A] = seqAsJavaList(s)

def asJava[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)

def asJava[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)

def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m)

def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m)

def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m)

def asScala[A](i: ju.Iterator[A]): Iterator[A] = asScalaIterator(i)

def asScala[A](e: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(e)

def asScala[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)

def asScala[A](c: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(c)

def asScala[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)

def asScala[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)

def asScala[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)

def asScala[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)

def asScala[A, B](d: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(d)

def asScala(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk.javaapi

import java.{lang => jl, util => ju}, java.util.{concurrent => juc}
import scala.collection.convert.{AsJavaConverters, AsScalaConverters}
import scala.collection._

/** This object contains methods that convert between Scala and Java collections.
*
* The explicit conversion methods defined here are intended to be used in Java code. For Scala
* code, it is recommended to use the extension methods defined in
* [[scala.jdk.CollectionConverters]].
*/
object CollectionConverters extends AsJavaConverters with AsScalaConverters {
def asJava[A](i: Iterator[A]): ju.Iterator[A] = asJavaIterator(i)

def asJava[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)

def asJava[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)

def asJava[A](s: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(s)

def asJava[A](s: Seq[A]): ju.List[A] = seqAsJavaList(s)

def asJava[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)

def asJava[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)

def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m)

def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m)

def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m)

def asScala[A](i: ju.Iterator[A]): Iterator[A] = asScalaIterator(i)

def asScala[A](e: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(e)

def asScala[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)

def asScala[A](c: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(c)

def asScala[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)

def asScala[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)

def asScala[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)

def asScala[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)

def asScala[A, B](d: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(d)

def asScala(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package test.scala.jdk.javaapi;

import org.junit.Assert;
import org.junit.Test;
import scala.Array;
import scala.Tuple2;
import scala.collection.Iterable;
import scala.collection.Iterator;
import scala.collection.concurrent.TrieMap;
import scala.collection.mutable.*;
import scala.collection.mutable.Map;
import scala.collection.mutable.Set;
import scala.jdk.javaapi.CollectionConverters;

import java.util.*;
import java.util.concurrent.ConcurrentMap;

public class CollectionConvertersTest {

/**
* The following conversions are supported via asScala and asJava:
*
* scala.collection.Iterable <=> java.lang.Iterable
* scala.collection.Iterator <=> java.util.Iterator
* scala.collection.mutable.Buffer <=> java.util.List
* scala.collection.mutable.Set <=> java.util.Set
* scala.collection.mutable.Map <=> java.util.Map
* scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
*/
@Test
public void shouldConvertAsScala() {
// scala.collection.Iterable <=> java.lang.Iterable
java.lang.Iterable iterable = CollectionConverters.asJava(TestObjects.iterable());
Assert.assertEquals("A", iterable.iterator().next());
Iterable scalaIterable = CollectionConverters.asScala(iterable);
Assert.assertEquals(TestObjects.iterable().head(), scalaIterable.head());

// scala.collection.Iterator <=> java.util.Iterator
java.util.Iterator iterator = CollectionConverters.asJava(TestObjects.iterator());
Assert.assertEquals("A", iterator.next());
Iterator scalaIterator = CollectionConverters.asScala(iterator);
Assert.assertTrue(scalaIterator.contains("B"));

// scala.collection.mutable.Buffer <=> java.util.List
List<String> list = CollectionConverters.asJava(TestObjects.buffer());
Assert.assertEquals("A", list.get(0));
Buffer<String> scalaBuffer = CollectionConverters.asScala(list);
Assert.assertEquals("A", scalaBuffer.head());

// scala.collection.mutable.Set <=> java.util.Set
java.util.Set<String> set = CollectionConverters.asJava(TestObjects.mutableSet());
Assert.assertTrue(set.contains("A"));
Set<String> scalaSet = CollectionConverters.asScala(set);
Assert.assertTrue(scalaSet.contains("A"));

// scala.collection.mutable.Map <=> java.util.Map
java.util.Map<String, String> map = CollectionConverters.asJava(TestObjects.mutableMap());
Assert.assertEquals("B", map.get("A"));
Map<String, String> scalaMap = CollectionConverters.asScala(map);
Assert.assertEquals("B", scalaMap.get("A").get());

// scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
ConcurrentMap<String, String> concurrentMap = CollectionConverters.asJava(TestObjects.concurrentMap());
Assert.assertEquals("B", concurrentMap.get("A"));
scala.collection.concurrent.Map<String, String> scalaConcurrentMap = CollectionConverters.asScala(concurrentMap);
Assert.assertEquals("B", scalaConcurrentMap.get("A").get());
}

/**
* The following conversions are supported via asScala and through specially-named methods to convert to Java collections, as shown:
*
* scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
* scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
* scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
*/
public void convertAsCollection() {
// scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
Collection<String> collection = CollectionConverters.asJavaCollection(TestObjects.iterable());
Assert.assertTrue(collection.contains("A"));
Iterable<String> iterable = CollectionConverters.asScala(collection);
Assert.assertEquals("A", iterable.head());

// scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
Enumeration<String> enumeration = CollectionConverters.asJavaEnumeration(TestObjects.iterator());
Assert.assertEquals("A", enumeration.nextElement());
Iterator<String> iterator = CollectionConverters.asScala(enumeration);
Assert.assertEquals("A", iterator.next());

// scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
Dictionary<String, String> dictionary = CollectionConverters.asJavaDictionary(TestObjects.mutableMap());
Assert.assertEquals("B", dictionary.get("A"));
Map<String, String> map = CollectionConverters.asScala(dictionary);
Assert.assertEquals("B", map.get("A").get());
}

/** In addition, the following one-way conversions are provided via asJava:
*
* scala.collection.Seq => java.util.List
* scala.collection.mutable.Seq => java.util.List
* scala.collection.Set => java.util.Set
* scala.collection.Map => java.util.Map
*/
public void convertsAsJava() {
// scala.collection.Seq => java.util.List
Assert.assertEquals("A", CollectionConverters.asJava(TestObjects.seq()).get(0));

// scala.collection.mutable.Seq => java.util.List
Assert.assertEquals("A", CollectionConverters.asJava(TestObjects.mutableSeq()).get(0));

// scala.collection.Set => java.util.Set
Assert.assertTrue(CollectionConverters.asJava(TestObjects.set()).contains("A"));

// scala.collection.Map => java.util.Map
Assert.assertEquals("B", CollectionConverters.asJava(TestObjects.map()).get("A"));
}

/**
* The following one way conversion is provided via asScala:
*
* java.util.Properties => scala.collection.mutable.Map
*/
public void convertsFromProperties() {
Properties properties = new Properties();
properties.put("key", "value");
Map<String, String> stringStringMap = CollectionConverters.asScala(properties);
Assert.assertEquals("value", stringStringMap.get("key").get());
}
}
24 changes: 24 additions & 0 deletions compat/src/test/scala-jvm/test/scala/jdk/javaapi/TestObjects.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package test.scala.jdk.javaapi

import scala.collection.concurrent.TrieMap
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer

/**
* Scala collection objects defined for easy access in a Java class
*/
object TestObjects {

val seq: scala.collection.Seq[String] = ArrayBuffer("A", "B")
val mutableSeq: scala.collection.mutable.Seq[String] = ArrayBuffer("A", "B")
val set: scala.collection.Set[String] = Set("A", "B")
val map: scala.collection.Map[String, String] = Map("A" -> "B")

val iterable: scala.collection.Iterable[String] = Iterable("A", "B")
val iterator: scala.collection.Iterator[String] = Iterator("A", "B")
val buffer: scala.collection.mutable.Buffer[String] = mutable.Buffer("A", "B")
val mutableSet: scala.collection.mutable.Set[String] = mutable.Set("A", "B")
val mutableMap: scala.collection.mutable.Map[String, String] = mutable.Map("A" -> "B")
val concurrentMap: scala.collection.concurrent.Map[String, String] = TrieMap("A" -> "B")
}