java - 在 Java 代码中访问 Drools 返回的事实对象

标签 java drools guvnor

我有一个通过 Guvnor 控制台创建的 drools 规则,如果满足条件,该规则将验证事实并将其插入工作内存中。规则是:

    1. | rule "EligibilityCheck001" 
    2. |     dialect "mvel" 
    3. |     when 
    4. |         Eligibility( XXX== "XXX" , YYY== "YYY" , ZZZ== "ZZZ" , BBB == "BBB" ) 
    5. |     then 
    6. |         EligibilityInquiry fact0 = new EligibilityInquiry(); 
    7. |         fact0.setServiceName( "ABCD" ); 
    8. |         fact0.setMemberStatus( true ); 
    9. |         insert(fact0 ); 
   10. |         System.out.println( "Hello from Drools"); 
   11. | end 

执行规则的Java代码如下

RuleAgent ruleAgent = RuleAgent.newRuleAgent("/Guvnor.properties");
RuleBase ruleBase = ruleAgent.getRuleBase();
FactType factType = ruleBase.getFactType("mortgages.Eligibility");

Object obj = factType.newInstance();
factType.set(obj, "XXX", "XXX");
factType.set(obj, "YYY", "YYY");
factType.set(obj, "ZZZ", "XXX");
factType.set(obj, "BBB", "BBB");

WorkingMemory workingMemory = ruleBase.newStatefulSession();
workingMemory.insert(obj);
workingMemory.fireAllRules();
System.out.println("After drools execution");
long count = workingMemory.getFactCount();
System.out.println("count " + count);

输出如下所示,一切看起来都很棒:

Hello from Drools
After drools execution
count 2

我似乎无法找到一种方法将 EligibilityInquiry 事实对象返回到我的 Java 代码中,并获取上述规则中设置的属性(serviceName状态)。我使用了 StatefulSession 方法。

属性文件包含快照的链接,通过用户名和密码进行基本身份验证。共有 2 个事实:EligibilityInquiryEligibility

我对流口水还很陌生,非常感谢任何有关上述内容的帮助。

最佳答案

(注意:我修正了语句的顺序,一个拼写错误(“XX”),并从输出中删除了注释。没什么惊喜。)

此代码段假定 EligibilityInquiry 也在 DRL 中声明。

FactType eligInqFactType = ruleBase.getFactType("mortgages", "EligibilityInquiry");
Class<?> eligInqClass = eligInqFactType.getFactClass();
ObjectFilter filter = new FilterByClass( eligInqClass );
Collection<Object> eligInqs = workingMemory.getObjects( filter );

过滤器是

public class FilterByClass implements ObjectFilter {
    private Class<?> theClass;
    public FilterByClass( Class<?> clazz ){
        theClass = clazz;
    }
    public boolean accept(Object object){
        return theClass.isInstance( object );
    } 
}

您还可以使用查询,它需要大约相同数量的代码。

// DRL code
query "eligInqs" 
    eligInq : EligibilityInquiry()
end

// after return from fireAllRules
QueryResults results = workingMemory.getQueryResults( "eligInqs" );
for ( QueryResultsRow row : results ) {
    Object eligInqObj = row.get( "eligInq" );
    System.out.println( eligInqClass.cast( eligInqObj ) );
}

或者您可以调用 workingMemory.getObjects() 并迭代集合并检查每个对象的类。

for( Object obj: workingMemory.getObjects() ){
    if( obj.isInstance( eligInqClass ) ){
        System.out.println( eligInqClass.cast( eligInqObj ) );
    }
}

或者您可以(无论是否插入创建的 EligibilityInquiry 对象作为事实)将事实添加到全局 java.util.List eligInqList 中,并在 Java 代码中迭代它。请注意,需要 StatefulKnowledgeSession 的 API(而不是 WorkingMemory)。

   // Java - prior to fireAllRules
   StatefulKnowledgeSession kSession() = ruleBase.newStatefulSession();

   List<?> list = new ArrayList();
   kSession.setGlobal( "eligInqList", list );

   // DRL
   global java.util.List eligInqList;

   // in a rule
   then
       EligibilityInquiry fact0 = new EligibilityInquiry(); 
       fact0.setServiceName( "ABCD" ); 
       fact0.setMemberStatus( true ); 
       insert(fact0 );  
       eligInqList.add( fact0 ); 
   end

   // after return from fireAllRules
   for( Object elem: list ){
    System.out.println( eligInqClass.cast( elem ) );
   }

可能是财富的尴尬。

关于java - 在 Java 代码中访问 Drools 返回的事实对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24835175/

相关文章:

java - 如何将文件传递到 Java Matcher 中?

drools - 如何开始使用 drools guvnor

tomcat - 部署 kie-wb-distribution-wars-6.0.1.Final-tomcat7 时出现问题

java - 确定 PDF 文件中的页数

Java 字符串不打印长度超过 4094

java - 在java中发送一个int。有时会引发异常?

java - 流口水查询 "wildcard"

java - Drools 规则未得到评估,以前的规则工作正常

java - Drools 获取具有更高优先级的对象

java - 错误的类格式将包从 Java 7 构建到 Java 8