/// <summary> /// The constructor for creating a new <see cref="ResourceObject"/> /// </summary> /// <param name="emk">The filtered entry. Can be null!</param> /// <param name="resource">The original entry. Can't be null!</param> public ResourceObject(EmkResource emk, OperationResource resource) { Assertions.AssertNotNull(resource, "resource"); Emk = emk; Resource = resource; }
/// <summary> /// Initializes a new instance of the <see cref="OperationResourceData"/> class, /// and copies the contents of the given <see cref="OperationResource"/> to this entity. /// </summary> /// <param name="operationResource">The resource to copy its contents.</param> public OperationResourceData(OperationResource operationResource) : this() { this.FullName = operationResource.FullName; this.Timestamp = operationResource.Timestamp; this.EquipmentCsv = CsvHelper.ToCsvLine(operationResource.RequestedEquipment); }
public void ContainsMatch_WithInactiveOnes_Negative_Test() { EmkResourceCollection collection = new EmkResourceCollection(); collection.Add(new EmkResource() { SiteAlias = "ABC", ResourceAlias = "77/7" }); collection.Add(new EmkResource() { SiteAlias = "ABC", ResourceAlias = "88/8", IsActive = false }); collection.Add(new EmkResource() { SiteAlias = "ABC", ResourceAlias = "99/9" }); OperationResource opRes = new OperationResource() { FullName = "1.2.3 ABC 88/8 LF", }; Assert.IsFalse(collection.ContainsMatch(opRes)); }
public void ContainsMatch_Positive_Test() { EmkResourceCollection collection = new EmkResourceCollection(); collection.Add(new EmkResource() { SiteAlias = "ABC", ResourceAlias = "77/7" }); collection.Add(new EmkResource() { SiteAlias = "ABC", ResourceAlias = "88/8" }); collection.Add(new EmkResource() { SiteAlias = "ABC", ResourceAlias = "99/9" }); OperationResource opRes = new OperationResource() { FullName = "1.2.3 ABC 88/8 LF", }; Assert.IsTrue(collection.ContainsMatch(opRes)); }
internal ResourceViewModel(OperationResource resource, EmkResource emkResource) : base() { if (resource == null && emkResource == null) { throw new InvalidOperationException(Properties.Resources.NoResourceGiven); } this.Resource = resource; EmkResourceItem = emkResource; if (EmkResourceItem != null) { LoadIconAsync(); } }
public void IsMatch_Negative_Test() { EmkResource emk = new EmkResource() { SiteAlias = "ABC", ResourceAlias = "99/9", DisplayName = "99.9", }; OperationResource opRes = new OperationResource() { FullName = "1.2.3 XYZ 99/9 HLF", }; Assert.IsFalse(emk.IsMatch(opRes)); }
Operation IFaxParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; bool keywordsOnly = true; for (int i = 0; i < lines.Length; i++) { try { string line = lines[i]; if (line.Length == 0) { continue; } // Try to parse the header and extract date and time if possible operation.Timestamp = ReadFaxTimestamp(line, operation.Timestamp); if (GetSection(line.Trim(), ref section, out keywordsOnly)) { continue; } string msg = line; string prefix = ""; // Make the keyword check - or not (depends on the section we are in; see above) if (keywordsOnly) { string keyword; if (!StartsWithKeyword(line, out keyword)) { continue; } int x = line.IndexOf(':'); if (x == -1) { // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning prefix = keyword; msg = line.Remove(0, prefix.Length).Trim(); } else { prefix = line.Substring(0, x); msg = line.Substring(x + 1).Trim(); } prefix = prefix.Trim().ToUpperInvariant(); } // Parse each section switch (section) { case CurrentSection.AHeader: { switch (prefix) { case "ABSENDER": operation.CustomData["Absender"] = msg; break; case "TERMIN": operation.CustomData["Termin"] = msg; break; case "EINSATZNUMMER": operation.OperationNumber = msg; break; } } break; case CurrentSection.BMitteiler: { // This switch would not be necessary in this section (there is only "Name")... switch (prefix) { case "NAME": operation.Messenger = msg; break; } } break; case CurrentSection.CEinsatzort: { switch (prefix) { case "STRAßE": { // The street here is mangled together with the street number. Dissect them... int streetNumberColonIndex = msg.LastIndexOf(':'); if (streetNumberColonIndex != -1) { // We need to check for occurrence of the colon, because it may have been omitted by the OCR-software string streetNumber = msg.Remove(0, streetNumberColonIndex + 1).Trim(); operation.Einsatzort.StreetNumber = streetNumber; } operation.Einsatzort.Street = msg.Substring(0, msg.IndexOf("Haus-", StringComparison.Ordinal)).Trim(); } break; case "ORT": { operation.Einsatzort.ZipCode = ReadZipCodeFromCity(msg); if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode)) { Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City); } operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim(); // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A"). // However we can (at least with google maps) omit this information without problems! int dashIndex = operation.Einsatzort.City.IndexOf('-'); if (dashIndex != -1) { // Ignore everything after the dash operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex).Trim(); } } break; case "OBJEKT": operation.Einsatzort.Property = msg.StartsWith("6") ? msg.Substring(10, msg.Length - 10) : msg; break; case "PLANNUMMER": operation.CustomData["Einsatzort Plannummer"] = msg; break; case "STATION": operation.CustomData["Einsatzort Station"] = msg; break; } } break; case CurrentSection.DZielort: { switch (prefix) { case "STRAßE": { // The street here is mangled together with the street number. Dissect them... int streetNumberColonIndex = msg.LastIndexOf(':'); if (streetNumberColonIndex != -1) { // We need to check for occurrence of the colon, because it may have been omitted by the OCR-software operation.Zielort.StreetNumber = msg.Remove(0, streetNumberColonIndex + 1).Trim(); } operation.Zielort.Street = msg.Substring(0, msg.IndexOf("Haus-", StringComparison.Ordinal)).Trim(); } break; case "ORT": { string plz = ReadZipCodeFromCity(msg); operation.Zielort.ZipCode = plz; operation.Zielort.City = msg.Remove(0, plz.Length).Trim(); } break; case "OBJEKT": operation.CustomData["Zielort Objekt"] = msg; break; case "STATION": operation.CustomData["Zielort Station"] = msg; break; } } break; case CurrentSection.EEinsatzgrund: { switch (prefix) { case "SCHLAGW.": operation.Picture = msg; break; case "STICHWORT B": operation.Keywords.B = msg; break; case "STICHWORT T": operation.Keywords.T = msg; break; case "STICHWORT S": operation.Keywords.S = msg; break; case "STICHWORT I": operation.CustomData["Stichwort I"] = msg; break; case "STICHWORT R": operation.Keywords.R = msg; break; case "PRIO.": operation.Priority = msg; break; } } break; case CurrentSection.FEinsatzmittel: { if (line.StartsWith("NAME", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "NAME"); last.FullName = msg.Trim(); } else if (line.StartsWith("ALARMIERT", StringComparison.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(msg)) { msg = GetMessageText(line, "Alarmiert"); // In case that parsing the time failed, we just assume that the resource got requested right away. DateTime dt; // Most of the time the OCR-software reads the colon as a "1", so we check this case right here. if (!DateTime.TryParseExact(msg, "dd.MM.yyyy HH1mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) { // If this is NOT the case and it was parsed correctly, try it here DateTime.TryParseExact(msg, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); } last.Timestamp = dt.ToString(CultureInfo.InvariantCulture); } else if (line.StartsWith("AUSSTATTUNG", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "Ausstattung"); // Only add to requested equipment if there is some text, // otherwise the whole vehicle is the requested equipment if (!string.IsNullOrWhiteSpace(msg)) { last.RequestedEquipment.Add(msg); Logger.Instance.LogFormat(LogType.Info, this, "Aus '" + msg + "'"); } foreach (KeyValuePair<string, string> fdUnit in _fdUnits) { if (last.FullName.ToLower().Contains(fdUnit.Key.ToLower())) { operation.OperationPlan += " - " + fdUnit.Value; break; } } // This line will end the construction of this resource. Add it to the list and go to the next. operation.Resources.Add(last); last = new OperationResource(); } } break; case CurrentSection.GBemerkung: { // Append with newline at the end in case that the message spans more than one line operation.Comment = operation.Comment += msg + "\n"; } break; case CurrentSection.HFooter: // The footer can be ignored completely. break; } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } // Post-processing the operation if needed if (!string.IsNullOrWhiteSpace(operation.Comment) && operation.Comment.EndsWith("\n")) { operation.Comment = operation.Comment.Substring(0, operation.Comment.Length - 1).Trim(); } return operation; }
Operation IParser.Parse(string[] lines) { Operation operation = new Operation(); CurrentSection section = CurrentSection.AAnfang; lines = Utilities.Trim(lines); foreach (var line in lines) { string keyword; if (GetKeyword(line, out keyword)) { switch (keyword.Trim()) { case "EINSATZNR": { section = CurrentSection.BeNr; break; } case "MITTEILER": { section = CurrentSection.CMitteiler; break; } case "EINSATZORT": { section = CurrentSection.DEinsatzort; break; } case "STRAßE": { section = CurrentSection.EStraße; break; } case "ABSCHNITT": { section = CurrentSection.FAbschnitt; break; } case "KREUZUNG": { section = CurrentSection.GKreuzung; break; } case "ORTSTEIL/ORT": { section = CurrentSection.HOrt; break; } case "OBJEKT": { section = CurrentSection.JObjekt; break; } case "EINSATZPLAN": { section = CurrentSection.KEinsatzplan; break; } case "MELDEBILD": { section = CurrentSection.LMeldebild; break; } case "HINWEIS": { section = CurrentSection.MHinweis; break; } case "GEFORDERTE EINSATZMITTEL": { section = CurrentSection.NEinsatzmittel; break; } case "(ALARMSCHREIBEN ENDE)": { section = CurrentSection.OEnde; break; } } } switch (section) { case CurrentSection.BeNr: int indexOf = line.IndexOf("ALARM", StringComparison.InvariantCultureIgnoreCase); if (indexOf == -1) { operation.OperationNumber = GetMessageText(line, keyword); break; } operation.OperationNumber = GetMessageText(line.Substring(0, indexOf), keyword); keyword = "ALARM"; try { operation.Timestamp = DateTime.Parse(GetMessageText(line.Substring(indexOf), keyword)); } catch (FormatException) { operation.Timestamp = DateTime.Now; } break; case CurrentSection.CMitteiler: operation.Messenger = GetMessageText(line, keyword); break; case CurrentSection.DEinsatzort: operation.Einsatzort.Location = GetMessageText(line, keyword); break; case CurrentSection.EStraße: string msg = GetMessageText(line, keyword); string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Einsatzort Zusatz"] = appendix; operation.Einsatzort.Street = street; operation.Einsatzort.StreetNumber = streetNumber; break; case CurrentSection.FAbschnitt: operation.CustomData["Einsatzort Abschnitt"] = GetMessageText(line, keyword); break; case CurrentSection.GKreuzung: operation.Einsatzort.Intersection = GetMessageText(line, keyword); break; case CurrentSection.HOrt: operation.Einsatzort.City = GetMessageText(line, keyword); break; case CurrentSection.JObjekt: operation.Einsatzort.Property = GetMessageText(line, keyword); break; case CurrentSection.KEinsatzplan: operation.OperationPlan = GetMessageText(line, keyword); break; case CurrentSection.LMeldebild: operation.Picture = GetMessageText(line, keyword); break; case CurrentSection.MHinweis: operation.Comment = GetMessageText(line, keyword); break; case CurrentSection.NEinsatzmittel: if (line.StartsWith("Geforderte Einsatzmittel", StringComparison.InvariantCultureIgnoreCase)) { break; } OperationResource resource = new OperationResource(); if (line.Contains('(')) { string tool = line.Substring(line.IndexOf("(", StringComparison.Ordinal) + 1); tool = tool.Length >= 2 ? tool.Substring(0, tool.Length - 2).Trim() : String.Empty; string unit = line.Substring(0, line.IndexOf("(", StringComparison.Ordinal)); resource.FullName = unit; resource.RequestedEquipment.Add(tool); operation.Resources.Add(resource); } else { operation.Resources.Add(new OperationResource() { FullName = line }); } break; case CurrentSection.OEnde: break; } } return operation; }
Operation IParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); bool keywordsOnly = true; CurrentSection section = CurrentSection.AHeader; for (int i = 0; i < lines.Length; i++) { try { string line = lines[i]; if (line.Length == 0) { continue; } if (GetSection(line.Trim(), ref section, ref keywordsOnly)) { continue; } string msg = line; string prefix = ""; // Make the keyword check - or not (depends on the section we are in; see above) if (keywordsOnly) { string keyword; if (!StartsWithKeyword(line, out keyword)) { continue; } int x = line.IndexOf(':'); if (x == -1) { // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning prefix = keyword; msg = line.Remove(0, prefix.Length).Trim(); } else { prefix = line.Substring(0, x); msg = line.Substring(x + 1).Trim(); } prefix = prefix.Trim().ToUpperInvariant(); } // Parse each section switch (section) { case CurrentSection.AHeader: { switch (prefix) { case "ABSENDER": operation.CustomData["Absender"] = msg; break; case "TERMIN": operation.CustomData["Termin"] = msg; break; case "EINSATZNUMMER": // Try to parse the header and extract date and time if possible operation.Timestamp = ReadFaxTimestamp(line, operation.Timestamp); if (msg.ToUpperInvariant().Contains("ALARMZEIT")) { msg = msg.Substring(0, msg.ToUpperInvariant().IndexOf("ALARMZEIT")).Trim(); } operation.OperationNumber = msg; break; } } break; case CurrentSection.BMitteiler: { // This switch would not be necessary in this section (there is only "Name")... switch (prefix) { case "NAME": operation.Messenger = msg; break; } } break; case CurrentSection.CEinsatzort: { switch (prefix) { case "STRAßE": { string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Einsatzort Zusatz"] = appendix; operation.Einsatzort.Street = street; operation.Einsatzort.StreetNumber = streetNumber; } break; case "ABSCHNITT": break; case "ORT": { operation.Einsatzort.ZipCode = ReadZipCodeFromCity(msg); if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode)) { Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City); } operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim(); // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A"). // However we can (at least with google maps) omit this information without problems! int dashIndex = operation.Einsatzort.City.IndexOf('-'); if (dashIndex != -1) { // Ignore everything after the dash operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex).Trim(); } } break; case "OBJEKT": operation.Einsatzort.Property = msg; break; case "KREUZUNG": operation.Einsatzort.Intersection = msg; break; case "STATION": operation.CustomData["Einsatzort Station"] = msg; break; } } break; case CurrentSection.EEinsatzgrund: { switch (prefix) { case "SCHLAGW.": operation.Keywords.Keyword = msg; break; case "STICHWORT B": operation.Keywords.B = msg.Substring(0, msg.IndexOf("STICHWORT RD:", StringComparison.InvariantCultureIgnoreCase)).Trim(); operation.Keywords.R = GetMessageText(msg.Substring(msg.IndexOf("STICHWORT RD:", StringComparison.InvariantCultureIgnoreCase)), "STICHWORT RD"); break; case "STICHWORT SO": operation.Keywords.S = msg.Substring(0, msg.IndexOf("STICHWORT TH:", StringComparison.InvariantCultureIgnoreCase)).Trim(); operation.Keywords.T = GetMessageText(msg.Substring(msg.IndexOf("STICHWORT TH:", StringComparison.InvariantCultureIgnoreCase), msg.IndexOf("STICHWORT IN:", StringComparison.InvariantCultureIgnoreCase)), "STICHWORT TH:"); operation.CustomData["Stichwort IN"] = GetMessageText(msg.Substring(msg.IndexOf("STICHWORT IN", StringComparison.InvariantCultureIgnoreCase)), "STICHWORT IN"); break; case "PRIO.": operation.Priority = msg; break; } } break; case CurrentSection.FEinsatzmittel: { if (line.StartsWith("EINSATZMITTELNAME", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "EINSATZMITTELNAME"); last.FullName = msg.Trim(); } else if (line.StartsWith("GEF. GERÄTE", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "GEF. GERÄTE"); // Only add to requested equipment if there is some text, // otherwise the whole vehicle is the requested equipment if (!string.IsNullOrWhiteSpace(msg)) { last.RequestedEquipment.Add(msg); } // This line will end the construction of this resource. Add it to the list and go to the next. operation.Resources.Add(last); last = new OperationResource(); } } break; case CurrentSection.GBemerkung: { // Append with newline at the end in case that the message spans more than one line operation.Comment = operation.Comment += msg + "\n"; } break; case CurrentSection.HFooter: // The footer can be ignored completely. break; } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } // Post-processing the operation if needed if (!string.IsNullOrWhiteSpace(operation.Comment) && operation.Comment.EndsWith("\n")) { operation.Comment = operation.Comment.Substring(0, operation.Comment.Length - 1).Trim(); } return operation; }
Operation IFaxParser.Parse(string[] lines) { Operation operation = new Operation(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; for (int index = 0; index < lines.Length; index++) { string line = lines[index]; if (line.ToUpper().StartsWith("ALARMPLAN")) { String temp = line.Substring(line.ToUpper().IndexOf("EINSATZNUMMER", StringComparison.Ordinal)).Trim(); temp = temp.Substring(temp.IndexOf(" ", StringComparison.Ordinal)).Trim(); operation.OperationNumber = temp.Substring(0, temp.IndexOf(" ", StringComparison.Ordinal)).Trim(); section = CurrentSection.BBody; } else if (line.ToUpper().StartsWith("PLZ ORT")) { operation.Einsatzort.City = GetMessageText(line, "PLZ ORT"); } else if (line.ToUpper().StartsWith("STRASSE")) { operation.Einsatzort.Street = GetMessageText(line, "STRASSE"); } else if (line.ToUpper().StartsWith("OBJEKT")) { operation.Einsatzort.Property = GetMessageText(line, "OBJEKT"); } else if (line.ToUpper().StartsWith("TELEFON")) { operation.Messenger = GetMessageText(line, "TELEFON"); } else if (line.ToUpper().StartsWith("MELDUNG INFO")) { operation.Comment = GetMessageText(line, "MELDUNG INFO"); } else if (line.ToUpper().StartsWith("EINSATZART")) { operation.Keywords.Keyword = GetMessageText(line, "EINSATZART"); } else if (line.ToUpper().StartsWith("STICHWORT")) { operation.Keywords.EmergencyKeyword = GetMessageText(line, "STICHWORT"); } else if (line.ToUpper().StartsWith("ANFAHRT")) { section = CurrentSection.CAnfahrt; continue; } else if (line.ToUpper().StartsWith("BETEILIGTE EINSATZMITTEL")) { section = CurrentSection.DEinsatzMittel; continue; } else if (line.ToUpper().StartsWith("AP")) { section = CurrentSection.EFooter; } switch (section) { case CurrentSection.CAnfahrt: if (line.Contains("PLZ")) { operation.OperationPlan = line.Substring(0, line.ToUpper().IndexOf("PLZ", StringComparison.Ordinal)); String temp = line.Substring(line.ToUpper().IndexOf("PLZ")); if (temp.Contains(" ")) { temp = temp.Substring(temp.IndexOf(" ")); } operation.Einsatzort.ZipCode = temp.Trim(); } else { operation.OperationPlan = line; } //Only the first line is interesting ;) section = CurrentSection.BBody; break; case CurrentSection.DEinsatzMittel: if (line.ToUpper().Contains("FAHRZEUG")) { continue; } Regex timeStamp = new Regex("\\d\\d:\\d\\d:\\d\\d"); line = timeStamp.Replace(line, "").Trim(); OperationResource resource = new OperationResource { FullName = line }; foreach (KeyValuePair<string, string> fdUnit in _fdUnits) { if (resource.FullName.ToLower().Contains(fdUnit.Key.ToLower())) { resource.FullName = fdUnit.Value; operation.Resources.Add(resource); break; } } operation.Resources.Add(resource); break; case CurrentSection.EFooter: return operation; } } return operation; }
internal ResourceViewModel(OperationResource resource) : this(resource, null) { }
Operation IParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; bool keywordsOnly = true; for (int i = 0; i < lines.Length; i++) { try { string line = lines[i]; if (line.Length == 0) { continue; } operation.Timestamp = ParserUtility.ReadFaxTimestamp(line, operation.Timestamp); if (GetSection(line.Trim(), ref section, ref keywordsOnly)) { continue; } string msg = line; string prefix = ""; string keyword = null; if (keywordsOnly) { if (!ParserUtility.StartsWithKeyword(line, Keywords, out keyword)) { continue; } int x = line.IndexOf(':'); if (x == -1) { prefix = keyword; msg = line.Remove(0, prefix.Length).Trim(); } else { prefix = line.Substring(0, x); msg = line.Substring(x + 1).Trim(); } prefix = prefix.Trim().ToUpperInvariant(); } switch (section) { case CurrentSection.AHeader: { switch (prefix) { case "ABSENDER": operation.CustomData["Absender"] = msg; break; case "TERMIN": operation.CustomData["Termin"] = msg; break; case "EINSATZNUMMER": operation.OperationNumber = msg; break; default: break; } } break; case CurrentSection.BMitteiler: { // This switch would not be necessary in this section (there is only "Name")... switch (prefix) { case "NAME": operation.Messenger = msg; break; default: break; } } break; case CurrentSection.CEinsatzort: { switch (prefix) { case "STRAßE": { string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Einsatzort Zusatz"] = appendix; operation.Einsatzort.Street = street; operation.Einsatzort.StreetNumber = streetNumber; } break; case "ORT": { operation.Einsatzort.ZipCode = ParserUtility.ReadZipCodeFromCity(msg); if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode)) { Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City); } operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim(); // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A"). // However we can (at least with google maps) omit this information without problems! int dashIndex = operation.Einsatzort.City.IndexOf('-'); if (dashIndex != -1) { // Ignore everything after the dash operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex); } } break; case "OBJEKT": operation.Einsatzort.Property = msg; break; case "PLANNUMMER": operation.CustomData["Einsatzort Plannummer"] = msg; break; case "STATION": operation.CustomData["Einsatzort Station"] = msg; break; default: break; } } break; case CurrentSection.DZielort: { switch (prefix) { case "STRAßE": { string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Zielort Zusatz"] = appendix; operation.Zielort.Street = street; operation.Zielort.StreetNumber = streetNumber; } break; case "ORT": { string plz = ParserUtility.ReadZipCodeFromCity(msg); operation.Zielort.ZipCode = plz; operation.Zielort.City = msg.Remove(0, plz.Length).Trim(); } break; case "OBJEKT": operation.Zielort.Property = msg; break; case "STATION": operation.CustomData["Zielort Station"] = msg; break; default: break; } } break; case CurrentSection.EEinsatzgrund: { switch (prefix) { case "SCHLAGW.": operation.Keywords.Keyword = msg; break; case "STICHWORT B": operation.Keywords.B = msg; break; case "STICHWORT R": operation.Keywords.R = msg; break; case "STICHWORT S": operation.Keywords.S = msg; break; case "STICHWORT T": operation.Keywords.T = msg; break; case "PRIO.": operation.Priority = msg; break; default: break; } } break; case CurrentSection.FEinsatzmittel: { if (line.StartsWith("EINSATZMITTEL", StringComparison.CurrentCultureIgnoreCase)) { msg = ParserUtility.GetMessageText(line, "EINSATZMITTEL"); last.FullName = msg; } else if (line.StartsWith("ALARMIERT", StringComparison.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(msg)) { msg = ParserUtility.GetMessageText(line, "Alarmiert"); DateTime dt = ParserUtility.TryGetTimestampFromMessage(msg, operation.Timestamp); last.Timestamp = dt.ToString(); } else if (line.StartsWith("GEFORDERTE AUSSTATTUNG", StringComparison.CurrentCultureIgnoreCase)) { msg = ParserUtility.GetMessageText(line, "Geforderte Ausstattung"); if (!string.IsNullOrWhiteSpace(msg)) { last.RequestedEquipment.Add(msg); } operation.Resources.Add(last); last = new OperationResource(); } } break; case CurrentSection.GBemerkung: { operation.Comment = operation.Comment += msg + "\n"; } break; case CurrentSection.HFooter: // The footer can be ignored completely. break; default: break; } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } operation.Comment = ParserUtility.RemoveTrailingNewline(operation.Comment); return operation; }
Operation IFaxParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; for (int i = 0; i < lines.Length; i++) { try { //Definition der bool Variablen //bool nextIsOrt = false; bool ReplStreet = false; bool ReplCity = false; bool ReplComment = false; bool ReplPicture = false; bool Faxtime = false; bool nextIsOrt = false; //bool getAlarmTime = false; foreach (string linex in lines) { string msgx; string prefix; int x = linex.IndexOf(':'); if (x != -1) { prefix = linex.Substring(0, x); msgx = linex.Substring(x + 1).Trim(); prefix = prefix.Trim().ToUpperInvariant(); switch (prefix) { //Füllen der Standardinformatione Alarmfax Cases mit ":" case "EINSATZORT": operation.Einsatzort.Location = msgx; break; case "STRAßE": case "STRABE": operation.Einsatzort.Street = msgx; break; case "EINSATZPLAN": operation.OperationPlan = msgx; break; } } } string line = lines[i]; if (line.Length == 0) { continue; } // Einlesen mehrzeilige Bemerkung switch (line.Trim()) { case "BEMERKUNG": { section = CurrentSection.GBemerkung; continue; } case "TEXTBAUSTEINE": { section = CurrentSection.HFooter; continue; } default: break; } string msg = line; // Bemerkung Section switch (section) { case CurrentSection.GBemerkung: { // Append with newline at the end in case that the message spans more than one line operation.Comment = operation.Comment += msg + "\n"; operation.Comment = operation.Comment.Substring(0, operation.Comment.Length - 1).Trim(); } break; case CurrentSection.HFooter: // The footer can be ignored completely. break; default: break; } //Auslesen der Alarmierungszeit //TODO INFO ILS Ausstehend int x0 = line.IndexOf("DEG FF"); if (x0 != -1) { int anfang = line.IndexOf(':'); string altime = line.Substring(anfang + 15); altime = altime.Substring(0, altime.Length - 1); altime = altime.Trim(); operation.CustomData["Alarmtime"] = "Alarmzeit: " + altime; //getAlarmTime = true; } // Auslesen des Zeitpunkts des Faxeingangs if (Faxtime == false) { DateTime uhrzeit = DateTime.Now; operation.CustomData["Faxtime"] = "Faxeingang: " + uhrzeit.ToString("HH:mm:ss "); Faxtime = true; } // Weitere Standardinfos auslesen, ohne ":" if (line.StartsWith("Einsatznummer")) { operation.OperationNumber = line.Substring(14); } if (line.StartsWith("Objekt")) { operation.Einsatzort.Property = line.Substring(7); operation.Einsatzort.Property = operation.Einsatzort.Property.Trim(); } if (line.StartsWith("Name")) { operation.Messenger = operation.Messenger + line.Substring(5); } operation.Messenger = operation.Messenger + " "; if (operation.Messenger.Contains("Ausgerückt") == true) { operation.Messenger = operation.Messenger.Replace(": Alarmiert : Ausgerückt", ""); operation.Messenger = operation.Messenger.Trim(); } if (line.StartsWith("Schlagw.")) { operation.Picture = operation.Picture + line.Substring(11); operation.Picture = operation.Picture.Trim(); } //TODO Prüfen mit TIF Faxen if (line.StartsWith("Stichw. B")) { operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword + line.Substring(10); operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword.Trim(); } if (line.StartsWith("Stichw. T")) { operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword + line.Substring(10); operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword.Trim(); } if (line.StartsWith("Stichw. S")) { operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword + line.Substring(10); operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword.Trim(); } if (line.StartsWith("Stichw. I")) { operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword + line.Substring(10); operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword.Trim(); } if (line.StartsWith("Stichw. R")) { operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword + line.Substring(10); operation.Keywords.EmergencyKeyword = operation.Keywords.EmergencyKeyword.Trim(); } //Ort Einlesen if ((line.StartsWith("Ort")) && (nextIsOrt == false)) { operation.Einsatzort.City = operation.Einsatzort.City + line.Substring(4); operation.Einsatzort.City = operation.Einsatzort.City.Trim(); nextIsOrt = true; } // Sonderzeichenersetzung im Meldebild if (ReplPicture == false) { operation.Picture = operation.Picture + " "; ReplPicture = true; } if (operation.Picture.Contains("ß") == true) { operation.Picture = operation.Picture.Replace("ß", "ss"); } if (operation.Picture.Contains("ä") == true) { operation.Picture = operation.Picture.Replace("ä", "ae"); } if (operation.Picture.Contains("ö") == true) { operation.Picture = operation.Picture.Replace("ö", "oe"); } if (operation.Picture.Contains("ü") == true) { operation.Picture = operation.Picture.Replace("ü", "ue"); } // Sonderzeichenersetzung im Ort if (ReplCity == false) { operation.Einsatzort.City = operation.Einsatzort.City + " "; ReplCity = true; } if (operation.Einsatzort.City.Contains("ß") == true) { operation.Einsatzort.City = operation.Einsatzort.City.Replace("ß", "ss"); } if (operation.Einsatzort.City.Contains("ä") == true) { operation.Einsatzort.City = operation.Einsatzort.City.Replace("ä", "ae"); } if (operation.Einsatzort.City.Contains("ö") == true) { operation.Einsatzort.City = operation.Einsatzort.City.Replace("ö", "oe"); } if (operation.Einsatzort.City.Contains("ü") == true) { operation.Einsatzort.City = operation.Einsatzort.City.Replace("ü", "ue"); } // Sonderzeichenersetzung in der Strasse if (ReplStreet == false) { operation.Einsatzort.Street = operation.Einsatzort.Street + " "; ReplStreet = true; } if (operation.Einsatzort.Street.Contains("Haus-Nr.:") == true) { operation.Einsatzort.Street = operation.Einsatzort.Street.Replace("Haus-Nr.:", ""); } if (operation.Einsatzort.Street.Contains("ß") == true) { operation.Einsatzort.Street = operation.Einsatzort.Street.Replace("ß", "ss"); } if (operation.Einsatzort.Street.Contains("ä") == true) { operation.Einsatzort.Street = operation.Einsatzort.Street.Replace("ä", "ae"); } if (operation.Einsatzort.Street.Contains("ö") == true) { operation.Einsatzort.Street = operation.Einsatzort.Street.Replace("ö", "oe"); } if (operation.Einsatzort.Street.Contains("ü") == true) { operation.Einsatzort.Street = operation.Einsatzort.Street.Replace("ü", "ue"); } // Sonderzeichenersetzung im Hinweis if (ReplComment == false) { operation.Comment = operation.Comment + " "; ReplComment = true; } if (operation.Comment.Contains("ß") == true) { operation.Comment = operation.Comment.Replace("ß", "ss"); } if (operation.Comment.Contains("ä") == true) { operation.Comment = operation.Comment.Replace("ä", "ae"); } if (operation.Comment.Contains("ö") == true) { operation.Comment = operation.Comment.Replace("ö", "oe"); } if (operation.Comment.Contains("ü") == true) { operation.Comment = operation.Comment.Replace("ü", "ue"); } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } // Post-processing the operation if needed if (!string.IsNullOrWhiteSpace(operation.Comment) && operation.Comment.EndsWith("\n")) { operation.Comment = operation.Comment.Substring(0, operation.Comment.Length - 1).Trim(); } return operation; }
/// <summary> /// Gets the vehicle type or specification (RW, DLK 23/12 etc.) from the resource name. /// </summary> /// <param name="resource">The resource to get the type or specification from.</param> /// <returns>The type or specification string. -or- null, if none found.</returns> private string GetVehicleType(OperationResource resource) { // Find the type/spec name entrenched between the brackets. int iOpenBracket = resource.FullName.LastIndexOf('('); int iClosingBracket = resource.FullName.LastIndexOf(')'); // Check invalid conditions. if (iOpenBracket == -1 || iClosingBracket == -1 || (iOpenBracket > iClosingBracket)) { return null; } // Cut out the middle part "1312fghasldkjf 30/1 (DLK 23/12)" ==> "DLK 23/12". int start = iOpenBracket + 1; int length = (iClosingBracket - 1) - iOpenBracket; return resource.FullName.Substring(start, length); }
void ISectionParser.OnEnterSection(Operation operation) { _currentResource = new OperationResource(); }
Operation IParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; bool keywordsOnly = true; for (int i = 0; i < lines.Length; i++) { try { string line = lines[i]; if (line.Length == 0) { continue; } if (GetSection(line.Trim(), ref section, ref keywordsOnly)) { continue; } string msg = line; string prefix = ""; // Make the keyword check - or not (depends on the section we are in; see above) string keyword = ""; if (keywordsOnly) { if (!StartsWithKeyword(line, out keyword)) { continue; } int x = line.IndexOf(':'); if (x == -1) { // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning prefix = keyword; msg = line.Remove(0, prefix.Length).Trim(); } else { prefix = line.Substring(0, x); msg = line.Substring(x + 1).Trim(); } prefix = prefix.Trim().ToUpperInvariant(); } // Parse each section switch (section) { case CurrentSection.AHeader: { switch (prefix) { case "EINSATZNUMMER": operation.OperationNumber = msg; break; } } break; case CurrentSection.BMitteiler: operation.Messenger = line.Remove(0, keyword.Length).Trim(); break; case CurrentSection.CEinsatzort: { switch (prefix) { case "STRAßE": { string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Einsatzort Zusatz"] = appendix; operation.Einsatzort.Street = street; operation.Einsatzort.StreetNumber = streetNumber; } break; case "ORT": { Match zip = Regex.Match(msg, @"[0-9]{5}"); if (zip.Success) { operation.Einsatzort.ZipCode = zip.Value; operation.Einsatzort.City = msg.Replace(zip.Value, "").Trim(); } else { operation.Einsatzort.City = msg; } break; } case "GEMEINDE": { operation.CustomData.Add("GEMEINDE", msg); } break; case "OBJEKT": if (msg.Contains("EPN:")) { string epn = msg.Substring(msg.IndexOf("EPN", StringComparison.Ordinal)); epn = GetMessageText(epn, "EPN"); operation.OperationPlan = epn; operation.Einsatzort.Property = msg.Substring(0, msg.IndexOf("EPN", StringComparison.Ordinal)); } else { operation.Einsatzort.Property = msg; } break; case "KREUZUNG": operation.Einsatzort.Intersection = msg; break; } } break; case CurrentSection.DEinsatzgrund: { switch (prefix) { case "SCHLAGW.": operation.Keywords.Keyword = msg; break; case "STICHWORT": operation.Keywords.EmergencyKeyword = msg; break; case "PRIO.": operation.Priority = msg; break; } } break; case CurrentSection.EEinsatzmittel: { if (line.StartsWith("NAME", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "NAME"); last.FullName = msg; } else if (line.StartsWith("ALARMIERT", StringComparison.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(msg)) { msg = GetMessageText(line, "ALARMIERT"); // In case that parsing the time failed, we just assume that the resource got requested right away. DateTime dt; // Most of the time the OCR-software reads the colon as a "1", so we check this case right here. if (!DateTime.TryParseExact(msg, "dd.MM.yyyy HH1mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) { // If this is NOT the case and it was parsed correctly, try it here DateTime.TryParseExact(msg, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); } last.Timestamp = dt.ToString(CultureInfo.InvariantCulture); } else if (line.StartsWith("GEF. GERÄT", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "GEF. GERÄT"); // Only add to requested equipment if there is some text, // otherwise the whole vehicle is the requested equipment if (!string.IsNullOrWhiteSpace(msg)) { last.RequestedEquipment.Add(msg); } operation.Resources.Add(last); last = new OperationResource(); } } break; case CurrentSection.FBemerkung: { // Append with newline at the end in case that the message spans more than one line operation.Comment = operation.Comment += msg + Environment.NewLine; } break; case CurrentSection.GFooter: // The footer can be ignored completely. break; } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } return operation; }
Operation IFaxParser.Parse(string[] lines) { Operation operation = new Operation(); CurrentSection section = CurrentSection.AAnfang; lines = Utilities.Trim(lines); foreach (var line in lines) { string keyword; if (GetKeyword(line, out keyword)) { switch (keyword.Trim()) { case "E-Nr": { section = CurrentSection.BeNr; break; } case "EINSATZORT": { section = CurrentSection.CEinsatzort; break; } case "STRAßE": { section = CurrentSection.DStraße; break; } case "ORTSTEIL/ORT": { section = CurrentSection.EOrt; break; } case "OBJEKT": { section = CurrentSection.FObjekt; break; } case "EINSATZPLAN": { section = CurrentSection.GEinsatzplan; break; } case "MELDEBILD": { section = CurrentSection.HMeldebild; break; } case "EINSATZSTICHWORT": { section = CurrentSection.JEinsatzstichwort; break; } case "HINWEIS": { section = CurrentSection.KHinweis; break; } case "EINSATZMITTEL": { section = CurrentSection.LEinsatzmittel; break; } case "(ALARMSCHREIBEN ENDE)": { section = CurrentSection.MEnde; break; ;} } } switch (section) { case CurrentSection.BeNr: operation.OperationNumber = GetMessageText(line.Substring(0, line.IndexOf("ALARM", StringComparison.Ordinal)), keyword); keyword = "ALARM"; try { operation.Timestamp = DateTime.Parse(GetMessageText(line.Substring(line.IndexOf("ALARM", StringComparison.Ordinal)), keyword)); } catch (FormatException) { operation.Timestamp = DateTime.Now; } break; case CurrentSection.CEinsatzort: operation.Zielort.Location = GetMessageText(line, keyword); break; case CurrentSection.DStraße: operation.Einsatzort.Street = GetMessageText(line, keyword); break; case CurrentSection.EOrt: operation.Einsatzort.City = GetMessageText(line, keyword); break; case CurrentSection.FObjekt: operation.Einsatzort.Property = GetMessageText(line, keyword); break; case CurrentSection.GEinsatzplan: operation.OperationPlan = GetMessageText(line, keyword); break; case CurrentSection.HMeldebild: operation.Picture = GetMessageText(line, keyword); break; case CurrentSection.JEinsatzstichwort: operation.Keywords.EmergencyKeyword = GetMessageText(line, keyword); break; case CurrentSection.KHinweis: operation.Comment += GetMessageText(line, keyword); break; case CurrentSection.LEinsatzmittel: if (line.Equals("EINSATZMITTEL: ", StringComparison.InvariantCultureIgnoreCase)) { break; } OperationResource resource = new OperationResource(); if (line.Contains('(')) { string tool = line.Substring(line.IndexOf("(", StringComparison.Ordinal) + 1); if (tool.Length >= 2) { tool = tool.Substring(0, tool.Length - 2).Trim(); } else { tool = String.Empty; } string unit = line.Substring(0, line.IndexOf("(", StringComparison.Ordinal)); resource.FullName = unit; resource.RequestedEquipment.Add(tool); foreach (KeyValuePair<string, string> fdUnit in _fdUnits) { if (resource.FullName.ToLower().Contains(fdUnit.Key.ToLower())) { resource.FullName = fdUnit.Value; operation.Resources.Add(resource); break; } } } break; case CurrentSection.MEnde: break; } } return operation; }
Operation IFaxParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; bool keywordsOnly = true; for (int i = 0; i < lines.Length; i++) { try { string line = lines[i]; if (line.Length == 0) { continue; } // Switch sections. The parsing may differ in each section. switch (line.Trim()) { case "MITTEILER": { section = CurrentSection.BMitteiler; continue; } case "EINSATZORT": { section = CurrentSection.CEinsatzort; continue; } case "EINSATZGRUND": { section = CurrentSection.DEinsatzgrund; continue; } case "EINSATZMITTEL": { section = CurrentSection.EEinsatzmittel; continue; } case "BEMERKUNG": { section = CurrentSection.FBemerkung; keywordsOnly = false; continue; } case "ENDE ALARMFAX — V2.0": { section = CurrentSection.GFooter; keywordsOnly = false; continue; } } string msg = line; string prefix = ""; // Make the keyword check - or not (depends on the section we are in; see above) string keyword = ""; if (keywordsOnly) { if (!StartsWithKeyword(line, out keyword)) { continue; } int x = line.IndexOf(':'); if (x == -1) { // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning prefix = keyword; msg = line.Remove(0, prefix.Length).Trim(); } else { prefix = line.Substring(0, x); msg = line.Substring(x + 1).Trim(); } prefix = prefix.Trim().ToUpperInvariant(); } // Parse each section switch (section) { case CurrentSection.AHeader: { switch (prefix) { case "EINSATZ-NR.": operation.OperationNumber = msg; break; } } break; case CurrentSection.BMitteiler: operation.Messenger = line.Remove(0, keyword.Length).Trim(); break; case CurrentSection.CEinsatzort: { switch (prefix) { case "STRAßE": { operation.Einsatzort.Street = msg; int empty = msg.LastIndexOf(" ", StringComparison.Ordinal); if (empty != -1 && empty != msg.Length) { operation.Einsatzort.Street = msg.Substring(0, empty).Trim(); operation.Einsatzort.StreetNumber = msg.Substring(empty).Trim(); } } break; case "ORTSTEIL": { operation.Einsatzort.City = msg; // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A"). // However we can (at least with google maps) omit this information without problems! int dashIndex = msg.IndexOf('-'); if (dashIndex != -1) { // Ignore everything after the dash operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex); } } break; case "OBJEKT": operation.Einsatzort.Property = msg; break; case "KREUZUNG": operation.Einsatzort.Intersection = msg; break; } } break; case CurrentSection.DEinsatzgrund: { switch (prefix) { case "SCHLAGW.": operation.Keywords.Keyword = msg; break; case "STICHWORT": operation.Keywords.EmergencyKeyword = msg; break; case "PRIORITÄT": operation.Priority = msg; break; } } break; case CurrentSection.EEinsatzmittel: { if (line.StartsWith("NAME", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "NAME"); last.FullName = msg; } else if (line.StartsWith("ALARMIERT", StringComparison.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(msg)) { msg = GetMessageText(line, "ALARMIERT"); // In case that parsing the time failed, we just assume that the resource got requested right away. DateTime dt; // Most of the time the OCR-software reads the colon as a "1", so we check this case right here. if (!DateTime.TryParseExact(msg, "dd.MM.yyyy HH1mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) { // If this is NOT the case and it was parsed correctly, try it here DateTime.TryParseExact(msg, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); } last.Timestamp = dt.ToString(CultureInfo.InvariantCulture); } else if (line.StartsWith("GEF. GERÄT", StringComparison.CurrentCultureIgnoreCase)) { msg = GetMessageText(line, "GEF. GERÄT"); // Only add to requested equipment if there is some text, // otherwise the whole vehicle is the requested equipment if (!string.IsNullOrWhiteSpace(msg)) { last.RequestedEquipment.Add(msg); } foreach (KeyValuePair<string, string> fdUnit in _fdUnits) { if (last.FullName.ToLower().Contains(fdUnit.Key.ToLower())) { operation.OperationPlan += " - " + fdUnit.Value; break; } } operation.Resources.Add(last); last = new OperationResource(); } } break; case CurrentSection.FBemerkung: { // Append with newline at the end in case that the message spans more than one line operation.Comment = operation.Comment += msg + Environment.NewLine; } break; case CurrentSection.GFooter: // The footer can be ignored completely. break; } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } return operation; }
Operation IParser.Parse(string[] lines) { Operation operation = new Operation(); OperationResource last = new OperationResource(); lines = Utilities.Trim(lines); CurrentSection section = CurrentSection.AHeader; bool keywordsOnly = true; InnerSection innerSection = InnerSection.AStraße; for (int i = 0; i < lines.Length; i++) { try { string line = lines[i]; if (line.Length == 0) { continue; } // Try to parse the header and extract date and time if possible operation.Timestamp = ReadFaxTimestamp(line, operation.Timestamp); if (GetSection(line.Trim(), ref section, ref keywordsOnly)) { continue; } string msg = line; string prefix = ""; // Make the keyword check - or not (depends on the section we are in; see above) if (keywordsOnly) { string keyword; if (!StartsWithKeyword(line, out keyword)) { continue; } int x = line.IndexOf(':'); if (x == -1) { // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning prefix = keyword; msg = line.Remove(0, prefix.Length).Trim(); } else { prefix = line.Substring(0, x); msg = line.Substring(x + 1).Trim(); } prefix = prefix.Trim().ToUpperInvariant(); } // Parse each section switch (section) { case CurrentSection.AHeader: { switch (prefix) { case "ALARM": operation.Timestamp = ReadFaxTimestamp(msg, DateTime.Now); break; case "EINSATZNUMMER": operation.OperationNumber = msg; break; } } break; case CurrentSection.BMitteiler: { // This switch would not be necessary in this section (there is only "Name")... switch (prefix) { case "NAME": operation.Messenger = msg; break; case "RUFNUMMER": if (operation.Messenger != null) { operation.Messenger += " " + msg; } break; } } break; case CurrentSection.CEinsatzort: { switch (prefix) { case "STRAßE": { innerSection = InnerSection.AStraße; string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Einsatzort Zusatz"] = appendix; operation.Einsatzort.Street = street; operation.Einsatzort.StreetNumber = streetNumber; } break; case "ABSCHNITT": operation.Einsatzort.Intersection = msg; break; case "ORT": { innerSection = InnerSection.BOrt; operation.Einsatzort.ZipCode = ReadZipCodeFromCity(msg); if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode)) { Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City); } operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim(); } break; case "OBJEKT": innerSection = InnerSection.CObjekt; operation.Einsatzort.Property = msg; break; case "EINSATZPLANNUMMER": operation.OperationPlan = msg; break; case "STATION": innerSection = InnerSection.DStation; operation.CustomData["Einsatzort Station"] = msg; break; default: switch (innerSection) { case InnerSection.AStraße: //Quite dirty because of Streetnumber. Looking for better solution operation.Einsatzort.Street += msg; break; case InnerSection.BOrt: operation.Einsatzort.City += msg; break; case InnerSection.CObjekt: operation.Einsatzort.Property += msg; break; case InnerSection.DStation: operation.CustomData["Einsatzort Station"] += msg; break; } break; } } break; case CurrentSection.DZielort: { switch (prefix) { case "STRAßE": { innerSection = InnerSection.AStraße; string street, streetNumber, appendix; ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix); operation.CustomData["Zielort Zusatz"] = appendix; operation.Zielort.Street = street; operation.Zielort.StreetNumber = streetNumber; } break; case "ORT": { innerSection = InnerSection.BOrt; operation.Zielort.ZipCode = ReadZipCodeFromCity(msg); if (string.IsNullOrWhiteSpace(operation.Zielort.ZipCode)) { Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Zielort.City); } operation.Zielort.City = msg.Remove(0, operation.Zielort.ZipCode.Length).Trim(); } break; case "OBJEKT": innerSection = InnerSection.CObjekt; operation.Zielort.Property = msg; break; case "STATION": innerSection = InnerSection.DStation; operation.CustomData["Zielort Station"] = msg; break; default: switch (innerSection) { case InnerSection.AStraße: //Quite dirty because of Streetnumber. Looking for better solution operation.Zielort.Street += msg; break; case InnerSection.BOrt: operation.Zielort.City += msg; break; case InnerSection.CObjekt: operation.Zielort.Property += msg; break; case InnerSection.DStation: operation.CustomData["Zielort Station"] += msg; break; } break; } } break; case CurrentSection.EEinsatzgrund: { switch (prefix) { case "SCHLAGW.": operation.Keywords.Keyword = msg; break; case "STICHWORT": operation.Keywords.EmergencyKeyword = msg; break; } } break; case CurrentSection.FEinsatzmittel: { switch (prefix) { case "NAME": last.FullName = msg.Trim(); break; case "GEF. GERÄTE": // Only add to requested equipment if there is some text, // otherwise the whole vehicle is the requested equipment if (!string.IsNullOrWhiteSpace(msg)) { last.RequestedEquipment.Add(msg); } break; case "ALARMIERT": // Only add to requested equipment if there is some text, // otherwise the whole vehicle is the requested equipment if (!string.IsNullOrWhiteSpace(msg)) { last.Timestamp = msg; } operation.Resources.Add(last); last = new OperationResource(); break; } } break; case CurrentSection.GBemerkung: { // Append with newline at the end in case that the message spans more than one line operation.Comment = operation.Comment += msg + "\n"; } break; case CurrentSection.HFooter: // The footer can be ignored completely. break; } } catch (Exception ex) { Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message); } } // Post-processing the operation if needed if (!string.IsNullOrWhiteSpace(operation.Comment) && operation.Comment.EndsWith("\n")) { operation.Comment = operation.Comment.Substring(0, operation.Comment.Length - 1).Trim(); } return operation; }