Drools5.0.1使用excel实例

本文中所有文件在同一Package下:

excelDrools.drt//规则编译模板

template header
space
chageNum
gainFlag
MaxNum
from
remark

package com.cheng_xy.drools.excel.util

import com.cheng_xy.drools.excel.bean.ExcelDrollsInputParam;
import com.cheng_xy.drools.excel.bean.ExcelDroolsOutputParam;

global ExcelDroolsOutputParam output;

template "Excel规则模板"

rule " Drools_@{remark}"
	when
		ExcelDrollsInputParam(space == "@{space}",starting  matches "@{from}",betweenNum <= @{MaxNum})
	then
	 output.setChageNum("@{chageNum}");
	 output.setGainFlag("@{gainFlag}");
	 output.setRemark("==说明==" + "@{remark}");
end

end template

excelDrools.drt//简单描述

1 template header
2 space
3 chageNum
4 gainFlag
5 MaxNum
6 from
7 remark
8 
9 package com.cheng_xy.drools.excel.util
10 
11 import com.cheng_xy.drools.excel.bean.ExcelDrollsInputParam;
12 import com.cheng_xy.drools.excel.bean.ExcelDroolsOutputParam;
13 
14 global ExcelDroolsOutputParam output;
15 
16 template "Excel规则模板"
17 
18 rule " Drools_@{remark}"
19 	when
20 		ExcelDrollsInputParam(space == "@{space}",starting  matches "@{from}",betweenNum <= @{MaxNum})
21 	then
22 	 output.setChageNum("@{chageNum}");
23 	 output.setGainFlag("@{gainFlag}");
24 	 output.setRemark("==说明==" + "@{remark}");
25 end
26 
27 end template

第1行:所有规则模板以template header开始。
第2-7行:在标题之后是按照它们在excel表中数据顺序排列的列名。
第8行:空行表示excel数据中列定义的结束。
第9-15行:标准规则标题文本。这是DRL的标准规则,将出现在生成的DRL的顶部。将package语句和任何导入以及全局和函数定义放入本节。
第9行:package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行。特别的是,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分。同样的package下定义的function和query等可以直接使用。
第11-12行:import:导入规则文件需要使用到的外部变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法。
    比如:
      import com.drools.demo.point.PointDomain;
      import com.drools.demo.point.PointDomain.getById;
第14行:此语法是用来定义全局变量的,被用于提供应用程序对象的规则,一般来说,global是用于提供数据或者服务使用的规则,特别是应用程序服务中使用规则的后果,并返回数据规则。
第16行:关键字模板表示规则模板的开始。模板文件中可以有多个模板,但每个模板都应该有唯一的名称。
第17-26行:模板规则。
第27行:关键字结束模板表示模板的结尾。

注:本文是个人见解,欢迎优化指出不足

excelDrools.xls//规则描述文件 即:决策表(decisiontable)决策表就是一个excel文件

Drools5.0.1使用excel实例_第1张图片

ExcelDroolsUtil.java//规则的执行类

package com.cheng_xy.drools.excel.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.compiler.DroolsParserException;
import org.drools.compiler.PackageBuilder;
import org.drools.decisiontable.ExternalSpreadsheetCompiler;
import org.drools.spi.Activation;
import com.cheng_xy.drools.excel.bean.ExcelDrollsInputParam;
import com.cheng_xy.drools.excel.bean.ExcelDroolsOutputParam;

public class ExcelDroolsUtil {
	private static ExcelDroolsUtil excelDroolsUtil = null;
	private RuleBase excelRuleBase = null;
	private static String excelDroolsURL = "";

	public ExcelDroolsUtil() throws DroolsParserException, IOException {
		InputStream in = this.getClass().getResourceAsStream("SysConfig.properties");
		Properties p = new Properties();
		p.load(in);
		excelDroolsURL = p.getProperty("ExcelDroolsURL");
		initExcelDrools();
	}

	/**
	 * 取得ExcelDroolsUtil的实例
	 * 
	 * @return
	 * @throws IOException
	 * @throws DroolsParserException
	 */
	public static ExcelDroolsUtil Instance() throws DroolsParserException,
			IOException {
		if (excelDroolsUtil == null) {
			excelDroolsUtil = new ExcelDroolsUtil();
		}
		return excelDroolsUtil;
	}
	
	/**
	 * 初始化规则引擎:规则的收集
	 * 
	 * @throws IOException
	 * @throws DroolsParserException
	 */
	private void initExcelDrools() throws IOException, DroolsParserException {

		final ExternalSpreadsheetCompiler converter = new ExternalSpreadsheetCompiler();
		String preUrl = "";
		String drl = "";
		/*
		 * excelDrools.drt 定义的参数 与excelDrools.xls文件中的列顺序对应
		 * */
		if (excelDroolsURL.equals("")) {
			drl = converter.compile(this.getClass().getResourceAsStream("excelDrools.xls"),
					this.getClass().getResourceAsStream("excelDrools.drt"),
					2,
					2);
		} else {
			preUrl = excelDroolsURL;
			/*  使用助手类的一个实例ExternalSpreadsheetCompiler将模板文件和电子表格中的数据转换到到DRL文件里。
			 *  ExternalSpreadsheetCompiler的compile()方法有四个参数:数据,模板,以及电子表格中数据的起始的的行和列。
			 *  在我们的用例里,数据起始值为2行2列
			 */
			drl = converter.compile(getFileStream(preUrl + "/excelDrools.xls"),
					getFileStream(preUrl + "/excelDrools.drt"),
					2,
					2);
		}
		excelRuleBase = buildRuleBase(drl);
	}
	
