Skip to content

Commit

Permalink
Complete Refactoring for Sinks Pattern (#5)
Browse files Browse the repository at this point in the history
- Obfuscated methods and classes from CSharp sink into the core Transpiler
 - Repurposed the `XmiTranspiler` into `TranspilerDispatcher`
 - Removed `CSharp` and `JavaScript` transpiler projects (look for them in separate Repositories)
  • Loading branch information
tbm0115 authored Feb 16, 2023
1 parent 2336eac commit 2838a74
Show file tree
Hide file tree
Showing 18 changed files with 323 additions and 252 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MtconnectTranspiler.Sinks.CSharp\MtconnectTranspiler.Sinks.CSharp.csproj" />
<ProjectReference Include="..\MtconnectTranspiler.Sinks.JavaScript\MtconnectTranspiler.Sinks.JavaScript.csproj" />
<ProjectReference Include="..\MtconnectTranspiler\MtconnectTranspiler.csproj" />
</ItemGroup>

Expand Down
49 changes: 1 addition & 48 deletions MtconnectTranspiler.Console/Views/MainView.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoulLibrary;
using ConsoulLibrary;
using ConsoulLibrary.Views;
using MtconnectTranspiler;
using MtconnectTranspiler.Contracts;

namespace MtconnectTranspiler.Console.Views
{
Expand All @@ -16,45 +9,5 @@ public MainView()
{
Title = (new BannerEntry($"MTConnect Transpiler")).Message;
}

[ViewOption("Transpile to C#")]
public void TranspileToCSharp()
{
string projectPath = Consoul.PromptForFilepath("Provide a project folder path", true);

var gitUrl = MTConnectHelper.BuildModelUri(MTConnectVersions.v2_1);
Consoul.Write($"Pulling the latest XMI from {gitUrl}");

var options = new TranspilerOptions();
options.Transpilers.Add(new MtconnectTranspiler.Sinks.CSharp.Transpiler(Path.Combine(projectPath, "CSharp")));

var cancelToken = new CancellationTokenSource();
using (var transpiler = new XmiTranspiler(options))
{
Consoul.Write("Press any key to cancel...");
var task = transpiler.TranspileAsync(gitUrl, cancelToken.Token);

while (!task.IsCompleted)
{
if (System.Console.KeyAvailable)
{
cancelToken.Cancel();
}
}
if (task.IsFaulted)
{
Consoul.Write(task.Exception.ToString(), ConsoleColor.Red);
if (task.Exception.InnerExceptions.Any())
{
foreach (var innerException in task.Exception.InnerExceptions)
{
Consoul.Write(innerException.ToString(), ConsoleColor.Red);
}
}
}
}
Consoul.Alert("Done!", ConsoleColor.Green);
Consoul.Wait();
}
}
}
3 changes: 1 addition & 2 deletions MtconnectTranspiler.Sinks.CSharp/Transpiler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MtconnectTranspiler.Contracts;
using MtconnectTranspiler.Model;
using MtconnectTranspiler.Model;
using MtconnectTranspiler.Sinks.CSharp.Attributes;
using MtconnectTranspiler.Sinks.CSharp.Models;
using MtconnectTranspiler.Xmi;
Expand Down
12 changes: 0 additions & 12 deletions MtconnectTranspiler.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MtconnectTranspiler", "Mtco
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MtconnectTranspiler.Console", "MtconnectTranspiler.Console\MtconnectTranspiler.Console.csproj", "{343B4861-1280-415F-8499-6C176C95AC1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MtconnectTranspiler.Sinks.CSharp", "MtconnectTranspiler.Sinks.CSharp\MtconnectTranspiler.Sinks.CSharp.csproj", "{AAFAB80F-F6F6-431B-93EF-1F3B34BE2DD9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MtconnectTranspiler.Sinks.JavaScript", "MtconnectTranspiler.Sinks.JavaScript\MtconnectTranspiler.Sinks.JavaScript.csproj", "{B0371D51-3C6A-4BD6-9AC9-105ABAAF46C1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -25,14 +21,6 @@ Global
{343B4861-1280-415F-8499-6C176C95AC1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{343B4861-1280-415F-8499-6C176C95AC1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{343B4861-1280-415F-8499-6C176C95AC1E}.Release|Any CPU.Build.0 = Release|Any CPU
{AAFAB80F-F6F6-431B-93EF-1F3B34BE2DD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAFAB80F-F6F6-431B-93EF-1F3B34BE2DD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAFAB80F-F6F6-431B-93EF-1F3B34BE2DD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAFAB80F-F6F6-431B-93EF-1F3B34BE2DD9}.Release|Any CPU.Build.0 = Release|Any CPU
{B0371D51-3C6A-4BD6-9AC9-105ABAAF46C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0371D51-3C6A-4BD6-9AC9-105ABAAF46C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0371D51-3C6A-4BD6-9AC9-105ABAAF46C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0371D51-3C6A-4BD6-9AC9-105ABAAF46C1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
26 changes: 0 additions & 26 deletions MtconnectTranspiler/Contracts/ITranspilerSink.cs

This file was deleted.

48 changes: 12 additions & 36 deletions MtconnectTranspiler/Contracts/MTConnectHelper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using MtconnectTranspiler.Model;
using MtconnectTranspiler.Xmi;
using MtconnectTranspiler.Xmi.Profile;
using MtconnectTranspiler.Xmi.UML;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -38,45 +36,23 @@ public static class MTConnectHelper
public static Uri BuildModelUri(MTConnectVersions version)
{
if (!VersionGitTags.TryGetValue(version, out string tag)) throw new KeyNotFoundException();
return new Uri($"https://github.com/mtconnect/mtconnect_sysml_model/releases/download/{tag}/Model.xml");
return BuildModelUri(tag);
}


/// <summary>
/// Builds the reference address for a released version of the SysML model on GitHub.
/// </summary>
/// <param name="tag">The raw tag name of the released version on GitHub.</param>
/// <returns><inheritdoc cref="BuildModelUri(MTConnectVersions)" path="/returns"/></returns>
public static Uri BuildModelUri(string tag)
=> tag.Equals("latest", StringComparison.OrdinalIgnoreCase)
? new Uri($"https://github.com/mtconnect/mtconnect_sysml_model/releases/latest/download/Model.xml")
: new Uri($"https://github.com/mtconnect/mtconnect_sysml_model/releases/download/{tag}/Model.xml");

public static Normative? LookupNormative(MTConnectModel model, string id)
=> model.NormativeReferences.FirstOrDefault(o => o.BaseElement == id);
public static Deprecated? LookupDeprecated(MTConnectModel model, string id)
=> model.DeprecatedReferences.FirstOrDefault(o => o.BaseElement == id);

public static UmlDataType? LookupDataType(MTConnectModel model, UmlProperty property)
{
var dataTypes = model?.AllDataTypes;
return dataTypes
?.Where(o => o.Id == property?.PropertyType)
?.FirstOrDefault();
}

public static Dictionary<string, System.Type> UmlToCsharpDataTypes = new Dictionary<string, System.Type>()
{
{ "boolean", typeof(bool) },
{ "ID", typeof(string) },
{ "string", typeof(string) },
{ "float", typeof(float) },
{ "datetime", typeof(DateTime) },
{ "integer", typeof(int) },
{ "xlinktype", typeof(string) },
{ "xslang", typeof(string) },
{ "SECOND", typeof(float) },
{ "IDREF", typeof(string) },
{ "xlinkhref", typeof(string) },
{ "MILLIMETER", typeof(float) },
{ "DEGREE", typeof(float) },
{ "x509", typeof(string) },
{ "unit", typeof(float) },
{ "CUBIC_MILLIMETER", typeof(float) },
{ "int32", typeof(int) },
{ "int64", typeof(long) },
{ "version", typeof(string) },
{ "uint32", typeof(uint) },
{ "uint64", typeof(ulong) },
};
}
}
3 changes: 1 addition & 2 deletions MtconnectTranspiler/Contracts/XmiDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
using MtconnectTranspiler.Contracts.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;

namespace MtconnectTranspiler.Contracts
{
internal class XmiDeserializer
public sealed class XmiDeserializer
{
private ILogger<XmiDeserializer>? _logger;
private XmlDocument xDoc;
Expand Down
29 changes: 29 additions & 0 deletions MtconnectTranspiler/FromFileOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using MtconnectTranspiler.Contracts;
using System.IO;

namespace MtconnectTranspiler
{
/// <summary>
/// Options for constructing an instance of <see cref="TranspilerDispatcher"/> by retrieving the <see cref="XmiDeserializer"/> using the <see cref="FromFileOptions.Filepath"/> as a reference to the <c>.xmi</c> of the MTConnect Standard SysML model.
/// </summary>
public class FromFileOptions : TranspilerDispatcherOptions
{
/// <summary>
/// Reference to a copy of the <c>.xmi</c> file (in XML format) representing the MTConnect Standard SysML model.
/// </summary>
public string Filepath { get; set; } = string.Empty;

/// <inheritdoc />
/// <exception cref="FileNotFoundException"></exception>
internal override XmiDeserializer GetDeserializer()
{
if (!File.Exists(Filepath)) throw new FileNotFoundException("Could not find specified XMI file", Filepath);

// NOTE: It's important for this method to handle transpile multiple languages at once isntead of iterating through the XMI multiple times for each language.
// NOTE: Make sure multiple project options cane be supplied to this class to handle concurrently processing multiple languages as we process the XMI.

var deserializer = XmiDeserializer.FromFile(Filepath);
return deserializer;
}
}
}
42 changes: 42 additions & 0 deletions MtconnectTranspiler/FromGitHubOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using MtconnectTranspiler.Contracts;
using System;
using System.ComponentModel;
using System.Net.Http;

namespace MtconnectTranspiler
{
/// <summary>
/// Options for constructing an instance of <see cref="TranspilerDispatcher"/> by retrieving the <see cref="XmiDeserializer"/> using the <see cref="FromGitHubOptions.GitHubRelease"/> as a reference to the Release on GitHub to fetch the <c>.xmi</c> of the MTConnect Standard SysML model.
/// </summary>
public class FromGitHubOptions : TranspilerDispatcherOptions
{
/// <summary>
/// Reference to the GitHub Release Tag for the version of the MTConnect Standard SysML model to download from GitHub.<br/>
/// **NOTE**: If you specify <c>latest</c>, the <c>.xmi</c> will be retrieved from the latest Release on GitHub.
/// </summary>
public string GitHubRelease { get; set; } = "latest";

/// <inheritdoc />
internal override XmiDeserializer GetDeserializer()
{
if (string.IsNullOrEmpty(GitHubRelease)) throw new ArgumentNullException();

var gitUrl = MTConnectHelper.BuildModelUri(GitHubRelease);

using (var client = new HttpClient())
{
var response = client.GetAsync(gitUrl).Result;
if (response.IsSuccessStatusCode)
{
string xml = response.Content.ReadAsStringAsync().Result;

var deserializer = XmiDeserializer.FromXml(xml);
return deserializer;
} else
{
throw new InvalidEnumArgumentException();
}
}
}
}
}
2 changes: 1 addition & 1 deletion MtconnectTranspiler/MtconnectTranspiler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>MTConnect Transpiler</Title>
<Version>0.0.1</Version>
<Version>0.0.2</Version>
<Authors>mtconnect, tbm0115</Authors>
<Company>MTConnect Institute; TAMS;</Company>
<Description>A library capable of parsing an XMI for the MTConnect Standard and passing it to an implemented transpiler.</Description>
Expand Down
31 changes: 31 additions & 0 deletions MtconnectTranspiler/Sinks/IModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using MtconnectTranspiler.Xmi;

namespace MtconnectTranspiler.Sinks.CSharp.Models
{
/// <summary>
/// Generic type for a model derived from <see cref="XmiElement" />.
/// </summary>
/// <typeparam name="T">The type of <see cref="XmiElement" />.</typeparam>
public interface IModel<T> where T : XmiElement
{
/// <summary>
/// Represents a hyperlink reference to the documentation hosted on <see href="https://model.mtconnect.org/">model.mtconnect.org</see>
/// </summary>
string Href { get; }

/// <summary>
/// Represents the internal ID within the XMI model.
/// </summary>
string SysML_ID { get; }

/// <summary>
/// Represents the name of the source XMI element.
/// </summary>
string SysML_Name { get; }

/// <summary>
/// Reference to the source <see cref="XmiElement" />.
/// </summary>
T Source { get; }
}
}
18 changes: 18 additions & 0 deletions MtconnectTranspiler/Sinks/ITranspilerSink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using MtconnectTranspiler.Model;
using System.Threading;

namespace MtconnectTranspiler.Sinks
{
/// <summary>
/// Basic interface for transpiling the XMI model into another language.
/// </summary>
public interface ITranspilerSink
{
/// <summary>
/// Transpiles the XMI definition of the MTConnect Standard into some other format.
/// </summary>
/// <param name="model">Object-oriented copy of the XMI structure in the context of the MTConnect Standard.</param>
/// <param name="cancellationToken">Reference to a cancellation token, the Transpile method may be a long running operation.</param>
void Transpile(MTConnectModel model, CancellationToken cancellationToken = default);
}
}
49 changes: 49 additions & 0 deletions MtconnectTranspiler/Sinks/VersionedObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using MtconnectTranspiler.Model;
using MtconnectTranspiler.Xmi;
using System.Linq;

namespace MtconnectTranspiler.Sinks.CSharp.Models
{
/// <summary>
/// Generic type for a model derived from <see cref="XmiElement" /> which also might have normative versioning.
/// </summary>
/// <typeparam name="T">The type of <see cref="XmiElement" />.</typeparam>
public abstract class VersionedObject : XmiModel<XmiElement>
{
/// <summary>
/// The version of MTConnect when this became normative.
/// </summary>
public string NormativeVersion { get; } = string.Empty;

/// <summary>
/// The version of MTConnect when this became deprecated.
/// </summary>
public string DeprecatedVersion { get; } = string.Empty;

/// <summary>
/// Constructs a new instance of the <see cref="VersionedObject"/>.
/// </summary>
/// <param name="model">Reference to the high-level <see cref="MTConnectModel"/>.</param>
/// <param name="source">Reference to the source <see cref="XmiElement"/> that may have Normative and Deprecated references in the XMI model.</param>
public VersionedObject(MTConnectModel model, XmiElement source) : base(source)
{
var normative = model?.NormativeReferences?.FirstOrDefault(o => o.BaseElement == Source.Id);
if (normative != null)
{
NormativeVersion = lookupMtconnectVersion(normative.Version);
var deprecated = model?.DeprecatedReferences?.FirstOrDefault(o => o.BaseElement == Source.Id);
if (deprecated != null)
{
DeprecatedVersion = lookupMtconnectVersion(deprecated.Version);
}
}
}

/// <summary>
/// Looks up the appropriate representation of MTConnect Standard version in the current context.
/// </summary>
/// <param name="version">Reference to the version of MTConnect Standard as labeled in the XMI model. For example, <c>1.0</c> or <c>2.1</c>.</param>
/// <returns>The representation of the MTConnect Standard version in the current context.</returns>
protected abstract string lookupMtconnectVersion(string version);
}
}
Loading

0 comments on commit 2838a74

Please sign in to comment.