Пример #1
0
 public virtual IDmnDecisionTableResult EvaluateDecisionTable(IDmnDecision decision,
                                                              IDictionary <string, ITypedValue> variables)
 {
     EnsureUtil.EnsureNotNull("decision", decision);
     EnsureUtil.EnsureNotNull("variables", variables);
     return(EvaluateDecisionTable(decision, Variables.FromMap(variables).AsVariableContext()));
 }
Пример #2
0
 /// <summary>
 /// Creates the execution context snapshot - to be called by decision after the evaluation
 /// </summary>
 /// <param name="decision">Decision evaluated just before the snapshot</param>
 /// <param name="result"><paramref name="decision"/> result</param>
 internal virtual void CreateSnapshot(IDmnDecision decision, DmnDecisionResult result)
 {
     if (Options.RecordSnapshots)
     {
         Snapshots.CreateSnapshot(this, decision, result);
     }
 }
Пример #3
0
 public virtual DmnEngineException decisionTypeNotSupported(IDmnDecision decision)
 {
     return
         (new DmnEngineException(ExceptionMessage("004",
                                                  string.Format("Decision type '{0}' not supported by DMN engine.",
                                                                decision.GetType()))));
 }
Пример #4
0
 public virtual DmnTransformException DecisionIdIsMissing(IDmnDecision dmnDecision)
 {
     return
         (new DmnTransformException(ExceptionMessage("010",
                                                     string.Format("The decision '{0}' must have an 'id' attribute set.",
                                                                   dmnDecision))));
 }
Пример #5
0
 public virtual DmnEngineException decisionIsNotADecisionTable(IDmnDecision decision)
 {
     return
         (new DmnEngineException(ExceptionMessage("013",
                                                  string.Format("The decision '{0}' is not implemented as decision table.",
                                                                decision))));
 }
Пример #6
0
        // listeners ////////////////////////////////////////////////////////////////

        protected internal virtual void NotifyTransformListeners(IDecision decision, IDmnDecision dmnDecision)
        {
            foreach (var transformListener in transformListeners)
            {
                transformListener.transformDecision(decision, dmnDecision);
            }
        }
Пример #7
0
        /// <summary>
        ///     Evaluate a decision with the given <seealso cref="IVariableContext" />
        /// </summary>
        /// <param name="decision"> the decision to evaluate </param>
        /// <param name="variableContext"> the available variable context </param>
        /// <returns> the result of the decision evaluation </returns>
        public virtual IDmnDecisionResult evaluateDecision(IDmnDecision decision, IVariableContext variableContext)
        {
            if (ReferenceEquals(decision.Key, null))
            {
                throw LOG.unableToFindAnyDecisionTable();
            }
            var variableMap = buildVariableMapFromVariableContext(variableContext);

            IList <IDmnDecision> requiredDecisions = new List <IDmnDecision>();

            buildDecisionTree(decision, requiredDecisions);

            IList <IDmnDecisionLogicEvaluationEvent> evaluatedEvents = new List <IDmnDecisionLogicEvaluationEvent>();
            IDmnDecisionResult evaluatedResult = null;

            foreach (var evaluateDecision in requiredDecisions)
            {
                var handler        = getDecisionEvaluationHandler(evaluateDecision);
                var evaluatedEvent = handler.Evaluate(evaluateDecision, variableMap.AsVariableContext());
                evaluatedEvents.Add(evaluatedEvent);

                evaluatedResult = handler.GenerateDecisionResult(evaluatedEvent);
                if (decision != evaluateDecision)
                {
                    addResultToVariableContext(evaluatedResult, variableMap, evaluateDecision);
                }
            }

            generateDecisionEvaluationEvent(evaluatedEvents);
            return(evaluatedResult);
        }
 protected internal virtual bool IsDeployedDecisionTable(IDmnDecision decision)
 {
     if (decision is IDecisionDefinition)
     {
         return(!ReferenceEquals(((IDecisionDefinition)decision).Id, null));
     }
     return(false);
 }
Пример #9
0
 public virtual DmnTransformException DecisionTableRuleIdIsMissing(IDmnDecision dmnDecision,
                                                                   DmnDecisionTableRuleImpl dmnDecisionTableRule)
 {
     return
         (new DmnTransformException(ExceptionMessage("013",
                                                     string.Format("The decision table rule '{0}' of decision '{1}' must have a 'id' attribute set.",
                                                                   dmnDecisionTableRule, dmnDecision))));
 }