	/**
	 * 读取规则文件
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	private InputStream getFileStream(String file) throws IOException {
		InputStream instream = null;
		instream = new FileInputStream(file);
		return instream;
	}

	/**
	 * 构建规则:规则编译
	 * 
	 * @param drls
	 * @return
	 * @throws DroolsParserException
	 * @throws IOException
	 */
	private RuleBase buildRuleBase(String... drls)
			throws DroolsParserException, IOException {

		PackageBuilder builder = new PackageBuilder();
		for (String drl : drls) {
			builder.addPackageFromDrl(new StringReader(drl));
		}
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage(builder.getPackage());
		return ruleBase;
	}
	
	/**
	 * 通过规则引擎获取业务想得到的结果:规则的执行
	 * 
	 * @param space			位置标识
	 * @param starting		开始拥有的物品
	 * @param betweenNum	想得到的奖励
	 * @return
	 */
	public ExcelDroolsOutputParam getExcelDrools(String space,String starting,int betweenNum) {
		
		if (null == excelRuleBase.getPackages() || 0 == excelRuleBase.getPackages().length) {
			System.out.println("规则 获取失败!");
			return null;
		}
		
		StatefulSession statefulSession;
		statefulSession = excelRuleBase.newStatefulSession();
		ExcelDrollsInputParam input = new ExcelDrollsInputParam();
		input.setSpace(space);
		input.setStarting(starting);
		input.setBetweenNum(betweenNum);
		/*
		 * Fact对象是指在Drools规则应用当中, 将一个普通的JavaBean插入到规则的WorkingMemory
当中后的对象。规则可以对 Fact 对象进行任意的读写操作,当一个 JavaBean 插入到
WorkingMemory 当中变成 Fact 之后,Fact 对象不是对原来的 JavaBean 对象进行 Clon,而是
原来 JavaBean 对象的引用。规则在进行计算的时候需要用到应用系统当中的数据,这些数
据设置在 Fact 对象当中,然后将其插入到规则的 WorkingMemory 当中,这样在规则当中就
可以通过对 Fact 对象数据的读写,从而实现对应用数据的读写操作。一个 Fact 对象通常是
一个具有 getter 和 setter 方法的 POJO 对象, 通过这些 getter 和 setter 方法可以方便的实现对
Fact 对象的读写操作,所以我们可以简单的把 Fact 对象理解为规则与应用系统数据交互的
桥梁或通道。
		 * */
		statefulSession.insert(input);//插入一个fact对象
		statefulSession.setGlobal("output", new ExcelDroolsOutputParam());//设置一个global对象
		// 执行匹配规则
		int num = statefulSession.fireAllRules(
				new org.drools.spi.AgendaFilter() {
					public boolean accept(Activation activation) {
						System.out.println("getExcelDrools()Rule name is:"+ activation.getRule().getName());
						return !activation.getRule().getName().contains("_test");//若规则名里包含_test,则该规则不生效
					}
				});
		//释放相关内存资源
		statefulSession.dispose();
		
		if (num == 0) {
			System.out.println("规则引擎执行失败!没有匹配到任何规则。");
			return null;
		}
		//通过源码得知,SetGlobal其实是放的Object,所以在规则文件中,读取的也是Object,所以我们定义的值,或者是泛型都要通过强转才能将值取出。
		ExcelDroolsOutputParam edOut = (ExcelDroolsOutputParam) statefulSession.getGlobal("output");
		System.out.println("getExcelDrools()结束 :所有取得的值=" + edOut.toString());

		return edOut;
	}
	
	/**
	 * 刷新规则
	 */
	public void refreshExcelDrools() throws DroolsParserException, Exception {
		// 取得规则包,将其删除
		org.drools.rule.Package[] packages = excelRuleBase.getPackages();
		for (org.drools.rule.Package pg : packages) {
			excelRuleBase.removePackage(pg.getName());
		}
		// 初始化规则
		initExcelDrools();
	}

	public static void main(String[] args) throws DroolsParserException, Exception {
		//规则的编译与运行要通过:规则编译、规则收集和规则的执行
		excelDroolsUtil = ExcelDroolsUtil.Instance();
		long startTime = System.currentTimeMillis(); // 获取开始时间
		// 调用
		ExcelDroolsOutputParam outputParam = excelDroolsUtil.getExcelDrools("P", "PEK", 90);
		long endTime = System.currentTimeMillis(); // 获取结束时间
		System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
	}
}

SysConfig.properties//规则文件地址配置//可以没有

##ExcelDroolsURL=E:/testFile
ExcelDroolsURL=

下载对应jar包后,可以直接运行,我的demo链接:https://pan.baidu.com/s/1jRYQq1Y2JTYjP2yEK-DrsA
提取码:cie0

希望对你有帮助,祝你有一个好心情,加油!

若有错误、不全、可优化的点,欢迎纠正与补充!

你可能感兴趣的:(规则引擎)