package org.dayatang.rule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.rules.RuleRuntime;
import javax.rules.RuleServiceProvider;
import javax.rules.StatefulRuleSession;
import javax.rules.admin.LocalRuleExecutionSetProvider;
import javax.rules.admin.RuleAdministrator;
import javax.rules.admin.RuleExecutionSet;
import javax.rules.admin.RuleExecutionSetCreateException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
/**
* 有状态规则服务模板类。负责创建StatefulRuleSession,执行规则和关闭StatefulRuleSession。
* 建立这个类的目的,一是消除了客户代码自行创建StatefulRuleSession的必要性,二是为了防止客户代码执行规则之后忘记释放StatefulRuleSession。
* @author yyang (<a href="mailto:gdyangyu@gmail.com">gdyangyu@gmail.com</a>) <a href="mailto:gdyangyu@gmail.com">杨宇</a>
*
*/
@SuppressWarnings("rawtypes")
public class StatefulRuleTemplate {
private static Logger LOGGER = LoggerFactory.getLogger(StatefulRuleTemplate.class);
private Map sessionProperties = new HashMap();
private RuleAdministrator ruleAdministrator;
private LocalRuleExecutionSetProvider ruleExecutionSetProvider;
private RuleRuntime ruleRuntime;
private RuleExecutionSet ruleExecutionSet;
public final StatefulRuleTemplate sessionProperties(Map sessionProperties) {
this.sessionProperties = sessionProperties;
return this;
}
/**
* 从指定的来源读取规则集
* @param ruleSource 规则定义源
* @param executionSetProperties 规则的属性Map(如:source=drl/xml dsl=java.io.Reader)
* @return
*/
public final StatefulRuleTemplate ruleSource(Object ruleSource, Map executionSetProperties) {
try {
if (ruleSource instanceof String) {
this.ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet(new StringReader((String) ruleSource), executionSetProperties);
} else if (ruleSource instanceof Reader) {
this.ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet((Reader) ruleSource, executionSetProperties);
} else if (ruleSource instanceof InputStream) {
this.ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet((InputStream) ruleSource, executionSetProperties);
} else {
this.ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet(ruleSource, executionSetProperties);
}
} catch (RuleExecutionSetCreateException e) {
throw new UnSupportedRuleFormatException(e);
} catch (IOException e) {
throw new UnSupportedRuleFormatException(e);
}
return this;
}
/**
* 从指定的来源读取规则集
* @param ruleSource 规则定义源
* @return
*/
public final StatefulRuleTemplate ruleSource(Object ruleSource) {
return ruleSource(ruleSource, null);
}
/**
* 构造函数
* @param ruleServiceProvider 规则服务提供者实现类,如Drools等。
*/
public StatefulRuleTemplate(RuleServiceProvider ruleServiceProvider) {
this(ruleServiceProvider, null);
}
/**
* 构造函数
* @param ruleServiceProvider 规则服务提供者实现类,如Drools等。
* @param serviceProviderProperties 具体规则服务提供者所需要的额外属性
*/
public StatefulRuleTemplate(RuleServiceProvider ruleServiceProvider, Map serviceProviderProperties) {
try {
ruleAdministrator = ruleServiceProvider.getRuleAdministrator();
ruleExecutionSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider(serviceProviderProperties);
ruleRuntime = ruleServiceProvider.getRuleRuntime();
LOGGER.info("The rule service provider of JSR94 is " + ruleServiceProvider.getClass());
} catch (Exception e) {
throw new RuleRuntimeException(e);
}
}
private RuleExecutionSet createRuleExecutionSet(Object ruleSource, Map executionSetProperties) {
try {
if (ruleSource instanceof String) {
Reader reader = new StringReader((String) ruleSource);
return ruleExecutionSetProvider.createRuleExecutionSet(reader, executionSetProperties);
}
if (ruleSource instanceof Reader) {
Reader reader = (Reader) ruleSource;
return ruleExecutionSetProvider.createRuleExecutionSet(reader, executionSetProperties);
}
if (ruleSource instanceof InputStream) {
InputStream in = (InputStream) ruleSource;
return ruleExecutionSetProvider.createRuleExecutionSet(in, executionSetProperties);
}
return ruleExecutionSetProvider.createRuleExecutionSet(ruleSource, executionSetProperties);
} catch (RuleExecutionSetCreateException e) {
throw new UnSupportedRuleFormatException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 提供StatefulRuleSession给StatefulRuleCallback执行
* @param callback
* @throws Exception
*/
public void execute(StatefulRuleCallback callback) throws Exception {
StatefulRuleSession session = getStatefulRuleSession();
try {
callback.doInRuleSession(session);
} finally {
releaseStatefulRuleSession(session);
}
}
private void releaseStatefulRuleSession(StatefulRuleSession session) {
try {
session.release();
} catch (Exception e) {
throw new RuleRuntimeException("Cannot release rule session!!", e);
}
}
/**
* 获取StatefulRuleSession。客户代码要记得在使用StatefulRuleSession之后通过调用其release()方法释放资源。
* @return
*/
public StatefulRuleSession getStatefulRuleSession() {
try{
String ruleExecutionSetUri = ruleExecutionSet.getName();
ruleAdministrator.registerRuleExecutionSet(ruleExecutionSetUri, ruleExecutionSet, null);
return (StatefulRuleSession) ruleRuntime.createRuleSession(ruleExecutionSetUri, sessionProperties, RuleRuntime.STATEFUL_SESSION_TYPE);
} catch (Exception e) {
e.printStackTrace();
throw new RuleRuntimeException("Cannot create Rule Session!!!", e);
}
}
}