diff --git a/Tests/Importer/ZaaImporter/ZaaImporterTest.cs b/Tests/Importer/ZaaImporter/ZaaImporterTest.cs index 44b8e23..58433cc 100755 --- a/Tests/Importer/ZaaImporter/ZaaImporterTest.cs +++ b/Tests/Importer/ZaaImporter/ZaaImporterTest.cs @@ -41,5 +41,15 @@ namespace Tests.Importer.ZaaImporter // Only 6 distinct time points (see method documentation above). Assert.AreEqual(6, importer.Laboratory.TimePoints.Count); } + + [Test] + public void ParseInvalidInput() + { + zaa.ZaaImporter importer = new zaa.ZaaImporter(); + importer.Import("some arbitrary text\r\nthat does not represent\r\na valid lab"); + Assert.IsFalse(importer.Success); + importer.Import("(03.03.1930 13:30:00)\r\nKlinische Chemie: Natrium 135 [135 - 145] mmol/l;"); + Assert.IsTrue(importer.Success); + } } } diff --git a/zaaReloaded2/Importer/IImporter.cs b/zaaReloaded2/Importer/IImporter.cs index 7da8fe3..d556d05 100755 --- a/zaaReloaded2/Importer/IImporter.cs +++ b/zaaReloaded2/Importer/IImporter.cs @@ -30,6 +30,11 @@ namespace zaaReloaded2.Importer /// Laboratory Laboratory { get; set; } + /// + /// Indicates whether the import was successful. + /// + bool Success { get; } + /// /// Imports laboratory data contained in a string. /// diff --git a/zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs b/zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs index c230a32..c81fb5d 100755 --- a/zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs +++ b/zaaReloaded2/Importer/ZaaImporter/LaurisParagraph.cs @@ -32,6 +32,19 @@ namespace zaaReloaded2.Importer.ZaaImporter /// public class LaurisParagraph { + #region Static methods + + /// + /// Investigates a paragraph and determines whether it looks + /// like a Lauris laboratory items paragraph. + /// + public static bool ResemblesLaurisParagraph(string paragraph) + { + return _expectedFormat.IsMatch(paragraph); + } + + #endregion + #region Public properties /// @@ -122,7 +135,7 @@ namespace zaaReloaded2.Importer.ZaaImporter #region Fields - static readonly Regex _expectedFormat = new Regex(@"(?[^:]+:\s*)?(?[^:]+:\s*[^;]+;)*"); + static readonly Regex _expectedFormat = new Regex(@"(?[^:]+:\s*)?(?[^:]+:\s*[^;]+;)+"); Thesaurus.Parameters _parameterDictionary; Thesaurus.Units _unitDictionary; diff --git a/zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs b/zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs index dd6abfa..080527c 100755 --- a/zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs +++ b/zaaReloaded2/Importer/ZaaImporter/LaurisTimePoint.cs @@ -65,11 +65,15 @@ namespace zaaReloaded2.Importer.ZaaImporter /// /// Gets an array of paragraphs in this LaurisText. /// - public string[] Paragraphs + public IList Paragraphs { [DebuggerStepThrough] get { + if (_paragraphs == null) + { + _paragraphs = new List(); + } return _paragraphs; } set @@ -101,7 +105,7 @@ namespace zaaReloaded2.Importer.ZaaImporter { Paragraphs = value.Split( new string[] { Environment.NewLine }, - StringSplitOptions.None); + StringSplitOptions.None).ToList(); } } } @@ -128,7 +132,7 @@ namespace zaaReloaded2.Importer.ZaaImporter { } public LaurisTimePoint( - string[] paragraphs, + IList paragraphs, Parameters parameterDictionary, Units unitDictionary) : this() @@ -138,72 +142,71 @@ namespace zaaReloaded2.Importer.ZaaImporter Paragraphs = paragraphs; } - public LaurisTimePoint(string[] paragraphs) + public LaurisTimePoint(IList paragraphs) : this(paragraphs, null, null) { } #endregion + #region Public methods + + /// + /// Adds a new paragraph to this time point by parsing + /// the paragraph for laboratory items. + /// + /// Paragraph to add. + public void AddParagraph(string paragraph) + { + Paragraphs.Add(paragraph); + ParseParagraph(paragraph); + } + + #endregion + #region Private methods /// /// Analyzes each Lauris paragraph in this time point, sets the date /// and time, and collects LabItem data. /// - /// True if the LaurisText has time stamp in the first paragraphs - /// and contains s in the others. - bool ParseParagraphs() + void ParseParagraphs() { - if (Paragraphs.Length > 0) + if (Paragraphs != null) { - if (!ParseTimeStamp()) return false; - LaurisParagraph lp; - if (IsValidTimePoint) + foreach (string paragraph in Paragraphs) { - for (int i = 1; i < Paragraphs.Length; i++) - { - lp = new LaurisParagraph( - Paragraphs[i], - _parameterDictionary, - _unitDictionary); - if (lp.IsLaurisParagraph) - { - Items.Merge(lp.Items); - } - } + ParseParagraph(paragraph); } - IsValidTimePoint = Items.Count > 0; } - return true; } - /// - /// Analyzes the date and time information that is expected to be - /// in the first paragraph. - /// - /// True if the LaurisText contains a time stamp in the - /// first paragraph. - bool ParseTimeStamp() + void ParseParagraph(string paragraph) { - if (Paragraphs.Length == 0) - throw new InvalidOperationException("The time point has no paragraphs."); - - Match m = _timeStampRegex.Match(Paragraphs[0]); - bool success = false; - if (m.Success) + if (_timeStampRegex.IsMatch(paragraph)) { DateTime dt; - success = DateTime.TryParseExact( - m.Groups["datetime"].Value, + if (DateTime.TryParseExact( + _timeStampRegex.Match(paragraph).Groups["datetime"].Value, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, - out dt); - TimeStamp = dt; + out dt)) + { + TimeStamp = dt; + } + } + else + { + LaurisParagraph lp = new LaurisParagraph( + paragraph, + _parameterDictionary, + _unitDictionary); + if (lp.IsLaurisParagraph) + { + Items.Merge(lp.Items); + } } - IsValidTimePoint = success; - return success; } void AddItems(IItemDictionary items) @@ -221,7 +224,7 @@ namespace zaaReloaded2.Importer.ZaaImporter /// static readonly Regex _timeStampRegex = new Regex( @"^\s*\(?\s*(?\d\d\.\d\d\.\d\d\d\d\s+\d\d:\d\d)"); - string[] _paragraphs; + IList _paragraphs; Parameters _parameterDictionary; Units _unitDictionary; diff --git a/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs b/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs index f2cd2e3..9583d7b 100755 --- a/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs +++ b/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs @@ -52,6 +52,14 @@ namespace zaaReloaded2.Importer.ZaaImporter } } + public bool Success + { + get + { + return Laboratory.TimePoints.Count > 0; + } + } + /// /// Splits the into individual time points /// and creates objects from them. @@ -62,42 +70,29 @@ namespace zaaReloaded2.Importer.ZaaImporter string[] paragraphs = text.Split( new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); - int i = 0; - int start = 0; - int numParagraphs = paragraphs.Length; + LaurisTimePoint timePoint = null; - while (i < numParagraphs) + foreach (string paragraph in paragraphs) { - // Search for the next occurrence of a time stamp line - while (i < numParagraphs - && !LaurisTimePoint.IsTimeStampLine(paragraphs[i])) + // If the current paragraph looks like a Lauris time stamp, + // create a new time point. + if (LaurisTimePoint.IsTimeStampLine(paragraph)) { - i++; + timePoint = new LaurisTimePoint(paragraph); + Laboratory.AddTimePoint(timePoint); } - - // TODO: Find an alternative to returning in the middle of the method. - if (i >= numParagraphs) return; - - if (LaurisTimePoint.IsTimeStampLine(paragraphs[i])) + // If the current paragraph looks like a paragraph with + // laboratory items, add it to the current time point; + // if no time point exists yet, create one. + else if (LaurisParagraph.ResemblesLaurisParagraph(paragraph)) { - // Remember the time stamp line's index - start = i; - - // Seek the next time stamp line - while (i + 1 < numParagraphs - && !LaurisTimePoint.IsTimeStampLine(paragraphs[i + 1])) + if (timePoint == null) { - i++; + timePoint = new LaurisTimePoint(); + Laboratory.AddTimePoint(timePoint); } + timePoint.AddParagraph(paragraph); } - - Laboratory.AddTimePoint( - new LaurisTimePoint( - paragraphs.Slice(start, i - start + 1), - _parameters, - _units - ) - ); } }