예제 #1
0
        public string ForOutput(string paramNames, TapestryAction action)
        {
            if (!action.OutputVars.Any() || string.IsNullOrWhiteSpace(paramNames))
            {
                return("");
            }

            /// split
            Dictionary <string, string> allParams;

            try
            {
                allParams = paramNames.Split(';').Select(i => i.Split('=')).ToDictionary(i => i[1], i => i[0]);
            }
            catch (Exception ex)
            {
                throw new TapestrySyntacticOmniusException($"Wrong item output format! [{paramNames}]", ex);
            }

            /// order
            List <string> result = new List <string>();

            for (int i = 0; i < action.OutputVars.Length; i++)
            {
                string outVarName = action.OutputVars[i];
                /// value -> /dev/null
                if (!allParams.ContainsKey(outVarName))
                {
                    result.Add("_core.Data[\"\"]");
                    continue;
                }

                string globalVarName = allParams[outVarName];

                /// system
                if (globalVarName[0] == '_')
                {
                    if (globalVarName == "__ModelId__")
                    {
                        result.Add("_core.ModelId");
                        continue;
                    }

                    if (globalVarName.StartsWith("__Result["))
                    {
                        result.Add($"_core.Results[\"{globalVarName.Substring(9).TrimEnd(']')}\"]");
                        continue;
                    }

                    result.Add($"_core.Data[\"{globalVarName}\"]");
                    continue;
                }

                /// add
                string realGlobalVarName = _realGlobalVarName(globalVarName);
                if (!_varNames.Contains(realGlobalVarName))
                {
                    _varNames.Add(realGlobalVarName);
                }

                result.Add(realGlobalVarName);
            }

            if (result.Count == 1)
            {
                if (result.First() == "_core.ModelId")
                {
                    return("_core.ModelId = (int)");
                }

                return($"{result.First()} = ");
            }

            return($"({string.Join(",", result)}) = ");
        }
