private void ParseRules(XmlNode poTargetXmlNode, WonkaBreRuleSet poTargetRuleSet) { var OpDesc = poTargetXmlNode.Attributes.GetNamedItem(CONST_RULES_OP_ATTR); if (OpDesc != null) { if (OpDesc.Value.ToLower() == "and") { poTargetRuleSet.RulesEvalOperator = RULE_OP.OP_AND; } else if (OpDesc.Value.ToLower() == "or") { poTargetRuleSet.RulesEvalOperator = RULE_OP.OP_OR; } } XmlNodeList ChildNodeList = poTargetXmlNode.ChildNodes; foreach (XmlNode TempChildXmlNode in ChildNodeList) { if (TempChildXmlNode.LocalName == CONST_RULE_TAG) { ParseSingleRule(TempChildXmlNode, poTargetRuleSet); } } }
private WonkaBreRuleSet ParseRuleSet(XmlNode RuleSetXmlNode, bool pbLeafNode = false) { WonkaBreRuleSet CurrentRuleSet = new WonkaBreRuleSet(++(this.RuleSetIdCounter)); AllParsedRuleSets.Add(CurrentRuleSet); var AttrDesc = RuleSetXmlNode.Attributes.GetNamedItem(CONST_RS_FLOW_DESC_ATTR); if (AttrDesc != null) { CurrentRuleSet.Description = AttrDesc.Value; } XmlNodeList ChildNodeList = RuleSetXmlNode.ChildNodes; foreach (XmlNode TempChildXmlNode in ChildNodeList) { if ((TempChildXmlNode.LocalName == CONST_RS_FLOW_TAG) || (TempChildXmlNode.LocalName == CONST_RS_VALID_TAG)) { bool bIsLeafNode = (TempChildXmlNode.LocalName == CONST_RS_VALID_TAG); WonkaBreRuleSet NewChildRuleSet = ParseRuleSet(TempChildXmlNode, bIsLeafNode); if (bIsLeafNode) { var AttrErrLevel = TempChildXmlNode.Attributes.GetNamedItem(CONST_RS_VALID_ERR_ATTR); if (AttrErrLevel != null) { if (AttrErrLevel.Value.ToLower() == CONST_RS_VALID_ERR_WARNING) { NewChildRuleSet.ErrorSeverity = RULE_SET_ERR_LVL.ERR_LVL_WARNING; } else if (AttrErrLevel.Value.ToLower() == CONST_RS_VALID_ERR_SEVERE) { NewChildRuleSet.ErrorSeverity = RULE_SET_ERR_LVL.ERR_LVL_SEVERE; } } } NewChildRuleSet.ParentRuleSetId = CurrentRuleSet.RuleSetId; CurrentRuleSet.AddChildRuleSet(NewChildRuleSet); } else if (TempChildXmlNode.LocalName == CONST_RULES_TAG) { ParseRules(TempChildXmlNode, CurrentRuleSet); } else if (pbLeafNode && (TempChildXmlNode.LocalName == CONST_RS_FAIL_MSG_TAG)) { CurrentRuleSet.CustomFailureMsg = TempChildXmlNode.InnerText; } else if (pbLeafNode && (TempChildXmlNode.LocalName == CONST_RS_CUSTOM_ID_TAG)) { CurrentRuleSet.CustomId = TempChildXmlNode.InnerText; } } return(CurrentRuleSet); }
/// <summary> /// /// This method will begin the evaluation of a RuleTree when applied to both the incoming and current Product /// records. /// /// <param name="poRootRuleSet">The root RuleSet of the RuleTree whose rules are being applied against the provided records</param> /// <param name="poIncomingProduct">The incoming Product record</param> /// <param name="poCurrentProduct">The current Product record (i.e., in the database)</param> /// <param name="poRuleTreeReport">The report that will contain all evaluations of RuleSets in the RuleTree</param> /// <returns>Indicates whether or not the RuleSet evaluated to a success</returns> /// </summary> public static bool MediateRuleTreeExecution(WonkaBreRuleSet poRootRuleSet, WonkaProduct poIncomingProduct, WonkaProduct poCurrentProduct, WonkaBreRuleTreeReport poRuleTreeReport) { bool bRuleTreeResult = true; bRuleTreeResult = MediateRuleSetExecution(poRootRuleSet, poIncomingProduct, poCurrentProduct, poRuleTreeReport); // NOTE: Should we do anything else here? return(bRuleTreeResult); }
public WonkaBreRuleSet ParseRuleTree() { WonkaBreRuleSet NewRootRuleSet = new WonkaBreRuleSet(); NewRootRuleSet.RuleSetId = ++(this.RuleSetIdCounter); NewRootRuleSet.Description = "Root"; this.RootRuleSet = NewRootRuleSet; AllParsedRuleSets.Add(NewRootRuleSet); XmlDocument XmlDoc = new XmlDocument(); if (BreXmlFilepath != null) { XmlDoc.Load(this.BreXmlFilepath); } else { using (var RuleReader = new StringReader(this.BreXmlContents)) { XmlDoc.Load(RuleReader); } } XmlNode RootNode = XmlDoc.LastChild; XmlNodeList FirstTierList = RootNode.ChildNodes; foreach (XmlNode FirstTierNode in FirstTierList) { if (FirstTierNode.LocalName == CONST_RS_FLOW_TAG) { WonkaBreRuleSet NewChildRuleSet = ParseRuleSet(FirstTierNode); NewChildRuleSet.ParentRuleSetId = NewRootRuleSet.RuleSetId; NewRootRuleSet.AddChildRuleSet(NewChildRuleSet); } } return(NewRootRuleSet); }
/// <summary> /// /// This method will flag the failure of a particular RuleSet by /// /// 1.) Setting the error properties on the corresponding RuleSetReport /// 2.) Adding the RuleSetReport to the Failures list /// 3.) Marking the RuleTree as a failure (since the failure of only one RuleSet flags the whole tree) /// /// <param name="poTargetRuleSet">The target RuleSet which will be marked as a failure</param> /// <param name="peRuleSetErrCd">The type of failure for the RuleSet</param> /// <param name="psRuleSetErrMsg">The error message that will provide details about the RuleSet's failure</param> /// <returns>The list of RuleReports that describes the execution of a specific RuleSet</returns> /// </summary> public bool AddResultSetFailure(WonkaBreRuleSet poTargetRuleSet, ERR_CD peRuleSetErrCd, string psRuleSetErrMsg) { bool bResult = true; WonkaBreRuleSetReportNode RuleSetReportNode = FindRuleSetReport(poTargetRuleSet.RuleSetId, false); if (RuleSetReportNode != null) { RuleSetReportNode.ErrorSeverity = poTargetRuleSet.ErrorSeverity; RuleSetReportNode.ErrorCode = peRuleSetErrCd; RuleSetReportNode.ErrorDescription = psRuleSetErrMsg; if ((poTargetRuleSet.ErrorSeverity == RULE_SET_ERR_LVL.ERR_LVL_WARNING) || (poTargetRuleSet.ErrorSeverity == RULE_SET_ERR_LVL.ERR_LVL_SEVERE)) { RuleSetFailures.Add(RuleSetReportNode); OverallRuleTreeResult = ERR_CD.CD_FAILURE; } } return(bResult); }
/// <summary> /// /// This method will apply the Rules of the RuleSet to either one or both of the incoming Product record /// and the current Product record. The collective result of those applied Rules will then determine /// whether or not the RuleSet was evaluated as a success. /// /// <param name="poTargetRuleSet">The RuleSet whose rules are being applied against the provided records</param> /// <param name="poIncomingProduct">The incoming Product record</param> /// <param name="poCurrentProduct">The current Product record (i.e., in the database)</param> /// <param name="poRuleTreeReport">The report that will contain all evaluations of RuleSets in the RuleTree</param> /// <param name="poRuleSetErrorMessage">The buffer that will contain an error message if the 'poTargetRuleSet' fails</param> /// <returns>Indicates whether or not the RuleSet evaluated to a success</returns> /// </summary> private static bool MediateRulesExecution(WonkaBreRuleSet poTargetRuleSet, WonkaProduct poIncomingProduct, WonkaProduct poCurrentProduct, WonkaBreRuleTreeReport poRuleTreeReport, StringBuilder poRuleSetErrorMessage) { bool bRuleSetResult = true; StringBuilder RuleErrorMsgBuilder = new StringBuilder(); List <bool> RuleResultList = new List <bool>(); foreach (WonkaBreRule TempRule in poTargetRuleSet.EvaluativeRules) { bool bRuleResult = true; string sRuleResult = ""; string sFinalRuleErrMsg = ""; RuleErrorMsgBuilder.Clear(); bRuleResult = TempRule.Execute(poIncomingProduct, poCurrentProduct, RuleErrorMsgBuilder); if (TempRule.IsPassive) { if (TempRule.NotOperator) { bRuleResult = !bRuleResult; } } RuleResultList.Add(bRuleResult); if (bRuleResult) { poRuleSetErrorMessage.Append("SUCCESS"); } else { var RuleSetReport = poRuleTreeReport.FindRuleSetReport(poTargetRuleSet.RuleSetId, true); if (RuleSetReport != null) { if (poTargetRuleSet.ErrorSeverity == RULE_SET_ERR_LVL.ERR_LVL_SEVERE) { sRuleResult = "SEVERE"; RuleSetReport.SevereFailureCount++; } else { sRuleResult = "WARNING"; RuleSetReport.WarningFailureCount++; } } sFinalRuleErrMsg = RuleErrorMsgBuilder.ToString() + " / " + poTargetRuleSet.CustomFailureMsg; } poRuleTreeReport.ArchiveRuleExecution(TempRule, bRuleResult ? ERR_CD.CD_SUCCESS : ERR_CD.CD_FAILURE, sRuleResult, sFinalRuleErrMsg); } // Calculate the final outcome of the RuleSet if (RuleResultList.Count > 0) { bRuleSetResult = RuleResultList[0]; foreach (bool bTempRuleResult in RuleResultList) { if (poTargetRuleSet.RulesEvalOperator == RULE_OP.OP_AND) { bRuleSetResult = bRuleSetResult && bTempRuleResult; } else if (poTargetRuleSet.RulesEvalOperator == RULE_OP.OP_OR) { bRuleSetResult = bRuleSetResult || bTempRuleResult; } else { bRuleSetResult = bRuleSetResult && bTempRuleResult; } } } // Only apply the assertive rules if the evaluative rules are applied successfully if (bRuleSetResult && (poTargetRuleSet.AssertiveRules.Count() > 0)) { foreach (WonkaBreRule TempRule in poTargetRuleSet.AssertiveRules) { bool bRuleResult = true; string sRuleResult = ""; string sFinalRuleErrMsg = ""; RuleErrorMsgBuilder.Clear(); bRuleResult = TempRule.Execute(poIncomingProduct, poCurrentProduct, RuleErrorMsgBuilder); RuleResultList.Add(bRuleResult); poRuleSetErrorMessage.Append("SUCCESS"); poRuleTreeReport.ArchiveRuleExecution(TempRule, bRuleResult ? ERR_CD.CD_SUCCESS : ERR_CD.CD_FAILURE, sRuleResult, sFinalRuleErrMsg); } } return(bRuleSetResult); }
/// <summary> /// /// This method helps to direct the navigation of a branch within the RuleTree. If the rules of 'poTargetRuleSet' /// evaluate to a success when applied to the records, then we will continue to traverse the branch by enumerating /// through the child branches that sprout from this node (i.e., by calling this method again recursively). If not, /// we will stop the traversal here and return back to the parent node of 'poTargetRuleSet'. /// /// <param name="poTargetRuleSet">The RuleSet whose rules are being applied against the provided records</param> /// <param name="poIncomingProduct">The incoming Product record</param> /// <param name="poCurrentProduct">The current Product record (i.e., in the database)</param> /// <param name="poRuleTreeReport">The report that will contain all evaluations of RuleSets in the RuleTree</param> /// <returns>Indicates whether or not the RuleSet evaluated to a success</returns> /// </summary> private static bool MediateRuleSetExecution(WonkaBreRuleSet poTargetRuleSet, WonkaProduct poIncomingProduct, WonkaProduct poCurrentProduct, WonkaBreRuleTreeReport poRuleTreeReport) { bool bTotalRuleSetResult = true; bool bTempRulesResult = true; bool bTempRuleSetResult = true; bool bTraverseChildren = true; string sGeneralRuleSetError = "ERROR! One of the rules failed."; StringBuilder RuleSetErrorBuilder = new StringBuilder(); poRuleTreeReport.LastRuleSetExecuted = poTargetRuleSet; /* * GOOD PLACE FOR TESTING * * if (!String.IsNullOrEmpty(poTargetRuleSet.Description)) * { * if (poTargetRuleSet.Description.Contains("Test RuleSet")) * { * int x = 1; * } * } */ bTempRulesResult = MediateRulesExecution(poTargetRuleSet, poIncomingProduct, poCurrentProduct, poRuleTreeReport, RuleSetErrorBuilder); if (bTempRulesResult) { poRuleTreeReport.SetRuleSetStatus(poTargetRuleSet.RuleSetId, poTargetRuleSet.Description, poTargetRuleSet.CustomId, ERR_CD.CD_SUCCESS); } else { poRuleTreeReport.SetRuleSetStatus(poTargetRuleSet.RuleSetId, poTargetRuleSet.Description, poTargetRuleSet.CustomId, ERR_CD.CD_FAILURE); var TargetRuleSetReport = poRuleTreeReport.FindRuleSetReport(poTargetRuleSet.RuleSetId); if ((TargetRuleSetReport.SevereFailureCount > 0) || (TargetRuleSetReport.WarningFailureCount > 0)) { poRuleTreeReport.AddResultSetFailure(poTargetRuleSet, ERR_CD.CD_FAILURE, sGeneralRuleSetError); } bTraverseChildren = false; } if (!bTraverseChildren) { // We should return here, preventing the recursion that will further traverse the branches of the RuleTree return(bTotalRuleSetResult); } foreach (WonkaBreRuleSet ChildRuleSet in poTargetRuleSet.ChildRuleSets) { bTempRuleSetResult = MediateRuleSetExecution(ChildRuleSet, poIncomingProduct, poCurrentProduct, poRuleTreeReport); if (!bTempRuleSetResult) { // NOTE: Currently, this condition will never happen...but at some point, should it? } } return(bTotalRuleSetResult); }
private void ParseSingleRule(XmlNode poRuleXmlNode, WonkaBreRuleSet poTargetRuleSet) { int nNewRuleId = ++(this.RuleIdCounter); string sRuleExpression = poRuleXmlNode.InnerText; WonkaBreRule NewRule = null; if (this.CustomOpSources.Keys.Any(s => sRuleExpression.Contains(s))) { NewRule = new CustomOperatorRule() { RuleId = nNewRuleId } } ; else if (this.ArithmeticLimitOps.Any(s => sRuleExpression.Contains(s))) { NewRule = new ArithmeticLimitRule() { RuleId = nNewRuleId } } ; else if (this.DateLimitOps.Any(s => sRuleExpression.Contains(s))) { NewRule = new DateLimitRule() { RuleId = nNewRuleId } } ; else if (sRuleExpression.Contains("NOT POPULATED")) { NewRule = new PopulatedRule() { RuleId = nNewRuleId, NotOperator = true } } ; else if (sRuleExpression.Contains("POPULATED")) { NewRule = new PopulatedRule() { RuleId = nNewRuleId, NotOperator = false } } ; else if (sRuleExpression.Contains("!=")) { NewRule = new DomainRule() { RuleId = nNewRuleId, NotOperator = true } } ; else if (sRuleExpression.Contains("==")) { NewRule = new DomainRule() { RuleId = nNewRuleId, NotOperator = false } } ; else if (sRuleExpression.Contains("NOT IN")) { NewRule = new DomainRule() { RuleId = nNewRuleId, NotOperator = true } } ; else if (sRuleExpression.Contains("IN")) { NewRule = new DomainRule() { RuleId = nNewRuleId, NotOperator = false } } ; else if (sRuleExpression.Contains("EXISTS AS")) { NewRule = new DomainRule() { RuleId = nNewRuleId, NotOperator = false, SearchAllDataRows = true } } ; else if (sRuleExpression.Contains("DEFAULT")) { NewRule = new AssignmentRule() { RuleId = nNewRuleId, NotOperator = false, DefaultAssignment = true } } ; else if (sRuleExpression.Contains("ASSIGN_SUM")) { NewRule = new ArithmeticRule() { RuleId = nNewRuleId, NotOperator = false, OpType = ARITH_OP_TYPE.AOT_SUM } } ; else if (sRuleExpression.Contains("ASSIGN_DIFF")) { NewRule = new ArithmeticRule() { RuleId = nNewRuleId, NotOperator = false, OpType = ARITH_OP_TYPE.AOT_DIFF } } ; else if (sRuleExpression.Contains("ASSIGN_PROD")) { NewRule = new ArithmeticRule() { RuleId = nNewRuleId, NotOperator = false, OpType = ARITH_OP_TYPE.AOT_PROD } } ; else if (sRuleExpression.Contains("ASSIGN_QUOT")) { NewRule = new ArithmeticRule() { RuleId = nNewRuleId, NotOperator = false, OpType = ARITH_OP_TYPE.AOT_QUOT } } ; else if (sRuleExpression.Contains("ASSIGN")) { NewRule = new AssignmentRule() { RuleId = nNewRuleId, NotOperator = false } } ; if (NewRule != null) { var RuleId = poRuleXmlNode.Attributes.GetNamedItem(CONST_RULE_ID_ATTR); if (RuleId != null) { NewRule.DescRuleId = RuleId.Value; } NewRule.ParentRuleSetId = poTargetRuleSet.RuleSetId; SetTargetAttribute(NewRule, sRuleExpression); if (NewRule.RuleType != RULE_TYPE.RT_POPULATED) { SetRuleValues(NewRule, sRuleExpression); } } if (NewRule != null) { poTargetRuleSet.AddRule(NewRule); } }