Esempio n. 1
0
        protected virtual void BuildWorkflow(IEnumerable <WorkflowNode> allNodes, DefinitionSourceV1 source, IEnumerable <AbpWorkflowStepBody> stepBodys, WorkflowNode node)
        {
            if (source.Steps.Any(u => u.Id == node.Key))
            {
                return;
            }

            var stepSource = new StepSourceV1();

            stepSource.Id   = node.Key;
            stepSource.Name = node.Key;
            AbpWorkflowStepBody stepbody = stepBodys.FirstOrDefault(u => u.Name == node.StepBody.Name);

            if (stepbody == null)
            {
                stepbody = new AbpWorkflowStepBody()
                {
                    StepBodyType = typeof(NullStepBody)
                };
            }
            stepSource.StepType = $"{stepbody.StepBodyType.FullName}, {stepbody.StepBodyType.Assembly.FullName}";

            foreach (var input in stepbody.Inputs)
            {
                var value = node.StepBody.Inputs[input.Key].Value;
                if (!(value is IDictionary <string, object> || value is IDictionary <object, object>))
                {
                    value = $"\"{value}\"";
                }
                stepSource.Inputs.TryAdd(input.Key, value);
            }
            source.Steps.Add(stepSource);
            BuildBranching(allNodes, source, stepSource, stepBodys, node.NextNodes);
        }
Esempio n. 2
0
        private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var output in source.Outputs)
            {
                var stepParameter = Expression.Parameter(stepType, "step");
                var sourceExpr    = DynamicExpressionParser.ParseLambda(new[] { stepParameter }, typeof(object), output.Value);

                var        dataParameter = Expression.Parameter(dataType, "data");
                Expression targetProperty;

                // Check if our datatype has a matching property
                var propertyInfo = dataType.GetProperty(output.Key);
                if (propertyInfo != null)
                {
                    targetProperty = Expression.Property(dataParameter, propertyInfo);
                }
                else
                {
                    // If we did not find a matching property try to find a Indexer with string parameter
                    propertyInfo   = dataType.GetProperty("Item");
                    targetProperty = Expression.Property(dataParameter, propertyInfo, Expression.Constant(output.Key));
                }
                var targetExpr = Expression.Lambda(targetProperty, dataParameter);

                step.Outputs.Add(new DataMapping
                {
                    Source = sourceExpr,
                    Target = targetExpr
                });
            }
        }
Esempio n. 3
0
        private void AttachInputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var input in source.Inputs)
            {
                var dataParameter            = Expression.Parameter(dataType, "data");
                var contextParameter         = Expression.Parameter(typeof(IStepExecutionContext), "context");
                var environmentVarsParameter = Expression.Parameter(typeof(IDictionary), "environment");
                var stepProperty             = stepType.GetProperty(input.Key);

                if (stepProperty == null)
                {
                    throw new ArgumentException($"Unknown property for input {input.Key} on {source.Id}");
                }

                if (input.Value is string)
                {
                    var acn = BuildScalarInputAction(input, dataParameter, contextParameter, environmentVarsParameter, stepProperty);
                    step.Inputs.Add(new ActionParameter <IStepBody, object>(acn));
                    continue;
                }

                if ((input.Value is IDictionary <string, object>) || (input.Value is IDictionary <object, object>))
                {
                    var acn = BuildObjectInputAction(input, dataParameter, contextParameter, environmentVarsParameter, stepProperty);
                    step.Inputs.Add(new ActionParameter <IStepBody, object>(acn));
                    continue;
                }

                throw new ArgumentException($"Unknown type for input {input.Key} on {source.Id}");
            }
        }
Esempio n. 4
0
        private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var output in source.Outputs)
            {
                var stepParameter = Expression.Parameter(stepType, "step");
                var sourceExpr    = DynamicExpressionParser.ParseLambda(new[] { stepParameter }, typeof(object), output.Value);

                var        dataParameter = Expression.Parameter(dataType, "data");
                Expression targetProperty;

                // Check if our datatype has a matching property
                var propertyInfo = dataType.GetProperty(output.Key);
                if (propertyInfo != null)
                {
                    targetProperty = Expression.Property(dataParameter, propertyInfo);
                    var targetExpr = Expression.Lambda(targetProperty, dataParameter);
                    step.Outputs.Add(new MemberMapParameter(sourceExpr, targetExpr));
                }
                else
                {
                    // If we did not find a matching property try to find a Indexer with string parameter
                    propertyInfo   = dataType.GetProperty("Item");
                    targetProperty = Expression.Property(dataParameter, propertyInfo, Expression.Constant(output.Key));

                    Action <IStepBody, object> acn = (pStep, pData) =>
                    {
                        object resolvedValue = sourceExpr.Compile().DynamicInvoke(pStep);;
                        propertyInfo.SetValue(pData, resolvedValue, new object[] { output.Key });
                    };

                    step.Outputs.Add(new ActionParameter <IStepBody, object>(acn));
                }
            }
        }
        private void AttachStatics(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var staticMap in source.Statics)
            {
                var targetExpr = Expression.Property(Expression.Parameter(stepType), staticMap.Key);

                step.Statics.Add(new DataMappingStatics()
                {
                    Source = staticMap.Value,
                    Target = Expression.Lambda(targetExpr)
                });
            }
        }
        private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var output in source.Outputs)
            {
                var stepParameter = Expression.Parameter(stepType, "step");
                var sourceExpr    = DynamicExpressionParser.ParseLambda(new[] { stepParameter }, typeof(object), output.Value);
                var targetExpr    = Expression.Property(Expression.Parameter(dataType), output.Key);

                step.Outputs.Add(new DataMapping()
                {
                    Source = sourceExpr,
                    Target = Expression.Lambda(targetExpr)
                });
            }
        }
