Index: src/Plugins/Wti/Wti.IO/Exceptions/CriticalFileReadException.cs
===================================================================
diff -u
--- src/Plugins/Wti/Wti.IO/Exceptions/CriticalFileReadException.cs (revision 0)
+++ src/Plugins/Wti/Wti.IO/Exceptions/CriticalFileReadException.cs (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -0,0 +1,32 @@
+using System;
+
+namespace Wti.IO.Exceptions
+{
+ ///
+ /// The exception that is thrown when a file reader class encounters a critical error
+ /// during the read.
+ ///
+ public class CriticalFileReadException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CriticalFileReadException(){}
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message.
+ ///
+ /// The error message that explains the reason for the exception.
+ public CriticalFileReadException(string message) : base(message){}
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message and a reference to the inner exception that is
+ /// the cause of this exception.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.
+ public CriticalFileReadException(string message, Exception inner) : base(message, inner) { }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -4,6 +4,7 @@
using System.Linq;
using Wti.Data;
+using Wti.IO.Exceptions;
using Wti.IO.Properties;
namespace Wti.IO
@@ -18,7 +19,11 @@
///
public class PipingSurfaceLinesCsvReader : IDisposable
{
- private readonly string[] acceptableIdNames = { "Profielnaam, LocationID" };
+ private readonly string[] acceptableIdNames =
+ {
+ "Profielnaam, LocationID"
+ };
+
private readonly string filePath;
private StreamReader fileReader;
@@ -31,70 +36,76 @@
public PipingSurfaceLinesCsvReader(string path)
{
CheckIfPathIsValid(path);
-
+
filePath = path;
}
- private void CheckIfPathIsValid(string path)
- {
- if (string.IsNullOrWhiteSpace(path))
- {
- throw new ArgumentException(Resources.Error_PathMustBeSpecified);
- }
-
- string name;
- try
- {
- name = Path.GetFileName(path);
- }
- catch (ArgumentException e)
- {
- throw new ArgumentException(String.Format(Resources.Error_PathCannotContainCharacters_0_,
- String.Join(", ", Path.GetInvalidFileNameChars())), e);
- }
- if (string.Empty == name)
- {
- throw new ArgumentException(Resources.Error_PathMustNotPointToFolder);
- }
- }
-
- public void Dispose()
- {
- if (fileReader != null)
- {
- fileReader.Dispose();
- fileReader = null;
- }
- }
-
///
/// Reads the file to determine the number of available
/// data rows.
///
/// A value greater than or equal to 0.
- /// The file cannot be found.
- /// The specified path is invalid, such as being on an unmapped drive.
- /// Filepath includes an incorrect or invalid syntax for file name, directory name, or volume label.
- /// There is insufficient memory to allocate a buffer for the returned string.
+ /// A critical error has occurred, which may be caused by:
+ ///
+ /// - File cannot be found at specified path.
+ /// - The specified path is invalid, such as being on an unmapped drive.
+ /// - Some other I/O related issue occurred, such as: path includes an incorrect
+ /// or invalid syntax for file name, directory name, or volume label.
+ /// - There is insufficient memory to allocate a buffer for the returned string.
+ ///
+ ///
/// The file in not properly formatted.
public int GetSurfaceLinesCount()
{
- var count = 0;
- using (var reader = new StreamReader(filePath))
+ int count = 0, lineNumber = 0;
+ StreamReader reader = null;
+ try
{
+ reader = new StreamReader(filePath);
+
// Skip header:
+ // TODO: Make sure header is valid
reader.ReadLine();
+ lineNumber++;
// Count SurfaceLines:
string line;
while ((line = reader.ReadLine()) != null)
{
+ lineNumber++;
if (!String.IsNullOrWhiteSpace(line))
{
count++;
}
}
}
+ catch (FileNotFoundException e)
+ {
+ var message = string.Format(Resources.Error_File_0_does_not_exist, filePath);
+ throw new CriticalFileReadException(message, e);
+ }
+ catch (DirectoryNotFoundException e)
+ {
+ var message = string.Format(Resources.Error_Directory_in_path_0_missing, filePath);
+ throw new CriticalFileReadException(message, e);
+ }
+ catch (OutOfMemoryException e)
+ {
+ var message = string.Format(Resources.Error_File_0_contains_Line_1_too_big, filePath, lineNumber);
+ throw new CriticalFileReadException(message, e);
+ }
+ catch (IOException e)
+ {
+ var message = string.Format(Resources.Error_General_IO_File_0_ErrorMessage_1_, filePath, e.Message);
+ throw new CriticalFileReadException(message, e);
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.Dispose();
+ }
+ }
return count;
}
@@ -124,15 +135,15 @@
var worldCoordinateValues = tokenizedString.Skip(1)
.Select(ts => Double.Parse(ts, CultureInfo.InvariantCulture))
.ToArray();
- int coordinateCount = worldCoordinateValues.Length/3;
+ int coordinateCount = worldCoordinateValues.Length / 3;
var points = new Point3D[coordinateCount];
for (int i = 0; i < coordinateCount; i++)
{
points[i] = new Point3D
{
- X = worldCoordinateValues[i*3],
- Y = worldCoordinateValues[i*3+1],
- Z = worldCoordinateValues[i*3+2]
+ X = worldCoordinateValues[i * 3],
+ Y = worldCoordinateValues[i * 3 + 1],
+ Z = worldCoordinateValues[i * 3 + 2]
};
}
@@ -146,5 +157,37 @@
return null;
}
+
+ public void Dispose()
+ {
+ if (fileReader != null)
+ {
+ fileReader.Dispose();
+ fileReader = null;
+ }
+ }
+
+ private void CheckIfPathIsValid(string path)
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentException(Resources.Error_PathMustBeSpecified);
+ }
+
+ string name;
+ try
+ {
+ name = Path.GetFileName(path);
+ }
+ catch (ArgumentException e)
+ {
+ throw new ArgumentException(String.Format(Resources.Error_PathCannotContainCharacters_0_,
+ String.Join(", ", Path.GetInvalidFileNameChars())), e);
+ }
+ if (string.Empty == name)
+ {
+ throw new ArgumentException(Resources.Error_PathMustNotPointToFolder);
+ }
+ }
}
}
\ No newline at end of file
Index: src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -61,6 +61,42 @@
}
///
+ /// Looks up a localized string similar to Het bestandspad '{0}' verwijst naar een map die niet bestaat..
+ ///
+ public static string Error_Directory_in_path_0_missing {
+ get {
+ return ResourceManager.GetString("Error_Directory_in_path_0_missing", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden..
+ ///
+ public static string Error_File_0_contains_Line_1_too_big {
+ get {
+ return ResourceManager.GetString("Error_File_0_contains_Line_1_too_big", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' bestaat niet..
+ ///
+ public static string Error_File_0_does_not_exist {
+ get {
+ return ResourceManager.GetString("Error_File_0_does_not_exist", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Er is een onverwachte inleesfout opgetreden tijdens het lezen van het bestand '{0}': {1}.
+ ///
+ public static string Error_General_IO_File_0_ErrorMessage_1_ {
+ get {
+ return ResourceManager.GetString("Error_General_IO_File_0_ErrorMessage_1_", resourceCulture);
+ }
+ }
+
+ ///
/// Looks up a localized string similar to Bestandspad mag niet de volgende tekens bevatten: {0}.
///
public static string Error_PathCannotContainCharacters_0_ {
@@ -86,5 +122,14 @@
return ResourceManager.GetString("Error_PathMustNotPointToFolder", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden..
+ ///
+ public static string Error_Unexpected_IOError_File_0_Line_1_ {
+ get {
+ return ResourceManager.GetString("Error_Unexpected_IOError_File_0_Line_1_", resourceCulture);
+ }
+ }
}
}
Index: src/Plugins/Wti/Wti.IO/Properties/Resources.resx
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- src/Plugins/Wti/Wti.IO/Properties/Resources.resx (.../Resources.resx) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ src/Plugins/Wti/Wti.IO/Properties/Resources.resx (.../Resources.resx) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -126,4 +126,19 @@
Bestandspad mag niet de volgende tekens bevatten: {0}
+
+ Het bestand op '{0}' bestaat niet.
+
+
+ Het bestandspad '{0}' verwijst naar een map die niet bestaat.
+
+
+ Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden.
+
+
+ Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden.
+
+
+ Er is een onverwachte inleesfout opgetreden tijdens het lezen van het bestand '{0}': {1}
+
\ No newline at end of file
Index: src/Plugins/Wti/Wti.IO/Wti.IO.csproj
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- src/Plugins/Wti/Wti.IO/Wti.IO.csproj (.../Wti.IO.csproj) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ src/Plugins/Wti/Wti.IO/Wti.IO.csproj (.../Wti.IO.csproj) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -50,6 +50,7 @@
Properties\GlobalAssembly.cs
+
Index: src/Plugins/Wti/Wti.Plugin/FileImporter/PipingSurfaceLinesCsvImporter.cs
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- src/Plugins/Wti/Wti.Plugin/FileImporter/PipingSurfaceLinesCsvImporter.cs (.../PipingSurfaceLinesCsvImporter.cs) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ src/Plugins/Wti/Wti.Plugin/FileImporter/PipingSurfaceLinesCsvImporter.cs (.../PipingSurfaceLinesCsvImporter.cs) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -9,6 +9,7 @@
using Wti.Data;
using Wti.IO;
+using Wti.IO.Exceptions;
using WtiFormsResources = Wti.Forms.Properties.Resources;
using ApplicationResources = Wti.Plugin.Properties.Resources;
@@ -137,9 +138,20 @@
var stepName = String.Format(ApplicationResources.PipingSurfaceLinesCsvImporter_ReadPipingSurfaceLines_0_,
Path.GetFileName(path));
- var itemCount = reader.GetSurfaceLinesCount();
- NotifyProgress(stepName, 0, itemCount);
+ int itemCount;
+ try
+ {
+ itemCount = reader.GetSurfaceLinesCount();
+ NotifyProgress(stepName, 0, itemCount);
+ }
+ catch (CriticalFileReadException e)
+ {
+ var message = string.Format(ApplicationResources.PipingSurfaceLinesCsvImporter_CriticalErrorReading_0_Cause_1_,
+ path, e.Message);
+ log.Error(message, e);
+ return new SurfaceLinesFileReadResult(true);
+ }
var readSurfaceLines = new List(itemCount);
for (int i = 0; i < itemCount && !ShouldCancel; i++)
Index: test/Plugins/Wti/Wti.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs
===================================================================
diff -u
--- test/Plugins/Wti/Wti.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs (revision 0)
+++ test/Plugins/Wti/Wti.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -0,0 +1,72 @@
+using System;
+
+using NUnit.Framework;
+
+using Wti.IO.Exceptions;
+
+namespace Wti.IO.Test.Exceptions
+{
+ [TestFixture]
+ public class CriticalFileReadExceptionTest
+ {
+ [Test]
+ [SetCulture("en-US")]
+ public void DefaultConstructor_ExpectedValues()
+ {
+ // Call
+ var exception = new CriticalFileReadException();
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ var expectedMessage = string.Format("Exception of type '{0}' was thrown.", exception.GetType());
+ Assert.AreEqual(expectedMessage, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.IsNull(exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+
+ [Test]
+ public void MessageConstructor_ExpectedValues()
+ {
+ // Setup
+ const string messageText = "";
+
+ // Call
+ var exception = new CriticalFileReadException(messageText);
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ Assert.AreEqual(messageText, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.IsNull(exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+
+ [Test]
+ public void MessageAndInnerExceptionConstructor_ExpectedValues()
+ {
+ // Setup
+ var innerException = new Exception();
+ const string messageText = "";
+
+ // Call
+ var exception = new CriticalFileReadException(messageText, innerException);
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ Assert.AreEqual(messageText, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.AreEqual(innerException, exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+ }
+}
\ No newline at end of file
Index: test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs (.../PipingSurfaceLinesCsvReaderTest.cs) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs (.../PipingSurfaceLinesCsvReaderTest.cs) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -5,6 +5,9 @@
using DelftTools.TestUtils;
using NUnit.Framework;
+
+using Wti.IO.Exceptions;
+
using IOResources = Wti.IO.Properties.Resources;
namespace Wti.IO.Test
@@ -144,6 +147,50 @@
}
}
+ [Test]
+ public void GetSurfaceLinesCount_FileCannotBeFound_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "I_do_not_exist.csv");
+
+ // Precondition
+ Assert.IsFalse(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_does_not_exist, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_DirectoryCannotBeFound_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "..", "this_folder_does_not_exist", "I_do_not_exist.csv");
+
+ // Precondition
+ Assert.IsFalse(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_Directory_in_path_0_missing, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
private void DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine()
{
// Setup
Index: test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj
===================================================================
diff -u -re5c186677d0ef8697eb04ea571b7c4ef8268183c -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj (.../Wti.IO.Test.csproj) (revision e5c186677d0ef8697eb04ea571b7c4ef8268183c)
+++ test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj (.../Wti.IO.Test.csproj) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -40,6 +40,7 @@
+
Index: test/Plugins/Wti/Wti.Plugin.Test/FileImporter/PipingSurfaceLineCsvImporterTest.cs
===================================================================
diff -u -r8fe3ae6f129251f98795abd491315924ca707a76 -rf2284364cde43ab7969dd8f0fb038f846138ec41
--- test/Plugins/Wti/Wti.Plugin.Test/FileImporter/PipingSurfaceLineCsvImporterTest.cs (.../PipingSurfaceLineCsvImporterTest.cs) (revision 8fe3ae6f129251f98795abd491315924ca707a76)
+++ test/Plugins/Wti/Wti.Plugin.Test/FileImporter/PipingSurfaceLineCsvImporterTest.cs (.../PipingSurfaceLineCsvImporterTest.cs) (revision f2284364cde43ab7969dd8f0fb038f846138ec41)
@@ -215,5 +215,37 @@
"No items should be added to collection when import is aborted.");
mocks.VerifyAll(); // Expect no calls on 'observer'
}
+
+ [Test]
+ public void ImportItem_FileDoesNotExist_AbortImportAndLog()
+ {
+ // Setup
+ string corruptPath = Path.Combine(testDataPath, "I_dont_exists.csv");
+
+ var mocks = new MockRepository();
+ var observer = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ var importer = new PipingSurfaceLinesCsvImporter();
+
+ var observableSurfaceLinesList = new ObservableList();
+ observableSurfaceLinesList.Attach(observer);
+
+ object importedItem = null;
+
+ // Call
+ Action call = () => importedItem = importer.ImportItem(corruptPath, observableSurfaceLinesList);
+
+ // Assert
+ var internalErrorMessage = String.Format(WtiIOResources.Error_File_0_does_not_exist,
+ corruptPath);
+ var expectedLogMessage = string.Format(ApplicationResources.PipingSurfaceLinesCsvImporter_CriticalErrorReading_0_Cause_1_,
+ corruptPath, internalErrorMessage);
+ TestHelper.AssertLogMessageIsGenerated(call, expectedLogMessage, 1);
+ Assert.AreSame(observableSurfaceLinesList, importedItem);
+ CollectionAssert.IsEmpty(observableSurfaceLinesList,
+ "No items should be added to collection when import is aborted.");
+ mocks.VerifyAll(); // Expect no calls on 'observer'
+ }
}
}
\ No newline at end of file