2016-11-17 15 views
1

我如何绑定变量的不同类型在规则LHS的or组匹配的事实?绑定变量中的情况下,不同的数据类型“或”在规则LHS

举例来说,如果我有以下规则文件:

package com.sample 

rule "Rule1" 
    when 
     object1: ObjectType1(id == 1) or 
     object2: ObjectType2(id == 2) 
    then 
     System.out.println(object1.getId()); 
     System.out.println(object2.getId()); 
end 

,我用这个驱动程序代码:

package com.sample; 

import org.kie.api.runtime.KieSession; 

public class DroolsTest { 

    public static final void main(String[] args) { 
    try { 
     String ruleFilePath = "src/main/resources/rules/ruleFile.drl"; 
     KieSession kSession = KSessionUtil.buildKSession(ruleFilePath); 

     ObjectType1 o1 = new ObjectType1(1); 
     ObjectType2 o2 = new ObjectType2(2); 

     kSession.insert(o1); 
     kSession.insert(o2); 

     kSession.fireAllRules(); 

     System.out.println("Bye"); 
    } catch (Throwable t) { 
     t.printStackTrace(); 
    } 
    } 
} 

ObjectType1.java

package com.sample; 

public class ObjectType1 { 
    public ObjectType1(int i) { 
    super(); 
    this.id = i; 
    } 

    public int getId() { 
    return id; 
    } 

    public void setId(int id) { 
    this.id = id; 
    } 

    public int id; 
} 

ObjectType2.java

package com.sample; 

public class ObjectType12 { 
    public ObjectType2(int i) { 
    super(); 
    this.id = i; 
    } 

    public int getId() { 
    return id; 
    } 

    public void setId(int id) { 
    this.id = id; 
    } 

    public int id; 
} 

我得到一个语法错误从Drools的Eclipse插件:

object1 cannot be resolved. 
object2 cannot be resolved. 

如果我更改了规则LHS的orand,错误消失。

我正在使用Drools 6.2.0。

回答

2

棘手的部分是Drools如何处理模式之间的or操作数。在你的榜样,呓会分解您的规则成2个独立的规则:

rule "Rule1_A" 
when 
    object1: ObjectType1(id == 1) 
then 
    System.out.println(object1.getId()); 
    System.out.println(object2.getId()); 
end 


rule "Rule1_B" 
when 
    object2: ObjectType2(id == 2) 
then 
    System.out.println(object1.getId()); 
    System.out.println(object2.getId()); 
end 

正如你所看到的,误差变现在更加突出。

Drools处理or的一个副作用是在此操作中没有短路:如果两个对象都出现在您的会话中,则该规则将执行两次。

希望它能帮助,

+0

那么,这是否意味着没有办法检查哪些事实触发规则 ?另外,在旁注中,关于“如果两个对象都存在于你的会话中,该规则将被执行两次。”,有什么办法可以防止这种情况发生? –

+0

不幸的是,防止它的最简单方法是创建2条显式规则:'(A和!B)'和'(!A和B)'。 –

+0

如果你想成为纯粹主义者,如果你在你的模式之间有一个'或',这应该意味着你想要执行的逻辑不取决于哪个条件是真实的;) –

1

正如this answer by Esteban提到的,它是不可能通过这种方式绑定变量。

相反,我们所能做的就是创建一个包装类,它包含一个对象的每个需要匹配不同的数据类型不同:现在

public class ObjectType { 
    ObjectType1 ob1; 
    ObjectType2 ob2; 

    // setters and getters 
} 

,如果我们想插入的对象,说,ObjectType1进入知识经济会议:

ObjectType1 object1 = new ObjectType1(); 
kSession.insert(object1); 

,我们可以改为设置ObjectType.ob1参考object1,然后插入新ObjectType对象到会话:

ObjectType1 object1 = new ObjectType1(); 
ObjectType object = new ObjectType(); 
object.setOb1(object1); 
kSession.insert(object); 

现在在规则文件,我们就需要用ObjectType(getOb1() != null)而非ObjectType1()匹配ObjectType1类型的对象:

rule "Rule1" 
    when 
     object: (ObjectType(ob1 != null && ob1.getId() == 1) or 
        ObjectType(ob2 != null && ob2.getId() == 2)) 
    then 
     if (object.getOb1() != null) 
     { 
      System.out.println(object.getOb1().getId()); 
     } 
     else 
     { 
      System.out.println(object.getOb2().getId()); 
     } 
end 
相关问题