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)}) = "); }
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); }