Esempio n. 7
0
        private void AttachInputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var input in source.Inputs)
            {
                var dataParameter    = Expression.Parameter(dataType, "data");
                var contextParameter = Expression.Parameter(typeof(IStepExecutionContext), "context");
                var sourceExpr       = DynamicExpressionParser.ParseLambda(new [] { dataParameter, contextParameter }, typeof(object), input.Value);

                var stepParameter  = Expression.Parameter(stepType, "step");
                var targetProperty = Expression.Property(stepParameter, input.Key);
                var targetExpr     = Expression.Lambda(targetProperty, stepParameter);

                step.Inputs.Add(new MemberMapParameter(sourceExpr, targetExpr));
            }
        }
        private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var output in source.Outputs)
            {
                var stepParameter = Expression.Parameter(stepType, "step");
                var sourceExpr    = DynamicExpressionParser.ParseLambda(new[] { stepParameter }, typeof(object), output.Value);

                var dataParameter = Expression.Parameter(dataType, "data");


                if (output.Key.Contains(".") || output.Key.Contains("["))
                {
                    AttachNestedOutput(output, step, source, sourceExpr, dataParameter);
                }
                else
                {
                    AttachDirectlyOutput(output, step, dataType, sourceExpr, dataParameter);
                }
            }
        }
Esempio n. 9
0
        private void AttachOutcomes(StepSourceV1 source, Type dataType, WorkflowStep step)
        {
            if (!string.IsNullOrEmpty(source.NextStepId))
            {
                step.Outcomes.Add(new StepOutcome()
                {
                    ExternalNextStepId = $"{source.NextStepId}"
                });
            }

            foreach (var nextStep in source.OutcomeSteps)
            {
                var dataParameter = Expression.Parameter(dataType, "data");
                var sourceExpr    = DynamicExpressionParser.ParseLambda(new[] { dataParameter }, typeof(object), nextStep.Value);
                step.Outcomes.Add(new StepOutcome()
                {
                    Value = sourceExpr,
                    ExternalNextStepId = $"{nextStep.Key}"
                });
            }
        }
Esempio n. 10
0
        private void AttachOutcomes(StepSourceV1 source, Type dataType, WorkflowStep step)
        {
            if (!string.IsNullOrEmpty(source.NextStepId))
            {
                step.Outcomes.Add(new ValueOutcome {
                    ExternalNextStepId = $"{source.NextStepId}"
                });
            }

            var dataParameter    = Expression.Parameter(dataType, "data");
            var outcomeParameter = Expression.Parameter(typeof(object), "outcome");

            foreach (var nextStep in source.SelectNextStep)
            {
                var sourceDelegate = DynamicExpressionParser.ParseLambda(new[] { dataParameter, outcomeParameter }, typeof(object), nextStep.Value).Compile();
                Expression <Func <object, object, bool> > sourceExpr = (data, outcome) => System.Convert.ToBoolean(sourceDelegate.DynamicInvoke(data, outcome));
                step.Outcomes.Add(new ExpressionOutcome <object>(sourceExpr)
                {
                    ExternalNextStepId = $"{nextStep.Key}"
                });
            }
        }
