/// <summary> /// Intended time of use it that of a "post cache reset" time. If cache has been cleared, all the logic behind this /// method will run. /// </summary> public static void TryDocRevImporting() => CacheMan.Cache(() => { ReadIDocModelCSharpCode(); dirs.PushRange(Directory .EnumerateDirectories(FilesystemTemplateController.DirectoryPath) .Select(dirpath => new DirectoryInfo(dirpath).FullName) .Where(dirpath => !dirs.Contains(dirpath)) .OrderByDescending(dirpath => new[] { Directory.GetLastWriteTime(dirpath).Ticks } .Union( GetRelativeFilePathsInDirectoryTree(dirpath, true) .Select(filepath => File.GetLastWriteTimeUtc(filepath).Ticks)) .Max()) .ToArray()); // starting with the newest directory, synchronously process each & abend when its found that nothing is imported string dir; while (dirs.TryPop(out dir) && ImportContentFolder(dir).Any()) { } // process the remaining directories queued asynchronously (as this is a resource intensive) on the chance that the "GetLastWriteTimeUtc" lied to us if (!dirs.IsEmpty) { Tasker.StartNewTask(() => { while (dirs.TryPop(out dir)) { ImportContentFolder(dir); } return(true); }); } return(new object()); }, false, "ImportDocModelsRunOnce" );
/// <summary> /// Scans AppDomain for classes implementing the IDocModel & performs all transformations needed to represent them as /// BaseDoc to be served. /// </summary> /// <param name="DocTypeName"> /// Processes only the given DocTypeName the IDocModel represents. If a IDocModel can not be /// located through out the AppDomain nothing will be processed & no IDocRev will be imported. If no DocTypeName is /// specified all IDocModel located will be processed. /// </param> public static List <ImporterLightDoc> ReadIDocModelCSharpCode() { List <ImporterLightDoc> List_ImporterLightDoc = new List <ImporterLightDoc>(); //TODO:Validate POCO utilizes correct title-case underscore separated labeling practices //TODO:add a placeholder file describing what goes in the given DocTypeName's form root directory var IDocModelItems = AppDomain .CurrentDomain .GetAssemblies() .SelectMany(a => a.GetTypes()) .Distinct() .Where(typ => (typ.GetInterfaces().Any(i => i == typeof(IDocModel)))) .Select(type => new { type, DirectoryInfo = new DirectoryInfo(FilesystemTemplateController.GetDocDirectoryPath(type.Name)).mkdir(), myschemaXsd = XsdExporter.ExportSchemas( type.Assembly, new List <string> { type.Name }, RuntimeTypeNamer.CalcSchemaUri(type.Name)).First() }); foreach (var docTypeDirectoryInfo in IDocModelItems) { string filepath = string.Format(@"{0}{1}", docTypeDirectoryInfo.DirectoryInfo.FullName, Runtime.MYSCHEMA_XSD_FILE_NAME); // always (over)write the xsd as this will always be generated by and for Rudine.Core regardless of the IDocInterpreter that is handling // compare the existing xsd on disk with the one generated here (excluding the "rolling" namespace) to see if anything has changed if ( !File.Exists(filepath) || RuntimeTypeNamer.VALID_CSHARP_NAMESPACE_PART_MATCH.Replace(docTypeDirectoryInfo.myschemaXsd, string.Empty) != RuntimeTypeNamer.VALID_CSHARP_NAMESPACE_PART_MATCH.Replace(File.ReadAllText(filepath), string.Empty) ) { File.WriteAllText(string.Format(@"{0}{1}", docTypeDirectoryInfo.DirectoryInfo.FullName, Runtime.MYSCHEMA_XSD_FILE_NAME), docTypeDirectoryInfo.myschemaXsd); } // create placeholder App_Code\DocTypeName.c_ files for developer to get started with myschema.xsd generation via cSharp file editing & thus auto translating string App_Code_Directory_Fullname = RequestPaths.GetPhysicalApplicationPath(Resources.App_Code_DirectoryPath); if (Directory.Exists(App_Code_Directory_Fullname)) { Tasker.StartNewTask(() => { foreach (string DocTypeName in DocExchange.DocTypeDirectories()) { if (!IDocModelItems.Any(m => m.DirectoryInfo.Name.Equals(DocTypeName, StringComparison.CurrentCultureIgnoreCase))) { string cSharpCodeFileName = string.Format(@"{0}\{1}.c_", App_Code_Directory_Fullname, DocTypeName); string xsdFileName = RequestPaths.GetPhysicalApplicationPath("doc", DocTypeName, Runtime.MYSCHEMA_XSD_FILE_NAME); string xsd = File.ReadAllText(xsdFileName); string myclasses_cs = new Xsd().ImportSchemasAsClasses( new[] { xsd }, null, CodeGenerationOptions.GenerateOrder | CodeGenerationOptions.GenerateProperties, new StringCollection()); if (!File.Exists(cSharpCodeFileName) || File.ReadAllText(cSharpCodeFileName) != myclasses_cs) { File.WriteAllText(cSharpCodeFileName, myclasses_cs); File.SetAttributes(cSharpCodeFileName, FileAttributes.Hidden); } } } return(true); }); } } return(List_ImporterLightDoc); }