Index: Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresCharacteristicsCsvReader.cs
===================================================================
diff -u -r653c18f73b4404d9ac58d818845474d68e48635d -r50d02243937ff6a19020bf095c778252c1c47561
--- Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresCharacteristicsCsvReader.cs (.../StructuresCharacteristicsCsvReader.cs) (revision 653c18f73b4404d9ac58d818845474d68e48635d)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresCharacteristicsCsvReader.cs (.../StructuresCharacteristicsCsvReader.cs) (revision 50d02243937ff6a19020bf095c778252c1c47561)
@@ -26,6 +26,7 @@
using Core.Common.IO.Readers;
using Core.Common.Utils;
using Core.Common.Utils.Builders;
+using Ringtoets.Common.IO.Properties;
using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources;
namespace Ringtoets.Common.IO.Structures
@@ -43,7 +44,7 @@
{
"identificatie",
"kunstwerken.identificatie",
- "numeriekeWaarde",
+ "numeriekewaarde",
"standarddeviatie.variance",
"boolean"
};
@@ -70,13 +71,14 @@
/// Counts the number of parameter definitions found in the file.
///
/// An integer greater than or equal to 0, being the number of parameter rows.
- /// File/directory cannot be found or
+ /// File/directory cannot be found or
/// some other I/O related problem occurred or the header is not in the required format.
public int GetLineCount()
{
using (var reader = StreamReaderHelper.InitializeStreamReader(filePath))
{
- ValidateHeader(reader, 1);
+ lineNumber = 1;
+ ValidateHeader(reader);
return CountNonEmptyLines(reader, 2);
}
@@ -87,15 +89,15 @@
///
/// The next based on the read file,
/// or null when at the end of the file.
- ///
+ ///
/// Thrown when either:
///
/// - The file or directory cannot be found.
/// - The file is empty.
/// - Some I/O related problem occurred.
/// - The header is not in the required format.
///
- /// Thrown when either:
+ /// Thrown when either:
///
/// - The line does not contain the separator character.
/// - Location id field is empty or consists out of only white spaces.
@@ -144,14 +146,13 @@
/// Validates the header of the file.
///
/// The reader, which is currently at the header row.
- /// Row index used in error messaging.
- /// The header is not in the required format.
- private void ValidateHeader(TextReader reader, int currentLine)
+ /// The header is not in the required format.
+ private void ValidateHeader(TextReader reader)
{
string[] tokenizedHeader = GetTokenizedHeader(reader);
const int uninitializedValue = -999;
int[] requiredHeaderColumnIndices = GetRequiredHeaderColumnIndices(uninitializedValue, tokenizedHeader);
- ValidateRequiredColumnIndices(currentLine, requiredHeaderColumnIndices, uninitializedValue);
+ ValidateRequiredColumnIndices(requiredHeaderColumnIndices, uninitializedValue);
}
///
@@ -160,7 +161,7 @@
/// The reader at the row from which counting should start.
/// The current line, used for error messaging.
/// An integer greater than or equal to 0, being the number of parameter rows.
- /// An I/O exception occurred.
+ /// An I/O exception occurred.
private int CountNonEmptyLines(TextReader reader, int currentLine)
{
int count = 0, lineNumberForMessage = currentLine;
@@ -182,7 +183,7 @@
/// The opened text file reader.
/// Row number for error messaging.
/// The read line, or null when at the end of the file.
- /// An critical I/O exception occurred.
+ /// An critical I/O exception occurred.
private string ReadLineAndHandleIOExceptions(TextReader reader, int currentLine)
{
try
@@ -195,7 +196,7 @@
}
catch (IOException e)
{
- string errorMessage = string.Format((string)CoreCommonUtilsResources.Error_General_IO_ErrorMessage_0_,
+ string errorMessage = string.Format((string) CoreCommonUtilsResources.Error_General_IO_ErrorMessage_0_,
e.Message);
var fullErrorMessage = new FileReaderErrorMessageBuilder(filePath).Build(errorMessage);
throw new CriticalFileReadException(fullErrorMessage, e);
@@ -206,15 +207,15 @@
/// Reads the header and sets the internal indices of the required header columns.
///
/// The reader used to read the file.
- /// The file is empty or some I/O exception
+ /// The file is empty or some I/O exception
/// occurred or the header is not in the required format.
private void IndexFile(TextReader reader)
{
string[] tokenizedHeader = GetTokenizedHeader(reader);
const int uninitializedValue = -999;
int[] requiredHeaderColumnIndices = GetRequiredHeaderColumnIndices(uninitializedValue, tokenizedHeader);
- ValidateRequiredColumnIndices(lineNumber, requiredHeaderColumnIndices, uninitializedValue);
+ ValidateRequiredColumnIndices(requiredHeaderColumnIndices, uninitializedValue);
SetColumnIndices(requiredHeaderColumnIndices);
}
@@ -224,7 +225,7 @@
///
/// The reader used to read the file.
/// The header split based on .
- /// The file is empty or some I/O exception
+ /// The file is empty or some I/O exception
/// occurred.
private string[] GetTokenizedHeader(TextReader reader)
{
@@ -249,26 +250,33 @@
int index = Array.IndexOf(requiredHeaderColumns, columnName);
if (index != -1)
{
- // TODO: same column multiple times!
- requiredHeaderColumnIndices[index] = columnIndex;
+ if (requiredHeaderColumnIndices[index] == initialColumnIndexValue)
+ {
+ requiredHeaderColumnIndices[index] = columnIndex;
+ }
+ else
+ {
+ string message = string.Format(Resources.StructuresCharacteristicsCsvReader_Column_0_must_be_defined_only_once, columnName);
+ throw CreateCriticalFileReadException(lineNumber, message);
+ }
}
}
return requiredHeaderColumnIndices;
}
///
- ///
+ /// Checks if all required header columns have been matched.
///
- ///
- ///
- ///
- /// The header is not in the required format.
- private void ValidateRequiredColumnIndices(int currentLine, int[] requiredHeaderColumnIndices, int uninitializedValue)
+ /// The array of matched column indices.
+ /// The initial index value put in .
+ /// The header is not in the required format.
+ private void ValidateRequiredColumnIndices(int[] requiredHeaderColumnIndices, int uninitializedValue)
{
if (requiredHeaderColumnIndices.Any(i => i == uninitializedValue))
{
- throw CreateCriticalFileReadException(currentLine, string.Format("Het bestand is niet geschikt om kunstwerken parameters uit te lezen (Verwachte koptekst moet de volgende kolommen bevatten: {0}.",
- string.Join(", ", requiredHeaderColumns)));
+ string message = string.Format(Resources.StructuresCharacteristicsCsvReader_ValidateRequiredColumnIndices_Invalid_header_Must_have_columns_0_,
+ string.Join(", ", requiredHeaderColumns));
+ throw CreateCriticalFileReadException(lineNumber, message);
}
}
@@ -286,7 +294,7 @@
///
/// The next line which is not a white line, or null when no non-white
/// line could be found before the end of file.
- /// An critical I/O exception occurred.
+ /// An critical I/O exception occurred.
private string ReadNextNonEmptyLine(StreamReader reader)
{
string readText;
@@ -309,7 +317,7 @@
///
/// The read text.
///
- /// Thrown when either:
+ /// Thrown when either:
///
/// - does not contain the separator character.
/// - Location id field is empty or consists out of only white spaces.
@@ -345,7 +353,7 @@
///
/// The text.
/// The tokenized parts.
- /// lacks separator character.
+ /// lacks separator character.
private string[] TokenizeString(string readText)
{
if (!readText.Contains(separator))
@@ -363,7 +371,7 @@
///
/// The tokenized text.
/// The location ID.
- /// Location ID field is empty or only has whitespaces.
+ /// Location ID field is empty or only has whitespaces.
private string ParseLocationId(string[] tokenizedText)
{
string locationId = tokenizedText[locationIdIndex];
@@ -380,7 +388,7 @@
/// The tokenized text.
///
/// The parameter ID.
- /// Parameter ID field is empty or only has whitespaces.
+ /// Parameter ID field is empty or only has whitespaces.
private string ParseParameterId(string[] tokenizedText)
{
string parameterId = tokenizedText[parameterIdIndex];
@@ -396,7 +404,7 @@
///
/// The tokenized text.
/// The numeric value (can be ).
- /// When the numeric value field is not a number
+ /// When the numeric value field is not a number
/// or when it's too large or too small to be represented as .
private double ParseNumericValue(string[] tokenizedText)
{
@@ -409,7 +417,7 @@
///
/// The tokenized text.
/// The standard deviation or coefficient of variation value (can be ).
- /// When the standard deviation or coefficient
+ /// When the standard deviation or coefficient
/// of variation value field is not a number or when it's too large or too small
/// to be represented as .
private double ParseVarianceValue(string[] tokenizedText)
@@ -425,7 +433,7 @@
/// Name of the parameter.
/// when is null
/// or only whitespaces; otherwise the parsed number.
- /// When is
+ /// When is
/// not a number or when it's too large or too small to be represented as .
private double ParseDoubleValue(string doubleValueText, string parameterName)
{
@@ -454,7 +462,7 @@
///
/// The tokenized text.
/// The based on the text in the file.
- /// When the 'boolean' field is not a valid value.
+ /// When the 'boolean' field is not a valid value.
private VarianceType ParseVarianceType(string[] tokenizedText)
{
string varianceTypeText = tokenizedText[varianceTypeIndex];
@@ -486,12 +494,12 @@
}
///
- /// Throws a configured instance of .
+ /// Throws a configured instance of .
///
/// The line number being read.
/// The critical error message.
/// Optional: exception that caused this exception to be thrown.
- /// New with message set.
+ /// New with message set.
private LineParseException CreateLineParseException(int currentLine, string lineParseErrorMessage, Exception innerException = null)
{
string locationDescription = string.Format(CoreCommonUtilsResources.TextFile_On_LineNumber_0_, currentLine);
@@ -501,12 +509,12 @@
}
///
- /// Throws a configured instance of .
+ /// Throws a configured instance of .
///
/// The line number being read.
/// The critical error message.
/// Optional: exception that caused this exception to be thrown.
- /// New with message and inner exception set.
+ /// New with message and inner exception set.
private CriticalFileReadException CreateCriticalFileReadException(int currentLine, string criticalErrorMessage, Exception innerException = null)
{
string locationDescription = string.Format(CoreCommonUtilsResources.TextFile_On_LineNumber_0_,