5

网上有很多关于如何加载 Drools DRL 规则集的示例。但是,我似乎找不到任何关于如何使用 JSR94 API 以 Excel 格式加载决策表的说明或示例。

有谁知道如何做到这一点?如果是这样,您能否提供一个简单的代码示例?

这是我在下面使用的示例代码。我已经标记了我怀疑某些属性需要设置并作为第二个参数传递给 createRuleExectuionSet() 的区域(尽管这可能不是解决方案)。

package com.sample;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.rules.RuleRuntime;
import javax.rules.RuleServiceProvider;
import javax.rules.RuleServiceProviderManager;
import javax.rules.StatelessRuleSession;
import javax.rules.admin.LocalRuleExecutionSetProvider;
import javax.rules.admin.RuleAdministrator;
import javax.rules.admin.RuleExecutionSet;

import org.drools.jsr94.rules.RuleServiceProviderImpl;

/**
 * This is a sample class to launch a decision table.
 */
public class DecisionTableTestJsr94 {

    // URL to the Decision Table file (via the classpath)
    private static final String DECISION_TABLE_PATH = "/rules/Sample.xls";

    // An arbitrary URI to identify the rule set
    private static final String BIND_URI = "uri://fake/bind/uri";

    public DecisionTableTestJsr94() throws Exception{
        // Initialize the needed services
        RuleServiceProviderManager.registerRuleServiceProvider(RuleServiceProviderImpl.RULE_SERVICE_PROVIDER, RuleServiceProviderImpl.class);
        RuleServiceProvider ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider(RuleServiceProviderImpl.RULE_SERVICE_PROVIDER);
        RuleAdministrator ruleAdmin = ruleServiceProvider.getRuleAdministrator();
        LocalRuleExecutionSetProvider ruleExecutionSetProvider = ruleAdmin.getLocalRuleExecutionSetProvider(null);

        // Read the decision table
        InputStream rules = this.getClass().getResourceAsStream(DECISION_TABLE_PATH);
        Map ruleProperties = new HashMap();

        // ** (probably something needs to happen hear with a properties Map, but what? **

        RuleExecutionSet ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet(rules, null);

        // Add the rules
        ruleAdmin.registerRuleExecutionSet(BIND_URI, ruleExecutionSet, null);

        // Start the rule session
        StatelessRuleSession ruleSession = null;
        ruleSession = (StatelessRuleSession) ruleServiceProvider.getRuleRuntime().createRuleSession(BIND_URI, null, RuleRuntime.STATELESS_SESSION_TYPE);

        // Create a domain object for the test
        Message message = new Message();
        message.setStatus(Message.HELLO);
        System.out.println("Message is: '" + message.getMessage() + "'"); // should be null

        // Run the object through the rules
        List<Message> inputList = new ArrayList<Message>();
        inputList.add(message);
        ruleSession.executeRules(inputList);

        // See if the rules modified the object
        System.out.println("Message is: '" + message.getMessage() + "'"); // should have the appropriate message
    }

    public static final void main(String[] args) throws Exception {
        new DecisionTableTestJsr94();
    }
}
4

2 回答 2

4

我认为 JSR-94 提供程序尚未提供决策表实现 - 您需要使用决策表 API 将 XLS 转换为 drl 格式,然后您可以将其传递给上述代码。

因此,如果您使用可以为您完成的 SpreadsheetCompiler(org.drools.decisiontables 包) - 不幸的是,这意味着您必须导入一个 drools 类(不是纯 JSR-94),这样可能会破坏目的。

无论如何,JSR-94 api 非常有用的情况很少见——它没有作为 API 规范发展是有原因的。可以说,与使用 JSR-94 相比,您可以用更少的代码行数为一些主要规则引擎实现“存根”(我已经做到了!)。

它对我有用的一次是当我编写一个适用于 JRules 和 Drools 的测试工具时(在那种情况下它很有用,因为我只处理数据 - 而不是规则本身 - 在你的上面的代码中 - JSR- 94 不同规则引擎的“可插入性”是没有用的——如果你要切换到其他东西,你的规则无论如何都必须重写)。

祝你好运 !

于 2010-03-18T04:52:17.080 回答
1

嗯,我不知道 JSr 但你肯定可以在 JBPM 中使用流口水决策表。我有一个类文件,它可以帮助您在代码中添加决策表 excel 表。

package com.sample;

import java.util.*;

import org.drools.*;

import org.jbpm.*;

public class ProcessRuleTest {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = createSession(kbase);
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
                    .newFileLogger(ksession, "test");

            // set the parameters
            Map<String, Object> params = new HashMap<String, Object>();
            HelloProcessModel hpm = new HelloProcessModel();
            hpm.setCount(new Integer("3"));
            hpm.setUserlocation("NewYorkUser");
            params.put("hpm", hpm);
            ksession.startProcess("looptest777",params);

            ksession.fireAllRules();
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        ProcessBuilderFactory
                .setProcessBuilderFactoryService(new ProcessBuilderFactoryServiceImpl());
        ProcessMarshallerFactory
                .setProcessMarshallerFactoryService(new ProcessMarshallerFactoryServiceImpl());
        ProcessRuntimeFactory
                .setProcessRuntimeFactoryService(new ProcessRuntimeFactoryServiceImpl());
        BPMN2ProcessFactory
                .setBPMN2ProcessProvider(new BPMN2ProcessProviderImpl());
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                .newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("processRuleslooptest777.bpmn"),
                ResourceType.BPMN2);

        DecisionTableConfiguration config = KnowledgeBuilderFactory.newDecisionTableConfiguration();
        config.setInputType(DecisionTableInputType.XLS);
        kbuilder.add(ResourceFactory.newClassPathResource("LoopConditionRules.xls"), ResourceType.DTABLE, config);


        /*
         * Add drl file
         */
        //kbuilder.add(ResourceFactory.newClassPathResource("LoopConditionRules.drl"), ResourceType.DRL);

        return kbuilder.newKnowledgeBase();
    }

    private static StatefulKnowledgeSession createSession(KnowledgeBase kbase) {
        Properties properties = new Properties();
        properties
                .put("drools.processInstanceManagerFactory",
                        "org.jbpm.process.instance.impl.DefaultProcessInstanceManagerFactory");
        properties.put("drools.processSignalManagerFactory",
                "org.jbpm.process.instance.event.DefaultSignalManagerFactory");
        KnowledgeSessionConfiguration config = KnowledgeBaseFactory
                .newKnowledgeSessionConfiguration(properties);
        return kbase.newStatefulKnowledgeSession(config,
                EnvironmentFactory.newEnvironment());
    }
}

kbuilder.add(ResourceFactory.newClassPathResource("LoopConditionRules.xls"),在此代码中是在项目中添加 drl 文件的方式,可能正在查看此您可以获得 jsr 项目的提示。一切顺利。

于 2013-01-24T10:11:42.650 回答