Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.cedarsoftware.ncube.rules
import com.cedarsoftware.ncube.ApplicationID
import com.cedarsoftware.ncube.Axis
import com.cedarsoftware.ncube.Column
import com.cedarsoftware.ncube.GroovyExpression
import com.cedarsoftware.ncube.NCube
import com.cedarsoftware.util.ReflectionUtils
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import java.lang.reflect.Method
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
import java.util.regex.Matcher
import java.util.regex.Pattern
import static com.cedarsoftware.ncube.AxisType.RULE
import static com.cedarsoftware.ncube.NCubeAppContext.getNcubeRuntime
import static com.cedarsoftware.ncube.NCubeConstants.INPUT_VALUE
import static com.cedarsoftware.ncube.NCubeConstants.OUTPUT_VALUE
import static com.cedarsoftware.ncube.NCubeConstants._OR_
import static com.cedarsoftware.util.StringUtilities.hasContent
@Slf4j
@CompileStatic
class RulesEngine
{
static final String AXIS_RULE = 'rules'
static final String COL_CLASS = 'className'
static final String COL_NCUBE = 'ncube'
static final String COL_RULE_GROUP = 'ruleGroup'
static final String COL_EXCEPTION = 'throwException'
private static final Set IGNORED_METHODS = ['equals', 'toString', 'hashCode', 'annotationType'] as Set
private static final Pattern PATTERN_METHOD_NAME = Pattern.compile(".*input\\.rule\\.((?:[^(]+))\\(.*")
private static final Pattern PATTERN_NCUBE_NAME = Pattern.compile(".*'(rule.(?:[^']+))'.*", Pattern.DOTALL)
protected volatile boolean verificationComplete = false
private ConcurrentMap verifiedOrchestrations = new ConcurrentHashMap<>()
private String name
private ApplicationID appId
private String rules
private NCube ncubeRules
RulesEngine(String name, ApplicationID appId, String rules)
{
this.name = name
this.appId = appId
this.rules = rules
}
/**
* Name of the RuleEngine
* @return String
*/
String getName()
{
return name
}
/**
* ApplicationID associated with the RuleEngine
* @return ApplicationID
*/
ApplicationID getAppId()
{
return appId
}
/**
* Low level execution. Execute rules, in order, for a list of named groups on a given root object.
* Each group will be executed in order. If any errors are recorded during execution for a given group, execution
* will not proceed to the next group.
* @param ruleGroups List
* @param root Object
* @param input Map (optional)
* @param output Map (optional)
* @return List
* @throws RulesException if any errors are recorded during execution
*/
List executeGroups(List ruleGroups, Object root, Map input = [:], Map output = [:])
{
// if you make a change here, also make a change in generateDocumentationForGroups()
verifyNCubeSetup()
if (ruleGroups == null)
{
throw new IllegalArgumentException("Rule groups to execute must not be null")
}
List errors = []
if (ruleGroups.empty)
{
return errors
}
List ruleGroupsForDecision = []
ruleGroupsForDecision.add(_OR_)
ruleGroupsForDecision.addAll(ruleGroups)
Map decision = (Map) ncubeRules.decisionTable.getDecision([(COL_RULE_GROUP): ruleGroupsForDecision])
Map> ruleGroupIndex = [:]
for (Comparable key : decision.keySet())
{
Map row = (Map) decision[key]
String ruleGroup = row[COL_RULE_GROUP]
ruleGroupIndex[ruleGroup] = row
}
for (String ruleGroup : ruleGroups)
{
Map ruleInfo = ruleGroupIndex[ruleGroup]
if (!ruleInfo)
{
log.info("RulesEngine: ${name}, AppId: ${appId}, NCube: ${ncubeRules.name}, rule group ${ruleGroup} is not defined.")
continue
}
String className = ruleInfo[COL_CLASS]
String ncubeName = ruleInfo[COL_NCUBE]
Boolean throwException = ruleInfo[COL_EXCEPTION]
if (!hasContent(className) || !hasContent(ncubeName))
{
throw new IllegalStateException("RulesEngine: ${name}, AppId: ${appId}, NCube: ${ncubeRules.name}, rule group: ${ruleGroup} must have className and ncube name defined.")
}
BusinessRule rule = (BusinessRule) Class.forName(className).newInstance(root)
rule.init(appId, input, output)
NCube ncube = ncubeRuntime.getCube(appId, ncubeName)
if (!ncube)
{
throw new IllegalStateException("RulesEngine: ${name}, AppId: ${appId}, NCube defined in ${COL_NCUBE} column of ${ncubeRules.name} does not exist.")
}
verifyOrchestration(ncube)
ncube.getCell(input, output)
errors.addAll(rule.errors)
if (throwException && !errors.empty)
{
throw new RulesException(errors)
}
}
return errors
}
/**
* Execute rules for a named group on a given root object.
* @param ruleGroups String
* @param root Object
* @param input Map (optional)
* @param output Map (optional)
* @return List
* @throws RulesException if any errors are recorded during execution
*/
List execute(String ruleGroup, Object root, Map input = [:], Map output = [:])
{
if (ruleGroup == null)
{
throw new IllegalArgumentException("Rule group must not be null.")
}
verifyNCubeSetup()
return executeGroups([ruleGroup], root, input, output)
}
/**
* Execute rules by defined by categories. Use the categories Map to define which categories apply for rule execution.
* Example Map: [product: 'workerscompensation', type: 'validation']
* The value for a given key can also be a List which will act like a logic OR for selection.
* Example Map: [product: 'workerscompensation', type: ['composition', 'validation']]
* @param categories Map see DecisionTable
* @param root Object
* @param input Map (optional)
* @param output Map (optional)
* @return List
* @throws RulesException if any errors are recorded during execution
*/
List execute(Map categories, Object root, Map input = [:], Map output = [:])
{
verifyNCubeSetup()
List ruleGroups = getRuleGroupsFromDecisionTable(categories)
return executeGroups(ruleGroups, root, input, output)
}
/**
* Execute rules by defined by categories. Use the categories List to define which categories apply for rule execution.
* Similar to executeGroups() which takes a Map, but provides an additional way to specify multiple groups.
* @param categories Iterable see DecisionTable
* @param root Object
* @param input Map (optional)
* @param output Map (optional)
* @return List
* @throws RulesException if any errors are recorded during execution
*/
List execute(Iterable