Пример #10
0
        public virtual IDmnDecisionResult EvaluateDecision(IDmnDecision decision, IVariableContext variableContext)
        {
            EnsureUtil.EnsureNotNull("decision", decision);
            EnsureUtil.EnsureNotNull("variableContext", variableContext);

            if (decision is DmnDecisionImpl)
            {
                var decisionContext = new DefaultDmnDecisionContext(dmnEngineConfiguration);
                return(decisionContext.evaluateDecision(decision, variableContext));
            }
            throw LOG.decisionTypeNotSupported(decision);
        }
Пример #11
0
        protected internal virtual void buildDecisionTree(IDmnDecision decision, IList <IDmnDecision> requiredDecisions)
        {
            if (requiredDecisions.Contains(decision))
            {
                return;
            }

            foreach (var dmnDecision in decision.RequiredDecisions)
            {
                buildDecisionTree(dmnDecision, requiredDecisions);
            }

            requiredDecisions.Add(decision);
        }
Пример #12
0
        public virtual IDmnDecisionTableResult EvaluateDecisionTable(IDmnDecision decision,
                                                                     IVariableContext variableContext)
        {
            EnsureUtil.EnsureNotNull("decision", decision);
            EnsureUtil.EnsureNotNull("variableContext", variableContext);

            if (decision is DmnDecisionImpl && decision.DecisionTable)
            {
                var decisionContext = new DefaultDmnDecisionContext(dmnEngineConfiguration);

                var decisionResult = decisionContext.evaluateDecision(decision, variableContext);
                return(DmnDecisionTableResultImpl.Wrap(decisionResult));
            }
            throw LOG.decisionIsNotADecisionTable(decision);
        }
Пример #13
0
        protected internal virtual IList <IDmnDecision> GetRequiredDmnDecisions(IDecision decision,
                                                                                IDictionary <string, DmnDecisionImpl> dmnDecisions)
        {
            IList <IDmnDecision> requiredDecisionList = new List <IDmnDecision>();

            foreach (var informationRequirement in decision.InformationRequirements)
            {
                var requiredDecision = informationRequirement.RequiredDecision;
                if (requiredDecision != null)
                {
                    IDmnDecision requiredDmnDecision = dmnDecisions[requiredDecision.Id];
                    requiredDecisionList.Add(requiredDmnDecision);
                }
            }
            return(requiredDecisionList);
        }
        public virtual IDmnDecisionLogicEvaluationEvent Evaluate(IDmnDecision decision, IVariableContext variableContext)
        {
            var evaluationResult = new DmnDecisionLiteralExpressionEvaluationEventImpl();

            evaluationResult.Decision = decision;
            evaluationResult.ExecutedDecisionElements = 1;

            var dmnDecisionLiteralExpression = (DmnDecisionLiteralExpressionImpl)decision.DecisionLogic;
            var variable   = dmnDecisionLiteralExpression.Variable;
            var expression = dmnDecisionLiteralExpression.Expression;

            var         evaluateExpression = EvaluateLiteralExpression(expression, variableContext);
            ITypedValue typedValue         = variable.TypeDefinition.Transform(evaluateExpression);

            evaluationResult.OutputValue = typedValue;
            evaluationResult.OutputName  = variable.Name;

            return(evaluationResult);
        }
Пример #15
0
        /// <summary>
        /// Executes (evaluates) given <paramref name="decision"/>
        /// </summary>
        /// <param name="decision">Decision to execute</param>
        /// <returns>Decision result</returns>
        /// <exception cref="ArgumentNullException"><paramref name="decision"/> is null</exception>
        public virtual DmnDecisionResult ExecuteDecision(IDmnDecision decision)
        {
            if (decision == null)
            {
                throw Logger.Fatal <ArgumentNullException>($"{nameof(decision)} is null");
            }

            if (Options.RecordSnapshots)
            {
                //clear snapshots and create "initial" snapshot of the variables
                Snapshots.Reset();
                Snapshots.CreateSnapshot(this);
            }

            var correlationId = Guid.NewGuid().ToString();
            var result        = decision.Execute(this, correlationId);

            //note: the decision-after-execute snapshot is created by decision (for each decision in "dependency graph")

            return(result);
        }
Пример #16
0
        protected internal virtual void EnsureNoLoopInDecision(IDmnDecision decision, IList <string> parentDecisionList,
                                                               IList <string> visitedDecisions)
        {
            if (visitedDecisions.Contains(decision.Key))
            {
                return;
            }

            parentDecisionList.Add(decision.Key);

            foreach (var requiredDecision in decision.RequiredDecisions)
            {
                if (parentDecisionList.Contains(requiredDecision.Key))
                {
                    throw LOG.RequiredDecisionLoopDetected(requiredDecision.Key);
                }

                EnsureNoLoopInDecision(requiredDecision, new List <string>(parentDecisionList), visitedDecisions);
            }
            visitedDecisions.Add(decision.Key);
        }
        public virtual IDmnDecisionLogicEvaluationEvent Evaluate(IDmnDecision decision, IVariableContext variableContext)
        {
            var evaluationResult = new DmnDecisionTableEvaluationEventImpl();

            evaluationResult.DecisionTable = decision;

            var decisionTable = (DmnDecisionTableImpl)decision.DecisionLogic;

            evaluationResult.ExecutedDecisionElements = CalculateExecutedDecisionElements(decisionTable);

            EvaluateDecisionTable(decisionTable, variableContext, evaluationResult);

            // apply hit policy
            decisionTable.HitPolicyHandler.apply(evaluationResult);

            // notify listeners
            foreach (var evaluationListener in EvaluationListeners)
            {
                evaluationListener.Notify(evaluationResult);
            }

            return(evaluationResult);
        }
Пример #18
0
        private static string GenerateDecisionBuilder(string prefix, IDmnDecision decision, string o, List <IDmnDecision> generatedDecisions)
        {
            if (generatedDecisions.Contains(decision))
            {
                return(o);
            }
            foreach (var requiredDecision in decision.RequiredDecisions)
            {
                o = GenerateDecisionBuilder(prefix, requiredDecision, o, generatedDecisions);
            }

            var nl          = Environment.NewLine;
            var outDecision = $"{prefix}{decision.Name.NormalizeName()}";

            if (decision is DmnExpressionDecision expressionDecision)
            {
                o += nl;
                o += $@"  .WithExpressionDecision(""{decision.Name.CodeEncodeStr()}"", eDecision =>" + nl;
                o +=
                    $@"       eDecision.Put(""{expressionDecision.Expression.CodeEncodeStr()}"").To({prefix}{expressionDecision.Output.Name})" +
                    nl;
                if (decision.RequiredInputs != null)
                {
                    o = decision.RequiredInputs.Aggregate(o,
                                                          (current, requiredInput) => current + $@"       .Requires({prefix}{requiredInput.Name})" + nl);
                }

                if (decision.RequiredDecisions != null)
                {
                    o = decision.RequiredDecisions.Aggregate(o,
                                                             (current, requiredDec) =>
                                                             current + $@"       .Requires({prefix}{requiredDec.Name.NormalizeName()})" + nl);
                }

                o += $@"     ,out var {outDecision})" + nl;
            }

            if (decision is DmnDecisionTable table)
            {
                o += nl;
                o += $@"  .WithTableDecision(""{decision.Name}"", table =>" + nl;
                o += $@"     table" + nl;
                foreach (var tableInput in table.Inputs)
                {
                    if (tableInput.Variable != null)
                    {
                        o += $@"        .WithInput({prefix}{tableInput.Variable.Name}, out var {prefix}Input{tableInput.Index}";
                    }
                    else
                    {
                        o +=
                            $@"        .WithInput(""{tableInput.Expression.CodeEncodeStr()}"", out var {prefix}Input{tableInput.Index}";
                    }

                    if (tableInput.AllowedValues != null && tableInput.AllowedValues.Length > 0)
                    {
                        o += "," + string.Join(", ", tableInput.AllowedValues.Select(a => $@"""{a}"""));
                    }

                    o += ")" + nl;
                }

                foreach (var tableOutput in table.Outputs.OrderBy(i => i.Index))
                {
                    o += $@"        .WithOutput({prefix}{tableOutput.Variable.Name}, out var {prefix}Output{tableOutput.Index}";

                    if (tableOutput.AllowedValues != null && tableOutput.AllowedValues.Length > 0)
                    {
                        o += "," + string.Join(", ", tableOutput.AllowedValues.Select(a => $@"""{a}"""));
                    }

                    o += ")" + nl;
                }

                o += $@"        .WithHitPolicy(HitPolicyEnum.{table.HitPolicy})" + nl;
                o += $@"        .WithAggregation(CollectHitPolicyAggregationEnum.{table.Aggregation})" + nl;

                foreach (var rule in table.Rules.OrderBy(r => r.Index))
                {
                    o += $@"        .WithRule(""{rule.Name}"",{(!string.IsNullOrEmpty(rule.Description) ? $@"""{rule.Description.CodeEncodeStr()}"", " : "")} r=>r" + nl;
                    var firstInput  = true;
                    var firstOutput = true;
                    foreach (var ruleInput in rule.Inputs)
                    {
                        o +=
                            $@"          .{(firstInput ? "When" : "And")}({prefix}Input{ruleInput.Input.Index},""{ruleInput.UnparsedExpression.CodeEncodeStr()}"")" +
                            nl;
                        firstInput = false;
                    }

                    if (firstInput)
                    {
                        //no input
                        o += $@"          .Always()" + nl;
                    }

                    foreach (var ruleOutput in rule.Outputs)
                    {
                        o +=
                            $@"          .{(firstOutput ? "Then" : "And")}({prefix}Output{ruleOutput.Output.Index},""{ruleOutput.Expression.CodeEncodeStr()}"")" +
                            nl;
                        firstOutput = false;
                    }

                    o += $@"          )" + nl;
                }

                if (decision.RequiredInputs != null)
                {
                    o = decision.RequiredInputs.Aggregate(o,
                                                          (current, requiredInput) => current + $@"       .Requires({prefix}{requiredInput.Name})" + nl);
                }

                if (decision.RequiredDecisions != null)
                {
                    o = decision.RequiredDecisions.Aggregate(o,
                                                             (current, requiredDec) =>
                                                             current + $@"       .Requires({prefix}{requiredDec.Name.NormalizeName()})" + nl);
                }

                o += $@"     ,out var {outDecision})" + nl;
            }

            generatedDecisions.Add(decision);
            return(o);
        }
