<!--drools-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>5.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>5.5.0.Final</version>
</dependency>
package com.sprucetec.tms.fee.service.impl.rule;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.sprucetec.tms.fee.utils.RuleBaseFacatory;
import com.sprucetec.tms.fee.service.rule.RuleEngineService;
import org.drools.RuleBase;
import org.drools.StatefulSession;
import org.drools.compiler.PackageBuilder;
import org.drools.spi.AgendaFilter;
import org.springframework.stereotype.Service;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
/**
* Created by duyinqiang on 2016/12/12.
* 規則接口實現類 .
*/
@Service
public class RuleEngineServiceImpl implements RuleEngineService {
private RuleBase ruleBase;
/**
* 初始化規則引擎.
*
* @param drlRuleDomains
*/
public void initEngine(List<String> drlRuleDomains) {
// 設置時間格式
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
try {
synchronized (this) {
ruleBase = RuleBaseFacatory.getRuleBase();
// 從DB加載規則
PackageBuilder backageBuilder = this.getPackBuilderFromDrlDB(drlRuleDomains);
ruleBase.addPackages(backageBuilder.getPackages());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public <T> T executeRuleEngine(List<String> drlRuleDomains, T t) {
if (CollectionUtils.isEmpty(drlRuleDomains)) {
return t;
}
this.initEngine(drlRuleDomains);
if (null == ruleBase.getPackages() || 0 == ruleBase.getPackages().length) {
return null;
}
StatefulSession statefulSession = ruleBase.newStatefulSession();
statefulSession.insert(t);
// fire
statefulSession.fireAllRules(new AgendaFilter() {
@Override
public boolean accept(org.drools.spi.Activation activation) {
return !activation.getRule().getName().contains("_test");
}
});
statefulSession.dispose();
return t;
}
/**
* 從Drl規則DB中讀取規則
*
* @return
* @throws Exception
*/
private PackageBuilder getPackBuilderFromDrlDB(List<String> drlRuleDomains) {
// 裝載規則
List<Reader> readers = this.buildReadersFromDrlDB(drlRuleDomains);
// 裝載PackageBuilder
try {
return this.buildPackageBuilder(readers);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 裝載PackageBuilder
*
* @param readers
* @return
* @throws Exception
*/
private PackageBuilder buildPackageBuilder(List<Reader> readers)
throws Exception {
if (null == readers || 0 == readers.size()) {
return null;
}
PackageBuilder backageBuilder = new PackageBuilder();
for (Reader r : readers) {
backageBuilder.addPackageFromDrl(r);
}
// 檢查腳本是否有問題
if (backageBuilder.hasErrors()) {
throw new Exception(backageBuilder.getErrors().toString());
}
return backageBuilder;
}
/**
* 裝載db中的規則到List<Reader>
*
* @return
*/
private List<Reader> buildReadersFromDrlDB(List<String> drlRuleDomains) {
List<Reader> readers = new ArrayList<Reader>();
if (null == drlRuleDomains) {
return readers;
}
for (String ruleContext : drlRuleDomains) {
Reader br = new StringReader(ruleContext);
readers.add(br);
}
return readers;
}
}
package com.sprucetec.tms.fee.utils;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.google.common.collect.Lists;
import com.sprucetec.tms.fee.entity.rule.TemFeeCalculateRule;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import java.util.List;
/**
* Created by meicai on 2016/12/12.
* RuleBaseFacatory 規則基礎工廠 .
*/
public class RuleBaseFacatory {
private static RuleBase ruleBase;
/**
* 單實例RuleBase生成工具.
*
* @return
*/
public static RuleBase getRuleBase() {
return null != ruleBase ? ruleBase : RuleBaseFactory.newRuleBase();
}
/**
* 構建規則對象.
*
* @param temFeeCalculateRules 規則實力對象集合.
* @return
*/
public static List<String> getDroolsRuleDomains(List<TemFeeCalculateRule> temFeeCalculateRules) {
List<String> domains = Lists.newArrayList();
if (CollectionUtils.isEmpty(temFeeCalculateRules)) {
return domains;
}
String domain = "";
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(temFeeCalculateRules.get(0).getPackageName() + "\n");
stringBuffer.append("import com.sprucetec.tms.fee.entity.rule.*;" + "\n");//對應於規則文件的實體對象所放的包
stringBuffer.append("import java.math.*;" + "\n");
stringBuffer.append("import java.lang.*;" + "\n");
stringBuffer.append("import java.io.*" + "\n");
stringBuffer.append("import java.util.*" + "\n");
for (int i = 0; i < temFeeCalculateRules.size(); i++) {
stringBuffer.append("rule " + temFeeCalculateRules.get(i).getRuleName() + "_" + i + "\n");//規則名稱
if (StringUtils.isNotEmpty(temFeeCalculateRules.get(i).getDateEffective())) {
stringBuffer.append("date-effective '" + temFeeCalculateRules.get(i).getDateEffective() + "'\n");//啓用時間
}
if (StringUtils.isNotEmpty(temFeeCalculateRules.get(i).getDateExpires())) {
stringBuffer.append("date-expires '" + temFeeCalculateRules.get(i).getDateExpires() + "'\n");//過期時間
}
stringBuffer.append("lock-on-active " + temFeeCalculateRules.get(i).getLockOnActive() + "\n");//規則是否循環執行
stringBuffer.append("salience " + temFeeCalculateRules.get(i).getSalience() + "\n" + "when" + "\n");//優先級
stringBuffer.append(temFeeCalculateRules.get(i).getRuleWhen() + "\n");//條件
stringBuffer.append("then" + "\n");
stringBuffer.append(temFeeCalculateRules.get(i).getRuleThen() + ";\n");//返回
stringBuffer.append("end" + "\n");
}
domain=stringBuffer + "";
domains.add(domain);
return domains;
}
}