Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS & C# conversion rewrite #660

Merged
merged 3 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 59 additions & 53 deletions FetchXmlBuilder/AppCode/CSharpCodeGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,75 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
using System.Security;
using System.Text;
using System.Xml;

namespace Cinteros.Xrm.FetchXmlBuilder.AppCode
{
public class CSharpCodeGenerator : CodeGeneratorBase
public class CSharpCodeGenerator
{
public static string GetCSharpCode(string fetchXml)
public static string GetCSharpCode(string fetchXml)
{
var data = new List<NameValue>();
var fetch = string.Empty;
var name = string.Empty;
fetchXml = fetchXml.Replace("\"", "'");
var lines = fetchXml.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
var data = new Dictionary<string, string>();
var xml = new XmlDocument();
xml.LoadXml(fetchXml);

var conditionAttributes = xml.SelectNodes("//condition/@value");

foreach (XmlAttribute attribute in conditionAttributes)
{
var value = AddData(attribute.OwnerElement.GetAttribute("attribute"), attribute.Value, data);
attribute.Value = $"{{{value}}}";
}

var conditionValues = xml.SelectNodes("//condition/value");

foreach (XmlElement val in conditionValues)
{
var space = line.Substring(0, line.IndexOf("<"));
if (line.Trim().StartsWith("<condition"))
{
var pattern = "('(.*?)' |'(.*?)'/>)";
var matches = new Regex(pattern).Matches(line);
name = matches[0].Value.Substring(1, matches[0].Value.Length - 3);
if (matches.Count == 3 || matches.Count == 5)
{
var @operator = matches[1].Value.Substring(1, matches[1].Value.Length - 3);
var value = matches[matches.Count - 1].Value.Substring(1, matches[matches.Count - 1].Value.Length - 3);
var fetchData = GetFetchData(data, name, value);
var codeValue = "fetchData." + fetchData.Name + "/*" + fetchData.Value + "*/";
data.Add(new NameValue { Name = fetchData.Name, Value = fetchData.Value });
fetch += space + "<condition attribute='" + name + "' operator='" + @operator + "' value='{" + codeValue + "}'/>\n";
}
else
fetch += line + "\n";
}
else if (line.Trim().StartsWith("<value"))
{
var pattern = ">.*<";
var matches = new Regex(pattern).Matches(line);
if (matches.Count == 1)
{
var value = matches[0].Value.Substring(1, matches[0].Value.Length - 2);
var fetchData = GetFetchData(data, name, value);
var codeValue = "fetchData." + fetchData.Name + "/*" + fetchData.Value + "*/";
data.Add(new NameValue { Name = fetchData.Name, Value = fetchData.Value });
fetch += space + "<value>{" + codeValue + "}</value>\n";
}
else
fetch += line + "\n";
}
else
fetch += line + "\n";
var value = AddData(((XmlElement)val.ParentNode).GetAttribute("attribute"), val.InnerText.Trim(), data);
val.InnerText = $"{{{value}}}";
}
var cs = string.Empty;

var cs = "";

if (data.Count > 0)
{
cs += "\tvar fetchData = new {\r\n";
foreach (var nv in data)
cs += "\t\t" + nv.Name + " = " + "\"" + nv.Value + "\",\r\n";
cs = cs.Substring(0, cs.Length - ",\r\n".Length);
cs += "\n\t};\r\n";
cs = "var fetchData = new {\r\n " + String.Join(",\r\n ", data.Select(kvp => $"{kvp.Key} = \"{kvp.Value.Replace("\\", "\\\\").Replace("\"", "\\\"")}\"")) + "\r\n};\r\n";
}

var sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.Replace
};
using (var writer = XmlWriter.Create(sb, settings))
{
xml.Save(writer);
}
cs += "\tvar fetchXml = $@\"\r\n";
cs += fetch.Substring(0, fetch.Length - 1);
cs += "\";\r\n";

cs += "var fetchXml = $@\"" + sb.Replace("\"", "\"\"").ToString() + "\";";

return cs;
}

private static string AddData(string attribute, string value, Dictionary<string, string> data)
{
var key = attribute;

var suffix = 1;
while (data.ContainsKey(key))
{
suffix++;
key = attribute + suffix;
}

data[key] = SecurityElement.Escape(value);

return $"fetchData.{key}/*{value.Replace("*/", "")}*/";
}
}
}
36 changes: 0 additions & 36 deletions FetchXmlBuilder/AppCode/CodeGeneratorBase.cs

This file was deleted.

128 changes: 80 additions & 48 deletions FetchXmlBuilder/AppCode/JavascriptCodeGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,101 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
using System.Security;
using System.Xml;
using Newtonsoft.Json;