Пример #19
0
 public override DmnDecisionResult ExecuteDecision(IDmnDecision decision)
 {
     RetrievedFromCache = false;
     AddedToCache       = false;
     return(base.ExecuteDecision(decision));
 }
Пример #20
0
        protected internal virtual IDmnDecisionLogicEvaluationHandler getDecisionEvaluationHandler(IDmnDecision decision)
        {
            var key = decision.DecisionLogic.GetType();

            if (evaluationHandlers.ContainsKey(key))
            {
                return(evaluationHandlers[key]);
            }
            throw LOG.decisionLogicTypeNotSupported(decision.DecisionLogic);
        }
Пример #21
0
 public virtual void AddDecision(IDmnDecision decision)
 {
     decisions[decision.Key] = decision;
 }
Пример #22
0
        protected internal virtual void addResultToVariableContext(IDmnDecisionResult evaluatedResult,
                                                                   IVariableMap variableMap, IDmnDecision evaluatedDecision)
        {
            var resultList = evaluatedResult.ResultList;

            if (resultList.Count == 0)
            {
            }
            else if ((resultList.Count == 1) && !isDecisionTableWithCollectOrRuleOrderHitPolicy(evaluatedDecision))
            {
                foreach (var it in evaluatedResult.SingleResult)
                {
                    variableMap.PutValue(it.Key, it.Value);
                }
                //variableMap.putAll(evaluatedResult.SingleResult);
            }
            else
            {
                ISet <string> outputs = new HashSet <string>();

                foreach (var resultMap in resultList)
                {
                    outputs.UnionWith(resultMap.Keys);
                }

                foreach (var output in outputs)
                {
                    var values = evaluatedResult.CollectEntries <object>(output);
                    variableMap.PutValue(output, values);
                }
            }
        }
Пример #23
0
        protected internal virtual bool isDecisionTableWithCollectOrRuleOrderHitPolicy(IDmnDecision evaluatedDecision)
        {
            var isDecisionTableWithCollectHitPolicy = false;

            if (evaluatedDecision.DecisionTable)
            {
                var decisionTable = (DmnDecisionTableImpl)evaluatedDecision.DecisionLogic;
                isDecisionTableWithCollectHitPolicy =
                    COLLECT_HIT_POLICY.Equals(decisionTable.HitPolicyHandler.HitPolicyEntry) ||
                    RULE_ORDER_HIT_POLICY.Equals(decisionTable.HitPolicyHandler.HitPolicyEntry);
            }

            return(isDecisionTableWithCollectHitPolicy);
        }
 /// <summary>
 /// CTOR
 /// </summary>
 /// <param name="step">Sequence number of the execution step</param>
 /// <param name="ctx">Execution context to create snapshot for</param>
 /// <param name="decision">Decision executed just before snapshot</param>
 /// <param name="result">Result of the decision executed just before snapshot</param>
 internal DmnExecutionSnapshot(int step, DmnExecutionContext ctx, IDmnDecision decision, DmnDecisionResult result)
     : this(step, ctx)
 {
     Decision       = decision;
     DecisionResult = result?.Clone();
 }
Пример #25
0
 /// <summary>
 /// Creates the snapshot with the decision information
 /// </summary>
 /// <param name="ctx">Execution context to create snapshot for</param>
 /// <param name="decision">Decision executed just before snapshot</param>
 /// <param name="result">Result of the decision executed just before snapshot</param>
 internal void CreateSnapshot(DmnExecutionContext ctx, IDmnDecision decision, DmnDecisionResult result)
 {
     snapshots.Add(new DmnExecutionSnapshot(snapshots.Count, ctx, decision, result));
 }