private ConcurrentDictionary <string, IList <string> > LoadClrToXmlNs() { ConcurrentDictionary <string, IList <string> > dict = XamlSchemaContext.CreateDictionary <string, IList <string> >(); System.Reflection.Assembly assembly = this.Assembly; if (assembly != null) { foreach (XmlNsDefinition definition in this.NsDefs) { IList <string> list; if (!dict.TryGetValue(definition.ClrNamespace, out list)) { list = new List <string>(); dict.TryAdd(definition.ClrNamespace, list); } list.Add(definition.XmlNamespace); } string assemblyName = this._fullyQualifyAssemblyName ? assembly.FullName : XamlSchemaContext.GetAssemblyShortName(assembly); foreach (KeyValuePair <string, IList <string> > pair in dict) { List <string> list2 = (List <string>)pair.Value; NamespaceComparer comparer = new NamespaceComparer(this, assembly); list2.Sort(new Comparison <string>(comparer.CompareNamespacesByPreference)); string uri = ClrNamespaceUriParser.GetUri(pair.Key, assemblyName); list2.Add(uri); } this.MakeListsImmutable(dict); } return(dict); }
internal int CompareContainingNamespace(ISymbol x, ISymbol y) { Debug.Assert(x.Kind != SymbolKind.Namespace, x.Kind.ToString()); Debug.Assert(y.Kind != SymbolKind.Namespace, y.Kind.ToString()); return(NamespaceComparer.Compare(x.ContainingNamespace, y.ContainingNamespace)); }
private ConcurrentDictionary<string, IList<string>> LoadClrToXmlNs() { ConcurrentDictionary<string, IList<string>> dict = XamlSchemaContext.CreateDictionary<string, IList<string>>(); System.Reflection.Assembly assembly = this.Assembly; if (assembly != null) { foreach (XmlNsDefinition definition in this.NsDefs) { IList<string> list; if (!dict.TryGetValue(definition.ClrNamespace, out list)) { list = new List<string>(); dict.TryAdd(definition.ClrNamespace, list); } list.Add(definition.XmlNamespace); } string assemblyName = this._fullyQualifyAssemblyName ? assembly.FullName : XamlSchemaContext.GetAssemblyShortName(assembly); foreach (KeyValuePair<string, IList<string>> pair in dict) { List<string> list2 = (List<string>) pair.Value; NamespaceComparer comparer = new NamespaceComparer(this, assembly); list2.Sort(new Comparison<string>(comparer.CompareNamespacesByPreference)); string uri = ClrNamespaceUriParser.GetUri(pair.Key, assemblyName); list2.Add(uri); } this.MakeListsImmutable(dict); } return dict; }
private int CompareSymbolAndNamespaceSymbol(ISymbol symbol, INamespaceSymbol namespaceSymbol) { int diff = NamespaceComparer.Compare(symbol.ContainingNamespace, namespaceSymbol); if (diff != 0) { return(diff); } return(1); }
private int CompareNamedTypeSymbol(INamedTypeSymbol typeSymbol1, INamedTypeSymbol typeSymbol2) { int diff = NamespaceComparer.Compare(typeSymbol1.ContainingNamespace, typeSymbol2.ContainingNamespace); if (diff != 0) { return(diff); } return(TypeComparer.Compare(typeSymbol1, typeSymbol2)); }
ConcurrentDictionary <string, IList <string> > LoadClrToXmlNs() { ConcurrentDictionary <string, IList <string> > result = XamlSchemaContext.CreateDictionary <string, IList <string> >(); Assembly assembly = Assembly; if (assembly == null) { return(result); } foreach (XmlNsDefinition nsDef in NsDefs) { IList <string> xmlNamespaceList; if (!result.TryGetValue(nsDef.ClrNamespace, out xmlNamespaceList)) { xmlNamespaceList = new List <string>(); result.TryAdd(nsDef.ClrNamespace, xmlNamespaceList); } xmlNamespaceList.Add(nsDef.XmlNamespace); } string assemblyName = _fullyQualifyAssemblyName ? assembly.FullName : XamlSchemaContext.GetAssemblyShortName(assembly); foreach (KeyValuePair <string, IList <string> > clrToXmlNs in result) { // Sort namespaces in preference order List <string> nsList = (List <string>)clrToXmlNs.Value; NamespaceComparer comparer = new NamespaceComparer(this, assembly); nsList.Sort(comparer.CompareNamespacesByPreference); // Add clr-namespace form as last choice string clrNsUri = ClrNamespaceUriParser.GetUri(clrToXmlNs.Key, assemblyName); nsList.Add(clrNsUri); } // Convert to read-only lists so we can safely return these from public API MakeListsImmutable(result); return(result); }
public int Compare(ISymbol x, ISymbol y) { if (object.ReferenceEquals(x, y)) { return(0); } if (x == null) { return(-1); } if (y == null) { return(1); } switch (x.Kind) { case SymbolKind.Namespace: { var namespaceSymbol = (INamespaceSymbol)x; switch (y.Kind) { case SymbolKind.Namespace: return(NamespaceComparer.Compare(namespaceSymbol, (INamespaceSymbol)y)); case SymbolKind.NamedType: case SymbolKind.Event: case SymbolKind.Field: case SymbolKind.Method: case SymbolKind.Property: return(-CompareSymbolAndNamespaceSymbol(y, namespaceSymbol)); } break; } case SymbolKind.NamedType: { var typeSymbol = (INamedTypeSymbol)x; switch (y.Kind) { case SymbolKind.Namespace: return(CompareSymbolAndNamespaceSymbol(typeSymbol, (INamespaceSymbol)y)); case SymbolKind.NamedType: return(CompareNamedTypeSymbol(typeSymbol, (INamedTypeSymbol)y)); case SymbolKind.Event: case SymbolKind.Field: case SymbolKind.Method: case SymbolKind.Property: return(-CompareSymbolAndNamedTypeSymbol(y, typeSymbol)); } break; } case SymbolKind.Event: case SymbolKind.Field: case SymbolKind.Method: case SymbolKind.Property: { switch (y.Kind) { case SymbolKind.Namespace: return(CompareSymbolAndNamespaceSymbol(x, (INamespaceSymbol)y)); case SymbolKind.NamedType: return(CompareSymbolAndNamedTypeSymbol(x, (INamedTypeSymbol)y)); case SymbolKind.Event: case SymbolKind.Field: case SymbolKind.Method: case SymbolKind.Property: return(CompareMemberSymbol(x, y)); } break; } } throw new InvalidOperationException(); }
/// <summary> /// Finds a namespace. /// </summary> /// <param name="name">The name of the namespace to find.</param> /// <param name="namespaces">The namespaces array.</param> /// <returns>The found namespace, or <c>null</c>.</returns> private NamespaceInfo FindNamespace(string name, NamespaceInfo[] namespaces) { if(name == null) return null; NamespaceInfo target = new NamespaceInfo(name, this, null); NamespaceComparer comp = new NamespaceComparer(); NamespaceInfo result = Array.Find(namespaces, delegate(NamespaceInfo n) { return comp.Compare(n, target) == 0; }); return result; }
/// <summary> /// Renames a namespace. /// </summary> /// <param name="nspace">The namespace to rename.</param> /// <param name="newName">The new name of the namespace.</param> /// <returns>The correct <see cref="T:NamespaceInfo" /> object.</returns> /// <exception cref="ArgumentNullException">If <b>nspace</b> or <b>newName</b> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <b>newName</b> is empty.</exception> public NamespaceInfo RenameNamespace(NamespaceInfo nspace, string newName) { if(nspace == null) throw new ArgumentNullException("nspace"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); lock(this) { if(NamespaceExists(newName)) return null; string oldName = nspace.Name; // Remove all pages and their messages from search engine index foreach(PageInfo page in GetPages(nspace)) { PageContent content = GetContent(page); UnindexPage(content); Message[] messages = GetMessages(page); foreach(Message msg in messages) { UnindexMessageTree(page, msg); } } // Load namespace list and change name NamespaceInfo[] allNamespaces = GetNamespaces(); NamespaceComparer comp = new NamespaceComparer(); NamespaceInfo result = FindNamespace(nspace.Name, allNamespaces); if(result == null) return null; result.Name = newName; // Change default page full name if(result.DefaultPage != null) { result.DefaultPage = new LocalPageInfo(NameTools.GetFullName(newName, NameTools.GetLocalName(result.DefaultPage.FullName)), this, result.DefaultPage.CreationDateTime, GetNamespacePartialPathForPageContent(newName) + Path.GetFileName(((LocalPageInfo)result.DefaultPage).File)); } DumpNamespaces(allNamespaces); // Update Category list with new namespace name CategoryInfo[] allCategories = GetAllCategories(); for(int k = 0; k < allCategories.Length; k++) { CategoryInfo category = allCategories[k]; string catNamespace = NameTools.GetNamespace(category.FullName); if(catNamespace != null && StringComparer.OrdinalIgnoreCase.Compare(catNamespace, oldName) == 0) { category.FullName = NameTools.GetFullName(newName, NameTools.GetLocalName(category.FullName)); for(int i = 0; i < category.Pages.Length; i++) { category.Pages[i] = NameTools.GetFullName(newName, NameTools.GetLocalName(category.Pages[i])); } } } DumpCategories(allCategories); // Rename namespace folder Directory.Move(GetFullPathForPageContent(GetNamespacePartialPathForPageContent(oldName)), GetFullPathForPageContent(GetNamespacePartialPathForPageContent(newName))); // Rename drafts folder string oldDraftsFullPath = GetFullPathForPageDrafts(nspace.Name); if(Directory.Exists(oldDraftsFullPath)) { string newDraftsFullPath = GetFullPathForPageDrafts(newName); Directory.Move(oldDraftsFullPath, newDraftsFullPath); } // Rename messages folder Directory.Move(GetFullPathForMessages(GetNamespacePartialPathForPageContent(oldName)), GetFullPathForMessages(GetNamespacePartialPathForPageContent(newName))); // Update Page list with new namespace name and file PageInfo[] allPages = GetAllPages(); foreach(PageInfo page in allPages) { string pageNamespace = NameTools.GetNamespace(page.FullName); if(pageNamespace != null && StringComparer.OrdinalIgnoreCase.Compare(pageNamespace, oldName) == 0) { LocalPageInfo local = (LocalPageInfo)page; local.FullName = NameTools.GetFullName(newName, NameTools.GetLocalName(local.FullName)); local.File = GetNamespacePartialPathForPageContent(newName) + Path.GetFileName(local.File); } } DumpPages(allPages); namespacesCache = null; pagesCache = null; categoriesCache = null; // Re-add all pages and their messages to the search engine index foreach(PageInfo page in GetPages(result)) { // result contains the new name PageContent content = GetContent(page); IndexPage(content); Message[] messages = GetMessages(page); foreach(Message msg in messages) { IndexMessageTree(page, msg); } } return result; } }
/// <summary> /// Removes a namespace. /// </summary> /// <param name="nspace">The namespace to remove.</param> /// <returns><c>true</c> if the namespace is removed, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">If <b>nspace</b> is <c>null</c>.</exception> public bool RemoveNamespace(NamespaceInfo nspace) { if(nspace == null) throw new ArgumentNullException("nspace"); lock(this) { // Load all namespaces and remove the one to remove List<NamespaceInfo> allNamespaces = new List<NamespaceInfo>(GetNamespaces()); NamespaceComparer comp = new NamespaceComparer(); int index = allNamespaces.FindIndex(delegate(NamespaceInfo x) { return comp.Compare(x, nspace) == 0; }); if(index >= 0) { // Delete all categories foreach(CategoryInfo cat in GetCategories(nspace)) { RemoveCategory(cat); } // Delete all pages in the namespace (RemovePage removes the page from the search engine index) nspace.DefaultPage = null; // TODO: Remove this trick (needed in order to delete the default page) foreach(PageInfo page in GetPages(nspace)) { RemovePage(page); } // Update namespaces file allNamespaces.RemoveAt(index); DumpNamespaces(allNamespaces.ToArray()); // Remove namespace folder Directory.Delete(GetFullPathForPageContent(GetNamespacePartialPathForPageContent(nspace.Name)), true); // Remove drafts folder string oldDraftsFullPath = GetFullPathForPageDrafts(nspace.Name); if(Directory.Exists(oldDraftsFullPath)) { Directory.Delete(oldDraftsFullPath, true); } // Remove messages folder Directory.Delete(GetFullPathForMessages(GetNamespacePartialPathForPageContent(nspace.Name)), true); namespacesCache = null; pagesCache = null; categoriesCache = null; return true; } else 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> /// Merges two Categories. /// </summary> /// <param name="source">The source Category.</param> /// <param name="destination">The destination Category.</param> /// <returns>True if the Categories have been merged successfully.</returns> /// <remarks>The destination Category remains, while the source Category is deleted, and all its Pages re-bound in the destination Category.</remarks> /// <exception cref="ArgumentNullException">If <paramref name="source"/> or <paramref name="destination"/> are <c>null</c>.</exception> public CategoryInfo MergeCategories(CategoryInfo source, CategoryInfo destination) { if(source == null) throw new ArgumentNullException("source"); if(destination == null) throw new ArgumentNullException("destination"); lock(this) { NamespaceInfo[] allNamespaces = GetNamespaces(); NamespaceInfo sourceNs = FindNamespace(NameTools.GetNamespace(source.FullName), allNamespaces); NamespaceInfo destinationNs = FindNamespace(NameTools.GetNamespace(destination.FullName), allNamespaces); NamespaceComparer nsComp = new NamespaceComparer(); if(!(sourceNs == null && destinationNs == null) && nsComp.Compare(sourceNs, destinationNs) != 0) { // Different namespaces return null; } CategoryInfo[] cats = GetAllCategories(); int idxSource = -1, idxDest = -1; CategoryNameComparer comp = new CategoryNameComparer(); for(int i = 0; i < cats.Length; i++) { if(comp.Compare(cats[i], source) == 0) idxSource = i; if(comp.Compare(cats[i], destination) == 0) idxDest = i; if(idxSource != -1 && idxDest != -1) break; } if(idxSource == -1 || idxDest == -1) return null; List<CategoryInfo> tmp = new List<CategoryInfo>(cats); List<string> newPages = new List<string>(cats[idxDest].Pages); for(int i = 0; i < cats[idxSource].Pages.Length; i++) { bool found = false; for(int k = 0; k < newPages.Count; k++) { if(StringComparer.OrdinalIgnoreCase.Compare(newPages[k], cats[idxSource].Pages[i]) == 0) { found = true; break; } } if(!found) { newPages.Add(cats[idxSource].Pages[i]); } } tmp[idxDest].Pages = newPages.ToArray(); tmp.Remove(tmp[idxSource]); DumpCategories(tmp.ToArray()); CategoryInfo newCat = new CategoryInfo(destination.FullName, this); newCat.Pages = newPages.ToArray(); categoriesCache = null; return newCat; } }