package org.dayatang.rule.impl;
import org.dayatang.rule.RuleRuntimeException;
import org.dayatang.rule.StatelessRuleService;
import org.dayatang.rule.UnSupportedRuleFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.rules.InvalidRuleSessionException;
import javax.rules.RuleRuntime;
import javax.rules.RuleServiceProvider;
import javax.rules.StatelessRuleSession;
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.rmi.RemoteException;
import java.util.List;
import java.util.Map;
/**
* 无状态规则服务的实现类,用JSR94实现。
*
* @author yyang (<a href="mailto:gdyangyu@gmail.com">gdyangyu@gmail.com</a>) <a href="mailto:gdyangyu@gmail.com">杨宇</a>
*/
@SuppressWarnings("rawtypes")
public class StatelessRuleServiceJsr94 implements StatelessRuleService {
private static final long serialVersionUID = -6550908446842944288L;
private static Logger LOGGER = LoggerFactory.getLogger(StatelessRuleServiceJsr94.class);
private StatelessRuleSession session;
private StatelessRuleServiceJsr94(RuleServiceProvider ruleServiceProvider, Map serviceProviderProperties,
Object ruleSource, Map executionSetProperties, Map sessionProperties) {
//this.ruleServiceProvider = ruleServiceProvider;
//this.serviceProviderProperties = serviceProviderProperties;
//this.ruleSource = ruleSource;
//this.executionSetProperties = executionSetProperties;
//this.sessionProperties = sessionProperties;
LOGGER.info("The rule service provider of JSR94 is " + ruleServiceProvider.getClass());
try {
RuleAdministrator ruleAdministrator = ruleServiceProvider.getRuleAdministrator();
LocalRuleExecutionSetProvider ruleExecutionSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider(serviceProviderProperties);
RuleRuntime ruleRuntime = ruleServiceProvider.getRuleRuntime();
RuleExecutionSet ruleExecutionSet = createRuleExecutionSet(ruleExecutionSetProvider, ruleSource, executionSetProperties);
String packageName = ruleExecutionSet.getName();
ruleAdministrator.registerRuleExecutionSet(packageName, ruleExecutionSet, null);
session = (StatelessRuleSession) ruleRuntime.createRuleSession(packageName, sessionProperties, RuleRuntime.STATELESS_SESSION_TYPE);
} catch (Exception e) {
throw new RuleRuntimeException(e);
}
}
private RuleExecutionSet createRuleExecutionSet(LocalRuleExecutionSetProvider ruleExecutionSetProvider,
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);
}
}
@Override
public List executeRules(List facts) {
try {
return session.executeRules(facts);
} catch (InvalidRuleSessionException e) {
throw new RuleRuntimeException("Invalid Rule Session.", e);
} catch (RemoteException e) {
throw new IllegalStateException(e);
}
}
public void release() {
try {
session.release();
} catch (Exception e) {
throw new RuleRuntimeException("Cannot release rule session!!", e);
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private RuleServiceProvider ruleServiceProvider;
private Map serviceProviderProperties;
private Map executionSetProperties;
private Map sessionProperties;
private Object ruleSource;
/**
* 设置规则服务提供者,例如Drools
* @param ruleServiceProvider 要设置的规则服务提供者
* @return
*/
public Builder ruleServiceProvider(RuleServiceProvider ruleServiceProvider) {
this.ruleServiceProvider = ruleServiceProvider;
return this;
}
/**
* 设置规则服务提供者特定的属性
* @param serviceProviderProperties 要设置的规则服务提供者属性
* @return
*/
public Builder serviceProviderProperties(Map serviceProviderProperties) {
this.serviceProviderProperties = serviceProviderProperties;
return this;
}
/**
* 设置规则执行集属性(如:source=drl/xml dsl=java.io.Reader)
* @param executionSetProperties 要设置的规则执行集属性
* @return
*/
public Builder executionSetProperties(Map executionSetProperties) {
this.executionSetProperties = executionSetProperties;
return this;
}
/**
* 设置会话属性(如全局变量等)
* @param sessionProperties 要设置的会话属性
* @return
*/
public Builder sessionProperties(Map sessionProperties) {
this.sessionProperties = sessionProperties;
return this;
}
/**
* 设置规则源
* @param ruleSource 要设置的规则源
* @return
*/
public Builder ruleSource(Object ruleSource) {
this.ruleSource = ruleSource;
return this;
}
public StatelessRuleServiceJsr94 bulid() {
if (ruleServiceProvider == null) {
throw new IllegalStateException("Rule Service Provider not assigned");
}
if (ruleSource == null) {
throw new IllegalStateException("Rule Source not assigned");
}
return new StatelessRuleServiceJsr94(ruleServiceProvider, serviceProviderProperties,
ruleSource, executionSetProperties, sessionProperties);
}
}
}