/// <summary> /// Gets a list of all the code articles of a given element type (e.g. Namespace, Class or Member). /// Code articles are not fetched from DB but from flat files that must be looked-up via an index file. /// </summary> /// <param name="version">The specific version of the Code articles to get.</param> /// <param name="elementTypeFilter">The specific element type of Code articles to get.</param> /// <returns>A list of all the code articles of a certain element type (e.g. Namespace, Class or Member).</returns> public static List<BaseCodeArticle> GetCodeArticles(string version, CodeElementType elementTypeFilter) { // Get the input directory and the index file used to match the article titles to their file names. string codeArticlesDirectory = Path.Combine(ConfigurationManager.AppSettings["codeArticlesDirectory"].ToString(), version); string indexFilePath = Path.Combine(codeArticlesDirectory, INDEX_FILE_NAME); List<BaseCodeArticle> codeArticles = new List<BaseCodeArticle>(); StreamReader indexFile = new StreamReader(indexFilePath); while (!indexFile.EndOfStream) { // Not EOF => We can read at least once more. string line = indexFile.ReadLine(); // Each line of the index file is composed of 3 parts separated by tabs. string[] lineParts = line.Split(new char[] { '\t' }); // The type of the code element (i.e. Namespace, Class or Member). string elementTypeValue = lineParts[0]; // The full unique name of the code element. This part is used to find the matching article title. string elementFullName = lineParts[1]; // The name of the file where the content of the wiki text lies. string wikiFileName = lineParts[2] + CODE_ARTICLE_FILE_EXTENSION; CodeElementType elementType; if (!string.IsNullOrEmpty(elementTypeValue) && Enum.IsDefined(typeof(CodeElementType), elementTypeValue)) elementType = (CodeElementType)Enum.Parse(typeof(CodeElementType), elementTypeValue); else throw new NotSupportedException("The provided code element type is invalid: " + elementTypeValue); // Note that several Code element types are Members (i.e. Fields, Constructor, Property, Method and Event). if (elementType == elementTypeFilter || (elementTypeFilter == CodeElementType.Member && (elementType == CodeElementType.Field || elementType == CodeElementType.Constructor || elementType == CodeElementType.Property || elementType == CodeElementType.Method || elementType == CodeElementType.Event))) { BaseCodeArticle codeArticle = new BaseCodeArticle(version, elementFullName, elementType); codeArticles.Add(codeArticle); } } return codeArticles; }
// Note that at this point, the Title contains the version. /// <summary> /// Constructor. /// </summary> /// <param name="baseCodeArticle">The base object upon which the new Code Article is created.</param> /// <param name="text">The content of the code article.</param> public CodeArticle(BaseCodeArticle baseCodeArticle, string text) : base(baseCodeArticle.Title, baseCodeArticle.ElementType) { base.Parent = baseCodeArticle.Parent; base.Children = baseCodeArticle.Children; this.m_Text = text; }
/// <summary> /// Get a code article by its full unique name via a lookup in the index file. /// </summary> /// <param name="version">The version of the Code article.</param> /// <param name="articleTitle">The title of the Code article.</param> /// <returns>A Code article.</returns> public static CodeArticle GetCodeArticle(string version, string articleTitle) { if (string.IsNullOrEmpty(version)) version = Tools.DEFAULT_CODE_VERSION; // Get the input directory and the index file used to match the article titles to their file names. string codeArticlesDirectory = Path.Combine(ConfigurationManager.AppSettings["codeArticlesDirectory"].ToString(), version); string indexFilePath = Path.Combine(codeArticlesDirectory, INDEX_FILE_NAME); BaseCodeArticle namespaceArticle = null; BaseCodeArticle classArticle = null; BaseCodeArticle memberArticle = null; BaseCodeArticle currentCodeArticle = null; CodeArticle resultCodeArticle = null; StreamReader indexFile = new StreamReader(indexFilePath); while (!indexFile.EndOfStream) { // Not EOF => We can read at least once more. string line = indexFile.ReadLine(); // Each line of the index file is composed of 3 parts separated by tabs. string[] lineParts = line.Split(new char[] { '\t' }); // The type of the code element (i.e. Namespace, Class or Member). string elementTypeValue = lineParts[0]; // The full unique name of the code element. This part is used to find the matching article title. string elementName = lineParts[1]; // The name of the file where the content of the wiki text lies. string wikiFileName = lineParts[2] + CODE_ARTICLE_FILE_EXTENSION; CodeElementType codeElementType; if (!string.IsNullOrEmpty(elementTypeValue) && Enum.IsDefined(typeof(CodeElementType), elementTypeValue)) codeElementType = (CodeElementType)Enum.Parse(typeof(CodeElementType), elementTypeValue); else throw new NotSupportedException("The provided code element type is invalid: " + elementTypeValue); if (codeElementType == CodeElementType.Namespace) { if (!ReferenceEquals(resultCodeArticle, null)) break; namespaceArticle = new BaseCodeArticle(version, elementName, CodeElementType.Namespace); currentCodeArticle = namespaceArticle; } else if (codeElementType == CodeElementType.Class) { if (!ReferenceEquals(resultCodeArticle, null) && resultCodeArticle.ElementType == CodeElementType.Member) break; classArticle = new BaseCodeArticle(version, elementName, CodeElementType.Class); if (ReferenceEquals(namespaceArticle, null) || ReferenceEquals(namespaceArticle.Children, null)) throw new NotSupportedException("Incorrect code sequence in index file."); classArticle.Parent = namespaceArticle; namespaceArticle.Children.Add(classArticle); currentCodeArticle = classArticle; } else if (codeElementType == CodeElementType.Member || codeElementType == CodeElementType.Field || codeElementType == CodeElementType.Constructor || codeElementType == CodeElementType.Property || codeElementType == CodeElementType.Method || codeElementType == CodeElementType.Event) { memberArticle = new BaseCodeArticle(version, elementName, codeElementType); if (ReferenceEquals(classArticle, null) || ReferenceEquals(classArticle.Children, null)) throw new NotSupportedException("Incorrect code sequence in index file."); memberArticle.Parent = classArticle; classArticle.Children.Add(memberArticle); currentCodeArticle = memberArticle; } else throw new NotSupportedException("The type of a code element could not be recognized: " + elementTypeValue); if (elementName == articleTitle) { // This is the code file that we want. Read its content. string codeFilePath = Path.Combine(codeArticlesDirectory, wikiFileName); string codeFileText = File.ReadAllText(codeFilePath); resultCodeArticle = new CodeArticle(currentCodeArticle, codeFileText); } } // Cleanup indexFile.Close(); return resultCodeArticle; }