Esempio n. 11
0
        private void AttachOutputs(StepSourceV1 source, Type dataType, Type stepType, WorkflowStep step)
        {
            foreach (var output in source.Outputs)
            {
                var stepParameter = Expression.Parameter(stepType, "step");
                var sourceExpr    = DynamicExpressionParser.ParseLambda(new[] { stepParameter }, typeof(object), output.Value);

                var        dataParameter = Expression.Parameter(dataType, "data");
                Expression targetProperty;

                // If the property has a point, check for a nested type
                Expression parentExpression = dataParameter;
                Type       parentDataType   = dataType;
                string     key          = output.Key;
                bool       continueLoop = key.Contains(".");
                while (continueLoop)
                {
                    var indexOfPoint    = key.IndexOf(".", StringComparison.InvariantCultureIgnoreCase);
                    var subPropertyName = key.Substring(0, indexOfPoint);
                    var subProperty     = parentDataType.GetProperty(subPropertyName);
                    key          = key.Substring(indexOfPoint + 1);
                    continueLoop = key.Contains(".");
                    var subPropertyParameterProperty = Expression.Property(parentExpression, subProperty);
                    parentExpression = subPropertyParameterProperty;
                    parentDataType   = subProperty.PropertyType;
                    if (!continueLoop)
                    {
                        subPropertyName = key;
                        subProperty     = parentDataType.GetProperty(subPropertyName);
                        subPropertyParameterProperty = Expression.Property(parentExpression, subProperty);
                        var subPropertyTarget =
                            Expression.Lambda(subPropertyParameterProperty, dataParameter);
                        step.Outputs.Add(new MemberMapParameter(sourceExpr, subPropertyTarget));
                        return;
                    }
                }

                // Check if our datatype has a matching property
                var propertyInfo = dataType.GetProperty(output.Key);
                if (propertyInfo != null)
                {
                    targetProperty = Expression.Property(dataParameter, propertyInfo);
                    var targetExpr = Expression.Lambda(targetProperty, dataParameter);
                    step.Outputs.Add(new MemberMapParameter(sourceExpr, targetExpr));
                }
                else
                {
                    // If we did not find a matching property try to find a Indexer with string parameter
                    propertyInfo   = dataType.GetProperty("Item");
                    targetProperty = Expression.Property(dataParameter, propertyInfo, Expression.Constant(output.Key));

                    Action <IStepBody, object> acn = (pStep, pData) =>
                    {
                        object resolvedValue = sourceExpr.Compile().DynamicInvoke(pStep);;
                        propertyInfo.SetValue(pData, resolvedValue, new object[] { output.Key });
                    };

                    step.Outputs.Add(new ActionParameter <IStepBody, object>(acn));
                }
            }
        }
Esempio n. 12
0
        private void AttachNestedOutput(KeyValuePair <string, string> output, WorkflowStep step, StepSourceV1 source, LambdaExpression sourceExpr, ParameterExpression dataParameter)
        {
            PropertyInfo propertyInfo = null;

            String[] paths = output.Key.Split('.');

            Expression targetProperty = dataParameter;

            bool hasAddOutput = false;

            foreach (String propertyName in paths)
            {
                if (hasAddOutput)
                {
                    throw new ArgumentException($"Unknown property for output {output.Key} on {source.Id}");
                }

                if (targetProperty == null)
                {
                    break;
                }

                if (propertyName.Contains("["))
                {
                    String[] items = propertyName.Split('[');

                    if (items.Length != 2)
                    {
                        throw new ArgumentException($"Unknown property for output {output.Key} on {source.Id}");
                    }

                    items[1] = items[1].Trim().TrimEnd(']').Trim().Trim('"');

                    MemberExpression memberExpression = Expression.Property(targetProperty, items[0]);

                    if (memberExpression == null)
                    {
                        throw new ArgumentException($"Unknown property for output {output.Key} on {source.Id}");
                    }
                    propertyInfo = ((PropertyInfo)memberExpression.Member).PropertyType.GetProperty("Item");

                    Action <IStepBody, object> acn = (pStep, pData) =>
                    {
                        var    targetExpr    = Expression.Lambda(memberExpression, dataParameter);
                        object data          = targetExpr.Compile().DynamicInvoke(pData);
                        object resolvedValue = sourceExpr.Compile().DynamicInvoke(pStep);;
                        propertyInfo.SetValue(data, resolvedValue, new object[] { items[1] });
                    };

                    step.Outputs.Add(new ActionParameter <IStepBody, object>(acn));
                    hasAddOutput = true;
                }
                else
                {
                    try
                    {
                        targetProperty = Expression.Property(targetProperty, propertyName);
                    }
                    catch
                    {
                        targetProperty = null;
                        break;
                    }
                }
            }

            if (targetProperty != null && !hasAddOutput)
            {
                var targetExpr = Expression.Lambda(targetProperty, dataParameter);
                step.Outputs.Add(new MemberMapParameter(sourceExpr, targetExpr));
            }
        }
Esempio n. 13
0
        protected virtual void BuildBranching(IEnumerable <WorkflowNode> allNodes, DefinitionSourceV1 source, StepSourceV1 stepSource, IEnumerable <AbpWorkflowStepBody> stepBodys, IEnumerable <WorkflowConditionNode> nodes)
        {
            foreach (var nextNode in nodes)
            {
                var node = allNodes.First(u => u.Key == nextNode.NodeId);
                stepSource.SelectNextStep[nextNode.NodeId] = "1==1";
                if (nextNode.Conditions.Count() > 0)
                {
                    List <string> exps = new List <string>();
                    foreach (var cond in nextNode.Conditions)
                    {
                        if (cond.Value is string && (!decimal.TryParse(cond.Value.ToString(), out decimal tempValue)))
                        {
                            if (cond.Operator != "==" && cond.Operator != "!=")
                            {
                                throw new AbpException($" if {cond.Field} is type of 'String', the Operator must be \"==\" or \"!=\"");
                            }
                            exps.Add($"data[\"{cond.Field}\"].ToString() {cond.Operator} \"{cond.Value}\"");
                            continue;
                        }
                        exps.Add($"decimal.Parse(data[\"{cond.Field}\"].ToString()) {cond.Operator} {cond.Value}");
                    }
                    stepSource.SelectNextStep[nextNode.NodeId] = string.Join(" && ", exps);
                }

                BuildWorkflow(allNodes, source, stepBodys, node);
            }
        }