Drools 规则验证 Scala Option 类型中的对象

Drools rule validating objects within Scala Option type

(强制性新手免责声明)

我正在尝试编写一个规则,每当 (scala) 列表中的对象匹配条件时触发。这里的问题是列表实际上是一个 Option(List[TypeA])... =13=]

我使用的案例 类 具有以下结构:

TypeA {
    arg1 : Option[List[TypeB]]
}

TypeB {
    value : String
}

我写了一个类似这样的规则:

when
    $a : TypeA($l : arg1)
    $b : TypeB() from $l.get()
then
    System.out.println($b)

我在没有“.get()”的情况下进行了尝试,只是为了获得一个类型为 Some() 的对象。

使用“.get()”,我已设法 return 选项的内容,但它似乎与预期类型 (List[TypeB]) 不匹配。相反,值 returned 的类型似乎是 scala.collection.immutable.$colon$colon

有什么问题吗?如果有任何正确的方法来处理 Drools 中的选项?

我唯一能想到的尝试:

when
    $a : TypeA($l : arg)
    $b : TypeB() from (ArrayList)$l.get() // or some other Java *-List
then
    System.out.println($b)

值得再试一次:

when
    $a : TypeA($l : arg)
    $b : TypeB() from $l.get()asJava()*-List
then
    System.out.println($b)

由于您正在做很多 Java 和 Scala 互操作,我建议您让自己非常熟悉 Scala 的 javaconverters 功能。这个方便的实用程序集合允许您将 Scala 集合转换为 Java 集合,反之亦然。

对于您的情况,我认为您需要将 Java 集合转换为 Scala 集合。尝试以下操作:

import scala.collection.JavaConverters._

val myScalaList = $b.asScala.toList

文档中的示例:

import scala.collection.JavaConverters._

val sl = new scala.collection.mutable.ListBuffer[Int]
val jl : java.util.List[Int] = sl.asJava
val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
assert(sl eq sl2)

您遇到的另一个问题是可变和不可变数据结构。 Java 中的标准列表结构是可变的,但默认情况下 Scala 会为您提供一个不可变列表,除非您明确指出您想要一个可变列表。因此,在两个世界之间进行简单的转换时,会有一些阻抗不匹配。

正如我在之前的 post 中提到的,您可以通过为需要推送到 Drools 的实体创建 Java classes 来避免很多问题。在基于 Scala 的项目中将 Java classes 与 Scala classes 混合不是问题。

另一种方法是在您的 Scala 案例 class 中创建一个函数,它使用 asJava 方法将 Scala 集合转换为 Java 集合,并且 returns它。每当您需要引用该 Scala 集合时,在您的 DRL 文件中调用此方法,以便您获得 Java 集合。

理想情况下,JBoss Drools,如果他们愿意,需要增强他们当前的编译器以更好地处理 Scala 类型,或者制作一个不会破坏 Scala 类型的专用 Drools Scala 编译器。