コード例 #1
0
        /// <summary>
        /// CTOR - Validates the <paramref name="source"/> model and creates the <see cref="DmnDefinition"/> from <see cref="DmnModel"/>
        /// </summary>
        /// <param name="source">Source DMN Model parsed from XML</param>
        ///<exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        protected DmnDefinitionFactory(DmnModel source)
        {
            if (source == null)
            {
                throw Logger.Fatal <ArgumentNullException>($"{nameof(source)} is null");
            }

            //Process input data
            var inputDataById = new Dictionary <string, DmnVariableDefinition>();

            if (source.InputData != null) //it's not common, but OK to have no input data
            {
                ProcessInputDataSource(source, inputDataById);
            }

            //Process decisions
            var decisionsById = new Dictionary <string, IDmnDecision>();

            // ReSharper disable once InvertIf
            if (source.Decisions != null && source.Decisions.Count > 0)
            {
                foreach (var sourceDecision in source.Decisions)
                {
                    ProcessDecision(sourceDecision, source.Decisions, decisionsById, inputDataById);
                }
            }
            else
            {
                throw Logger.Fatal <DmnParserException>($"No decision in DMN model.");
            }
        }
コード例 #2
0
        /// <summary>
        /// Validates the inputs of the <see cref="DmnModel"/> (<paramref name="source"/> and populates <see cref="InputData"/> and related <see cref="Variables"/>
        /// </summary>
        /// <param name="source">Source DMN Model parsed from XML</param>
        /// <param name="inputDataById">Temporary dictionary of input data (by ID) - input data are populated here</param>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="inputDataById"/> is null.</exception>
        /// <exception cref="DmnParserException">Missing input id</exception>
        /// <exception cref="DmnParserException">Duplicate input data name</exception>
        protected void ProcessInputDataSource(DmnModel source, IDictionary <string, DmnVariableDefinition> inputDataById)
        {
            if (source == null)
            {
                throw Logger.Fatal <ArgumentNullException>($"{nameof(source)} is null");
            }
            if (inputDataById == null)
            {
                throw Logger.Fatal <ArgumentNullException>($"{nameof(inputDataById)} is null");
            }
            if (source.InputData == null || source.InputData.Count == 0)
            {
                return;                                                         //it's not common, but OK to have no input data
            }
            //TODO    ?Input name in form varName:varType for (complex) input types
            foreach (var sourceInput in source.InputData)
            {
                if (string.IsNullOrWhiteSpace(sourceInput.Id))
                {
                    throw Logger.Fatal <DmnParserException>($"Missing input id");
                }

                var inputName    = !string.IsNullOrWhiteSpace(sourceInput.Name) ? sourceInput.Name : sourceInput.Id;
                var variableName = DmnVariableDefinition.NormalizeVariableName(inputName);
                if (InputData.ContainsKey(variableName))
                {
                    throw Logger.Fatal <DmnParserException>($"Duplicate input data name {variableName} (from {inputName})");
                }

                var variable = new DmnVariableDefinition(variableName, inputName);
                InputData.Add(variableName, variable);
                Variables.Add(variableName, variable);
                inputDataById.Add(sourceInput.Id, variable);
            }
        }
コード例 #3
0
        /// <summary>
        /// Creates the execution context from <paramref name="sourceModel"/>
        /// </summary>
        /// <param name="sourceModel">Source model to create the execution context for</param>
        /// <returns><paramref name="sourceModel"/> execution context</returns>
        /// <exception cref="ArgumentNullException"><paramref name="sourceModel"/> is null</exception>
        public static DmnExecutionContext CreateExecutionContext(DmnModel sourceModel)
        {
            if (sourceModel == null)
            {
                throw new ArgumentNullException(nameof(sourceModel));
            }

            var definition = DmnDefinitionFactory.CreateDmnDefinition(sourceModel);

            return(CreateExecutionContext(definition));
        }
コード例 #4
0
        /// <summary>
        /// Validates the <paramref name="source"/> model and creates the <see cref="DmnDefinition"/> from <see cref="DmnModel"/>
        /// </summary>
        /// <param name="source">Source DMN Model parsed from XML</param>
        ///<exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        /// <returns>DMN model definition that can be used to execute the decisions within the <see cref="runtime.DmnExecutionContext"/></returns>
        public static DmnDefinition CreateDmnDefinition(DmnModel source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            var factory = new DmnDefinitionFactory(source);

            return(new DmnDefinition(factory.Variables, factory.InputData, factory.Decisions));
        }
