Index: Core/Common/src/Core.Common.Base/IO/FileImporterBase.cs =================================================================== diff -u -r83379c80ce51791b09941604a562684e54dbf17d -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/src/Core.Common.Base/IO/FileImporterBase.cs (.../FileImporterBase.cs) (revision 83379c80ce51791b09941604a562684e54dbf17d) +++ Core/Common/src/Core.Common.Base/IO/FileImporterBase.cs (.../FileImporterBase.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -24,6 +24,8 @@ using System.Drawing; using System.Linq; +using Core.Common.Utils.Reflection; + namespace Core.Common.Base.IO { /// @@ -48,6 +50,11 @@ public abstract string FileFilter { get; } public abstract ProgressChangedDelegate ProgressChanged { protected get; set; } + public virtual bool CanImportOn(object targetItem) + { + return targetItem.GetType().Implements(SupportedItemType); + } + public abstract bool Import(object targetItem, string filePath); public void Cancel() Index: Core/Common/src/Core.Common.Base/IO/IFileImporter.cs =================================================================== diff -u -rdcd6469f6000957bc1604da8e92bd5ea09e43769 -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/src/Core.Common.Base/IO/IFileImporter.cs (.../IFileImporter.cs) (revision dcd6469f6000957bc1604da8e92bd5ea09e43769) +++ Core/Common/src/Core.Common.Base/IO/IFileImporter.cs (.../IFileImporter.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -65,6 +65,13 @@ ProgressChangedDelegate ProgressChanged { set; } /// + /// Determines whether this importer can import data to target item. + /// + /// The item to perform the import on. + /// True if the import was successful; false otherwise. + bool CanImportOn(object targetItem); + + /// /// This method imports the data to an item from a file at the given location. /// /// The item to perform the import on. Index: Core/Common/src/Core.Common.Base/Plugin/ApplicationCore.cs =================================================================== diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/src/Core.Common.Base/Plugin/ApplicationCore.cs (.../ApplicationCore.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71) +++ Core/Common/src/Core.Common.Base/Plugin/ApplicationCore.cs (.../ApplicationCore.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -79,10 +79,8 @@ return Enumerable.Empty(); } - var targetType = target.GetType(); - return plugins.SelectMany(plugin => plugin.GetFileImporters()) - .Where(fileImporter => (fileImporter.SupportedItemType == targetType || targetType.Implements(fileImporter.SupportedItemType))); + .Where(fileImporter => fileImporter.CanImportOn(target)); } /// Index: Core/Common/test/Core.Common.Base.Test/IO/FileImporterBaseTest.cs =================================================================== diff -u -r925d8a1d7dec6ef95d89b2ff67d78c8d5a49387f -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/test/Core.Common.Base.Test/IO/FileImporterBaseTest.cs (.../FileImporterBaseTest.cs) (revision 925d8a1d7dec6ef95d89b2ff67d78c8d5a49387f) +++ Core/Common/test/Core.Common.Base.Test/IO/FileImporterBaseTest.cs (.../FileImporterBaseTest.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -26,6 +26,51 @@ } [Test] + public void CanImportOn_ObjectIsOfCorrectType_ReturnTrue() + { + // Setup + var importer = new SimpleFileImporter(); + + var targetItem = new SimpleFileImporterTargetType(); + + // Call + var canImportOn = importer.CanImportOn(targetItem); + + // Assert + Assert.IsTrue(canImportOn); + } + + [Test] + public void CanImportOn_ObjectInheritsOfCorrectType_ReturnTrue() + { + // Setup + var importer = new SimpleFileImporter(); + + var targetItem = new InheritorOfImporterTargetType(); + + // Call + var canImportOn = importer.CanImportOn(targetItem); + + // Assert + Assert.IsTrue(canImportOn); + } + + [Test] + public void CanImportOn_ObjectTypeDoesNotMatch_ReturnFalse() + { + // Setup + var importer = new SimpleFileImporter(); + + var targetItem = new object(); + + // Call + var canImportOn = importer.CanImportOn(targetItem); + + // Assert + Assert.IsFalse(canImportOn); + } + + [Test] public void DoPostImportUpdates_TargetIsObservable_NotifyObservers() { // Setup @@ -164,7 +209,7 @@ { get { - throw new NotImplementedException(); + return typeof(SimpleFileImporterTargetType); } } @@ -194,5 +239,15 @@ NotifyProgress(currentStepName, currentStep, totalNumberOfSteps); } } + + private class SimpleFileImporterTargetType + { + + } + + private class InheritorOfImporterTargetType : SimpleFileImporterTargetType + { + + } } } \ No newline at end of file Index: Core/Common/test/Core.Common.Base.Test/Plugin/ApplicationCoreTest.cs =================================================================== diff -u -r81982c798fc50dab94c8f1eb8799c04242515564 -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/test/Core.Common.Base.Test/Plugin/ApplicationCoreTest.cs (.../ApplicationCoreTest.cs) (revision 81982c798fc50dab94c8f1eb8799c04242515564) +++ Core/Common/test/Core.Common.Base.Test/Plugin/ApplicationCoreTest.cs (.../ApplicationCoreTest.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using Core.Common.Base.IO; using Core.Common.Base.Plugin; @@ -42,12 +43,13 @@ public void AddPlugin_SimpleApplicationPluginWithImporter_ShouldExposePluginDefinitions() { // Setup - var mocks = new MockRepository(); var targetItem = new object(); - var fileImporter = mocks.Stub(); - fileImporter.Stub(i => i.SupportedItemType).Return(typeof(object)); + var mocks = new MockRepository(); + var fileImporter = mocks.Stub(); + fileImporter.Stub(i => i.CanImportOn(targetItem)).Return(true); + mocks.ReplayAll(); var applicationCore = new ApplicationCore(); @@ -63,7 +65,7 @@ applicationCore.AddPlugin(applicationPlugin); // Assert - var supportedFileImporters = applicationCore.GetSupportedFileImporters(targetItem).ToArray(); + IFileImporter[] supportedFileImporters = applicationCore.GetSupportedFileImporters(targetItem).ToArray(); Assert.AreEqual(1, supportedFileImporters.Length); Assert.AreSame(fileImporter, supportedFileImporters[0]); } @@ -89,12 +91,13 @@ public void RemovePlugin_SimpleApplicationPluginWithImport_ShouldNoLongerExposePluginDefinitions() { // Setup - var mocks = new MockRepository(); var targetItem = new object(); + + var mocks = new MockRepository(); + var fileImporter = mocks.Stub(); + fileImporter.Stub(i => i.CanImportOn(targetItem)).Return(true); - fileImporter.Stub(i => i.SupportedItemType).Return(typeof(object)); - mocks.ReplayAll(); var applicationCore = new ApplicationCore(); @@ -122,22 +125,16 @@ public void GetSupportedFileImporters_SimpleApplicationPluginWithImportersAdded_ShouldOnlyProvideSupportedImporters() { // Setup - var mocks = new MockRepository(); var targetItem = new B(); - var supportedFileImporter1 = mocks.Stub(); - var supportedFileImporter2 = mocks.Stub(); - var unsupportedFileImporter = mocks.Stub(); - supportedFileImporter1.Stub(i => i.SupportedItemType).Return(typeof(B)); - supportedFileImporter2.Stub(i => i.SupportedItemType).Return(typeof(A)); - unsupportedFileImporter.Stub(i => i.SupportedItemType).Return(typeof(C)); // Wrong type + var supportedFileImporter1 = new SimpleFileImporter(); + var supportedFileImporter2 = new SimpleFileImporter(); + var unsupportedFileImporter = new SimpleFileImporter(); - mocks.ReplayAll(); - var applicationCore = new ApplicationCore(); var applicationPlugin = new SimpleApplicationPlugin { - FileImporters = new[] + FileImporters = new IFileImporter[] { supportedFileImporter1, supportedFileImporter2, @@ -161,10 +158,40 @@ { // Setup var mocks = new MockRepository(); + var fileImporter = mocks.Stub(); + fileImporter.Stub(i => i.CanImportOn(Arg.Is.Anything)).Return(true); - fileImporter.Stub(i => i.SupportedItemType).Return(null); + mocks.ReplayAll(); + var applicationCore = new ApplicationCore(); + var applicationPlugin = new SimpleApplicationPlugin + { + FileImporters = new[] + { + fileImporter + } + }; + + applicationCore.AddPlugin(applicationPlugin); + + // Assert + IEnumerable supportedImporters = applicationCore.GetSupportedFileImporters(null); + + // Assert + CollectionAssert.IsEmpty(supportedImporters); + } + + [Test] + public void GetSupportedFileImporters_ImporterCannotImportToTargetObject_ReturnEmpty() + { + // Setup + var targetObject = new object(); + var mocks = new MockRepository(); + + var fileImporter = mocks.Stub(); + fileImporter.Stub(i => i.CanImportOn(targetObject)).Return(false); + mocks.ReplayAll(); var applicationCore = new ApplicationCore(); @@ -178,11 +205,44 @@ applicationCore.AddPlugin(applicationPlugin); - // Call / Assert - CollectionAssert.IsEmpty(applicationCore.GetSupportedFileImporters(null)); + // Assert + IEnumerable supportedImporters = applicationCore.GetSupportedFileImporters(targetObject); + + // Assert + CollectionAssert.IsEmpty(supportedImporters); } [Test] + public void GetSupportedFileImporters_ImporterCanImportToTargetObject_ReturnImporter() + { + // Setup + var targetObject = new object(); + var mocks = new MockRepository(); + + var fileImporter = mocks.Stub(); + fileImporter.Stub(i => i.CanImportOn(targetObject)).Return(true); + + mocks.ReplayAll(); + + var applicationCore = new ApplicationCore(); + var applicationPlugin = new SimpleApplicationPlugin + { + FileImporters = new[] + { + fileImporter + } + }; + + applicationCore.AddPlugin(applicationPlugin); + + // Assert + IEnumerable supportedImporters = applicationCore.GetSupportedFileImporters(targetObject); + + // Assert + CollectionAssert.AreEqual(new[]{fileImporter}, supportedImporters); + } + + [Test] public void GetSupportedFileExporters_SimpleApplicationPluginWithExportersAdded_ShouldOnlyProvideSupportedExporters() { // Setup @@ -354,6 +414,56 @@ } } + private class SimpleFileImporter : FileImporterBase + { + public override string Name + { + get + { + throw new NotImplementedException(); + } + } + + public override string Category + { + get + { + throw new NotImplementedException(); + } + } + + public override Bitmap Image + { + get + { + throw new NotImplementedException(); + } + } + + public override Type SupportedItemType + { + get + { + return typeof(T); + } + } + + public override string FileFilter + { + get + { + throw new NotImplementedException(); + } + } + + public override ProgressChangedDelegate ProgressChanged { protected get; set; } + + public override bool Import(object targetItem, string filePath) + { + throw new NotImplementedException(); + } + } + private class A {} private class B : A {} Index: Core/Common/test/Core.Common.Gui.Test/Commands/ExportImportCommandHandlerTest.cs =================================================================== diff -u -r791e86bf9004a55178386416eb6a9c545380bd1c -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/test/Core.Common.Gui.Test/Commands/ExportImportCommandHandlerTest.cs (.../ExportImportCommandHandlerTest.cs) (revision 791e86bf9004a55178386416eb6a9c545380bd1c) +++ Core/Common/test/Core.Common.Gui.Test/Commands/ExportImportCommandHandlerTest.cs (.../ExportImportCommandHandlerTest.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -1,5 +1,4 @@ -using System; -using System.Windows.Forms; +using System.Windows.Forms; using Core.Common.Base.IO; using Core.Common.Base.Plugin; @@ -43,8 +42,7 @@ var mocks = new MockRepository(); var dialogParent = mocks.Stub(); var objectImporter = mocks.Stub(); - objectImporter.Stub(i => i.SupportedItemType) - .Return(target.GetType()); + objectImporter.Stub(i => i.CanImportOn(target)).Return(true); var objectApplicationPluginMock = mocks.Stub(); objectApplicationPluginMock.Stub(p => p.Activate()); @@ -61,14 +59,47 @@ var commandHandler = new ExportImportCommandHandler(dialogParent, applicationCore); // Call - var isImportPossible = commandHandler.CanImportOn(new object()); + var isImportPossible = commandHandler.CanImportOn(target); // Assert Assert.IsTrue(isImportPossible); mocks.VerifyAll(); } [Test] + public void CanImportOn_HasOneFileImporterForTargetThatCannotImportOnTarget_ReturnFalse() + { + // Setup + var target = new object(); + + var mocks = new MockRepository(); + var dialogParent = mocks.Stub(); + var objectImporter = mocks.Stub(); + objectImporter.Stub(i => i.CanImportOn(target)).Return(false); + + var objectApplicationPluginMock = mocks.Stub(); + objectApplicationPluginMock.Stub(p => p.Activate()); + objectApplicationPluginMock.Expect(p => p.GetFileImporters()) + .Return(new[] + { + objectImporter + }); + mocks.ReplayAll(); + + var applicationCore = new ApplicationCore(); + applicationCore.AddPlugin(objectApplicationPluginMock); + + var commandHandler = new ExportImportCommandHandler(dialogParent, applicationCore); + + // Call + var isImportPossible = commandHandler.CanImportOn(target); + + // Assert + Assert.IsFalse(isImportPossible); + mocks.VerifyAll(); + } + + [Test] public void CanImportOn_HasMultipleFileImporterForTarget_ReturnTrue() { // Setup @@ -77,11 +108,9 @@ var mocks = new MockRepository(); var dialogParent = mocks.Stub(); var objectImporter1 = mocks.Stub(); - objectImporter1.Stub(i => i.SupportedItemType) - .Return(target.GetType()); + objectImporter1.Stub(i => i.CanImportOn(target)).Return(false); var objectImporter2 = mocks.Stub(); - objectImporter2.Stub(i => i.SupportedItemType) - .Return(target.GetType()); + objectImporter2.Stub(i => i.CanImportOn(target)).Return(true); var objectApplicationPluginMock = mocks.Stub(); objectApplicationPluginMock.Stub(p => p.Activate()); @@ -99,14 +128,50 @@ var commandHandler = new ExportImportCommandHandler(dialogParent, applicationCore); // Call - var isImportPossible = commandHandler.CanImportOn(new object()); + var isImportPossible = commandHandler.CanImportOn(target); // Assert Assert.IsTrue(isImportPossible); mocks.VerifyAll(); } [Test] + public void CanImportOn_HasMultipleFileImporterForTargetThatCannotBeUsedForImporting_ReturnFalse() + { + // Setup + var target = new object(); + + var mocks = new MockRepository(); + var dialogParent = mocks.Stub(); + var objectImporter1 = mocks.Stub(); + objectImporter1.Stub(i => i.CanImportOn(target)).Return(false); + var objectImporter2 = mocks.Stub(); + objectImporter2.Stub(i => i.CanImportOn(target)).Return(false); + + var objectApplicationPluginMock = mocks.Stub(); + objectApplicationPluginMock.Stub(p => p.Activate()); + objectApplicationPluginMock.Expect(p => p.GetFileImporters()) + .Return(new[] + { + objectImporter1, + objectImporter2 + }); + mocks.ReplayAll(); + + var applicationCore = new ApplicationCore(); + applicationCore.AddPlugin(objectApplicationPluginMock); + + var commandHandler = new ExportImportCommandHandler(dialogParent, applicationCore); + + // Call + var isImportPossible = commandHandler.CanImportOn(target); + + // Assert + Assert.IsFalse(isImportPossible); + mocks.VerifyAll(); + } + + [Test] public void CanExportFrom_HasNoFileExportersForTarget_ReturnFalse() { // Setup Index: Core/Common/test/Core.Common.Gui.Test/ContextMenu/GuiContextMenuItemFactoryTest.cs =================================================================== diff -u -ref1c61d94f2aec3b4ff32fcf03253d7ad386c8e5 -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Core/Common/test/Core.Common.Gui.Test/ContextMenu/GuiContextMenuItemFactoryTest.cs (.../GuiContextMenuItemFactoryTest.cs) (revision ef1c61d94f2aec3b4ff32fcf03253d7ad386c8e5) +++ Core/Common/test/Core.Common.Gui.Test/ContextMenu/GuiContextMenuItemFactoryTest.cs (.../GuiContextMenuItemFactoryTest.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -196,15 +196,15 @@ [Test] [TestCase(true)] [TestCase(false)] - public void CreateImportItem_Always_ItemWithPropertiesSet(bool hasImportersForNodeData) + public void CreateImportItem_Always_ItemWithPropertiesSet(bool canImportOn) { // Setup var commandHandlerMock = mocks.StrictMock(); var exportImportCommandHandlerMock = mocks.StrictMock(); var viewCommandsMock = mocks.StrictMock(); var nodeData = new object(); - exportImportCommandHandlerMock.Expect(ch => ch.CanImportOn(nodeData)).Return(hasImportersForNodeData); - if (hasImportersForNodeData) + exportImportCommandHandlerMock.Expect(ch => ch.CanImportOn(nodeData)).Return(canImportOn); + if (canImportOn) { exportImportCommandHandlerMock.Expect(ch => ch.ImportOn(nodeData)); } @@ -221,7 +221,7 @@ Assert.AreEqual(Resources.Import, item.Text); Assert.AreEqual(Resources.Import_ToolTip, item.ToolTipText); TestHelper.AssertImagesAreEqual(Resources.ImportIcon, item.Image); - Assert.AreEqual(hasImportersForNodeData, item.Enabled); + Assert.AreEqual(canImportOn, item.Enabled); mocks.VerifyAll(); } Index: Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/FailureMechanismSectionsImporter.cs =================================================================== diff -u -r8f1db6ac4fd537aba5d537744eb55e557d977cac -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/FailureMechanismSectionsImporter.cs (.../FailureMechanismSectionsImporter.cs) (revision 8f1db6ac4fd537aba5d537744eb55e557d977cac) +++ Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/FailureMechanismSectionsImporter.cs (.../FailureMechanismSectionsImporter.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -31,6 +31,7 @@ /// The snapping tolerance in meters. /// private const double snappingTolerance = 1; + /// /// The length tolerance between the reference line and the imported FailureMechanismSections in meters. /// @@ -80,6 +81,11 @@ public override ProgressChangedDelegate ProgressChanged { protected get; set; } + public override bool CanImportOn(object targetItem) + { + return base.CanImportOn(targetItem) && ReferenceLineAvailable(targetItem); + } + public override bool Import(object targetItem, string filePath) { var context = (FailureMechanismSectionsContext)targetItem; @@ -126,6 +132,11 @@ return true; } + private static bool ReferenceLineAvailable(object targetItem) + { + return ((FailureMechanismSectionsContext)targetItem).ParentAssessmentSection.ReferenceLine != null; + } + private void HandleUserCancellingImport() { log.Info(Resources.FailureMechanismSectionsImporter_Import_cancelled_no_data_read); @@ -209,7 +220,7 @@ ReferenceLine referenceLine = context.ParentAssessmentSection.ReferenceLine; IEnumerable allStartAndEndPoints = failureMechanismSections.Select(s => s.GetStart()).Concat(failureMechanismSections.Select(s => s.GetLast())); - if (allStartAndEndPoints.Any(point => GetDistanceToReferenceLine(point, referenceLine) > snappingTolerance)) + if (allStartAndEndPoints.Any(point => GetDistanceToReferenceLine(point, referenceLine) > snappingTolerance)) { return false; } Index: Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/FailureMechanismSectionsImporterTest.cs =================================================================== diff -u -r8f1db6ac4fd537aba5d537744eb55e557d977cac -r97fb97c5677e2afbd1675ba0fb3e989028a65d09 --- Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/FailureMechanismSectionsImporterTest.cs (.../FailureMechanismSectionsImporterTest.cs) (revision 8f1db6ac4fd537aba5d537744eb55e557d977cac) +++ Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/FailureMechanismSectionsImporterTest.cs (.../FailureMechanismSectionsImporterTest.cs) (revision 97fb97c5677e2afbd1675ba0fb3e989028a65d09) @@ -41,6 +41,50 @@ } [Test] + public void CanImportOn_ValidContextWithReferenceLine_ReturnTrue() + { + // Setup + var mocks = new MockRepository(); + var failureMechanism = mocks.Stub(); + var assessmentSection = mocks.Stub(); + assessmentSection.ReferenceLine = new ReferenceLine(); + mocks.ReplayAll(); + + var targetContext = new FailureMechanismSectionsContext(failureMechanism, assessmentSection); + + var importer = new FailureMechanismSectionsImporter(); + + // Call + var canImport = importer.CanImportOn(targetContext); + + // Assert + Assert.IsTrue(canImport); + mocks.VerifyAll(); + } + + [Test] + public void CanImportOn_ValidContextWithoutReferenceLine_ReturnFalse() + { + // Setup + var mocks = new MockRepository(); + var failureMechanism = mocks.Stub(); + var assessmentSection = mocks.Stub(); + assessmentSection.ReferenceLine = null; + mocks.ReplayAll(); + + var targetContext = new FailureMechanismSectionsContext(failureMechanism, assessmentSection); + + var importer = new FailureMechanismSectionsImporter(); + + // Call + var canImport = importer.CanImportOn(targetContext); + + // Assert + Assert.IsFalse(canImport); + mocks.VerifyAll(); + } + + [Test] public void Import_ValidFileCorrespondingToReferenceLineAndNoSectionImportedYet_ImportSections() { // Setup