static void Main(string[] args) { Console.WriteLine("XML ITS1 Formatter Pregenerator Utility"); Console.WriteLine("Copyright (C) 2012, Mohawk College of Applied Arts and Technology"); ParameterParser<Parameters> parser = new ParameterParser<Parameters>(); try { var arguments = parser.Parse(args); if (arguments.ShowHelp) { ShowHelp(); return; } // Generate formatter utility MARC.Everest.Formatters.XML.ITS1.CodeGen.TypeFormatterCreator creator = new MARC.Everest.Formatters.XML.ITS1.CodeGen.TypeFormatterCreator(); // Create code namespace CodeNamespace ns = new CodeNamespace(arguments.TargetNs); // Load assembly Assembly rmimAssembly = Assembly.LoadFile(arguments.AssemblyFile); List<Type> rmimTypes = new List<Type>(); if (arguments.Interactions != null) foreach (var s in arguments.Interactions) rmimTypes.Add(rmimAssembly.GetTypes().First(o => o.Name == s)); else rmimTypes.AddRange(rmimAssembly.GetTypes()); // Validate parameters if (rmimTypes.Count == 0) throw new ArgumentException("Type array must have at least one element", "t"); // Create a list of types (a todo list) that represent the types we want to format List<Type> types = new List<Type>(200); // Iterate through types and create formatter // Iterate throgh the types foreach (Type type in rmimTypes) { if (type.Assembly != rmimAssembly) throw new InvalidOperationException("All types must belong to the same revision assembly"); GetUniqueTypes(type, types, true); } // Waith thread pool WaitThreadPool wtp = new WaitThreadPool(); try { // Create type definitions foreach (Type t in types) { // Check if we need to gen this type if (t.GetCustomAttributes(typeof(StructureAttribute), false).Length == 0 || s_formatterGenerated.Contains(t)) continue; s_formatterGenerated.Add(t); // Structure Attribute StructureAttribute sta = t.GetCustomAttributes(typeof(StructureAttribute), false)[0] as StructureAttribute; // Type formatter creator TypeFormatterCreator crtr = new TypeFormatterCreator(); // Reset event crtr.CodeTypeDeclarationCompleted += new CreateTypeFormatterCompletedDelegate(delegate(CodeTypeDeclaration result) { // Add to the code currently created if (result != null) lock (ns) ns.Types.Add(result); }); // Helper result wtp.QueueUserWorkItem(crtr.CreateTypeFormatter, t); } // Wait for final pool to clear wtp.WaitOne(); } finally { wtp.Dispose(); } if (ns.Types.Count == 0) { Console.WriteLine("Didn't create any formatter helpers..."); return; } // Setup compiler and referenced assemblies CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider(); using (TextWriter tw = File.CreateText(arguments.Output ?? "output.cs")) csharpCodeProvider.GenerateCodeFromNamespace(ns, tw, new System.CodeDom.Compiler.CodeGeneratorOptions() { IndentString = "\t" }); } catch (ArgumentNullException) { ShowHelp(); } catch (Exception e) { Console.WriteLine(e.ToString()); return; } finally { } #if DEBUG Console.ReadKey(); #endif }
/// <summary> /// Creates the formatter assembly for the specified types /// </summary> public Assembly CreateFormatterAssembly(Type[] rmimTypes, List<IStructureFormatter> aides, bool generateDeep) { // Enter and lock lock(m_syncObject) { while(m_codeGenBlocking) Monitor.Wait(m_syncObject); m_codeGenBlocking = true; } // Create code namespace CodeNamespace ns = new CodeNamespace(String.Format("MARC.Everest.Formatters.XML.ITS1.d{0}", Guid.NewGuid().ToString("N"))); List<Assembly> rmimAssemblies = new List<Assembly>() { rmimTypes[0].Assembly }; try { // Validate parameters if (rmimTypes.Length == 0) throw new ArgumentException("Type array must have at least one element", "t"); // Scan all classes in any graph aides List<string> graphAidesClasses = new List<string>(200); foreach (IStructureFormatter isf in aides) graphAidesClasses.AddRange(isf.HandleStructure); // Create a list of types (a todo list) that represent the types we want to format List<Type> types = new List<Type>(200); // Iterate through types and create formatter if (generateDeep) { foreach (var type in Array.FindAll<Type>(rmimAssemblies[0].GetTypes(), o => o.IsClass && !o.IsAbstract && o.GetCustomAttributes(typeof(StructureAttribute), false).Length > 0)) { //if (!rmimAssemblies.Contains(type.Assembly)) // rmimAssemblies.Add(type.Assembly); GetUniqueTypes(type, types, true); } } else { // Iterate throgh the types foreach (Type type in rmimTypes) { //if (!rmimAssemblies.Contains(type.Assembly)) // throw new InvalidOperationException("All types must belong to the same revision assembly"); GetUniqueTypes(type, types, false); } } // Waith thread pool WaitThreadPool wtp = new WaitThreadPool(); try { // Create type definitions foreach (Type t in types) { // Check if we need to gen this type if (t.GetCustomAttributes(typeof(StructureAttribute), false).Length == 0 || s_formatterGenerated.Contains(t)) continue; s_formatterGenerated.Add(t); // Scan and add base type Type dScan = t.BaseType; while (dScan != null && dScan != typeof(System.Object)) { if (!rmimAssemblies.Contains(dScan.Assembly)) rmimAssemblies.Add(dScan.Assembly); dScan = dScan.BaseType; } // Structure Attribute StructureAttribute sta = t.GetCustomAttributes(typeof(StructureAttribute), false)[0] as StructureAttribute; // Is this type already handled by a helper formatter? bool hasHelper = graphAidesClasses.Contains(sta.Name); // Compile if helper is not available if (!hasHelper) { // Type formatter creator TypeFormatterCreator crtr = new TypeFormatterCreator(); // Reset event crtr.CodeTypeDeclarationCompleted += new CreateTypeFormatterCompletedDelegate(delegate(CodeTypeDeclaration result) { // Add to the code currently created if (result != null) lock (ns) { ns.Types.Add(result); } }); // Helper result wtp.QueueUserWorkItem(crtr.CreateTypeFormatter, t); } } // Wait for final pool to clear wtp.WaitOne(); } finally { wtp.Dispose(); } if (ns.Types.Count == 0) return null; } finally { m_codeGenBlocking = false; lock(m_syncObject) Monitor.Pulse(m_syncObject); } // Setup compiler and referenced assemblies CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider(); CodeCompileUnit compileUnit = new CodeCompileUnit(); compileUnit.Namespaces.Add(ns); compileUnit.ReferencedAssemblies.Add(typeof(II).Assembly.Location); compileUnit.ReferencedAssemblies.Add(typeof(ITypeFormatter).Assembly.Location); // Was this assembly loaded directly from disk or from a byte array foreach(var asm in rmimAssemblies) compileUnit.ReferencedAssemblies.Add(asm.Location); compileUnit.ReferencedAssemblies.Add("System.dll"); compileUnit.ReferencedAssemblies.Add("System.Xml.dll"); // Assembly info CodeAttributeDeclaration cadecl = new CodeAttributeDeclaration("System.Reflection.AssemblyVersion", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression("1.0.*")) }); compileUnit.AssemblyCustomAttributes.Add(cadecl); // Setup compiler CompilerParameters compilerParms = new CompilerParameters(); compilerParms.GenerateInMemory = !generateDeep; compilerParms.WarningLevel = 1; compilerParms.TempFiles.KeepFiles = generateDeep; // Compile code dom // To see the generated code, set a breakpoint on the next line. // Then take a look at the results.TempFiles array to find the // path to the generated C# files CompilerResults results = csharpCodeProvider.CompileAssemblyFromDom(compilerParms, new CodeCompileUnit[] { compileUnit }); if (results.Errors.HasErrors) throw new Exceptions.FormatterCompileException(results); else { Assembly a = !generateDeep ? results.CompiledAssembly : Assembly.LoadFile(results.PathToAssembly); AddFormatterAssembly(a); return a; } }
public ArticleCollection Process(ClassRepository rep) { ArticleCollection artc = new ArticleCollection(); List<Feature> features = new List<Feature>(); foreach (KeyValuePair<string, Feature> kv in rep) features.Add(kv.Value); // Sort so classes are processed first features.Sort(delegate(Feature a, Feature b) { if ((a is SubSystem) && !(b is SubSystem)) return -1; else if ((b is SubSystem) && !(a is SubSystem)) return 1; else if ((a is Class) && !(b is Class)) return 1; else if ((b is Class) && !(a is Class)) return -1; else return a.GetType().Name.CompareTo(b.GetType().Name); }); //var vocabArticle = new MohawkCollege.EHR.gpmr.Pipeline.Renderer.Deki.Article.Article() //{ // Title = "Vocabulary", // Children = new ArticleCollection() //}; //vocabArticle.Children.Add(new Article.Article() { Title = "Code Systems" }); //vocabArticle.Children.Add(new Article.Article() { Title = "Concept Domains" }); //vocabArticle.Children.Add(new Article.Article() { Title = "Value Sets" }); //artc.Add(vocabArticle); WaitThreadPool wtp = new WaitThreadPool(); // A thread that does the doohickey thing Thread doohickeyThread = new Thread((ThreadStart)delegate() { string[] hickeythings = { "|", "/", "-", "\\" }; int hickeyThingCount = 0; try { while (true) { int cPosX = Console.CursorLeft, cPosY = Console.CursorTop; Console.SetCursorPosition(1, cPosY); Console.Write(hickeythings[hickeyThingCount++ % hickeythings.Length]); Console.SetCursorPosition(cPosX, cPosY); Thread.Sleep(1000); } } catch { } }); doohickeyThread.Start(); // Loop through each feature foreach (Feature f in features) { // Find the feature template FeatureTemplate ftpl = NonParameterizedTemplate.Spawn(FindTemplate(f.GetType().FullName, f) as NonParameterizedTemplate, this, f) as FeatureTemplate; if (ftpl == null) System.Diagnostics.Trace.WriteLine(string.Format("Feature '{0}' won't be published as no feature template could be located", f.Name), "warn"); else if(f.Annotations.Find(o=>o is SuppressBrowseAnnotation) != null) System.Diagnostics.Trace.WriteLine(String.Format("Feature '{0}' won't be published as a SuppressBrowse annotation was found", f.Name), "warn"); else if(ftpl.NewPage) { System.Diagnostics.Trace.WriteLine(string.Format("Queueing ({1}) '{0}'...", f.Name, f.GetType().Name), "debug"); // Create a new worker Worker w = new Worker(); w.ArticleCollection = artc; w.FeatureTemplate = ftpl; w.OnComplete += delegate(object sender, EventArgs e) { Worker wrkr = sender as Worker; System.Diagnostics.Trace.WriteLine(String.Format("Rendered ({1}) '{0}'...", (wrkr.FeatureTemplate.Context as Feature).Name, wrkr.FeatureTemplate.Context.GetType().Name), "debug"); }; wtp.QueueUserWorkItem(w.Start); } } System.Diagnostics.Trace.WriteLine("Waiting for work items to complete...", "debug"); wtp.WaitOne(); doohickeyThread.Abort(); ArticleCollection retVal = new ArticleCollection(); Article.Article MasterTOC = new MohawkCollege.EHR.gpmr.Pipeline.Renderer.Deki.Article.Article(); MasterTOC.Children = artc; System.Diagnostics.Trace.WriteLine("Creating Table of Contents...", "information"); PrepareTOC(MasterTOC); MasterTOC.Children = null; artc.Add(MasterTOC); return artc; }