コード例 #5
0
        /// <summary>
        /// Validates the inputs of the <see cref="DmnModel"/> (<paramref name="source"/> and populates <see cref="InputData"/> and related <see cref="Variables"/>
        /// </summary>
        /// <param name="source">Source DMN Model parsed from XML</param>
        /// <param name="inputDataById">Temporary dictionary of input data (by ID) - input data are populated here</param>
        ///<exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="inputDataById"/> is null.</exception>
        /// <exception cref="DmnParserException">Missing input id</exception>
        /// <exception cref="DmnParserException">Duplicate input data name</exception>
        protected void ProcessInputDataSource(DmnModel source, IDictionary <string, DmnVariableDefinition> inputDataById)
        {
            if (source == null)
            {
                throw Logger.Fatal <ArgumentNullException>($"{nameof(source)} is null");
            }
            if (inputDataById == null)
            {
                throw Logger.Fatal <ArgumentNullException>($"{nameof(inputDataById)} is null");
            }
            if (source.InputData == null || source.InputData.Count == 0)
            {
                return;                                                         //it's not common, but OK to have no input data
            }
            var inputExpressionTypeByNames = source.Decisions?.Where(d => d.DecisionTable?.Inputs != null).SelectMany(d => d.DecisionTable?.Inputs)?
                                             .ToDictionary(i => string.IsNullOrEmpty(i.InputExpression?.Text) ? i.Label : i.InputExpression.Text, i => i.InputExpression?.TypeRef) ?? new Dictionary <string, string>();

            //TODO    ?Input name in form varName:varType for (complex) input types
            //TODO ?Required input parameters check for null??
            foreach (var sourceInput in source.InputData)
            {
                if (string.IsNullOrWhiteSpace(sourceInput.Id))
                {
                    throw Logger.Fatal <DmnParserException>($"Missing input id");
                }

                var inputName    = !string.IsNullOrWhiteSpace(sourceInput.Name) ? sourceInput.Name : sourceInput.Id;
                var variableName = NormalizeVariableName(inputName);
                if (InputData.ContainsKey(variableName))
                {
                    throw Logger.Fatal <DmnParserException>($"Duplicate input data name {variableName} (from {inputName})");
                }

                var variable = new DmnVariableDefinition(variableName)
                {
                    IsInputParameter = true, HasValueSetter = true
                };

                // try to evaluate variable type from expression type
                if (inputExpressionTypeByNames.TryGetValue(variableName, out var expressionType))
                {
                    CheckAndUpdateVariableType(variable, expressionType);
                }

                variable.ValueSetters.Add($"Input: {inputName}");
                InputData.Add(variableName, variable);
                Variables.Add(variableName, variable);
                inputDataById.Add(sourceInput.Id, variable);
            }
        }
コード例 #6
0
        /// <summary>
        /// Creates the execution context from <paramref name="sourceModel"/>
        /// </summary>
        /// <param name="sourceModel">Source model to create the execution context for</param>
        /// <param name="configure">Optional configuration action</param>
        /// <typeparam name="T">Type of the execution context to be created. Must be <see cref="DmnExecutionContext"/> or its descendant</typeparam>
        /// <returns><paramref name="sourceModel"/> execution context</returns>
        /// <exception cref="ArgumentNullException"><paramref name="sourceModel"/> is null</exception>
        public static DmnExecutionContext CreateCustomExecutionContext <T>(
            DmnModel sourceModel,
            Action <DmnExecutionContextOptions> configure = null)
            where T : DmnExecutionContext
        {
            if (sourceModel == null)
            {
                throw new ArgumentNullException(nameof(sourceModel));
            }

            var definition = DmnDefinitionFactory.CreateDmnDefinition(sourceModel);

            return(CreateCustomExecutionContext <T>(definition, configure));
        }
コード例 #7
0
        /// <summary>
        /// Validates the <paramref name="source"/> model and creates the <see cref="DmnDefinition"/> from <see cref="DmnModel"/>
        /// </summary>
        /// <param name="source">Source DMN Model parsed from XML</param>
        ///<exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        /// <returns>DMN model definition that can be used to execute the decisions within the <see cref="runtime.DmnExecutionContext"/></returns>
        public static DmnDefinition CreateDmnDefinition(DmnModel source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            var factory = new DmnDefinitionFactory(source);

            return(new DmnDefinition(
                       factory.Variables.ToDictionary(
                           v => v.Key,
                           v => (IDmnVariable)v.Value),
                       factory.Decisions));
        }
コード例 #8
0
 /// <summary>
 /// Creates the execution context from <paramref name="sourceModel"/>
 /// </summary>
 /// <param name="sourceModel">Source model to create the execution context for</param>
 /// <param name="configure">Optional configuration action</param>
 /// <returns><paramref name="sourceModel"/> execution context</returns>
 /// <exception cref="ArgumentNullException"><paramref name="sourceModel"/> is null</exception>
 public static DmnExecutionContext CreateExecutionContext(
     DmnModel sourceModel,
     Action <DmnExecutionContextOptions> configure = null)
 {
     return(CreateCustomExecutionContext <DmnExecutionContext>(sourceModel, configure));
 }