/// <summary> /// Adds the required input reference to the decision. /// </summary> /// <remarks>Required inputs represents the "link" between input and decision in a model. /// Technically, the input requirements (existence of the input) are not checked during the execution, /// it's more for better understanding the DMN model</remarks> /// <param name="input">Reference to the input variable</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> protected void AddRequiredInput(Variable.Ref input) { if (IsBuilt) { throw Logger.Error <DmnBuilderException>("Decision is already built"); } if (input == null) { throw new ArgumentNullException(nameof(input)); } if (!input.IsInputParameter) { throw Logger.Error <DmnBuilderException>($"Variable {input.Name} is not an input parameter"); } if (Variables[input] == null) { throw Logger.Error <DmnBuilderException>($"Can't get the variable from reference {input.Name}"); } if (!RequiredInputs.Contains(input)) { RequiredInputs.Add(input); } }
/// <summary> /// Adds the (non-input) variable of given <paramref name="name"/> and <paramref name="variableType">type</paramref> into the definition /// </summary> /// <param name="name">Name of the variable to add</param> /// <param name="variableType">Type of the variable to add</param> /// <param name="variableRef">Reference to the variable added</param> /// <returns>The current <see cref="DmnDefinitionBuilder"/></returns> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public DmnDefinitionBuilder WithVariable(string name, Type variableType, out Variable.Ref variableRef) { if (IsBuilt) { throw Logger.Error <DmnBuilderException>("Definition is already built"); } if (name == null) { throw new ArgumentNullException(nameof(name)); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Missing variable name", nameof(name)); } var variableName = DmnVariableDefinition.NormalizeVariableName(name); if (Variables.Variables.ContainsKey(variableName)) { throw Logger.Error <DmnBuilderException>($"Duplicate variable name {variableName} (normalized from {name})"); } var variable = new Variable(Variables, Decisions, variableName, variableType); variableRef = variable.Reference; Variables.AddVariable(variable); return(this); }
/// <summary> /// CTOR - create a new token representing a reference to variable /// </summary> /// <param name="variableRef">Reference to existing variable</param> public Token(Variable.Ref variableRef) { if (variableRef is null) { throw new ArgumentNullException(nameof(variableRef)); } value = variableRef.Name; }
/// <summary> /// Sets the output variable to store the result of the decision expression evaluation to /// </summary> /// <param name="variable">Reference to the variable used to store the expression decision output</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> /// <exception cref="ArgumentNullException">When the <paramref name="variable"/> is null</exception> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the <paramref name="variable"/> can't be found in <see cref="VariableCatalog"/></exception> private void SetOutput(Variable.Ref variable) { if (IsBuilt) { throw Logger.Error <DmnBuilderException>("Decision is already built"); } if (variable == null) { throw new ArgumentNullException(nameof(variable)); } OutputVariableInternal = Variables[variable] ?? throw Logger.Error <DmnBuilderException>($"Can't get the variable from reference {variable.Name}"); OutputVariableInternal.AddValueSetter($"Expression Decision {Name}"); }
/// <summary> /// Binds the table input to given variable reference /// </summary> /// <param name="variableRef">Reference to variable used as the table input source</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> /// <exception cref="ArgumentNullException">Throws <see cref="DmnBuilderException"/> when <paramref name="variableRef"/> is missing</exception> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when <paramref name="variableRef"/> can't be found in the variable catalog</exception> public TableInput WithVariable(Variable.Ref variableRef) { if (IsBuilt) { throw Logger.Error <DmnBuilderException>("Table input is already built"); } if (variableRef == null) { throw new ArgumentNullException(nameof(variableRef)); } var variable = Variables[variableRef] ?? throw Logger.Error <DmnBuilderException>($"Can't get the variable from reference {variableRef.Name}"); VariableInternal = variable; Expression = null; return(this); }
/// <summary> /// Adds the table output with reference to the variable to store the output value to /// </summary> /// <remarks>The outputs are "indexed" in the order as added to the table definition builder</remarks> /// <param name="variableRef">Reference to variable used to store the table output to</param> /// <param name="outputRef">Reference to added table output that can be used in rule builders</param> /// <param name="allowedValues">Allowed output values</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> /// <exception cref="ArgumentNullException"> when the <paramref name="variableRef"/> is not provided</exception> public TableDecision WithOutput(Variable.Ref variableRef, out TableOutput.Ref outputRef, params string[] allowedValues) { if (IsBuilt) { throw Logger.Error <DmnBuilderException>($"Decision is already built"); } if (variableRef == null) { throw new ArgumentNullException(nameof(variableRef)); } var output = new TableOutput(Variables, Decisions, OutputsInternal.Count).WithVariable(variableRef); _ = allowedValues != null && allowedValues.Length > 0 ? output.WithAllowedValues(allowedValues) : output.WithoutAllowedValuesConstraint(); outputRef = output.Reference; OutputsInternal.Add(output); OutputsByRef.Add(outputRef, output); return(this); }
/// <summary> /// Retrieves the <see cref="Variable"/> definition builder by its <see cref="Variable.Ref">reference</see> /// </summary> /// <param name="reference">Variable definition builder reference</param> /// <returns>Variable definition builder or null when the reference is not found</returns> public Variable this[Variable.Ref reference] => VariablesByRef.TryGetValue(reference, out var variable) ? variable : null;
/// <summary> /// Adds the required input reference to the decision. /// </summary> /// <remarks>Required inputs represents the "link" between input and decision in a model. /// Technically, the input requirements (existence of the input) are not checked during the execution, /// it's more for better understanding the DMN model</remarks> /// <param name="input">Reference to the input variable</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public ExpressionDecision Requires(Variable.Ref input) { AddRequiredInput(input); return(this); }
/// <summary> /// Sets the output variable to store the result of the decision expression evaluation to /// </summary> /// <param name="variable">Reference to the variable used to store the expression decision output</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public ExpressionDecision To(Variable.Ref variable) { Decision.SetOutput(variable); return(Decision); }
/// <summary> /// Adds the table output with reference to the variable to store the output value to /// </summary> /// <remarks>The outputs are "indexed" in the order as added to the table definition builder</remarks> /// <param name="variableRef">Reference to variable used to store the table output to</param> /// <param name="outputRef">Reference to added table output that can be used in rule builders</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> /// <exception cref="ArgumentNullException"> when the <paramref name="variableRef"/> is not provided</exception> public TableDecision WithOutput(Variable.Ref variableRef, out TableOutput.Ref outputRef) { return(WithOutput(variableRef, out outputRef, null)); }
/// <summary> /// Adds the variable based table input /// </summary> /// <remarks>The inputs are "indexed" in the order as added to the table definition builder</remarks> /// <param name="variableRef">Reference to variable used as table input</param> /// <param name="inputRef">Reference to added table input that can be used in rule builders</param> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public TableDecision WithInput(Variable.Ref variableRef, out TableInput.Ref inputRef) { return(WithInput(variableRef, out inputRef, null)); }
/// <summary> /// Adds the untyped input with given <paramref name="name"/> into the definition. /// Avoid using the untyped inputs where possible - the input type will be set based on the value assigned to the <see cref="execution.context.DmnExecutionContext"/>, /// so this needs to be taken into the consideration when defining the decisions /// </summary> /// <param name="name">Name of the input to add</param> /// <param name="inputVariable">Reference to the input variable backing the input added</param> /// <returns>The current <see cref="DmnDefinitionBuilder"/></returns> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public DmnDefinitionBuilder WithInput(string name, out Variable.Ref inputVariable) { return(WithInput(name, null, out inputVariable)); }
/// <summary> /// Adds the expression decision into the definition /// </summary> /// <param name="name">Name of the decision to add</param> /// <param name="expression">Expression to be evaluated during the decision execution</param> /// <param name="outputVariable">Reference to existing variable to store the output of the decision evaluation</param> /// <param name="decisionRef">Reference to the decision added</param> /// <returns>The current <see cref="DmnDefinitionBuilder"/></returns> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public DmnDefinitionBuilder WithExpressionDecision(string name, string expression, Variable.Ref outputVariable, out Decision.Ref decisionRef) { return(WithExpressionDecision(name, e => e.Put(expression).To(outputVariable), out decisionRef)); }
/// <summary> /// Adds the (non-input) variable of given <paramref name="name"/> and <typeparamref name="TVariableType">type</typeparamref> into the definition /// </summary> /// <param name="name">Name of the variable to add</param> /// <param name="variableRef">Reference to the variable added</param> /// <typeparam name="TVariableType">Type of the variable to add</typeparam> /// <returns>The current <see cref="DmnDefinitionBuilder"/></returns> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public DmnDefinitionBuilder WithVariable <TVariableType>(string name, out Variable.Ref variableRef) { return(WithVariable(name, typeof(TVariableType), out variableRef)); }
/// <summary> /// Adds the inputs of given <paramref name="name"/> and <typeparamref name="TVariableType">type</typeparamref> into the definition /// </summary> /// <param name="name">Name of the input to add</param> /// <param name="inputVariable">Reference to the input variable backing the input added</param> /// <typeparam name="TVariableType">Type of the input to add</typeparam> /// <returns>The current <see cref="DmnDefinitionBuilder"/></returns> /// <exception cref="DmnBuilderException">Throws <see cref="DmnBuilderException"/> when the definition has already been built</exception> public DmnDefinitionBuilder WithInput <TVariableType>(string name, out Variable.Ref inputVariable) { return(WithInput(name, typeof(TVariableType), out inputVariable)); }