namespace Cinteros.Xrm.FetchXmlBuilder.AppCode
{
public class JavascriptCodeGenerator : CodeGeneratorBase
public class JavascriptCodeGenerator
{
public static string GetJavascriptCode(string fetchXml)
{
var data = new List<NameValue>();
var fetch = string.Empty;
var name = string.Empty;
fetchXml = fetchXml.Replace("\"", "'");
var lines = fetchXml.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
var data = new Dictionary<string, string>();
var lines = new List<string>();
var xml = new XmlDocument();
xml.LoadXml(fetchXml);

Convert(xml.DocumentElement, 0, lines, data);

var js = "";

if (data.Count > 0)
{
var space = line.Substring(0, line.IndexOf("<"));
if (line.Trim().StartsWith("<condition"))
js = $"var fetchData = {JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented)};\r\n";
}

js += $"var fetchXml = [\r\n{String.Join(",\r\n", lines)}\r\n].join(\"\");";

return js;
}

private static void Convert(XmlElement element, int depth, List<string> lines, Dictionary<string, string> data)
{
var lineComponents = new List<string>();
var line = new string(' ', depth * 2) + $"<{element.Name}";

foreach (XmlAttribute attribute in element.Attributes)
{
line += $" {attribute.Name}='";

if (attribute.Name == "value" && element.Name == "condition")
{
var pattern = "('(.*?)' |'(.*?)'/>)";
var matches = new Regex(pattern).Matches(line);
name = matches[0].Value.Substring(1, matches[0].Value.Length - 3);
if (matches.Count == 3 || matches.Count == 5)
{
var @operator = matches[1].Value.Substring(1, matches[1].Value.Length - 3);
var value = matches[matches.Count - 1].Value.Substring(1, matches[matches.Count - 1].Value.Length - 3);
var fetchData = GetFetchData(data, name, value);
var codeValue = "fetchData." + fetchData.Name + "/*" + fetchData.Value + "*/";
data.Add(new NameValue { Name = fetchData.Name, Value = fetchData.Value });
fetch += "\"" + space + "<condition attribute='" + name + "' operator='" + @operator + "' value='" + "\", " + codeValue + ", \"'/>\",\n";
}
else
fetch += "\"" + line + "\",\n";
lineComponents.Add(JsonConvert.SerializeObject(line));
AddData(element.GetAttribute("attribute"), attribute.Value, data, lineComponents);
line = "'";
}
else
{
line += $"{SecurityElement.Escape(attribute.Value)}'";
}
else if (line.Trim().StartsWith("<value"))
}

if (element.IsEmpty)
{
line += "/>";
lineComponents.Add(JsonConvert.SerializeObject(line));
lines.Add(String.Join(", ", lineComponents));
}
else
{
line += ">";
lineComponents.Add(JsonConvert.SerializeObject(line));

if (element.Name == "value" && element.ParentNode is XmlElement parentElement && parentElement.Name == "condition")
{
var pattern = ">.*<";
var matches = new Regex(pattern).Matches(line);
if (matches.Count == 1)
AddData(parentElement.GetAttribute("attribute"), element.InnerText.Trim(), data, lineComponents);
lineComponents.Add("\"</value>\"");
lines.Add(String.Join(", ", lineComponents));
}
else
{
lines.Add(String.Join(", ", lineComponents));

foreach (var child in element.ChildNodes.OfType<XmlElement>())
{
var value = matches[0].Value.Substring(1, matches[0].Value.Length - 2);
var fetchData = GetFetchData(data, name, value);
var codeValue = "fetchData." + fetchData.Name + "/*" + fetchData.Value + "*/";
data.Add(new NameValue { Name = fetchData.Name, Value = fetchData.Value });
fetch += "\"" + space + "<value>\", " + codeValue + ", \"</value>\",\n";
Convert(child, depth + 1, lines, data);
}
else
fetch += "\"" + line + "\",\n";

lines.Add(JsonConvert.SerializeObject(new string(' ', depth * 2) + $"</{element.Name}>"));
}
else
fetch += "\"" + line + "\",\n";
}
var js = string.Empty;
if (data.Count > 0)
}

private static void AddData(string attribute, string value, Dictionary<string, string> data, List<string> lineComponents)
{
var key = attribute;

var suffix = 1;
while (data.ContainsKey(key))
{
js += "\tvar fetchData = {\r\n";
foreach (var nv in data)
js += "\t\t" + nv.Name + ": " + "\"" + nv.Value + "\",\r\n";
js = js.Substring(0, js.Length - ",\r\n".Length);
js += "\n\t};\r\n";
suffix++;
key = attribute + suffix;
}
js += "\tvar fetchXml = [\r\n";
js += fetch.Substring(0, fetch.Length - 1);
js += "\r\n\t].join(\"\");";
return js;

data[key] = SecurityElement.Escape(value);

lineComponents.Add($"fetchData.{key}/*{value.Replace("*/", "")}*/");
}
}
}
1 change: 0 additions & 1 deletion FetchXmlBuilder/FetchXmlBuilder.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@
<Compile Include="AppCode\Extensions.cs" />
<Compile Include="AppCode\ServiceExtensions.cs" />
<Compile Include="AppCode\AttributeItem.cs" />
<Compile Include="AppCode\CodeGeneratorBase.cs" />
<Compile Include="AppCode\GroupBoxExpanderExtensions.cs" />
<Compile Include="AppCode\CSharpCodeGenerator.cs" />
<Compile Include="AppCode\DockExtensions.cs" />
Expand Down