Skip to content

Commit

Permalink
Allow to convert Map toList in the same way as we convert List toMap (#…
Browse files Browse the repository at this point in the history
…7156)

* Allow to convert Map toList in the same way as List is converted toMap

* Updated snapshots

* tests fix

---------

Co-authored-by: arkadius <[email protected]>
  • Loading branch information
arkadius and arkadius authored Nov 18, 2024
1 parent d798a6d commit 469c3fb
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 20 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -13613,6 +13613,32 @@
"refClazzName": "java.util.Map"
},
"methods": {
"canBe": [
{
"description": "Checks if a type can be converted to a given class",
"name": "canBe",
"signatures": [
{
"noVarArgs": [
{"name": "className", "refClazz": {"refClazzName": "java.lang.String"}}
],
"result": {"refClazzName": "java.lang.Boolean"}
}
]
}
],
"canBeList": [
{
"description": "Check whether can be convert to a list",
"name": "canBeList",
"signatures": [
{
"noVarArgs": [],
"result": {"refClazzName": "java.lang.Boolean"}
}
]
}
],
"containsKey": [
{
"name": "containsKey",
Expand Down Expand Up @@ -13710,6 +13736,78 @@
}
}
],
"to": [
{
"description": "Converts a type to a given class or throws exception if type cannot be converted.",
"name": "to",
"signatures": [
{
"noVarArgs": [
{"name": "className", "refClazz": {"refClazzName": "java.lang.String"}}
],
"result": {"type": "Unknown"}
}
]
}
],
"toList": [
{
"description": "Convert to a list or throw exception in case of failure",
"name": "toList",
"signatures": [
{
"noVarArgs": [],
"result": {
"params": [
{
"display": "Unknown",
"params": [],
"refClazzName": "java.lang.Object",
"type": "Unknown"
}
],
"refClazzName": "java.util.List"
}
}
]
}
],
"toListOrNull": [
{
"description": "Convert to a list or null in case of failure",
"name": "toListOrNull",
"signatures": [
{
"noVarArgs": [],
"result": {
"params": [
{
"display": "Unknown",
"params": [],
"refClazzName": "java.lang.Object",
"type": "Unknown"
}
],
"refClazzName": "java.util.List"
}
}
]
}
],
"toOrNull": [
{
"description": "Converts a type to a given class or return null if type cannot be converted.",
"name": "toOrNull",
"signatures": [
{
"noVarArgs": [
{"name": "className", "refClazz": {"refClazzName": "java.lang.String"}}
],
"result": {"type": "Unknown"}
}
]
}
],
"toString": [
{
"name": "toString",
Expand Down Expand Up @@ -15664,4 +15762,4 @@
]
}
}
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -14005,6 +14005,32 @@
"refClazzName": "java.util.Map"
},
"methods": {
"canBe": [
{
"description": "Checks if a type can be converted to a given class",
"name": "canBe",
"signatures": [
{
"noVarArgs": [
{"name": "className", "refClazz": {"refClazzName": "java.lang.String"}}
],
"result": {"refClazzName": "java.lang.Boolean"}
}
]
}
],
"canBeList": [
{
"description": "Check whether can be convert to a list",
"name": "canBeList",
"signatures": [
{
"noVarArgs": [],
"result": {"refClazzName": "java.lang.Boolean"}
}
]
}
],
"containsKey": [
{
"name": "containsKey",
Expand Down Expand Up @@ -14102,6 +14128,78 @@
}
}
],
"to": [
{
"description": "Converts a type to a given class or throws exception if type cannot be converted.",
"name": "to",
"signatures": [
{
"noVarArgs": [
{"name": "className", "refClazz": {"refClazzName": "java.lang.String"}}
],
"result": {"type": "Unknown"}
}
]
}
],
"toList": [
{
"description": "Convert to a list or throw exception in case of failure",
"name": "toList",
"signatures": [
{
"noVarArgs": [],
"result": {
"params": [
{
"display": "Unknown",
"params": [],
"refClazzName": "java.lang.Object",
"type": "Unknown"
}
],
"refClazzName": "java.util.List"
}
}
]
}
],
"toListOrNull": [
{
"description": "Convert to a list or null in case of failure",
"name": "toListOrNull",
"signatures": [
{
"noVarArgs": [],
"result": {
"params": [
{
"display": "Unknown",
"params": [],
"refClazzName": "java.lang.Object",
"type": "Unknown"
}
],
"refClazzName": "java.util.List"
}
}
]
}
],
"toOrNull": [
{
"description": "Converts a type to a given class or return null if type cannot be converted.",
"name": "toOrNull",
"signatures": [
{
"noVarArgs": [
{"name": "className", "refClazz": {"refClazzName": "java.lang.String"}}
],
"result": {"type": "Unknown"}
}
]
}
],
"toString": [
{
"name": "toString",
Expand Down Expand Up @@ -17635,4 +17733,4 @@
]
}
}
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,6 @@ object ToStringConversion extends Conversion[String] {
override def convertEither(value: Any): Either[Throwable, String] = Right(value.toString)
}

abstract class ToCollectionConversion[T >: Null <: AnyRef: ClassTag] extends Conversion[T] {
private val collectionClass = classOf[JCollection[_]]

override def appliesToConversion(clazz: Class[_]): Boolean =
clazz != resultTypeClass && (clazz.isAOrChildOf(collectionClass) || clazz == unknownClass || clazz.isArray)
}

object ToByteConversion extends ToNumericConversion[JByte] {

override def convertEither(value: Any): Either[Throwable, JByte] = value match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package pl.touk.nussknacker.engine.extension
import cats.data.ValidatedNel
import cats.implicits.catsSyntaxValidatedId
import pl.touk.nussknacker.engine.api.generics.{GenericFunctionTypingError, MethodTypeInfo}
import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypedClass, TypingResult, Unknown}
import pl.touk.nussknacker.engine.api.typed.typing.{Typed, TypedClass, TypedObjectTypingResult, TypingResult, Unknown}
import pl.touk.nussknacker.engine.definition.clazz.{FunctionalMethodDefinition, MethodDefinition}
import pl.touk.nussknacker.engine.extension.CastOrConversionExt.{canBeMethodName, orNullSuffix, toMethodName}
import pl.touk.nussknacker.engine.spel.internal.ConversionHandler
import pl.touk.nussknacker.engine.util.classes.Extensions.ClassExtensions

import java.lang.{Boolean => JBoolean}
import java.util.{ArrayList => JArrayList, Collection => JCollection, List => JList}
import java.util.{ArrayList => JArrayList, Collection => JCollection, HashMap => JHashMap, List => JList, Map => JMap}

object ToListConversionExt extends ConversionExt(ToListConversion) {

Expand Down Expand Up @@ -46,16 +46,26 @@ object ToListConversionExt extends ConversionExt(ToListConversion) {

}

object ToListConversion extends ToCollectionConversion[JList[_]] {
object ToListConversion extends Conversion[JList[_]] {

private val collectionClass = classOf[JCollection[_]]
private val mapClass = classOf[JMap[_, _]]

override def convertEither(value: Any): Either[Throwable, JList[_]] = {
value match {
case l: JList[_] => Right(l)
case c: JCollection[_] => Right(new JArrayList[Any](c))
case a: Array[_] => Right(ConversionHandler.convertArrayToList(a))
case x => Left(new IllegalArgumentException(s"Cannot convert: $x to a List"))
case m: JMap[_, _] =>
val l = new JArrayList[JMap[_, _]]()
m.entrySet().forEach { entry =>
val entryRecord = new JHashMap[String, Any]()
entryRecord.put(ToMapConversion.keyName, entry.getKey)
entryRecord.put(ToMapConversion.valueName, entry.getValue)
l.add(entryRecord)
}
Right(l)
case x => Left(new IllegalArgumentException(s"Cannot convert: $x to a List"))
}
}

Expand All @@ -66,11 +76,44 @@ object ToListConversion extends ToCollectionConversion[JList[_]] {
invocationTarget.withoutValue match {
case TypedClass(klass, params) if klass.isAOrChildOf(collectionClass) || klass.isArray =>
Typed.genericTypeClass[JList[_]](params).validNel
case TypedObjectTypingResult(_, TypedClass(klass, _ :: valuesSuperType :: Nil), _)
if klass.isAOrChildOf(mapClass) =>
Typed
.genericTypeClass[JList[_]](
List(
Typed.record(
List(
ToMapConversion.keyName -> Typed[String],
ToMapConversion.valueName -> valuesSuperType
)
)
)
)
.validNel
case TypedClass(klass, keysSuperType :: valuesSuperType :: Nil) if klass.isAOrChildOf(mapClass) =>
Typed
.genericTypeClass[JList[_]](
List(
Typed.record(
List(
ToMapConversion.keyName -> keysSuperType,
ToMapConversion.valueName -> valuesSuperType
)
)
)
)
.validNel
case Unknown => Typed.genericTypeClass[JList[_]](List(Unknown)).validNel
case _ => GenericFunctionTypingError.ArgumentTypeError.invalidNel
}

// We could leave underlying method using convertEither as well but this implementation is faster
override def canConvert(value: Any): JBoolean = value.getClass.isAOrChildOf(collectionClass) || value.getClass.isArray
override def canConvert(value: Any): JBoolean =
value.getClass.isAOrChildOf(collectionClass) || value.getClass.isAOrChildOf(mapClass) || value.getClass.isArray

override def appliesToConversion(clazz: Class[_]): Boolean =
clazz != resultTypeClass && (clazz.isAOrChildOf(collectionClass) || clazz.isAOrChildOf(
mapClass
) || clazz == unknownClass || clazz.isArray)

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ object ToMapConversionExt extends ConversionExt(ToMapConversion) {

}

object ToMapConversion extends ToCollectionConversion[JMap[_, _]] {
object ToMapConversion extends Conversion[JMap[_, _]] {

private val mapClass = classOf[JMap[_, _]]

private val keyName = "key"
private val valueName = "value"
private val keyAndValueNames = JSet.of(keyName, valueName)
private val collectionClass = classOf[JCollection[_]]

private[extension] val keyName = "key"
private[extension] val valueName = "value"
private val keyAndValueNames = JSet.of(keyName, valueName)

override val typingResult: TypingResult = Typed.genericTypeClass(resultTypeClass, List(Unknown, Unknown))

Expand Down Expand Up @@ -99,4 +101,7 @@ object ToMapConversion extends ToCollectionConversion[JMap[_, _]] {
case _ => false
}

override def appliesToConversion(clazz: Class[_]): Boolean =
clazz != resultTypeClass && (clazz.isAOrChildOf(collectionClass) || clazz == unknownClass || clazz.isArray)

}
Loading

0 comments on commit 469c3fb

Please sign in to comment.