diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RegisteredXmlSchemas.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RegisteredXmlSchemas.cs index 1ce15e0e72..489c9653ec 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RegisteredXmlSchemas.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RegisteredXmlSchemas.cs @@ -144,8 +144,8 @@ namespace ICSharpCode.XmlEditor string baseUri = XmlSchemaCompletion.GetUri(fileName); XmlSchemaCompletion schema = factory.CreateXmlSchemaCompletionData(baseUri, fileName); schema.FileName = fileName; - schema.IsReadOnly = readOnly; - return schema; + schema.IsReadOnly = readOnly; + return schema; } catch (Exception ex) { schemaErrors.Add(new RegisteredXmlSchemaError("Unable to read schema '" + fileName + "'.", ex)); } @@ -160,11 +160,7 @@ namespace ICSharpCode.XmlEditor void AddSchema(XmlSchemaCompletion schema) { if (schema.HasNamespaceUri) { - if (!schemas.Contains(schema.NamespaceUri)) { - schemas.Add(schema); - } else { - schemaErrors.Add(new RegisteredXmlSchemaError("Ignoring duplicate schema namespace '" + schema.NamespaceUri + "'. File '" + schema.FileName + "'.")); - } + schemas.Add(schema); } else { schemaErrors.Add(new RegisteredXmlSchemaError("Ignoring schema with no namespace '" + schema.FileName + "'.")); } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletion.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletion.cs index 9fee304318..8b4ca27767 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletion.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletion.cs @@ -358,7 +358,7 @@ namespace ICSharpCode.XmlEditor void ReadSchema(XmlReader reader) { try { - schema = XmlSchema.Read(reader, new ValidationEventHandler(SchemaValidation)); + schema = XmlSchema.Read(reader, SchemaValidation); if (schema != null) { XmlSchemaSet schemaSet = new XmlSchemaSet(); schemaSet.ValidationEventHandler += SchemaValidation; diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletionCollection.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletionCollection.cs index 9529db565d..fa184eeb9d 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletionCollection.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlSchemaCompletionCollection.cs @@ -41,8 +41,10 @@ namespace ICSharpCode.XmlEditor XmlCompletionItemCollection completionItems = new XmlCompletionItemCollection(); foreach (XmlSchemaCompletion schema in this) { - XmlCompletionItem completionData = new XmlCompletionItem(schema.NamespaceUri, XmlCompletionItemType.NamespaceUri); - completionItems.Add(completionData); + XmlCompletionItem completionItem = new XmlCompletionItem(schema.NamespaceUri, XmlCompletionItemType.NamespaceUri); + if (!completionItems.Contains(completionItem)) { + completionItems.Add(completionItem); + } } return completionItems; @@ -82,14 +84,10 @@ namespace ICSharpCode.XmlEditor public void AddRange(XmlSchemaCompletionCollection schemas) { for (int i = 0; i < schemas.Count; i++) { - this.Add(schemas[i]); + Add(schemas[i]); } } - /// - /// Gets the schema completion data with the same filename. - /// - /// if no matching schema found. public XmlSchemaCompletion GetSchemaFromFileName(string fileName) { foreach (XmlSchemaCompletion schema in this) { @@ -100,32 +98,43 @@ namespace ICSharpCode.XmlEditor return null; } - public XmlSchemaCompletion FindSchema(XmlElementPath path, XmlSchemaCompletion defaultSchema) + public XmlSchemaCompletionCollection GetSchemas(string namespaceUri) { - if (path.Elements.HasItems) { - string namespaceUri = path.GetRootNamespace(); - if (namespaceUri.Length > 0) { - return this[namespaceUri]; - } else if (defaultSchema != null) { - path.SetNamespaceForUnqualifiedNames(defaultSchema.NamespaceUri); - return defaultSchema; + XmlSchemaCompletionCollection schemas = new XmlSchemaCompletionCollection(); + foreach (XmlSchemaCompletion schema in this) { + if (schema.NamespaceUri == namespaceUri) { + schemas.Add(schema); } } - return null; + return schemas; } - public XmlCompletionItemCollection GetChildElementCompletion(XmlElementPath path) + public XmlSchemaCompletionCollection GetSchemas(XmlElementPath path, XmlSchemaCompletion defaultSchema) { - return GetChildElementCompletion(path, null); + string namespaceUri = path.GetRootNamespace(); + if (String.IsNullOrEmpty(namespaceUri)) { + return GetSchemaCollectionUsingDefaultSchema(path, defaultSchema); + } + return GetSchemas(namespaceUri); } - public XmlCompletionItemCollection GetChildElementCompletion(XmlElementPath path, XmlSchemaCompletion defaultSchema) + XmlSchemaCompletionCollection GetSchemaCollectionUsingDefaultSchema(XmlElementPath path, XmlSchemaCompletion defaultSchema) { - XmlSchemaCompletion schema = FindSchema(path, defaultSchema); - if (schema != null) { - return schema.GetChildElementCompletion(path); - } - return new XmlCompletionItemCollection(); + XmlSchemaCompletionCollection schemas = new XmlSchemaCompletionCollection(); + if (defaultSchema != null) { + path.SetNamespaceForUnqualifiedNames(defaultSchema.NamespaceUri); + schemas.Add(defaultSchema); + } + return schemas; + } + + public XmlCompletionItemCollection GetChildElementCompletion(XmlElementPath path) + { + XmlCompletionItemCollection items = new XmlCompletionItemCollection(); + foreach (XmlSchemaCompletion schema in GetSchemas(path, null)) { + items.AddRange(schema.GetChildElementCompletion(path)); + } + return items; } public XmlCompletionItemCollection GetElementCompletionForAllNamespaces(XmlElementPath path, XmlSchemaCompletion defaultSchema) @@ -161,8 +170,7 @@ namespace ICSharpCode.XmlEditor { XmlCompletionItemCollection items = new XmlCompletionItemCollection(); foreach (XmlNamespace ns in namespaces) { - XmlSchemaCompletion schema = this[ns.Name]; - if (schema != null) { + foreach (XmlSchemaCompletion schema in GetSchemas(ns.Name)) { items.AddRange(schema.GetRootElementCompletion(ns.Prefix)); } } @@ -171,11 +179,11 @@ namespace ICSharpCode.XmlEditor public XmlCompletionItemCollection GetAttributeCompletion(XmlElementPath path, XmlSchemaCompletion defaultSchema) { - XmlSchemaCompletion schema = FindSchema(path, defaultSchema); - if (schema != null) { - return schema.GetAttributeCompletion(path); + XmlCompletionItemCollection items = new XmlCompletionItemCollection(); + foreach (XmlSchemaCompletion schema in GetSchemas(path, defaultSchema)) { + items.AddRange(schema.GetAttributeCompletion(path)); } - return new XmlCompletionItemCollection(); + return items; } public XmlCompletionItemCollection GetElementCompletion(string textUpToCursor, XmlSchemaCompletion defaultSchema) @@ -221,11 +229,11 @@ namespace ICSharpCode.XmlEditor public XmlCompletionItemCollection GetAttributeValueCompletion(XmlElementPath path, string attributeName, XmlSchemaCompletion defaultSchema) { path.Compact(); - XmlSchemaCompletion schema = FindSchema(path, defaultSchema); - if (schema != null) { - return schema.GetAttributeValueCompletion(path, attributeName); + XmlCompletionItemCollection items = new XmlCompletionItemCollection(); + foreach (XmlSchemaCompletion schema in GetSchemas(path, defaultSchema)) { + items.AddRange(schema.GetAttributeValueCompletion(path, attributeName)); } - return new XmlCompletionItemCollection(); + return items; } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/RegisteredSchemaWithSameNamespaceAddedTwiceTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/RegisteredSchemaWithSameNamespaceAddedTwiceTestFixture.cs index 9d0baa36b5..b88ef307dd 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/RegisteredSchemaWithSameNamespaceAddedTwiceTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/RegisteredSchemaWithSameNamespaceAddedTwiceTestFixture.cs @@ -51,12 +51,9 @@ namespace XmlEditor.Tests.Editor } [Test] - public void SchemaNamespaceAlreadyAddedRecordedAsError() + public void NoSchemaErrorsRecordedForDuplicateSchemaNamespace() { - string message = @"Ignoring duplicate schema namespace 'http://test'. File 'c:\users\user\schemas\test2.xsd'."; - RegisteredXmlSchemaError error = new RegisteredXmlSchemaError(message); - RegisteredXmlSchemaError[] expectedErrors = new RegisteredXmlSchemaError[] { error }; - Assert.AreEqual(expectedErrors, registeredXmlSchemas.GetSchemaErrors()); + Assert.AreEqual(0, registeredXmlSchemas.GetSchemaErrors().Length); } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/TwoRegisteredSchemasTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/TwoRegisteredSchemasTestFixture.cs index fe989b5cbf..c5be23ed9b 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/TwoRegisteredSchemasTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Editor/TwoRegisteredSchemasTestFixture.cs @@ -133,15 +133,15 @@ namespace XmlEditor.Tests.Editor [Test] public void RemoveTestSchemaFiresUserSchemaRemovedEvent() { - registeredXmlSchemas.RemoveUserDefinedSchema("http://test"); + registeredXmlSchemas.RemoveUserDefinedSchema("http://test"); Assert.AreEqual(1, userSchemaRemovedEventFiredCount); } [Test] public void TrytoRemoveTestSchemaTwiceButSchemaRemovedEventShouldOnlyFireOnce() { - registeredXmlSchemas.RemoveUserDefinedSchema("http://test"); - registeredXmlSchemas.RemoveUserDefinedSchema("http://test"); + registeredXmlSchemas.RemoveUserDefinedSchema("http://test"); + registeredXmlSchemas.RemoveUserDefinedSchema("http://test"); Assert.AreEqual(1, userSchemaRemovedEventFiredCount); } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Schema.Multiple/DuplicateSchemaNamespaceAddedToCollectionTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Schema.Multiple/DuplicateSchemaNamespaceAddedToCollectionTestFixture.cs new file mode 100644 index 0000000000..06371d9ebb --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Schema.Multiple/DuplicateSchemaNamespaceAddedToCollectionTestFixture.cs @@ -0,0 +1,292 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.IO; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Schema.Multiple +{ + [TestFixture] + public class DuplicateSchemaNamespaceAddedToCollectionTestFixture + { + XmlSchemaCompletionCollection schemas; + XmlSchemaCompletion fooSchema; + XmlSchemaCompletion barSchema; + XmlSchemaCompletion duplicateFooSchema; + + [SetUp] + public void Init() + { + CreateBarSchema(); + CreateFooSchema(); + CreateDuplicateFooSchema(); + + schemas = new XmlSchemaCompletionCollection(); + schemas.Add(fooSchema); + schemas.Add(barSchema); + schemas.Add(duplicateFooSchema); + } + + void CreateFooSchema() + { + string xml = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + ""; + + fooSchema = new XmlSchemaCompletion(new StringReader(xml)); + fooSchema.FileName = "foo.xsd"; + } + + void CreateBarSchema() + { + string xml = ""; + barSchema = new XmlSchemaCompletion(new StringReader(xml)); + barSchema.FileName = "bar.xsd"; + } + + void CreateDuplicateFooSchema() + { + string xml = + "\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + ""; + + duplicateFooSchema = new XmlSchemaCompletion(new StringReader(xml)); + duplicateFooSchema.FileName = "duplicate-foo.xsd"; + } + + [Test] + public void SchemasHaveTheSameNamespace() + { + Assert.AreEqual(fooSchema.NamespaceUri, duplicateFooSchema.NamespaceUri); + } + + [Test] + public void SchemaNamespaceIsNotEmptyString() + { + Assert.AreEqual("foo", fooSchema.NamespaceUri); + } + + [Test] + public void ThreeSchemasInCollection() + { + Assert.AreEqual(3, schemas.Count); + } + + [Test] + public void GetSchemasForFooNamespaceReturnsTwoSchemas() + { + Assert.AreEqual(2, schemas.GetSchemas("foo").Count); + } + + [Test] + public void GetSchemasForFooNamespaceReturnedSchemasContainDuplicateSchemas() + { + XmlSchemaCompletionCollection matchedSchemas = schemas.GetSchemas("foo"); + string[] expectedFileNames = new string[] {"foo.xsd", "duplicate-foo.xsd"}; + + Assert.AreEqual(expectedFileNames, XmlSchemaCompletionCollectionFileNames.GetFileNames(matchedSchemas)); + } + + [Test] + public void GetSchemasForElementPathReturnsEmptyCollectionWhenNoNamespaceUsedInPathAndNoDefaultSchema() + { + XmlElementPath path = new XmlElementPath(); + path.AddElement(new QualifiedName("root", String.Empty)); + + XmlSchemaCompletionCollection foundSchemas = schemas.GetSchemas(path, null); + Assert.AreEqual(0, foundSchemas.Count); + } + + [Test] + public void GetSchemasForElementPathReturnsDefaultSchemaWhenNoNamespaceUsedInPathButHasDefaultSchema() + { + XmlElementPath path = new XmlElementPath(); + path.AddElement(new QualifiedName("root", String.Empty)); + + XmlSchemaCompletion defaultSchema = new XmlSchemaCompletion(); + defaultSchema.FileName = "default.xsd"; + + XmlSchemaCompletionCollection foundSchemas = schemas.GetSchemas(path, defaultSchema); + + string[] expectedFileNames = new string[] {"default.xsd"}; + Assert.AreEqual(expectedFileNames, XmlSchemaCompletionCollectionFileNames.GetFileNames(foundSchemas)); + } + + [Test] + public void GetSchemasForElementPathUpdatesElementNamespacesUsingDefaultSchemaNamespace() + { + XmlElementPath path = new XmlElementPath(); + path.AddElement(new QualifiedName("root", String.Empty)); + path.AddElement(new QualifiedName("different-ns-element", "unknown-namespace")); + path.AddElement(new QualifiedName("child", String.Empty)); + + string xml = ""; + XmlSchemaCompletion defaultSchema = new XmlSchemaCompletion(new StringReader(xml)); + defaultSchema.FileName = "default.xsd"; + + schemas.GetSchemas(path, defaultSchema); + + XmlElementPath expectedPath = new XmlElementPath(); + expectedPath.AddElement(new QualifiedName("root", "default-ns")); + expectedPath.AddElement(new QualifiedName("different-ns-element", "unknown-namespace")); + expectedPath.AddElement(new QualifiedName("child", "default-ns")); + + Assert.AreEqual(expectedPath, path); + } + + [Test] + public void GetSchemasForElementPathReturnsDuplicateFooSchemasWhenFooNamespaceUsedInPath() + { + XmlElementPath path = new XmlElementPath(); + path.AddElement(new QualifiedName("root", "foo")); + + XmlSchemaCompletionCollection foundSchemas = schemas.GetSchemas(path, null); + string[] expectedFileNames = new string[] {"foo.xsd", "duplicate-foo.xsd"}; + Assert.AreEqual(expectedFileNames, XmlSchemaCompletionCollectionFileNames.GetFileNames(foundSchemas)); + } + + [Test] + public void NamespaceCompletionDoesNotContainDuplicateNamespaces() + { + XmlCompletionItemCollection items = schemas.GetNamespaceCompletion(); + items.Sort(); + + List expectedItems = new List(); + expectedItems.Add(new XmlCompletionItem("bar", XmlCompletionItemType.NamespaceUri)); + expectedItems.Add(new XmlCompletionItem("foo", XmlCompletionItemType.NamespaceUri)); + + Assert.AreEqual(expectedItems.ToArray(), items.ToArray()); + } + + [Test] + public void GetRootElementCompletionReturnsRootElementsFromBothFooSchemas() + { + XmlNamespaceCollection namespaces = new XmlNamespaceCollection(); + namespaces.Add(new XmlNamespace(String.Empty, "foo")); + XmlCompletionItemCollection items = schemas.GetRootElementCompletion(namespaces); + items.Sort(); + + List expectedItems = new List(); + expectedItems.Add(new XmlCompletionItem("duplicate-foo-note", XmlCompletionItemType.XmlElement)); + expectedItems.Add(new XmlCompletionItem("foo-note", XmlCompletionItemType.XmlElement)); + + Assert.AreEqual(expectedItems.ToArray(), items.ToArray()); + } + + [Test] + public void GetChildElementCompletionForDuplicateFooRootElement() + { + XmlElementPath path = new XmlElementPath(); + path.AddElement(new QualifiedName("duplicate-foo-note", "foo")); + XmlCompletionItemCollection items = schemas.GetChildElementCompletion(path); + items.Sort(); + + List expectedItems = new List(); + expectedItems.Add(new XmlCompletionItem("duplicate-foo-text", XmlCompletionItemType.XmlElement)); + + Assert.AreEqual(expectedItems.ToArray(), items.ToArray()); + } + + [Test] + public void GetAttributeCompletionReturnsAttributesFromDuplicateFooSchema() + { + string xml = + "\r\n" + + " \r\n" + + " +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.XmlEditor; +using NUnit.Framework; + +namespace XmlEditor.Tests.Utils.Tests +{ + [TestFixture] + public class XmlSchemaCompletionCollectionFileNamesTests + { + XmlSchemaCompletionCollection schemas; + + [SetUp] + public void Init() + { + schemas = new XmlSchemaCompletionCollection(); + } + + [Test] + public void NoItemsInSchemaCollection() + { + Assert.AreEqual(0, XmlSchemaCompletionCollectionFileNames.GetFileNames(schemas).Length); + } + + [Test] + public void OneSchemaWithFileName() + { + XmlSchemaCompletion schema = new XmlSchemaCompletion(); + schema.FileName = "a.xsd"; + schemas.Add(schema); + + string[] expectedFileNames = new string[] {"a.xsd"}; + Assert.AreEqual(expectedFileNames, XmlSchemaCompletionCollectionFileNames.GetFileNames(schemas)); + } + + [Test] + public void TwoSchemasWithFileName() + { + XmlSchemaCompletion schema = new XmlSchemaCompletion(); + schema.FileName = "a.xsd"; + schemas.Add(schema); + + schema = new XmlSchemaCompletion(); + schema.FileName = "b.xsd"; + schemas.Add(schema); + + string[] expectedFileNames = new string[] {"a.xsd", "b.xsd"}; + Assert.AreEqual(expectedFileNames, XmlSchemaCompletionCollectionFileNames.GetFileNames(schemas)); + } + + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/XmlSchemaCompletionCollectionFileNames.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/XmlSchemaCompletionCollectionFileNames.cs new file mode 100644 index 0000000000..06df4a92b2 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/XmlSchemaCompletionCollectionFileNames.cs @@ -0,0 +1,29 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using ICSharpCode.XmlEditor; + +namespace XmlEditor.Tests.Utils +{ + public class XmlSchemaCompletionCollectionFileNames + { + XmlSchemaCompletionCollectionFileNames() + { + } + + public static string[] GetFileNames(XmlSchemaCompletionCollection schemas) + { + List fileNames = new List(); + foreach (XmlSchemaCompletion schema in schemas) { + fileNames.Add(schema.FileName); + } + return fileNames.ToArray(); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj b/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj index c77097d277..54e5eb706b 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj @@ -154,6 +154,7 @@ + @@ -258,7 +259,9 @@ + + diff --git a/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln b/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln index 4e88ae7bda..72df631912 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln +++ b/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.0.0.5201 +# SharpDevelop 4.0.0.5293 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "Project\XmlEditor.csproj", "{DCA2703D-250A-463E-A68A-07ED105AE6BD}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor.Tests", "Test\XmlEditor.Tests.csproj", "{FC0FE702-A87D-4D70-A9B6-1ECCD611125F}"