// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.ComponentModel; using System.Linq; using System.Xml; using System.Xml.Linq; using Core.Common.Base.IO; using Ringtoets.Common.IO.Configurations; using Ringtoets.Common.IO.Properties; using Ringtoets.Common.IO.Schema; namespace Ringtoets.Common.IO.Readers { /// /// Extensions methods for . /// public static class XElementExtensions { /// /// Gets the value from a descendant element. /// /// The that contains the descendant element. /// The name of the descendant element. /// The value of the element, or null when the /// does not have descendant elements of . /// Thrown when any parameter is null. /// Thrown when the value isn't in the correct format. /// Thrown when the value represents a number /// less than or greater than . public static double? GetDoubleValueFromDescendantElement(this XElement parentElement, string descendantElementName) { XElement descendantElement = parentElement.GetDescendantElement(descendantElementName); return descendantElement != null ? (double?) XmlConvert.ToDouble(descendantElement.Value) : null; } /// /// Gets the value from a descendant element. /// /// The that contains the descendant element. /// The name of the descendant element. /// The value of the element, or null when the /// does not have descendant elements of . /// Thrown when any parameter is null. /// Thrown when the value isn't in the correct format. /// Thrown when the value represents a number /// less than or greater than . public static int? GetIntegerValueFromDescendantElement(this XElement parentElement, string descendantElementName) { XElement descendantElement = parentElement.GetDescendantElement(descendantElementName); return descendantElement != null ? (int?) XmlConvert.ToInt32(descendantElement.Value) : null; } /// /// Gets the value from a descendant element. /// /// The that contains the descendant element. /// The name of the descendant element. /// The value of the element, or null when the /// does not have descendant elements of . /// Thrown when any parameter is null. public static string GetStringValueFromDescendantElement(this XElement parentElement, string descendantElementName) { XElement descendantElement = parentElement.GetDescendantElement(descendantElementName); return descendantElement?.Value; } /// /// Gets the value from a descendant element. /// /// The that contains the descendant element. /// The name of the descendant element. /// The value, or null when the /// does not have descendant elements of . /// Thrown when any parameter is null. /// Thrown when the value does not represent a value. public static bool? GetBoolValueFromDescendantElement(this XElement parentElement, string descendantElementName) { XElement descendantElement = parentElement.GetDescendantElement(descendantElementName); return descendantElement != null ? (bool?) XmlConvert.ToBoolean(descendantElement.Value) : null; } /// /// Gets the converted value from a descendant element containing a string. /// /// The to use /// The that contains the descendant element. /// The name of the descendant element. /// The converted value, or null when the /// does not have descendant elements of . /// Thrown when calling . /// results in an exception being thrown. /// Thrown when any parameter is null. /// Thrown when the conversion cannot be performed. public static object GetConvertedValueFromDescendantStringElement(this XElement parentElement, string descendantElementName) where TConverter : TypeConverter, new() { string stringValue = parentElement.GetStringValueFromDescendantElement(descendantElementName); if (stringValue == null) { return null; } return new TConverter().ConvertFromInvariantString(stringValue); } /// /// Gets the converted value from a descendant element containing a double. /// /// The to use /// The that contains the descendant element. /// The name of the descendant element. /// The converted value, or null when the /// does not have descendant elements of . /// Thrown when calling . /// results in an exception being thrown. /// Thrown when any parameter is null. /// Thrown when the value from a descendant element is /// not in the correct format. /// Thrown when the value from a descendant element /// represents a number less than or greater than . /// Thrown when the conversion cannot be performed. public static object GetConvertedValueFromDescendantDoubleElement(this XElement parentElement, string descendantElementName) where TConverter : TypeConverter, new() { double? doubleValue = parentElement.GetDoubleValueFromDescendantElement(descendantElementName); if (doubleValue == null) { return null; } return new TConverter().ConvertFrom(doubleValue); } /// /// Gets the 'stochast' element from the descendant 'stochasts' element. /// /// The that contains the descendant element. /// The name of the stochast element. /// The stochast element, or null when the /// does not have stochast elements with the name . /// Thrown when any parameter is null. public static XElement GetStochastElement(this XElement parentElement, string stochastName) { if (parentElement == null) { throw new ArgumentNullException(nameof(parentElement)); } if (stochastName == null) { throw new ArgumentNullException(nameof(stochastName)); } return parentElement.Elements(ConfigurationSchemaIdentifiers.StochastsElement) .FirstOrDefault()? .Elements(ConfigurationSchemaIdentifiers.StochastElement) .FirstOrDefault(e => e.Attribute(ConfigurationSchemaIdentifiers.NameAttribute)?.Value == stochastName); } /// /// Gets a descendant element with the given . /// /// The that contains the descendant element. /// The name of the descendant element. /// The element, or null when the /// does not have descendant elements of . /// Thrown when any parameter is null. public static XElement GetDescendantElement(this XElement parentElement, string descendantElementName) { if (parentElement == null) { throw new ArgumentNullException(nameof(parentElement)); } if (descendantElementName == null) { throw new ArgumentNullException(nameof(descendantElementName)); } return parentElement.Descendants(descendantElementName).FirstOrDefault(); } /// Thrown when any parameter is null. /// Thrown when the value isn't in the correct format. /// Thrown when the value for mean or standard deviation represents a /// number less than or greater than . public static StochastConfiguration GetStandardDeviationStochastParameters(this XElement calculationElement, string stochastName) { if (calculationElement == null) { throw new ArgumentNullException(nameof(calculationElement)); } if (stochastName == null) { throw new ArgumentNullException(nameof(stochastName)); } XElement element = calculationElement.GetStochastElement(stochastName); if (element != null) { if (element.Element(ConfigurationSchemaIdentifiers.VariationCoefficientElement) != null) { string calculationName = calculationElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute)?.Value; string message = string.Format( Resources.XElementExtensions_GetStandardDeviationStochastParameters_Stochast_0_defines_VariationCoefficient_instead_of_StandardDeviation_in_Calculation_1_, stochastName, calculationName); throw new CriticalFileReadException(message); } return new StochastConfiguration { Mean = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.MeanElement), StandardDeviation = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.StandardDeviationElement) }; } return null; } public static StochastConfiguration GetVariationCoefficientStochastParameters(this XElement calculationElement, string stochastName) { if (calculationElement == null) { throw new ArgumentNullException(nameof(calculationElement)); } if (stochastName == null) { throw new ArgumentNullException(nameof(stochastName)); } XElement element = calculationElement.GetStochastElement(stochastName); if (element != null) { if (element.Element(ConfigurationSchemaIdentifiers.StandardDeviationElement) != null) { string calculationName = calculationElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute)?.Value; string message = string.Format( Resources.XElementExtensions_GetVariationCoefficientStochastParameters_Stochast_0_defines_StandardDeviation_instead_of_VariationCoefficient_in_Calculation_1_, stochastName, calculationName); throw new CriticalFileReadException(message); } return new StochastConfiguration { Mean = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.MeanElement), VariationCoefficient = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.VariationCoefficientElement) }; } return null; } } }