private static bool AreAllSearchConditionsPresent(IConditionNode <TConditionType> conditionNode, IEnumerable <Condition <TConditionType> > conditions) { // Conditions checklist is a mere control construct to avoid a full sweep of the condition nodes tree when we already found all conditions. IDictionary <TConditionType, bool> conditionsChecklist = new Dictionary <TConditionType, bool>(conditions.ToDictionary(ks => ks.Type, vs => false)); return(VisitConditionNode(conditionNode, conditionsChecklist)); }
private async Task <IConditionNode> CreateConditionNodeRecursive(Guid tenantId, CreateConditionNodeBase createConditionNodeBase) { switch (createConditionNodeBase) { case CreateComposedConditionNode cccn: LogicalOperatorCodes logicalOperatorCode = (LogicalOperatorCodes)cccn.LogicalOperatorCode; List <IConditionNode> conditionNodes = new List <IConditionNode>(); foreach (CreateConditionNodeBase ccnb in cccn.ChildNodes) { IConditionNode conditionNode = await this.CreateConditionNodeRecursive(tenantId, ccnb); conditionNodes.Add(conditionNode); } return(this.conditionNodeAbstractFactory.CreateComposedConditionNode(logicalOperatorCode, conditionNodes)); case CreateValueConditionNode cvcn: ConditionTypeKey conditionTypeKey = ConditionTypeKey.New(tenantId, cvcn.ConditionTypeCode); ConditionType conditionType = await this.conditionTypeRepository.GetById(conditionTypeKey); DataTypeCodes dataTypeCode = (DataTypeCodes)cvcn.DataTypeCode; OperatorCodes operatorCode = (OperatorCodes)cvcn.OperatorCode; return(this.conditionNodeAbstractFactory.CreateValueConditionNode(conditionType, dataTypeCode, operatorCode, cvcn.RightHandOperand)); default: throw new NotSupportedException("Unsupported condition node creation."); } }
private static bool VisitConditionNode(IConditionNode <TConditionType> conditionNode, IDictionary <TConditionType, bool> conditionsChecklist) { switch (conditionNode) { case IValueConditionNode <TConditionType> valueConditionNode: if (conditionsChecklist.ContainsKey(valueConditionNode.ConditionType)) { conditionsChecklist[valueConditionNode.ConditionType] = true; } return(conditionsChecklist.All(kvp => kvp.Value)); case ComposedConditionNode <TConditionType> composedConditionNode: foreach (IConditionNode <TConditionType> childConditionNode in composedConditionNode.ChildConditionNodes) { bool allPresentAlready = VisitConditionNode(childConditionNode, conditionsChecklist); if (allPresentAlready) { return(true); } } return(false); default: throw new NotSupportedException($"Unsupported condition node: '{conditionNode.GetType().Name}'."); } }
private ConditionNodeBaseDto ConvertNodeToDto(IConditionNode conditionNode) { switch (conditionNode) { case ComposedConditionNode ccn: return(new ComposedConditionNodeDto { ChildNodes = ccn.ChildNodes.Select(cn => this.ConvertNodeToDto(cn)), LogicalOperatorCode = ccn.LogicalOperatorCode.AsInteger() }); case IValueConditionNode vcn: return(new ValueConditionNodeDto { ConditionTypeCode = vcn.ConditionTypeCode, DataTypeCode = vcn.DataTypeCode.AsInteger(), LogicalOperatorCode = vcn.LogicalOperatorCode.AsInteger(), OperatorCode = vcn.OperatorCode.AsInteger(), RightHandOperand = vcn.GetRightHandOperandAsObject() }); default: throw new NotSupportedException("Condition node type is not supported."); } }
public async Task <RuleResult> CreateRule(CreateRule createRule) { RuleResult ruleResult = new RuleResult(); IEnumerable <RuleValidationMessage> ruleValidationMessages = this.createRuleValidator.Validate(createRule); foreach (RuleValidationMessage validationMessage in ruleValidationMessages) { ruleResult.AddErrorMessage(validationMessage.Code, validationMessage.Message); } if (!ruleResult.HasErrors) { // Fetch content type and validate. ContentTypeKey contentTypeKey = ContentTypeKey.New(createRule.TenantId, createRule.ContentTypeCode); ContentType contentType = await this.contentTypeRepository.GetById(contentTypeKey); IConditionNode rootCondition = null; if (createRule.RootCondition != null) { rootCondition = await this.CreateConditionNodeRecursive(createRule.TenantId, createRule.RootCondition); } CreateRuleArgs createRuleArgs = new CreateRuleArgs { Content = createRule.Content, ContentType = contentType, DateBegin = createRule.DateBegin, DateEnd = createRule.DateEnd, Name = createRule.Name, Priority = createRule.Priority, RootCondition = rootCondition, TenantId = createRule.TenantId }; Rule rule = this.ruleFactory.CreateRule(createRuleArgs); IEnumerable <Rule> existentRules = await this.ruleRepository.GetAll( createRule.TenantId, new RulesFilter { ContentTypeCode = contentType.Key.Code }, null); // Move rules w/ priority >= to new rule's priority 1 value forward. foreach (Rule existentRule in existentRules.Where(r => r.Priority >= createRule.Priority)) { existentRule.Priority++; await this.ruleRepository.Update(existentRule); } await this.ruleRepository.Add(rule); ruleResult.AffectedRule = rule; } return(ruleResult); }
public IComposedConditionNodeBuilder <TConditionType> AddCondition(Func <IConditionNodeBuilder <TConditionType>, IConditionNode <TConditionType> > addConditionFunc) { IConditionNode <TConditionType> conditionNode = addConditionFunc.Invoke(this.conditionNodeBuilder); this.conditions.Add(conditionNode); return(this); }
public IRuleBuilder <TContentType, TConditionType> WithCondition(Func <IConditionNodeBuilder <TConditionType>, IConditionNode <TConditionType> > conditionFunc) { ConditionNodeBuilder <TConditionType> conditionNodeBuilder = new ConditionNodeBuilder <TConditionType>(); IConditionNode <TConditionType> condition = conditionFunc.Invoke(conditionNodeBuilder); return(this.WithCondition(condition)); }
public bool Eval(IConditionNode <TConditionType> conditionNode, IEnumerable <Condition <TConditionType> > conditions, EvaluationOptions evaluationOptions) { if (evaluationOptions.ExcludeRulesWithoutSearchConditions && !AreAllSearchConditionsPresent(conditionNode, conditions)) { return(false); } ISpecification <IEnumerable <Condition <TConditionType> > > specification = this.BuildSpecification(conditionNode, evaluationOptions.MatchMode); return(specification.IsSatisfiedBy(conditions)); }
/// <summary> /// Register a conditional node. /// </summary> /// <param name="Node">Conditional node</param> public void Register(IConditionNode Node) { if (this.condition is null) { this.condition = Node; } else { throw new Exception("While construct already has a condition node defined."); } }
public void RootCondition_HavingSettedInstance_ReturnsProvidedInstance() { // Arrange Mock <IConditionNode <ConditionType> > mockConditionNode = new Mock <IConditionNode <ConditionType> >(); IConditionNode <ConditionType> expected = mockConditionNode.Object; Rule <ContentType, ConditionType> sut = new Rule <ContentType, ConditionType> { RootCondition = expected }; // Act IConditionNode <ConditionType> actual = sut.RootCondition; // Assert actual.Should().BeSameAs(expected); }
public void ComposedConditionNode_Init_GivenSetupWithChildConditionsAndLogicalOperator_ReturnsSettedValues() { // Arrange LogicalOperators expectedLogicalOperator = LogicalOperators.Eval; IEnumerable <IConditionNode <ConditionType> > expectedChildConditionNodes = new IConditionNode <ConditionType>[] { new Mock <IConditionNode <ConditionType> >().Object, new Mock <IConditionNode <ConditionType> >().Object }; ComposedConditionNode <ConditionType> sut = new ComposedConditionNode <ConditionType>(expectedLogicalOperator, expectedChildConditionNodes); // Act LogicalOperators actualLogicalOperator = sut.LogicalOperator; IEnumerable <IConditionNode <ConditionType> > actualChildConditionNodes = sut.ChildConditionNodes; // Assert actualLogicalOperator.Should().Be(expectedLogicalOperator); actualChildConditionNodes.Should().NotBeNull().And.BeSameAs(expectedChildConditionNodes); }
public static void PerformValidation <TConditionType>(this IConditionNode <TConditionType> conditionNode, ConditionNodeValidationArgs <TConditionType> conditionNodeValidationArgs) { ValidationResult validationResult; switch (conditionNode) { case ComposedConditionNode <TConditionType> composedConditionNode: validationResult = conditionNodeValidationArgs.ComposedConditionNodeValidator.Validate(composedConditionNode); break; case IntegerConditionNode <TConditionType> integerConditionNode: validationResult = conditionNodeValidationArgs.IntegerConditionNodeValidator.Validate(integerConditionNode); break; case DecimalConditionNode <TConditionType> decimalConditionNode: validationResult = conditionNodeValidationArgs.DecimalConditionNodeValidator.Validate(decimalConditionNode); break; case StringConditionNode <TConditionType> stringConditionNode: validationResult = conditionNodeValidationArgs.StringConditionNodeValidator.Validate(stringConditionNode); break; case BooleanConditionNode <TConditionType> booleanConditionNode: validationResult = conditionNodeValidationArgs.BooleanConditionNodeValidator.Validate(booleanConditionNode); break; default: return; } if (!validationResult.IsValid) { foreach (ValidationFailure validationFailure in validationResult.Errors) { conditionNodeValidationArgs.CustomContext.AddFailure(validationFailure); } } }
/// <summary> /// Register a conditional node. /// </summary> /// <param name="Node">Conditional node</param> public void Register(IConditionNode Node) { this.conditions.AddLast(Node); }
public virtual bool HasCondition(IConditionNode node) { return(conditionList_.Contains(node)); }
public virtual void AddCondition(IConditionNode node) { conditionList_.Add(node); }
private ISpecification <IEnumerable <Condition <TConditionType> > > BuildSpecification(IConditionNode <TConditionType> conditionNode, MatchModes matchMode) { return(conditionNode switch { IValueConditionNode <TConditionType> valueConditionNode => this.BuildSpecificationForValueNode(valueConditionNode, matchMode), ComposedConditionNode <TConditionType> composedConditionNode => this.BuildSpecificationForComposedNode(composedConditionNode, matchMode), _ => throw new NotSupportedException($"Unsupported condition node: '{conditionNode.GetType().Name}'."), });
public virtual void RemoveCondition(IConditionNode node) { conditionList_.Remove(node); }
/// <summary> /// 设置前提条件 /// </summary> /// <param name="precondition"></param> public virtual void AddPrecondition(IConditionNode condition) { mCondition = condition; }
public IRuleBuilder <TContentType, TConditionType> WithCondition(IConditionNode <TConditionType> condition) { this.rootCondition = condition; return(this); }