Java 如何在Drools DRL中的运行时将事实添加到工作内存中,并在无状态会话的执行结果中检索它们?

Java 如何在Drools DRL中的运行时将事实添加到工作内存中,并在无状态会话的执行结果中检索它们?,java,drools,Java,Drools,背景: 我正在开发一个应用程序,它根据一组drools规则将一个输入对象转换为两个输出对象之一。直到运行时才知道输出对象,它是在要执行的第一个规则中创建的 以下是创建输出对象的规则和示例转换规则: rule "Initialization" dialect "java" salience 1000 no-loop true when t : Trade() then if(t.getTran().getInsType().

背景:

我正在开发一个应用程序,它根据一组drools规则将一个输入对象转换为两个输出对象之一。直到运行时才知道输出对象,它是在要执行的第一个规则中创建的

以下是创建输出对象的规则和示例转换规则:

rule "Initialization"
    dialect "java"
    salience 1000
    no-loop true
    when
        t : Trade()
    then 
        if(t.getTran().getInsType().equalsIgnoreCase("EEO") ||
           t.getTran().getInsType().equalsIgnoreCase("EEF"))
        {
            insert(new Option());
        }
        else
        {
            insert(new Swap());
        }
end

rule "Example Rule"
    dialect "java"
    when
        t : Trade()
        opt : Option()
    then
        opt.setCounterpartyName(t.getTran().getCParty());
end
以下是调用规则的代码:

private void test(){
    for(File xmlFile : getXmlFilesFromDirectory(XML_DIRECTORY))
    {
        Trade trade = (Trade)unmarshall(xmlFile, Trade.class);

        KnowledgeBase kbase = readKnowledgeBase();

        StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
        KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);

        List<Command> commands = new ArrayList<Command>();
        commands.add(CommandFactory.newInsert(trade, "trade"));
        commands.add(CommandFactory.newFireAllRules());

        ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands));
        logger.close();
    }
 }

private static KnowledgeBase readKnowledgeBase() throws Exception 
{
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newClassPathResource("security-transformation.drl"), ResourceType.DRL);
    KnowledgeBuilderErrors errors = kbuilder.getErrors();
    if (errors.size() > 0) 
    {
        for (KnowledgeBuilderError error: errors) 
        {
            System.err.println(error);
        }

        throw new IllegalArgumentException("Could not parse knowledge.");
    }

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    return kbase;
}
private void test(){
for(文件xmlFile:getXmlFilesFromDirectory(XML_目录))
{
Trade=(Trade)解组(xmlFile,Trade.class);
KnowledgeBase kbase=readKnowledgeBase();
无状态知识会话ksession=kbase.newStatelessKnowledgeSession();
KnowledgeRuntimeLogger logger=KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
List命令=new ArrayList();
commands.add(CommandFactory.newInsert(trade,“trade”));
commands.add(CommandFactory.newFireAllRules());
ExecutionResults=ksession.execute(CommandFactory.newBatchExecution(commands));
logger.close();
}
}
私有静态KnowledgeBase readKnowledgeBase()引发异常
{
KnowledgeBuilder kbuilder=KnowledgeBuilderFactory.newKnowledgeBuilder();
添加(ResourceFactory.newClassPathResource(“security transformation.drl”)、ResourceType.drl);
KnowledgeBuilderErrors errors=kbuilder.getErrors();
如果(errors.size()>0)
{
for(KnowledgeBuilderError:错误)
{
系统错误打印项次(错误);
}
抛出新的IllegalArgumentException(“无法解析知识”);
}
KnowledgeBase kbase=KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
返回kbase;
}
问题:

当我执行规则时,我没有在返回的事实中接收输出对象。我收到了交易对象,但是我没有得到选项或交换对象,这取决于第一条规则将哪个对象添加到工作内存

问题:

如何在drl中的运行时将事实添加到工作内存中,并在无状态会话的执行结果中检索它们

编辑:
我需要使用drools查询吗?

我继续使用drools查询。我会把密码给其他任何人

添加到上述规则中的查询(对象扩展为
BaseTrade
):

从执行结果检索查询结果的代码:

    StatelessKnowledgeSession ksession = this.kbase.newStatelessKnowledgeSession();

    KnowledgeRuntimeLogger klogger = configureKnowledgeRuntimeLogger(ksession);

    List<Command> commands = new ArrayList<Command>();
    commands.add(CommandFactory.newInsert(inputObj, "inputObj"));
    commands.add(CommandFactory.newFireAllRules());
    commands.add(CommandFactory.newQuery("outputObj", "GetOutputObj"));

    ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands));

    QueryResults queryResults = ((NativeQueryResults)results.getValue("baseTrade")).getResults();

    try
    {
        Iterator iter = queryResults.iterator();
        while(iter.hasNext())
        {
            QueryResult result = iter.next();

            //There can be only one... just like Highlander
            //Could switch this up and return a list, but we only expect one thing from here.
            return (BaseTrade) result.get("baseTrade");
        }
    }
    finally
    {
        if(klogger != null)
        {
            klogger.close();
        }
    }
StatelessKnowledgeSession ksession=this.kbase.newStatelessKnowledgeSession();
KnowledgeRuntimeLogger klogger=配置KnowledgeRuntimeLogger(ksession);
List命令=new ArrayList();
add(CommandFactory.newInsert(inputObj,“inputObj”);
commands.add(CommandFactory.newFireAllRules());
add(CommandFactory.newQuery(“outputObj”、“GetOutputObj”);
ExecutionResults=ksession.execute(CommandFactory.newBatchExecution(commands));
QueryResults QueryResults=((NativeQueryResults)results.getValue(“baseTrade”)).getResults();
尝试
{
迭代器iter=queryResults.Iterator();
while(iter.hasNext())
{
QueryResult result=iter.next();
//只有一个…就像高地人一样
//我们可以切换这个并返回一个列表,但我们只希望从这里得到一件事。
返回(BaseTrade)结果。获取(“BaseTrade”);
}
}
最后
{
if(klogger!=null)
{
klogger.close();
}
}

请回答这个问题。谢谢感谢@gwhitake的宝贵帖子。只需编辑解决方案的一部分,就可以让用户第一次清楚地了解它。检索具有标识符的对象。使用“outputObj”而不是“baseTrade”。QueryResults QueryResults=((NativeQueryResults)results.getValue(“outputObj”)).getResults();
    StatelessKnowledgeSession ksession = this.kbase.newStatelessKnowledgeSession();

    KnowledgeRuntimeLogger klogger = configureKnowledgeRuntimeLogger(ksession);

    List<Command> commands = new ArrayList<Command>();
    commands.add(CommandFactory.newInsert(inputObj, "inputObj"));
    commands.add(CommandFactory.newFireAllRules());
    commands.add(CommandFactory.newQuery("outputObj", "GetOutputObj"));

    ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands));

    QueryResults queryResults = ((NativeQueryResults)results.getValue("baseTrade")).getResults();

    try
    {
        Iterator iter = queryResults.iterator();
        while(iter.hasNext())
        {
            QueryResult result = iter.next();

            //There can be only one... just like Highlander
            //Could switch this up and return a list, but we only expect one thing from here.
            return (BaseTrade) result.get("baseTrade");
        }
    }
    finally
    {
        if(klogger != null)
        {
            klogger.close();
        }
    }