Skip to content
Snippets Groups Projects
Commit cae3ae12 authored by Bensong Liu's avatar Bensong Liu
Browse files

Merge branch 'allow_explicit_arg' into 'master'

Allow explicit arg

See merge request bensl/cis-workflow-gen!1
parents 816e66b2 741e4231
No related branches found
No related tags found
1 merge request!1Allow explicit arg
......@@ -9,7 +9,7 @@
#include <queue>
#include <algorithm>
#include "uuid.hpp"
#include "utility.hpp"
#include "xaml-template.hpp"
#include <rlib/string.hpp>
#include <rlib/require/cxx14>
......@@ -24,39 +24,61 @@ namespace CIS {
class Activity {
public:
friend Flow;
// All `Name` should not contain QuotationMark(")
Activity(string displayName, string className, string entityName = "")
: displayName(displayName), className(className), entityName(entityName), taskId(GenUUID()) {}
: displayName(Utility::HtmlEscapeString(displayName)), className(className), entityName(entityName), taskId(Utility::GenUUID()) {}
Flow operator>>(const Flow &seqNext) const;
Flow operator|(const Flow &seqNext) const;
void addInputSetting(string k, string v) {
inputSettings[k] = v;
}
void addRawActivityArgument(string xamlTypeString, string csharpValueCode) {
throw std::invalid_argument("Not implemented yet.");
void explicitSetRawArgument(string argTypeInXaml, string argValueInCSharp) {
throw std::runtime_error("NotSupported! Activity seems doesn't support custom type inputSettings at all. Refer to commit 7fd539d6d5f6b102337da9591217b781cb71ced9 if we get new info and want to support it again. ");
}
private:
string displayName, className, entityName;
string taskId;
std::unordered_map<string, string> inputSettings;
auto inputSettingsToCodelines() const {
// Convert InputSettings Dictionary to C# code.
std::list<string> inputSettingStrings;
std::transform(this->inputSettings.begin(), this->inputSettings.end(), std::back_inserter(inputSettingStrings), [](auto &&kv) {
return " {\"{}\", \"{}\"}"_rs.format(kv.first, kv.second);
});
auto inputSettingsString = ",\n"_rs.join(inputSettingStrings);
return rlib::string(templates::ACTIVITY_DICT_TEMPLATE_UNESCAPED).replace_once("__TEMPLATE_ARG_DictLines", inputSettingsString);
}
auto generateXaml() const {
rlib::string xamlCode;
if(inputSettings.empty()) {
// Also no inputSettings.
xamlCode = templates::ACTIVITY_XAML_TEMPLATE_WITHOUT_INPUTSETTINGS;
}
else {
// Generate inputSettings.
xamlCode = templates::ACTIVITY_XAML_TEMPLATE;
xamlCode.replace("__TEMPLATE_ARG_TypeName", templates::ACTIVITY_DICT_TYPENAME);
xamlCode.replace_once("__TEMPLATE_ARG_TypeValue", Utility::HtmlEscapeString(inputSettingsToCodelines()));
}
xamlCode.replace_once("__TEMPLATE_ARG_ClassName", this->className);
xamlCode.replace_once("__TEMPLATE_ARG_DisplayName", this->displayName);
xamlCode.replace_once("__TEMPLATE_ARG_TaskId", this->taskId);
auto entityXaml = this->entityName == "" ? "" : rlib::string(templates::ENTITY_DEF_TEMPLATE).replace("__TEMPLATE_ARG_EntityName", this->entityName);
xamlCode.replace_once("__TEMPLATE_ARG_EntityDefPlaceholder", entityXaml);
return xamlCode;
}
};
class Flow {
public:
Flow(const Activity &activity) {
xamlCode = templates::ACTIVITY_XAML_TEMPLATE;
xamlCode.replace_once("__TEMPLATE_ARG_ClassName", activity.className);
xamlCode.replace_once("__TEMPLATE_ARG_DisplayName", activity.displayName);
xamlCode.replace_once("__TEMPLATE_ARG_TaskId", activity.taskId);
auto entityXaml = activity.entityName == "" ? "" : rlib::string(templates::ENTITY_DEF_TEMPLATE).replace("__TEMPLATE_ARG_EntityName", activity.entityName);
xamlCode.replace_once("__TEMPLATE_ARG_EntityDefPlaceholder", entityXaml);
std::list<string> inputSettingStrings;
std::transform(activity.inputSettings.begin(), activity.inputSettings.end(), std::back_inserter(inputSettingStrings), [](auto &&kv) {
return "{\"{}\", \"{}\"}"_rs.format(kv.first, kv.second);
});
auto inputSettingsString = ",\n "_rs.join(inputSettingStrings);
xamlCode.replace_once("__TEMPLATE_ARG_DictLines", inputSettingsString);
xamlCode = activity.generateXaml();
}
Flow(rlib::string xamlCode) : xamlCode(xamlCode) {}
Flow(const Flow &another) : queued(another.queued), xamlCode(another.xamlCode), prevOperationIsSequential(another.prevOperationIsSequential) {}
......
......@@ -3,8 +3,12 @@
#include <random>
#include <string>
#include <rlib/string.hpp>
inline static std::string GenUUID() {
namespace Utility {
inline static auto GenUUID() {
static std::random_device dev;
static std::mt19937 rng(dev());
......@@ -22,4 +26,10 @@ inline static std::string GenUUID() {
return res;
}
inline static auto HtmlEscapeString(rlib::string s) {
return s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
}
}
#endif
\ No newline at end of file
......@@ -12,17 +12,26 @@ namespace templates {
constexpr auto ACTIVITY_XAML_TEMPLATE =
R"XAMLTL( <mwcwa:ControlledActivity ClassName="__TEMPLATE_ARG_ClassName" DisplayName="__TEMPLATE_ARG_DisplayName" TaskId="__TEMPLATE_ARG_TaskId" __TEMPLATE_ARG_EntityDefPlaceholder>
<mwcwa:ControlledActivity.InputSettings>
<InArgument x:TypeArguments="scg:Dictionary(x:String, x:String)">
<mca:CSharpValue x:TypeArguments="scg:Dictionary(x:String, x:String)" xml:space="preserve">
new Dictionary&lt;string, string&gt;()
{
__TEMPLATE_ARG_DictLines
}
</mca:CSharpValue>
<InArgument x:TypeArguments="__TEMPLATE_ARG_TypeName">
<mca:CSharpValue x:TypeArguments="__TEMPLATE_ARG_TypeName" xml:space="preserve">
__TEMPLATE_ARG_TypeValue </mca:CSharpValue>
</InArgument>
</mwcwa:ControlledActivity.InputSettings>
</mwcwa:ControlledActivity>
)XAMLTL";
constexpr auto ACTIVITY_XAML_TEMPLATE_WITHOUT_INPUTSETTINGS =
R"XAMLTL( <mwcwa:ControlledActivity ClassName="__TEMPLATE_ARG_ClassName" DisplayName="__TEMPLATE_ARG_DisplayName" TaskId="__TEMPLATE_ARG_TaskId" InputSettings="{x:Null}" __TEMPLATE_ARG_EntityDefPlaceholder>
</mwcwa:ControlledActivity>
)XAMLTL";
// This 2 variable below were designed to support custom TypeArguments type, but CIS seems not support it...
constexpr auto ACTIVITY_DICT_TYPENAME = "scg:Dictionary(x:String, x:String)";
constexpr auto ACTIVITY_DICT_TEMPLATE_UNESCAPED =
R"XAMLTL( new Dictionary<string, string>()
{
__TEMPLATE_ARG_DictLines
}
)XAMLTL";
constexpr auto ENTITY_DEF_TEMPLATE = R"(coordination:DependencyBinder.EntityName="__TEMPLATE_ARG_EntityName")";
......
......@@ -31,10 +31,13 @@ auto complexExample() {
DEFINE_ACTIVITY(IntegrationTesting, "")
DEFINE_ACTIVITY(TSConfigAndInterop, "PreRteg.InitiateBareMetalComplete")
// All Names of activity should not contain quotation mark (")
Activity OneMoreMagicActivity("MyName Contains Symbols: {(&)} <>", "FleetAGC.Workflow.Magic");
auto block1 = SCS >> (SearchAnalytics | (SearchFarms >> (ClassisSearchUX | ModernSearch)));
auto block3 = Loki >> Yggdrasil >> OfficeGraph;
auto block4 = IC3Tooling >> (MonitoringSetup | (MicroServices >> DevelopmentValidation >> IntegrationTesting));
auto completeFlow = block1 | TSConfigAndInterop | block3 | block4;
auto completeFlow = (block1 | TSConfigAndInterop | block3 | block4) >> OneMoreMagicActivity;
auto myMetadata = Metadata("FleetAGC.Workflows.BuildTeams").setXtraAssemblies({"FleetAGC.Workflows"});
println(to_file("BuildTeams.xaml"), completeFlow.generateXaml(myMetadata));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment