-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
172 lines (162 loc) · 6.57 KB
/
Program.cs
File metadata and controls
172 lines (162 loc) · 6.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using System.CodeDom.Compiler;
using System.Text;
using Newtonsoft.Json.Schema.Generation;
using static System.String;
namespace csharp2jsonschema
{
internal class Program
{
private static string PathSource { get; set; } = "SchemaSrc";
private static string PathDest { get; set; } = "./";
private static string _schemaDll = "";
private static string CommonNamespace { get; set; } = "Common";
private static string JClass { get; set; } = "./../src/JsonSchema";
private static void Main(string[] args)
{
var options = new NDesk.Options.OptionSet
{
{ "src=", v=> PathSource = v },
{ "dst=", v=> PathDest = v },
{ "n=", v=> CommonNamespace = v },
{ "jc=", v=> JClass = v },
};
options.Parse(args);
_schemaDll = Path.Combine(PathDest, CommonNamespace, CommonNamespace + ".dll");
var dest = Path.Combine(PathDest, CommonNamespace);
ClearDirectory(dest);
var assembly = LoadAssembly(LoadSource(PathSource));
UpdateSchemas(assembly, PathDest);
Console.WriteLine("Done");
}
private static string LoadSource(string path)
{
var files = new List<string>();
DirSearch(ref files, path, "*.cs");
var res = new StringBuilder();
foreach (var file in files)
{
res.Append("namespace " + CommonNamespace + " {\n");
res.Append(File.ReadAllText(file));
res.Append("\n}");
res.Append("\n");
}
return res.ToString();
}
private static Assembly LoadAssembly(string sourceCode)
{
//Console.WriteLine(sourceCode);
var cp = new CompilerParameters
{
GenerateExecutable = false,
GenerateInMemory = true,
OutputAssembly = _schemaDll
};
var providerOptions = new Dictionary<string, string> { { "CompilerVersion", "v4.0" } };
var compiler = CodeDomProvider.CreateProvider("C#", providerOptions);
var cr = compiler.CompileAssemblyFromSource(cp, sourceCode);
if (!cr.Errors.HasErrors) return cp.GenerateInMemory ? cr.CompiledAssembly : Assembly.LoadFrom(_schemaDll);
var errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in cr.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
}
Console.WriteLine(errors);
return cp.GenerateInMemory ? cr.CompiledAssembly : Assembly.LoadFrom(_schemaDll);
}
public static void UpdateSchemas(Assembly assembly, string dest)
{
var generator = new JSchemaGenerator();
var schemas = new Dictionary<string, string>();
var q = from t in assembly.GetTypes()
where t.IsClass
select t;
q.ToList().ForEach(t =>
{
if (t.Namespace == null)
{
return;
}
var names = t.Namespace.Split('.');
if (names.Length <= 0 || names[0] != CommonNamespace) return;
var schema = generator.Generate(t);
var path = names.Aggregate(dest, Path.Combine);
Directory.CreateDirectory(path);
File.WriteAllText(Path.Combine(path, t.Name + ".json"), schema.ToString());
schemas[t.Namespace + "." + t.Name] = schema.ToString();
});
Console.WriteLine($"Schemas:");
var list = new List<string>();
DirSearch(ref list, Path.Combine(dest, CommonNamespace), "*.json");
var jsFile = $"var Class = require('{JClass}')\n";
var definedNamespaces = new List<string>();
foreach (var e in list)
{
var currentPath = Path.GetDirectoryName(e);
var nameSpace = Join(".", GetRelativePath(currentPath, "./").Split(Path.DirectorySeparatorChar));
if (!definedNamespaces.Contains(nameSpace))
{
jsFile += nameSpace + " = {}\n";
definedNamespaces.Add(nameSpace);
}
var schemaName = nameSpace + "." + Path.GetFileNameWithoutExtension(e);
jsFile += $"{schemaName} = new Class({schemas[schemaName]})\n";
Console.WriteLine($" {schemaName}");
}
jsFile += "module.exports = " + CommonNamespace;
File.WriteAllText(Path.Combine(Path.Combine(dest, CommonNamespace), CommonNamespace + ".js"), jsFile);
}
private static string GetRelativePath(string filespec, string folder)
{
var pathUri = new Uri(Path.GetFullPath(filespec));
// Folders must end in a slash
if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
folder += Path.DirectorySeparatorChar;
}
var folderUri = new Uri(Path.GetFullPath(folder));
return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
private static void DirSearch(ref List<string> list, string sDir, string extension)
{
try
{
list.AddRange(Directory.GetFiles(sDir, extension));
foreach (var d in Directory.GetDirectories(sDir))
{
DirSearch(ref list, d, extension);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
private static void ClearDirectory(string path)
{
var di = new DirectoryInfo(path);
if (!di.Exists)
{
Console.WriteLine($"Creating folder {path}");
Directory.CreateDirectory(path);
return;
}
else
{
Console.WriteLine($"Clearing folder {path}");
}
foreach (var file in di.GetFiles())
{
file.Delete();
}
foreach (var dir in di.GetDirectories())
{
dir.Delete(true);
}
}
}
}