diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 60ff0c4..8a3aaa5 100755
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -63,6 +63,7 @@
+
diff --git a/Tests/TimePointTest.cs b/Tests/TimePointTest.cs
new file mode 100755
index 0000000..cfd3091
--- /dev/null
+++ b/Tests/TimePointTest.cs
@@ -0,0 +1,66 @@
+/* TimePointTest.cs
+ * part of zaaReloaded2
+ *
+ * Copyright 2015 Daniel Kraus
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using zaaReloaded2.Models;
+
+namespace Tests
+{
+ [TestFixture]
+ class TimePointTest
+ {
+ [Test]
+ public void ParseValidTimePoint()
+ {
+ TimePoint tp = new TimePoint(
+ "[22.10.2013 12:30:00]" + Environment.NewLine +
+ "Klinische Chemie: Natrium: 139 [135 - 145] mmol/l; Kalium: 5.2 [3.5 - 5] mmol/l;");
+ Assert.IsTrue(tp.IsValidTimePoint);
+ }
+
+ [Test]
+ public void ParseInvalidTimePoints()
+ {
+ TimePoint tp = new TimePoint("Aerobe Kultur: Enterokokken ; Wachstum: 10 ;");
+ Assert.IsFalse(tp.IsValidTimePoint,
+ "Bogus paragraph should be invalid TimePoint");
+
+ tp.LaurisText = "[22.10.2013 12:30:00]";
+ Assert.IsFalse(tp.IsValidTimePoint,
+ "TimePoint should be invalid if it consists of time stamp only.");
+
+ }
+
+ [Test]
+ public void ParseTimePointWithDuplicateItems()
+ {
+ TimePoint tp = new TimePoint(
+ "[22.10.2013 12:30:00]" + Environment.NewLine +
+ "Klinische Chemie: Natrium: 139 [135 - 145] mmol/l; Kalium: 5.2 [3.5 - 5] mmol/l;" + Environment.NewLine +
+ "Klinische Chemie: Natrium: 142 [135 - 145] mmol/l; Kalium: 3.7 [3.5 - 5] mmol/l;"
+ );
+ Assert.IsTrue(tp.Items.ContainsKey("Kalium"),
+ "TimePoint should contain 'Kalium' item.");
+ Assert.AreEqual(3.7, tp.Items["Kalium"].NumericalValue,
+ "TimePoint does not use last occurrence of 'Kalium'.");
+ }
+ }
+}
diff --git a/zaaReloaded2/Dictionaries/IItemDictionary.cs b/zaaReloaded2/Dictionaries/IItemDictionary.cs
new file mode 100755
index 0000000..9d96c1e
--- /dev/null
+++ b/zaaReloaded2/Dictionaries/IItemDictionary.cs
@@ -0,0 +1,32 @@
+/* ItemDictionary.cs
+ * part of zaaReloaded2
+ *
+ * Copyright 2015 Daniel Kraus
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace zaaReloaded2.Dictionaries
+{
+ ///
+ /// A dictionary of s.
+ ///
+ public interface IItemDictionary : IDictionary
+ {
+ void Merge(IItemDictionary otherItemDictionary);
+ }
+}
diff --git a/zaaReloaded2/Dictionaries/ItemDictionary.cs b/zaaReloaded2/Dictionaries/ItemDictionary.cs
new file mode 100755
index 0000000..56d7482
--- /dev/null
+++ b/zaaReloaded2/Dictionaries/ItemDictionary.cs
@@ -0,0 +1,41 @@
+/* ItemDictionary.cs
+ * part of zaaReloaded2
+ *
+ * Copyright 2015 Daniel Kraus
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using zaaReloaded2.Models;
+
+namespace zaaReloaded2.Dictionaries
+{
+ public class ItemDictionary : SortedDictionary, IItemDictionary
+ {
+ ///
+ /// Adds all key-value pairs contained in
+ /// to this dictionary, overwriting existing values.
+ ///
+ ///
+ public void Merge(IItemDictionary otherItemDictionary)
+ {
+ foreach (KeyValuePair kvp in otherItemDictionary)
+ {
+ this[kvp.Key] = kvp.Value;
+ }
+ }
+ }
+}
diff --git a/zaaReloaded2/Models/LaurisParagraph.cs b/zaaReloaded2/Models/LaurisParagraph.cs
index 3983c0e..01937b9 100755
--- a/zaaReloaded2/Models/LaurisParagraph.cs
+++ b/zaaReloaded2/Models/LaurisParagraph.cs
@@ -21,6 +21,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using zaaReloaded2.Dictionaries;
namespace zaaReloaded2.Models
{
@@ -35,7 +36,7 @@ namespace zaaReloaded2.Models
///
/// Gets a collection of s found in this paragraph.
///
- public IDictionary Items { get; private set; }
+ public IItemDictionary Items { get; private set; }
///
/// Gets the caption that was extracted from the ,
@@ -97,7 +98,7 @@ namespace zaaReloaded2.Models
Match m = _expectedFormat.Match(OriginalParagraph);
if (m.Success)
{
- Items = new Dictionary();
+ Items = new ItemDictionary();
if (m.Groups["caption"].Success)
{
Caption = m.Groups["caption"].Value.Trim(new char[] {' ', ':'});
diff --git a/zaaReloaded2/Models/TimePoint.cs b/zaaReloaded2/Models/TimePoint.cs
new file mode 100755
index 0000000..f7f2705
--- /dev/null
+++ b/zaaReloaded2/Models/TimePoint.cs
@@ -0,0 +1,192 @@
+/* TimePoint.cs
+ * part of zaaReloaded2
+ *
+ * Copyright 2015 Daniel Kraus
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using zaaReloaded2.Dictionaries;
+
+namespace zaaReloaded2.Models
+{
+ ///
+ /// Represents all Lauris items for a given time point.
+ ///
+ public class TimePoint
+ {
+ #region Properties
+
+ ///
+ /// Gets or sets the original Lauris text for this timepoint.
+ ///
+ public string LaurisText
+ {
+ [DebuggerStepThrough]
+ get
+ {
+ return String.Join(Environment.NewLine, Paragraphs);
+ }
+ set
+ {
+ if (!String.IsNullOrEmpty(value))
+ {
+ Paragraphs = value.Split(
+ new string[] { Environment.NewLine },
+ StringSplitOptions.None);
+ ParseParagraphs();
+ }
+ }
+ }
+
+ ///
+ /// Gets an array of paragraphs in this LaurisText.
+ ///
+ public string[] Paragraphs { get; private set; }
+
+ ///
+ /// Is true if the LaurisText has time stamp in the first
+ /// paragraph and s in the others.
+ ///
+ public bool IsValidTimePoint { get; private set; }
+
+ ///
+ /// Gets the date and time information for this TimePoint.
+ /// If IsValidTimePoint is false, the value of TimeStamp
+ /// is undefined.
+ ///
+ public DateTime TimeStamp { get; private set; }
+
+ ///
+ /// Returns a sorted dictionary of all s found in
+ /// the . If a laboratory parameter occurs more
+ /// than once, only the last occurrence is saved.
+ ///
+ public IItemDictionary Items { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ public TimePoint() { }
+
+ public TimePoint(string laurisTest)
+ : this()
+ {
+ _parameterDictionary = null;
+ _unitDictionary = null;
+ LaurisText = laurisTest;
+ }
+
+ public TimePoint(
+ string laurisTest,
+ ParameterDictionary parameterDictionary,
+ UnitDictionary unitDictionary)
+ : this()
+ {
+ _parameterDictionary = parameterDictionary;
+ _unitDictionary = unitDictionary;
+ LaurisText = laurisTest;
+ }
+
+ #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()
+ {
+ Items = new ItemDictionary();
+ if (Paragraphs.Length > 0)
+ {
+ if (!ParseTimeStamp()) return false;
+ LaurisParagraph lp;
+ if (IsValidTimePoint)
+ {
+ for (int i = 1; i < Paragraphs.Length; i++)
+ {
+ lp = new LaurisParagraph(
+ Paragraphs[i],
+ _parameterDictionary,
+ _unitDictionary);
+ if (lp.IsLaurisParagraph)
+ {
+ Items.Merge(lp.Items);
+ }
+ }
+ }
+ 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()
+ {
+ if (Paragraphs.Length == 0)
+ throw new InvalidOperationException("The time point has no paragraphs.");
+
+ Match m = _dateStampRegex.Match(Paragraphs[0]);
+ bool success = false;
+ if (m.Success)
+ {
+ DateTime dt;
+ success = DateTime.TryParseExact(
+ m.Groups["datetime"].Value,
+ "dd.MM.yyyy HH:mm",
+ CultureInfo.InvariantCulture,
+ DateTimeStyles.AllowWhiteSpaces,
+ out dt);
+ TimeStamp = dt;
+ }
+ IsValidTimePoint = success;
+ return success;
+ }
+
+ void AddItems(IItemDictionary items)
+ {
+
+ }
+
+ #endregion
+
+ #region Private fields
+
+ ///
+ /// A regular expression that matches the time stamp in the first
+ /// paragraph of a LaurisText.
+ ///
+ static readonly Regex _dateStampRegex = new Regex(
+ @"^\s*\[?\s*(?\d\d\.\d\d\.\d\d\d\d\s+\d\d:\d\d)");
+ ParameterDictionary _parameterDictionary;
+ UnitDictionary _unitDictionary;
+
+ #endregion
+ }
+}
diff --git a/zaaReloaded2/zaaReloaded2.csproj b/zaaReloaded2/zaaReloaded2.csproj
index 0ec9ef0..fdd98af 100755
--- a/zaaReloaded2/zaaReloaded2.csproj
+++ b/zaaReloaded2/zaaReloaded2.csproj
@@ -161,12 +161,15 @@
-->
+
+
+
Code