예제 #2
0
        private (TapestryDesignerWorkflowItem, int) DrainBranch(CodeBuilder result, TapestryDesignerWorkflowItem startItem, BranchType branchType)
        {
            /// INIT
            int branchGoesThrought = 1;
            TapestryDesignerWorkflowItem currentItem = startItem;

            /// foreach in branch
            while (currentItem != null)
            {
                try
                {
                    // join
                    int targetToCount = currentItem.TargetToConnection.Count(c => c.Source.TypeClass != "integrationItem" && c.Source.TypeClass != "templateItem");
                    if (targetToCount > branchGoesThrought)
                    {
                        return(currentItem, branchGoesThrought);
                    }
                    else
                    {
                        branchGoesThrought = 1;
                    }

                    // compile symbol
                    result.AppendLine($"_symbolAction({currentItem.Id}, this);");

                    // lock
                    if (currentItem.HasParallelLock)
                    {
                        result.AppendLine($"lock (_core.Lock({currentItem.Id}))");
                        result.StartBlock();
                    }

                    string inputVariables = currentItem.InputVariables ?? "";
                    switch (currentItem.TypeClass)
                    {
                    // action
                    // action with params
                    case "actionItem":
                        // params
                        var paramItem = currentItem.TargetToConnection.SingleOrDefault(c => c.Source.TypeClass == "integrationItem" || c.Source.TypeClass == "templateItem")?.Source;
                        if (paramItem != null)
                        {
                            switch (paramItem.TypeClass)
                            {
                            case "integrationItem":
                                inputVariables = $"{currentItem.InputVariables.Trim().TrimEnd(';')};WSName=s${paramItem.Label.Substring(4)}";         // remove 'WS: ' from beginning
                                break;

                            case "templateItem":
                                inputVariables = $"{currentItem.InputVariables.Trim().TrimEnd(';')};Template=s${paramItem.Label}";
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                        }

                        // Action
                        if (!ActionManager.All.ContainsKey(currentItem.ActionId.Value))
                        {
                            throw new TapestrySyntacticOmniusException($"Action[Id:{currentItem.ActionId.Value},Name:{currentItem.Label}] not found");
                        }
                        TapestryAction action = ActionManager.All[currentItem.ActionId.Value];
                        result.AppendLine($"{ForOutput(currentItem.OutputVariables?.Trim(), action)}{action.Repository}.{action.Method.Name}(_core{string.Join("", transformInputParams(currentItem, inputVariables, action.Method).Select(p => $",{p}"))});");
                        break;

                    // target
                    case "targetItem":
                        result.AppendLine($"this.TargetName = \"{currentItem.Target.Name.RemoveDiacritics()}\";");
                        result.AppendLine("return;");
                        break;

                    // gw x
                    // gw +
                    case "symbol":
                        switch (currentItem.SymbolType)
                        {
                        case "gateway-x":
                            branchGoesThrought--;         // removes current
                            result.AppendLine($"if ({currentItem.ConditionGroups.SingleOrDefault()?.ToString(this) ?? "true"})");
                            result.StartBlock();
                            (var joinItem, int returnedBranchCount) = DrainBranch(result, currentItem.SourceToConnection.SingleOrDefault(c => c.SourceSlot == 0)?.Target, branchType);
                            branchGoesThrought += returnedBranchCount;         // add if
                            result.Else();
                            (currentItem, returnedBranchCount) = DrainBranch(result, currentItem.SourceToConnection.SingleOrDefault(c => c.SourceSlot == 1)?.Target, branchType);
                            branchGoesThrought += returnedBranchCount;         // add else
                            result.EndBlock();
                            // wrong syntactic - branch has to meet, if it not end
                            if (joinItem != null && currentItem != null && joinItem != currentItem)
                            {
                                throw new TapestrySyntacticOmniusException($"Gateway ends on different items[{joinItem.Id}:{joinItem.Label}, {currentItem.Id}:{currentItem.Label}]");
                            }
                            // 'else' ends with return -> continue with 'if'
                            if (currentItem == null)
                            {
                                currentItem = joinItem;
                            }
                            continue;

                        case "gateway-plus":
                            branchGoesThrought--;         // removes current
                            TapestryDesignerWorkflowItem gatewayItem = currentItem;
                            result.AppendLine($"_ParallelRun({gatewayItem.Id}, () => ThreadMethod_{gatewayItem.Id}(_symbolAction));");
                            (currentItem, returnedBranchCount) = DrainBranch(result, gatewayItem.SourceToConnection.Single(c => c.SourceSlot == 0).Target, branchType);
                            branchGoesThrought += returnedBranchCount;

                            _threadMethods.AppendLine($"private void ThreadMethod_{gatewayItem.Id}(Action<int, Block> _symbolAction)");
                            _threadMethods.StartBlock();
                            (joinItem, returnedBranchCount) = DrainBranch(_threadMethods, gatewayItem.SourceToConnection.Single(c => c.SourceSlot == 1).Target, BranchType.Method);
                            branchGoesThrought += returnedBranchCount;
                            _threadMethods.EndBlock();

                            // wrong syntactic - branch has to meet, if it not end
                            if (joinItem != null && currentItem != null && joinItem != currentItem)
                            {
                                throw new TapestrySyntacticOmniusException($"Gateway ends on different items[{joinItem.Id}:{joinItem.Label}, {currentItem.Id}:{currentItem.Label}]");
                            }

                            // merge
                            if (joinItem != null && currentItem != null)
                            {
                                result.AppendLine($"_WaitForParallel({gatewayItem.Id});");
                            }
                            continue;

                        case "circle-single":
                            // wf beginning
                            // DONE
                            break;
                        }
                        break;

                    case "stateItem":
                        break;

                    // foreach
                    case "virtualAction":
                        string itemName = currentItem.ParentForeach.ItemName ?? "__item__";
                        switch (currentItem.SymbolType)
                        {
                        case "foreach":
                            if (currentItem.ParentForeach.IsParallel)
                            {
                                result.AppendLine($"Parallel.ForEach((IEnumerable<dynamic>){_realGlobalVarName(currentItem.ParentForeach.DataSource)}, ({itemName}) => ");
                                result.StartBlock();
                                _varNames.Add("__item__");
                                DrainBranch(result, _context.TapestryDesignerWorkflowItems.Single(i => i.ParentForeachId == currentItem.ParentForeachId && i.IsForeachStart == true), BranchType.Method);
                                _varNames.Remove("__item__");
                                result.EndBlock(");");         // end foreach
                            }
                            else
                            {
                                result.AppendLine($"foreach (object {itemName} in (IEnumerable<dynamic>){_realGlobalVarName(currentItem.ParentForeach.DataSource)})");
                                result.StartBlock();
                                _varNames.Add(itemName);
                                DrainBranch(result, _context.TapestryDesignerWorkflowItems.Single(i => i.ParentForeachId == currentItem.ParentForeachId && i.IsForeachStart == true), BranchType.ForeachLoop);
                                _varNames.Remove(itemName);
                                result.EndBlock();         // end foreach
                            }
                            break;
                        }
                        break;


                    case "uiItem":          // button - wf beginning
                    case "integrationItem": // integration - param
                    case "templateItem":    // email template - param
                        break;

                    case "attributeItem":
                    case "circle-single":
                    default:
                        throw new NotImplementedException();
                    }

                    // lock
                    if (currentItem.HasParallelLock)
                    {
                        result.EndBlock();
                    }

                    /// next
                    // foreach
                    if (currentItem?.IsForeachEnd == true)
                    {
                        return(null, 0);
                    }

                    // ok
                    currentItem = currentItem?.SourceToConnection.SingleOrDefault()?.Target;
                }
                catch (Exception ex)
                {
                    throw new TapestrySyntacticOmniusException(ex.Message, currentItem?.Id, ex);
                }
            }

            /// END of thread, foreach or WF
            switch (branchType)
            {
            case BranchType.ForeachLoop:
                // compile end symbol
                result.AppendLine($"_symbolAction(-2, this);");
                // next
                result.AppendLine("continue;");
                break;

            case BranchType.Method:
                // compile end symbol
                result.AppendLine($"_symbolAction(-1, this);");
                // end
                result.AppendLine("return;");
                break;

            default:
                throw new Exception("Unknown branchType");
            }
            return(null, 0);
        }