Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load an Excel-based Decision Table with Drools using JSR94?

Tags:

drools

There's a bunch of examples on the web of how to load a Drools DRL rule set. However, I can't seem to find any instructions or examples of how to load a Decision Table in Excel format using the JSR94 API.

Does anyone know how to do this? If so, could you provide a simple code example?

Here's a sample piece of code I'm working with below. I've marked the area that I suspect that some properties need to get setup and passed in as the second parameter to createRuleExectuionSet() (Although that may not be the solution).

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();
    }
}
like image 621
jeffmaher Avatar asked Mar 17 '10 20:03

jeffmaher


People also ask

How do you make a decision table in drools?

A Drool Decision Table is a way to generate rules from the data entered into a spreadsheet. The spreadsheet can be a standard Excel (XLS) or a CSV File. In this spreadsheet a simple rule is included: if the Customer object's age parameter equals to “1” the Customer is allowed a discount of 15%.


1 Answers

I do not think the JSR-94 provider provides a Decision table implementation as yet - you would need to use the decision table API to convert the XLS to the drl format, which you could then pass to the above code.

So if you use SpreadsheetCompiler (org.drools.decisiontables package) that could do it for you - unfortunately that means you have to import a drools class (not pure JSR-94) so that may defeat the purpose.

In any case, it is rare that the JSR-94 api is very useful - there is a reason why it has not progressed as an API spec. You could arguably implement "stubs" for a few major rule engines in less lines of code than using JSR-94 (I have done it !).

The one time it was useful for me was when I was writing a testing tool which worked for both JRules and Drools (it was useful in that case because I was only dealing with data - not rules themselves - in your above code - the JSR-94 "pluggability" of a different rule engine is no use - if you were to switch to something else your rules would have to be rewritten anyway).

Good luck !

like image 129
Michael Neale Avatar answered Oct 12 '22 05:10

Michael Neale