简单drools规则java代码自动生成

简单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 文件提供规则描述,解析动态生成规则,如果产品给的是决策表,那就很容易了,不过产品一般会根据自己的喜好,制定自己的"决策表".

  比如:(一行放不下,截取了两种图)
简单drools规则java代码自动生成_第1张图片

      博文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 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.
* 简单规则组成,并不不包含drools复杂的语法规则 */ public class TravelRuleGenerate { //规则包名 private String packageName; //规则需要外部类的包 private List 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 rulePropertyNameAlias = new HashMap<>(); public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public List getImportPackages() { return importPackages; } public void setImportPackages(List 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 getRulePropertyNameAlias() { return rulePropertyNameAlias; } public void setRulePropertyNameAlias(Map 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 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.
* 简单规则组成,并不不包含drools复杂的语法规则 */ public class TravelRuleGenerate { //规则包名 private String packageName; //规则需要外部类的包 private List 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 rulePropertyNameAlias = new HashMap<>(); public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public List getImportPackages() { return importPackages; } public void setImportPackages(List 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 getRulePropertyNameAlias() { return rulePropertyNameAlias; } public void setRulePropertyNameAlias(Map 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 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 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 ruelList = Splitter.on(Pattern.compile("AND")).trimResults().splitToList(rule); List 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 pair = getRulePropertyNameAliasAndValuesForIn(rule, "NOT"); return pair.getKey() + " not in " + pair.getValue(); } if (rule.contains("IN")) { Pair 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 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 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 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 rulePropertyNameAlias1 = getRulePropertyNameAlias(express1); express1 = String.format(template1, rulePropertyNameAlias1.getValue()); Pair 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 getRulePropertyNameAlias(final String content) { for (Entry 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 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 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 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 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


你可能感兴趣的:(java,Drools,管理-代码-文档等自动生成,Drools,JBoss,Rules,规则引擎)