/// <summary> /// Appends a breadbrumb trail element. /// </summary> /// <param name="sb">The destination <see cref="T:StringBuilder" />.</param> /// <param name="page">The page to append.</param> /// <param name="dpPrefix">The drop-down menu ID prefix.</param> private void AppendBreadcrumb(StringBuilder sb, PageInfo page, string dpPrefix) { PageNameComparer comp = new PageNameComparer(); PageContent pc = Content.GetPageContent(page, true); string id = AppendBreadcrumbDropDown(sb, page, dpPrefix); string nspace = NameTools.GetNamespace(page.FullName); sb.Append("» "); if (comp.Compare(page, currentPage) == 0) { sb.Append("<b>"); } sb.AppendFormat(@"<a href=""{0}"" title=""{1}""{2}{3}{4}>{1}</a>", Tools.UrlEncode(page.FullName) + Settings.PageExtension, FormattingPipeline.PrepareTitle(pc.Title, false, FormattingContext.PageContent, currentPage) + (string.IsNullOrEmpty(nspace) ? "" : (" (" + NameTools.GetNamespace(page.FullName) + ")")), (id != null ? @" onmouseover=""javascript:return __ShowDropDown(event, '" + id + @"', this);""" : ""), (id != null ? @" id=""lnk" + id + @"""" : ""), (id != null ? @" onmouseout=""javascript:return __HideDropDown('" + id + @"');""" : "")); if (comp.Compare(page, currentPage) == 0) { sb.Append("</b>"); } sb.Append(" "); }
/// <summary> /// Searches for pages with name or title similar to a specified value. /// </summary> /// <param name="wiki">The wiki.</param> /// <param name="name">The name to look for (<c>null</c> for the root).</param> /// <param name="nspace">The namespace to search into.</param> /// <returns>The similar pages, if any.</returns> public static PageContent[] SearchSimilarPages(string wiki, string name, string nspace) { if (string.IsNullOrEmpty(nspace)) { nspace = null; } var searchFields = new [] { SearchField.PageFullName }; List <SearchResult> searchResults = Search(wiki, searchFields, name, SearchOptions.AtLeastOneWord); var result = new List <PageContent>(20); foreach (SearchResult res in searchResults) { var pageDoc = res.Document as PageDocument; if (pageDoc != null) { string pageNamespace = NameTools.GetNamespace(pageDoc.PageFullName); if (string.IsNullOrEmpty(pageNamespace)) { pageNamespace = null; } if (pageNamespace == nspace) { var page = new PageContent(pageDoc.PageFullName, null, new DateTime(), pageDoc.Title, null, new DateTime(), null, pageDoc.Content, null, null); result.Add(page); } } } // Search page names for matches List <PageContent> allPages = Pages.GetPages(wiki, Pages.FindNamespace(wiki, nspace)); var comp = new PageNameComparer(); string currentName = name.ToLowerInvariant(); foreach (PageContent page in allPages) { if (NameTools.GetLocalName(page.FullName).ToLowerInvariant().Contains(currentName)) { if (result.Find(p => comp.Compare(p, page) == 0) == null) { result.Add(page); } } } return(result.ToArray()); }
/// <summary> /// Searches for pages with name or title similar to a specified value. /// </summary> /// <param name="name">The name to look for (<c>null</c> for the root).</param> /// <param name="nspace">The namespace to search into.</param> /// <returns>The similar pages, if any.</returns> public static PageInfo[] SearchSimilarPages(string name, string nspace) { if (string.IsNullOrEmpty(nspace)) { nspace = null; } SearchResultCollection searchResults = Search(name, false, false, SearchOptions.AtLeastOneWord); var result = new List <PageInfo>(20); foreach (SearchResult res in searchResults) { var pageDoc = res.Document as PageDocument; if (pageDoc != null) { var pageNamespace = NameTools.GetNamespace(pageDoc.PageInfo.FullName); if (string.IsNullOrEmpty(pageNamespace)) { pageNamespace = null; } if (pageNamespace == nspace) { result.Add(pageDoc.PageInfo); } } } // Search page names for matches List <PageInfo> allPages = Pages.GetPages(Pages.FindNamespace(nspace)); var comp = new PageNameComparer(); var currentName = name.ToLowerInvariant(); foreach (PageInfo page in allPages) { if (NameTools.GetLocalName(page.FullName).ToLowerInvariant().Contains(currentName)) { if (result.Find(delegate(PageInfo p) { return(comp.Compare(p, page) == 0); }) == null) { result.Add(page); } } } return(result.ToArray()); }
/// <summary> /// Finds a page by name. /// </summary> /// <param name="page">The page.</param> /// <returns>The index in the collection.</returns> private int FindPage(PageInfo page) { lock (this) { if (pages == null || pages.Count == 0) { return(-1); } PageNameComparer comp = new PageNameComparer(); for (int i = 0; i < pages.Count; i++) { if (comp.Compare(pages[i], page) == 0) { return(i); } } return(-1); } }
/// <summary> /// Gets all the categories of a page. /// </summary> /// <param name="page">The page.</param> /// <returns>The categories, sorted by name.</returns> /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <c>null</c>.</exception> public CategoryInfo[] GetCategoriesForPage(PageInfo page) { if(page == null) throw new ArgumentNullException("page"); string pageNamespace = NameTools.GetNamespace(page.FullName); CategoryInfo[] categories = GetCategories(FindNamespace(pageNamespace, GetNamespaces())); // Sorted List<CategoryInfo> result = new List<CategoryInfo>(10); PageNameComparer comp = new PageNameComparer(); foreach(CategoryInfo cat in categories) { foreach(string p in cat.Pages) { if(comp.Compare(page, new PageInfo(p, this, DateTime.Now)) == 0) { result.Add(cat); break; } } } return result.ToArray(); }
/// <summary> /// Determines whether a page exists. /// </summary> /// <param name="page">The instance of <see cref="T:PageInfo" /> to look for.</param> /// <returns><c>true</c> if the page exists, <c>false</c> otherwise.</returns> private bool PageExists(PageInfo page) { lock(this) { PageInfo[] pages = GetAllPages(); PageNameComparer comp = new PageNameComparer(); for(int i = 0; i < pages.Length; i++) { if(comp.Compare(pages[i], page) == 0) return true; } } return false; }
/// <summary> /// Finds a corresponding instance of <see cref="T:LocalPageInfo" /> in the available pages. /// </summary> /// <param name="page">The instance of <see cref="T:PageInfo" /> to "convert" to <see cref="T:LocalPageInfo" />.</param> /// <returns>The instance of <see cref="T:LocalPageInfo" />, or <c>null</c>.</returns> private LocalPageInfo LoadLocalPageInfo(PageInfo page) { if(page == null) return null; lock(this) { PageInfo[] pages = GetAllPages(); PageNameComparer comp = new PageNameComparer(); for(int i = 0; i < pages.Length; i++) { if(comp.Compare(pages[i], page) == 0) return pages[i] as LocalPageInfo; } } return null; }
/// <summary> /// Finds a page. /// </summary> /// <param name="nspace">The namespace that contains the page.</param> /// <param name="name">The name of the page to find.</param> /// <param name="pages">The pages array.</param> /// <returns>The found page, or <c>null</c>.</returns> private PageInfo FindPage(string nspace, string name, PageInfo[] pages) { if(name == null) return null; PageNameComparer comp = new PageNameComparer(); PageInfo target = new PageInfo(NameTools.GetFullName(nspace, name), this, DateTime.Now); PageInfo result = Array.Find(pages, delegate(PageInfo p) { return comp.Compare(p, target) == 0; }); return result; }
/// <summary> /// Renames a Page. /// </summary> /// <param name="page">The Page to rename.</param> /// <param name="newName">The new Name.</param> /// <returns>True if the Page has been renamed successfully.</returns> /// <exception cref="ArgumentNullException">If <paramref name="page"/> or <paramref name="newName"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="newName"/> is empty.</exception> public PageInfo RenamePage(PageInfo page, string newName) { if(page == null) throw new ArgumentNullException("page"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); lock(this) { if(PageExists(new PageInfo(NameTools.GetFullName(NameTools.GetNamespace(page.FullName), newName), this, DateTime.Now))) return null; NamespaceInfo currentNs = FindNamespace(NameTools.GetNamespace(page.FullName), GetNamespaces()); if(currentNs != null && currentNs.DefaultPage != null) { // Cannot rename the default page if(new PageNameComparer().Compare(currentNs.DefaultPage, page) == 0) return null; } PageInfo[] pgs = GetAllPages(); PageNameComparer comp = new PageNameComparer(); // Store page's categories for rebinding with new page CategoryInfo[] tmp = GetCategoriesForPage(page); string[] cats = new string[tmp.Length]; for(int i = 0; i < tmp.Length; i++) { cats[i] = tmp[i].FullName; } // Remove all bindings for old page RebindPage(page, new string[0]); // Find page and rename files for(int i = 0; i < pgs.Length; i++) { if(comp.Compare(pgs[i], page) == 0) { LocalPageInfo local = pgs[i] as LocalPageInfo; PageContent oldContent = GetContent(page); Message[] messages = GetMessages(local); // Update search engine index UnindexPage(oldContent); foreach(Message msg in messages) { UnindexMessageTree(local, msg); } string oldFullName = local.FullName; local.FullName = NameTools.GetFullName(NameTools.GetNamespace(local.FullName), newName); string newFile = GetNamespacePartialPathForPageContent(NameTools.GetNamespace(local.FullName)) + newName + Path.GetExtension(local.File); // Rename content file string oldLocalName = local.File; string oldFullPath = GetFullPathForPageContent(local.File); string newFullPath = GetFullPathForPageContent(newFile); File.Move(oldFullPath, newFullPath); // Rename messages file if(File.Exists(GetFullPathForMessages(oldLocalName))) { File.Move(GetFullPathForMessages(oldLocalName), GetFullPathForMessages(newFile)); } // Rename draft file, if any string oldDraftFullPath = GetDraftFullPath(local); if(File.Exists(oldDraftFullPath)) { string newDraftFullPath = GetDraftFullPath(new LocalPageInfo(local.FullName, this, local.CreationDateTime, newFile)); File.Move(oldDraftFullPath, newDraftFullPath); } // Rename all backups, store new page list on disk // and rebind new page with old categories RenameBackups(new LocalPageInfo(oldFullName, this, local.CreationDateTime, oldLocalName), newName); // Set new filename (local references an element in the pgs array) local.File = newFile; DumpPages(pgs); // Clear internal cache categoriesCache = null; pagesCache = null; // Re-bind page with previously saved categories RebindPage(local, cats); // Update search engine index IndexPage(new PageContent(local, oldContent.Title, oldContent.User, oldContent.LastModified, oldContent.Comment, oldContent.Content, oldContent.Keywords, oldContent.Description)); foreach(Message msg in messages) { IndexMessageTree(local, msg); } return local; } } // Page not found, return null return null; } }
/// <summary> /// Removes a Page. /// </summary> /// <param name="page">The Page to remove.</param> /// <returns><c>true</c> if the Page has been removed successfully, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <c>null</c>.</exception> public bool RemovePage(PageInfo page) { if(page == null) throw new ArgumentNullException("page"); lock(this) { NamespaceInfo currentNs = FindNamespace(NameTools.GetNamespace(page.FullName), GetNamespaces()); if(currentNs != null && currentNs.DefaultPage != null) { // Cannot remove the default page if(new PageNameComparer().Compare(currentNs.DefaultPage, page) == 0) return false; } List<PageInfo> allPages = new List<PageInfo>(GetAllPages()); PageNameComparer comp = new PageNameComparer(); for(int i = 0; i < allPages.Count; i++) { if(comp.Compare(allPages[i], page) == 0) { PageContent content = GetContent(page); LocalPageInfo local = page as LocalPageInfo; // Update search engine index UnindexPage(content); Message[] messages = GetMessages(local); foreach(Message msg in messages) { UnindexMessageTree(local, msg); } allPages.Remove(allPages[i]); DeleteBackups(page, -1); DumpPages(allPages.ToArray()); try { File.Delete(GetFullPathForPageContent(GetNamespacePartialPathForPageContent(NameTools.GetNamespace(page.FullName)) + ((LocalPageInfo)page).File)); } catch { } try { File.Delete(GetDraftFullPath(local)); } catch { } try { File.Delete(GetFullPathForMessages(local.File)); } catch { } pagesCache = null; categoriesCache = null; return true; } } } return false; }
/// <summary> /// Moves a page from its namespace into another. /// </summary> /// <param name="page">The page to move.</param> /// <param name="destination">The destination namespace (null for the root).</param> /// <param name="copyCategories">A value indicating whether to copy the page categories in the destination /// namespace, if not already available.</param> /// <returns>The correct instance of <see cref="T:PageInfo" />.</returns> /// <exception cref="ArgumentNullException">If <b>page</b> is <c>null</c>.</exception> public PageInfo MovePage(PageInfo page, NamespaceInfo destination, bool copyCategories) { if(page == null) throw new ArgumentNullException("page"); string destinationName = destination != null ? destination.Name : null; NamespaceInfo currentNs = FindNamespace(NameTools.GetNamespace(page.FullName), GetNamespaces()); NamespaceComparer nsComp = new NamespaceComparer(); if((currentNs == null && destination == null) || nsComp.Compare(currentNs, destination) == 0) return null; if(PageExists(new PageInfo(NameTools.GetFullName(destinationName, NameTools.GetLocalName(page.FullName)), this, page.CreationDateTime))) return null; if(!NamespaceExists(destinationName)) return null; if(currentNs != null && currentNs.DefaultPage != null) { // Cannot move the default page if(new PageNameComparer().Compare(currentNs.DefaultPage, page) == 0) return null; } // Store categories for copying them, if needed CategoryInfo[] pageCategories = GetCategoriesForPage(page); // Update categories names with new namespace (don't modify the same instance because it's actually the cache!) for(int i = 0; i < pageCategories.Length; i++) { string[] pages = pageCategories[i].Pages; pageCategories[i] = new CategoryInfo(NameTools.GetFullName(destinationName, NameTools.GetLocalName(pageCategories[i].FullName)), this); pageCategories[i].Pages = new string[pages.Length]; for(int k = 0; k < pages.Length; k++) { pageCategories[i].Pages[k] = NameTools.GetFullName(destinationName, NameTools.GetLocalName(pages[k])); } } // Delete category bindings RebindPage(page, new string[0]); // Change namespace and file PageInfo[] allPages = GetAllPages(); PageNameComparer comp = new PageNameComparer(); PageInfo newPage = null; foreach(PageInfo current in allPages) { if(comp.Compare(current, page) == 0) { // Page found, update data // Change namespace and file LocalPageInfo local = (LocalPageInfo)current; // Update search engine index PageContent oldPageContent = GetContent(local); UnindexPage(oldPageContent); foreach(Message msg in GetMessages(local)) { UnindexMessageTree(local, msg); } // Move backups in new folder MoveBackups(page, destination); string newFile = GetNamespacePartialPathForPageContent(destinationName) + Path.GetFileName(local.File); // Move data file File.Move(GetFullPathForPageContent(local.File), GetFullPathForPageContent(newFile)); // Move messages file string messagesFullPath = GetFullPathForMessages(local.File); if(File.Exists(messagesFullPath)) { File.Move(messagesFullPath, GetFullPathForMessages(newFile)); } // Move draft file string draftFullPath = GetFullPathForPageDrafts(local.File); if(File.Exists(draftFullPath)) { string newDraftFullPath = GetFullPathForPageDrafts(newFile); if(!Directory.Exists(Path.GetDirectoryName(newDraftFullPath))) { Directory.CreateDirectory(Path.GetDirectoryName(newDraftFullPath)); } File.Move(draftFullPath, newDraftFullPath); } //local.Namespace = destinationName; local.FullName = NameTools.GetFullName(destinationName, NameTools.GetLocalName(local.FullName)); local.File = newFile; newPage = local; DumpPages(allPages); // Update search engine index IndexPage(new PageContent(newPage, oldPageContent.Title, oldPageContent.User, oldPageContent.LastModified, oldPageContent.Comment, oldPageContent.Content, oldPageContent.Keywords, oldPageContent.Description)); foreach(Message msg in GetMessages(local)) { IndexMessageTree(newPage, msg); } break; } } // Rebind page, if needed if(copyCategories) { // Foreach previously bound category, verify that is present in the destination namespace, if not then create it List<string> newCategories = new List<string>(pageCategories.Length); foreach(CategoryInfo oldCategory in pageCategories) { if(!CategoryExists(new CategoryInfo(oldCategory.FullName, this))) { AddCategory(destination != null ? destination.Name : null, NameTools.GetLocalName(oldCategory.FullName)); } newCategories.Add(oldCategory.FullName); } RebindPage(newPage, newCategories.ToArray()); } namespacesCache = null; pagesCache = null; categoriesCache = null; return newPage; }
/// <summary> /// Searches for pages with name or title similar to a specified value. /// </summary> /// <param name="name">The name to look for (<c>null</c> for the root).</param> /// <param name="nspace">The namespace to search into.</param> /// <returns>The similar pages, if any.</returns> public static PageInfo[] SearchSimilarPages(string name, string nspace) { if(string.IsNullOrEmpty(nspace)) nspace = null; SearchResultCollection searchResults = Search(name, false, false, SearchOptions.AtLeastOneWord); List<PageInfo> result = new List<PageInfo>(20); foreach(SearchResult res in searchResults) { PageDocument pageDoc = res.Document as PageDocument; if(pageDoc != null) { string pageNamespace = NameTools.GetNamespace(pageDoc.PageInfo.FullName); if(string.IsNullOrEmpty(pageNamespace)) pageNamespace = null; if(pageNamespace == nspace) { result.Add(pageDoc.PageInfo); } } } // Search page names for matches List<PageInfo> allPages = Pages.GetPages(Pages.FindNamespace(nspace)); PageNameComparer comp = new PageNameComparer(); string currentName = name.ToLowerInvariant(); foreach(PageInfo page in allPages) { if(NameTools.GetLocalName(page.FullName).ToLowerInvariant().Contains(currentName)) { if(result.Find(delegate(PageInfo p) { return comp.Compare(p, page) == 0; }) == null) { result.Add(page); } } } return result.ToArray(); }
/// <summary> /// Finds a page by name. /// </summary> /// <param name="page">The page.</param> /// <returns>The index in the collection.</returns> private int FindPage(PageInfo page) { lock(this) { if(pages == null || pages.Count == 0) return -1; PageNameComparer comp = new PageNameComparer(); for(int i = 0; i < pages.Count; i++) { if(comp.Compare(pages[i], page) == 0) return i; } return -1; } }
/// <summary> /// Appends a breadbrumb trail element. /// </summary> /// <param name="sb">The destination <see cref="T:StringBuilder" />.</param> /// <param name="page">The page to append.</param> /// <param name="dpPrefix">The drop-down menu ID prefix.</param> private void AppendBreadcrumb(StringBuilder sb, PageInfo page, string dpPrefix) { PageNameComparer comp = new PageNameComparer(); PageContent pc = Content.GetPageContent(page, true); string id = AppendBreadcrumbDropDown(sb, page, dpPrefix); string nspace = NameTools.GetNamespace(page.FullName); sb.Append("» "); if(comp.Compare(page, currentPage) == 0) sb.Append("<b>"); sb.AppendFormat(@"<a href=""{0}"" title=""{1}""{2}{3}{4}>{1}</a>", Tools.UrlEncode(page.FullName) + Settings.PageExtension, FormattingPipeline.PrepareTitle(pc.Title, false, FormattingContext.PageContent, currentPage) + (string.IsNullOrEmpty(nspace) ? "" : (" (" + NameTools.GetNamespace(page.FullName) + ")")), (id != null ? @" onmouseover=""javascript:return __ShowDropDown(event, '" + id + @"', this);""" : ""), (id != null ? @" id=""lnk" + id + @"""" : ""), (id != null ? @" onmouseout=""javascript:return __HideDropDown('" + id + @"');""" : "")); if(comp.Compare(page, currentPage) == 0) sb.Append("</b>"); sb.Append(" "); }