简单drools规则java代码自动生成
2017-05-21 22:10
260 查看
简单drools规则自动生成
规则自动生成,drools也提供了支持,比如:1.决策表(decision table)https://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html_single/index.html#d0e5713,
2.规则模板(Rule Templates)https://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html_single/index.html#d0e6464
3. 流式API http://docs.jboss.org/drools/release/5.2.0.Final/droolsjbpm-introduction-docs/html/ch02.html#d0e124
不过由于现实环境中,我们会根据Excel 文件提供规则描述,解析动态生成规则,如果产品给的是决策表,那就很容易了,不过产品一般会根据自己的喜好,制定自己的"决策表".
比如:(一行放不下,截取了两种图)
博文http://blog.csdn.net/doctor_who2004/article/details/72600232介绍了如何读取Excel文件转换为java类,此不复述。
文件中的内容对应的java类:
package com.beaver.drools.exampl.travel.rule; import org.javafunk.excelparser.annotations.ExcelField; import org.javafunk.excelparser.annotations.ExcelObject; import org.javafunk.excelparser.annotations.ParseType; /** * Created by beaver on 2017/5/20. */ @ExcelObject(parseType = ParseType.ROW, start = 2, end = 61) public class TravelRule { //公司名称 @ExcelField(position = 1) private String companyName; //费用类型 @ExcelField(position = 2) private String expenseType; //规则应用场景 @ExcelField(position = 3) private String applyPoint; //规则结果 @ExcelField(position = 4) private String ruleAction; //规则内容 @ExcelField(position = 7) private String rule; //提示信息 @ExcelField(position = 9) private String alertMessage; //规则ID @ExcelField(position = 11) private String ruleId; //解析出的drools规则内容 private String droolsRule; public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public String getExpenseType() { return expenseType; } public void setExpenseType(String expenseType) { this.expenseType = expenseType; } public String getRule() { return rule; } public void setRule(String rule) { this.rule = rule; } public String getApplyPoint() { return applyPoint; } public void setApplyPoint(String applyPoint) { this.applyPoint = applyPoint; } public String getRuleAction() { return ruleAction; } public void setRuleAction(String ruleAction) { this.ruleAction = ruleAction; } public String getAlertMessage() { return alertMessage; } public void setAlertMessage(String alertMessage) { this.alertMessage = alertMessage; } public String getRuleId() { return ruleId; } public void setRuleId(String ruleId) { this.ruleId = ruleId; } public String getDroolsRule() { return droolsRule; } public void setDroolsRule(String droolsRule) { this.droolsRule = droolsRule; } @Override public String toString() { return "TravelRule{" + "companyName='" + companyName + '\'' + ", expenseType='" + expenseType + '\'' + ", applyPoint='" + applyPoint + '\'' + ", ruleAction='" + ruleAction + '\'' + ", rule='" + rule + '\'' + ", alertMessage='" + alertMessage + '\'' + ", ruleId='" + ruleId + '\'' + ", droolsRule='" + droolsRule + '\'' + '}'; } }
规则内when条件的匹配对象一般我们使用java中自定义的类最好,此类为:
package com.beaver.drools.exampl.travel.rule; import com.beaver.drools.common.model.RuleResult; import lombok.Data; import java.util.HashMap; import java.util.Map; /** * Created by beaver on 2017/5/20. */ @Data public class MatchInvoiceTravelRuleRequestDto { //规则ID private String ruleOID; //出差申请ID private String invoiceOID; //出差信息-人员级别、出差地点、出差费用等等 private Map<String, String> data = new HashMap<>(); //规则执行结果 private RuleResult result = RuleResult.OK; //备注-规则明细 private String remarkMessage; }
本博文只是实现简单drools规则的自动生成,一个简单的规则的定义如下:
package com.beaver.drools.exampl.travel.rule; import com.beaver.drools.common.model.RuleResult; import com.google.common.base.Splitter; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import java.util.*; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * Created by beaver on 2017/5/20.<br> * 简单规则组成,并不不包含drools复杂的语法规则 */ public class TravelRuleGenerate { //规则包名 private String packageName; //规则需要外部类的包 private List<String> importPackages = new ArrayList<>(); //规则名字 private String ruleName; //规则匹配的类型,如 $o: OrderItem( $p : price, $code : custCode )中的OrderItem private String objectType; //规则匹配类型的变量名,如 $o: OrderItem( $p : price, $code : custCode )中的OrderItem中$o private String objectVar; //规则信息 private TravelRule travelRule; //规则执行动作结果赋值属性名,如 $invoice.setResult(RuleResult.REJECT); 中的resultr; private String resultPropertyName; //规则执行动作结果的提示信息赋值属性名,如 $invoice.setRemarkMessage("您的房费高于公司标准 ");中的remarkMessage. private String alertMessagePropertyName; //规则匹配属性别名,如data["EXPENSE_LEVEL"] not in ("总裁"), // 中的EXPENSE_LEVEL在travelRule中droolsRule中的名不一样,类似mybatis映射一下 //不过key为正则表达式 private Map<String, String> rulePropertyNameAlias = new HashMap<>(); public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public List<String> getImportPackages() { return importPackages; } public void setImportPackages(List<String> importPackages) { this.importPackages = importPackages; } public String getRuleName() { return ruleName; } public void setRuleName(String ruleName) { this.ruleName = ruleName; } public TravelRule getTravelRule() { return travelRule; } public void setTravelRule(TravelRule travelRule) { this.travelRule = travelRule; } public String getObjectType() { return objectType; } public void setObjectType(String objectType) { this.objectType = objectType; } public String getObjectVar() { return objectVar; } public void setObjectVar(String objectVar) { this.objectVar = objectVar; } public String getResultPropertyName() { return resultPropertyName; } public void setResultPropertyName(String resultPropertyName) { this.resultPropertyName = resultPropertyName; } public String getAlertMessagePropertyName() { return alertMessagePropertyName; } public void setAlertMessagePropertyName(String alertMessagePropertyName) { this.alertMessagePropertyName = alertMessagePropertyName; } public Map<String, String> getRulePropertyNameAlias() { return rulePropertyNameAlias; } public void setRulePropertyNameAlias(Map<String, String> rulePropertyNameAlias) { this.rulePropertyNameAlias = rulePropertyNameAlias; } }
其中,
//规则信息 private TravelRule travelRule;
是我们解析Excel文件得到的原生规则,我们需要对其处理,生成drools规则描述。
下面的定义主要是为业务和代码需求定制,Excel文件中规则属性名多个对应一个意思,后者和我们java代码定义的不一样,所以类似mybatis,做个映射。
//规则匹配属性别名,如data["EXPENSE_LEVEL"] not in ("总裁"), // 中的EXPENSE_LEVEL在travelRule中droolsRule中的名不一样,类似mybatis映射一下 //不过key为正则表达式 private Map<String, String> rulePropertyNameAlias = new HashMap<>();
下面代码是对
private TravelRule travelRule;
及本类提供的规则信息产生drools规则,实现是比较笨重的方法,因为规则比较简单,复杂的规则如何实现呢?
package com.beaver.drools.exampl.travel.rule; import com.beaver.drools.common.model.RuleResult; import com.google.common.base.Splitter; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import java.util.*; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * Created by beaver on 2017/5/20.<br> * 简单规则组成,并不不包含drools复杂的语法规则 */ public class TravelRuleGenerate { //规则包名 private String packageName; //规则需要外部类的包 private List<String> importPackages = new ArrayList<>(); //规则名字 private String ruleName; //规则匹配的类型,如 $o: OrderItem( $p : price, $code : custCode )中的OrderItem private String objectType; //规则匹配类型的变量名,如 $o: OrderItem( $p : price, $code : custCode )中的OrderItem中$o private String objectVar; //规则信息 private TravelRule travelRule; //规则执行动作结果赋值属性名,如 $invoice.setResult(RuleResult.REJECT); 中的resultr; private String resultPropertyName; //规则执行动作结果的提示信息赋值属性名,如 $invoice.setRemarkMessage("您的房费高于公司标准 ");中的remarkMessage. private String alertMessagePropertyName; //规则匹配属性别名,如data["EXPENSE_LEVEL"] not in ("总裁"), // 中的EXPENSE_LEVEL在travelRule中droolsRule中的名不一样,类似mybatis映射一下 //不过key为正则表达式 private Map<String, String> rulePropertyNameAlias = new HashMap<>(); public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public List<String> getImportPackages() { return importPackages; } public void setImportPackages(List<String> importPackages) { this.importPackages = importPackages; } public String getRuleName() { return ruleName; } public void setRuleName(String ruleName) { this.ruleName = ruleName; } public TravelRule getTravelRule() { return travelRule; } public void setTravelRule(TravelRule travelRule) { this.travelRule = travelRule; } public String getObjectType() { return objectType; } public void setObjectType(String objectType) { this.objectType = objectType; } public String getObjectVar() { return objectVar; } public void setObjectVar(String objectVar) { this.objectVar = objectVar; } public String getResultPropertyName() { return resultPropertyName; } public void setResultPropertyName(String resultPropertyName) { this.resultPropertyName = resultPropertyName; } public String getAlertMessagePropertyName() { return alertMessagePropertyName; } public void setAlertMessagePropertyName(String alertMessagePropertyName) { this.alertMessagePropertyName = alertMessagePropertyName; } public Map<String, String> getRulePropertyNameAlias() { return rulePropertyNameAlias; } public void setRulePropertyNameAlias(Map<String, String> rulePropertyNameAlias) { this.rulePropertyNameAlias = rulePropertyNameAlias; } //规则生成 public String Generate() { StringBuilder sb = new StringBuilder(); //规则头部 sb.append("package ").append(packageName).append("\n").append("\n"); importPackages.stream().forEach(t -> sb.append("import ").append(t).append("\n")); sb.append("\n\n"); //规则名称 sb.append("rule \"").append(generateRuleName()).append("\n\n"); //规则条件 sb.append("when").append("\n"); sb.append(" ").append(objectVar).append(" : ").append(objectType).append("(").append("\n"); //规则条件内容 List<String> rules = generateWhenContent(); rules.stream().forEach(t -> { sb.append(" ").append(t).append(",\n"); }); int lastIndexOf = sb.lastIndexOf(","); if (lastIndexOf > 0) { sb.deleteCharAt(lastIndexOf); } sb.append(" ) \n"); //规则执行动作 sb.append("then \n"); //规则执行结果 sb.append(" ").append(objectVar).append(".set").append(StringUtils.capitalize(resultPropertyName)).append("("); RuleResult ruleResult = RuleResult.valueOf(travelRule.getRuleAction()); sb.append(RuleResult.class.getSimpleName()).append(".").append(ruleResult.name()).append("); \n"); //规则执行提示信息 sb.append(" ").append(objectVar).append(".set").append(StringUtils.capitalize(alertMessagePropertyName)).append("(\""); sb.append(travelRule.getAlertMessage()).append(" \");"); sb.append("\n").append("end"); return sb.toString(); } //{EXP_LEVEL}IN[一般员工] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*300 private List<String> generateWhenContent() { String rule = travelRule.getRule().trim(); if (rule.contains("OR") || rule.contains("or")) { throw new UnsupportedOperationException("请知悉drools 的基本使用:复杂的规则拆成简单的规则执行,or的规则请拆分"); } if (rule.contains("and")) { throw new UnsupportedOperationException("AND条件单词大写"); } List<String> ruelList = Splitter.on(Pattern.compile("AND")).trimResults().splitToList(rule); List<String> rules = ruelList.stream().map(this::generateARule).collect(Collectors.toList()); return rules; } //去除AND条件的一条简单规则 private String generateARule(final String rule) { if (StringUtils.deleteWhitespace(rule).contains("NOTIN")) { Pair<String, String> pair = getRulePropertyNameAliasAndValuesForIn(rule, "NOT"); return pair.getKey() + " not in " + pair.getValue(); } if (rule.contains("IN")) { Pair<String, String> pair = getRulePropertyNameAliasAndValuesForIn(rule, "IN"); return pair.getKey() + " in " + pair.getValue(); } if (rule.contains(">")) { return getRulePropertyNameAliasAndValuesForCompare(rule, ">"); } throw new UnsupportedOperationException(); } //{EXP_LEVEL}IN[一般员工] , {ER_LOCATION}NOT IN[北京/上海/深圳] to //data["EXPENSE_LEVEL"] in ("一般员工"), data["city"] not in ("上海","北京","深圳","广州"), private Pair<String, String> getRulePropertyNameAliasAndValuesForIn(final String rule, final String separators) { String name = StringUtils.splitByWholeSeparator(rule, separators)[0]; name = getRulePropertyNameAlias(name).getValue(); name = "data[\"" + name + "\"]"; String value = StringUtils.substring(rule , StringUtils.lastIndexOf(rule, "[") + 1 , StringUtils.lastIndexOf(rule, "]")); List<String> values = Splitter.on("/").trimResults().splitToList(value); value = values.stream().map(t -> "\"" + t + "\"").collect(Collectors.joining(",")); value = "(" + value + ")"; return Pair.of(name, value); } //{ER_EXP_FEE}>{ER_DAYS}*300 to // BigDecimal.valueOf(Double.valueOf(data.["INVOICE_AMOUNT"])) > 300 * Double.valueOf(data["days"]) private String getRulePropertyNameAliasAndValuesForCompare(final String rule, final String separator) { if (!Arrays.asList(">", "<", "=").contains(separator.trim())) { throw new UnsupportedOperationException(); } List<String> list = Splitter.on(separator.trim()).trimResults().splitToList(rule); String express1 = list.get(0); String express2 = list.get(1); String template1 = "BigDecimal.valueOf(Double.valueOf(data[\"%s\"]))"; String tempalte2 = "Double.valueOf(data[\"%s\"])"; Pair<String, String> rulePropertyNameAlias1 = getRulePropertyNameAlias(express1); express1 = String.format(template1, rulePropertyNameAlias1.getValue()); Pair<String, String> rulePropertyNameAlias2 = getRulePropertyNameAlias(express2); express2 = String.format(tempalte2, rulePropertyNameAlias2.getValue()); String replace = rule.replace(rulePropertyNameAlias1.getKey(), express1); replace = replace.replace(rulePropertyNameAlias2.getKey(), express2); return replace; } private Pair<String, String> getRulePropertyNameAlias(final String content) { for (Entry<String, String> entry : rulePropertyNameAlias.entrySet()) { Pattern compile = Pattern.compile(entry.getKey()); Matcher matcher = compile.matcher(content); if (matcher.find()) { String name = content.substring(matcher.regionStart(), matcher.regionEnd()); String aliasName = entry.getValue(); return Pair.of(name, aliasName); } } throw new UnsupportedOperationException(content); } private String generateRuleName() { StringBuilder sb = new StringBuilder(); sb.append(travelRule.getCompanyName()) .append("-") .append(travelRule.getExpenseType()) .append("-") .append(ruleName).append("\""); return sb.toString(); } }
其中
//规则生成
public String Generate() {。。。}
方法主要是drools规则组装的实现。
我们测试一下:
package com.beaver.drools.exampl.travel.rule; import com.beaver.drools.util.KieSessionUtil; import com.google.gson.Gson; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.javafunk.excelparser.SheetParser; import org.kie.api.io.ResourceType; import java.io.IOException; import java.io.InputStream; import java.util.*; import java.util.stream.Collectors; /** * Created by beaver on 2017/5/20. */ public class TravleRuelTest { static String packageName = "com.beaver.drools.exampl.travel.rule"; static List<String> importPackages = Arrays.asList( "java.math.*" , "com.beaver.drools.common.model.*"); static String sheetName = "工作表1"; static String fileName = "腾讯差标规则1.xlsx"; static String objectType = "MatchInvoiceTravelRuleRequestDto"; static String objectVar = "$invoice"; static String resultPropertyName = "result"; static String alertMessagePropertyName = "remarkMessage"; //规则内容属性别名,如{EXP_LEVEL}IN[一般员工],EXP_LEVEL 可以起别名 static Map<String, String> rulePropertyNameAlias = new HashMap<>(); static { rulePropertyNameAlias.put("\\{.*LEVEL.*\\}", "EXPENSE_LEVEL"); rulePropertyNameAlias.put("\\{.*LOCATION.*\\}", "city"); rulePropertyNameAlias.put("\\{.*FEE.*\\}", "INVOICE_AMOUNT"); rulePropertyNameAlias.put("\\{.*DAYS.*\\}", "days"); } public static void main(String[] args) throws IOException { //Get the sheet using POI API. SheetParser parser = new SheetParser(); InputStream inputStream = TravleRuelTest.class.getClassLoader().getResourceAsStream(fileName); Sheet sheet = new XSSFWorkbook(inputStream).getSheet(sheetName); //Invoke the Sheet parser. List<TravelRule> entityList = parser.createEntity(sheet, TravelRule.class, t -> t.printStackTrace()); // entityList = entityList.stream() .filter(t -> t.getCompanyName() != null && !t.getCompanyName().isEmpty()) .collect(Collectors.toList()); System.out.println(new Gson().toJson(entityList)); Set<String> set = entityList.stream().map(TravelRule::getRuleId).collect(Collectors.toSet()); if (set.size() != entityList.size()) { throw new IllegalArgumentException("id 有重复"); } entityList.stream() .map(TravleRuelTest::travelRuleGenerate) .forEach(t -> { System.out.println(t); }); } public static TravelRule travelRuleGenerate(TravelRule travelRule) { TravelRuleGenerate travelRuleGenerate = new TravelRuleGenerate(); travelRuleGenerate.setPackageName(packageName); travelRuleGenerate.setImportPackages(importPackages); travelRuleGenerate.setRuleName(travelRule.getRule()); travelRuleGenerate.setObjectType(objectType); travelRuleGenerate.setObjectVar(objectVar); travelRuleGenerate.setTravelRule(travelRule); travelRuleGenerate.setResultPropertyName(resultPropertyName); travelRuleGenerate.setAlertMessagePropertyName(alertMessagePropertyName); travelRuleGenerate.setRulePropertyNameAlias(rulePropertyNameAlias); String generate = travelRuleGenerate.Generate(); KieSessionUtil kieSessionUtil = new KieSessionUtil(); kieSessionUtil.addContent(generate, ResourceType.DRL); kieSessionUtil.verifyRules(); travelRule.setDroolsRule(generate); return travelRule; } }
输出:
.................................. [ { "companyName": "微民", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[1] AND {ER_EXP_FEE}\u003e{ER_DAYS} *600", "alertMessage": "您的房费高于公司标准", "ruleId": "8a24ef78-d1c4-4c7c-924f-f199fa3c5eb1" }, { "companyName": "微民", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[2] AND {ER_EXP_FEE}\u003e{ER_DAYS}*700", "alertMessage": "您的房费高于公司标准", "ruleId": "f9b17610-7917-4f71-b369-602224fdd20d" }, { "companyName": "微民", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[3] AND {ER_EXP_FEE}\u003e{ER_DAYS}*800", "alertMessage": "您的房费高于公司标准", "ruleId": "128e621a-832a-4876-81c8-a5a9624b6ca7" }, { "companyName": "微民", "expenseType": "差旅补贴", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{ER_LOCATION_COUNTRY}IN[中国] AND {ER_EXP_FEE}\u003e{ER_DAYS}*140", "alertMessage": "您的补贴高于公司标准", "ruleId": "06d1afc9-4a0e-4ad6-b0b1-01af068997fe" }, { "companyName": "微民", "expenseType": "差旅补贴", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{ER_LOCATION_COUNTRY}NOT IN[中国] AND {ER_EXP_FEE}\u003e{ER_DAYS}*400", "alertMessage": "您的补贴高于公司标准", "ruleId": "922d99ff-c5bc-4f26-a365-d8b6e8a9a999" }, { "companyName": "腾南", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[一般员工] AND {ER_EXP_FEE}\u003e{ER_DAYS}*400", "alertMessage": "您的房费高于公司标准", "ruleId": "7c170ce0-080e-499a-9046-0dc7d226b86c" }, { "companyName": "腾南", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[一般员工] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}\u003e{ER_DAYS}*300", "alertMessage": "您的房费高于公司标准", "ruleId": "6135e677-867b-41ed-8d00-7512b5ec5c2a" }, { "companyName": "腾南", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[总监] AND {ER_EXP_FEE}\u003e{ER_DAYS}*550", "alertMessage": "您的房费高于公司标准", "ruleId": "636ebfda-6d78-4ec7-a441-234ff931fa57" }, { "companyName": "腾南", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[总监] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}\u003e{ER_DAYS}*400", "alertMessage": "您的房费高于公司标准", "ruleId": "b236a113-e547-4f65-9ddc-3b9549efa6ce" }, { "companyName": "腾南", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[总裁] AND {ER_EXP_FEE}\u003e{ER_DAYS}*700", "alertMessage": "您的房费高于公司标准", "ruleId": "8bb7e480-bf94-4c24-a46e-963ae60bee7e" }, { "companyName": "腾南", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}\u003e{ER_DAYS}*500", "alertMessage": "您的房费高于公司标准", "ruleId": "f74d0d7c-d31d-49d9-84ff-c0889bf37771" }, { "companyName": "腾南", "expenseType": "差旅补贴", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{ER_EXP_FEE}\u003e{ER_DAYS}*80", "alertMessage": "您的补贴高于公司标准", "ruleId": "154866b0-fdc5-433f-9c3f-640e9a812564" }, { "companyName": "腾新", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}IN[总裁] AND {ER_EXP_FEE}\u003e{ER_DAYS}*600", "alertMessage": "您的房费高于公司标准", "ruleId": "e4ece4c7-f9ca-46fc-bb7b-2a4443513daf" }, { "companyName": "腾新", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}NOT IN[总裁] AND {ER_EXP_FEE}\u003e{ER_DAYS}*500", "alertMessage": "您的房费高于公司标准", "ruleId": "51768055-8a13-4d44-9c61-e261bcb74149" }, { "companyName": "腾新", "expenseType": "住宿费", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{EXP_LEVEL}NOT IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳/成都/广州/杭州] AND {ER_EXP_FEE}\u003e{ER_DAYS}*400", "alertMessage": "您的房费高于公司标准", "ruleId": "0d3f86b6-f937-4544-916d-8fac5061c479" }, { "companyName": "腾新", "expenseType": "差旅补贴", "applyPoint": "ER_SUBMIT", "ruleAction": "REJECT", "rule": "{ER_EXP_FEE}\u003e{ER_DAYS}*100", "alertMessage": "您的补贴高于公司标准", "ruleId": "a9c0f423-7880-4f86-a761-ba2f2ec83c66" } ] ..................... TravelRule{companyName='微民', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[1] AND {ER_EXP_FEE}>{ER_DAYS} *600', alertMessage='您的房费高于公司标准', ruleId='8a24ef78-d1c4-4c7c-924f-f199fa3c5eb1', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "微民-住宿费-{EXP_LEVEL}IN[1] AND {ER_EXP_FEE}>{ER_DAYS} *600" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("1"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='微民', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[2] AND {ER_EXP_FEE}>{ER_DAYS}*700', alertMessage='您的房费高于公司标准', ruleId='f9b17610-7917-4f71-b369-602224fdd20d', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "微民-住宿费-{EXP_LEVEL}IN[2] AND {ER_EXP_FEE}>{ER_DAYS}*700" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("2"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='微民', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[3] AND {ER_EXP_FEE}>{ER_DAYS}*800', alertMessage='您的房费高于公司标准', ruleId='128e621a-832a-4876-81c8-a5a9624b6ca7', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "微民-住宿费-{EXP_LEVEL}IN[3] AND {ER_EXP_FEE}>{ER_DAYS}*800" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("3"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='微民', expenseType='差旅补贴', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{ER_LOCATION_COUNTRY}IN[中国] AND {ER_EXP_FEE}>{ER_DAYS}*140', alertMessage='您的补贴高于公司标准', ruleId='06d1afc9-4a0e-4ad6-b0b1-01af068997fe', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "微民-差旅补贴-{ER_LOCATION_COUNTRY}IN[中国] AND {ER_EXP_FEE}>{ER_DAYS}*140" when $invoice : MatchInvoiceTravelRuleRequestDto( data["city"] in ("中国"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的补贴高于公司标准 "); end'} TravelRule{companyName='微民', expenseType='差旅补贴', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{ER_LOCATION_COUNTRY}NOT IN[中国] AND {ER_EXP_FEE}>{ER_DAYS}*400', alertMessage='您的补贴高于公司标准', ruleId='922d99ff-c5bc-4f26-a365-d8b6e8a9a999', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "微民-差旅补贴-{ER_LOCATION_COUNTRY}NOT IN[中国] AND {ER_EXP_FEE}>{ER_DAYS}*400" when $invoice : MatchInvoiceTravelRuleRequestDto( data["city"] not in ("中国"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的补贴高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[一般员工] AND {ER_EXP_FEE}>{ER_DAYS}*400', alertMessage='您的房费高于公司标准', ruleId='7c170ce0-080e-499a-9046-0dc7d226b86c', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-住宿费-{EXP_LEVEL}IN[一般员工] AND {ER_EXP_FEE}>{ER_DAYS}*400" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("一般员工"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[一般员工] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*300', alertMessage='您的房费高于公司标准', ruleId='6135e677-867b-41ed-8d00-7512b5ec5c2a', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-住宿费-{EXP_LEVEL}IN[一般员工] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*300" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("一般员工"), data["city"] not in ("北京","上海","深圳"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[总监] AND {ER_EXP_FEE}>{ER_DAYS}*550', alertMessage='您的房费高于公司标准', ruleId='636ebfda-6d78-4ec7-a441-234ff931fa57', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-住宿费-{EXP_LEVEL}IN[总监] AND {ER_EXP_FEE}>{ER_DAYS}*550" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("总监"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[总监] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*400', alertMessage='您的房费高于公司标准', ruleId='b236a113-e547-4f65-9ddc-3b9549efa6ce', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-住宿费-{EXP_LEVEL}IN[总监] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*400" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("总监"), data["city"] not in ("北京","上海","深圳"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[总裁] AND {ER_EXP_FEE}>{ER_DAYS}*700', alertMessage='您的房费高于公司标准', ruleId='8bb7e480-bf94-4c24-a46e-963ae60bee7e', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-住宿费-{EXP_LEVEL}IN[总裁] AND {ER_EXP_FEE}>{ER_DAYS}*700" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("总裁"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*500', alertMessage='您的房费高于公司标准', ruleId='f74d0d7c-d31d-49d9-84ff-c0889bf37771', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-住宿费-{EXP_LEVEL}IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳] AND {ER_EXP_FEE}>{ER_DAYS}*500" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("总裁"), data["city"] not in ("北京","上海","深圳"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾南', expenseType='差旅补贴', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{ER_EXP_FEE}>{ER_DAYS}*80', alertMessage='您的补贴高于公司标准', ruleId='154866b0-fdc5-433f-9c3f-640e9a812564', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾南-差旅补贴-{ER_EXP_FEE}>{ER_DAYS}*80" when $invoice : MatchInvoiceTravelRuleRequestDto( BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的补贴高于公司标准 "); end'} TravelRule{companyName='腾新', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}IN[总裁] AND {ER_EXP_FEE}>{ER_DAYS}*600', alertMessage='您的房费高于公司标准', ruleId='e4ece4c7-f9ca-46fc-bb7b-2a4443513daf', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾新-住宿费-{EXP_LEVEL}IN[总裁] AND {ER_EXP_FEE}>{ER_DAYS}*600" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] in ("总裁"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾新', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}NOT IN[总裁] AND {ER_EXP_FEE}>{ER_DAYS}*500', alertMessage='您的房费高于公司标准', ruleId='51768055-8a13-4d44-9c61-e261bcb74149', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾新-住宿费-{EXP_LEVEL}NOT IN[总裁] AND {ER_EXP_FEE}>{ER_DAYS}*500" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] not in ("总裁"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾新', expenseType='住宿费', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{EXP_LEVEL}NOT IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳/成都/广州/杭州] AND {ER_EXP_FEE}>{ER_DAYS}*400', alertMessage='您的房费高于公司标准', ruleId='0d3f86b6-f937-4544-916d-8fac5061c479', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾新-住宿费-{EXP_LEVEL}NOT IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳/成都/广州/杭州] AND {ER_EXP_FEE}>{ER_DAYS}*400" when $invoice : MatchInvoiceTravelRuleRequestDto( data["EXPENSE_LEVEL"] not in ("总裁"), data["city"] not in ("北京","上海","深圳","成都","广州","杭州"), BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的房费高于公司标准 "); end'} TravelRule{companyName='腾新', expenseType='差旅补贴', applyPoint='ER_SUBMIT', ruleAction='REJECT', rule='{ER_EXP_FEE}>{ER_DAYS}*100', alertMessage='您的补贴高于公司标准', ruleId='a9c0f423-7880-4f86-a761-ba2f2ec83c66', droolsRule='package com.beaver.drools.exampl.travel.rule import java.math.* import com.beaver.drools.common.model.* rule "腾新-差旅补贴-{ER_EXP_FEE}>{ER_DAYS}*100" when $invoice : MatchInvoiceTravelRuleRequestDto( BigDecimal.valueOf(Double.valueOf(data["INVOICE_AMOUNT"]))>Double.valueOf(data["days"]) ) then $invoice.setResult(RuleResult.REJECT); $invoice.setRemarkMessage("您的补贴高于公司标准 "); end'} Process finished with exit code 0
每产生一个规则,都用drools引擎校验了一下,以防出错。
上面只是对简单的规则如:
{EXP_LEVEL}NOT IN[总裁] AND {ER_LOCATION}NOT IN[北京/上海/深圳/成都/广州/杭州] AND {ER_EXP_FEE}>{ER_DAYS}*400 |
https://github.com/antlr/antlr4 https://github.com/antlr/stringtemplate4 http://freemarker.org
这些工具更简单呢,后面学习一下第一个工具,再试试。
本文代码地址:
https://github.com/sdcuike/drools-example/tree/2017-05-21/src/main/java/com/beaver/drools/exampl/travel/rule
相关文章推荐
- Web Service 简单实例(java 版本) ,IDE自动生成客户端代码方法
- IBM将公布能够自动生成Java代码的编程工具
- Java生成静态页面的简单方法和代码
- UML工具推荐 Poseidon版本 可以免费下载,自动生成代码 C++ Java C# VB.NET等 (来自德国汉堡的国际性建模软件开发商Gentleware AG的)
- java 自动生成略缩图示例代码
- 在Eclipse里利用javah把java代码声明的JNI方法自动生成成C\C++头文件
- [C#]一步一步开发自己的自动代码生成工具之四:简单三层代码模板实例Model层
- CXF 2.6.1 中WSDL2Java自动生成代码super出错
- 利用Velocity自动生成自定义代码_java版_源码下载
- MyBatisGenerator 自动生成java代码(反向工具)
- java如何在eclipse编译时自动生成代码
- Java Web开发中可否自动生成结构一致的代码?
- java 代码自动生成getAndset
- java代码自动生成
- Lombok — Java代码自动生成 开发利器
- java代码自动生成
- java,jsp生成UUID 超简单,只需一行代码
- oracle script : java 实体互相付值自动匹配 ,自动生成代码
- java中的代码生成工具简单罗列
- mybatis-generator自动生成java代码和配置文件的注意事项