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 编译器。
(强制性新手免责声明)
我正在尝试编写一个规则,每当 (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 编译器。