private static SpecificationValue ParseSpecificationValue( XElement element, XmlSchema schema, XmlSchemaSet schemaSet, string ns) { SpecificationValue value; string isRef = GetRef(element, ns); if (isRef != null) { element.Validate( schema.SchemaTypes[new XmlQualifiedName("valueReference", ns)], schemaSet, (sender, args) => throw new ArgumentException(args.Message, args.Exception)); value = SpecificationValue.Ref(isRef); } else { SpecificationValue.Multiplicity mul = GetMul(element, ns); SpecificationValue.DataType type = GetType(element, ns); string[] values = GetValues(element, ns).ToArray(); if (values.Length <= 1) { element.Validate( schema.SchemaTypes[new XmlQualifiedName("valueSingle", ns)], schemaSet, (sender, args) => throw new ArgumentException(args.Message, args.Exception)); } else { element.Validate( schema.SchemaTypes[new XmlQualifiedName("valueMultiple", ns)], schemaSet, (sender, args) => throw new ArgumentException(args.Message, args.Exception)); } SpecificationValueSettings settings = ValueSettings.GetOrAdd( (int)mul * 1000 + (int)type, i => new SpecificationValueSettings { AllowCast = true, DefaultMultiplicity = mul, IncludeDetails = true, ExpectedType = type }); if (!SpecificationValue.TryFrom(values, settings, out value, out string error)) { throw new ArgumentException(error); } } return(value); }
public static SpecificationValue Ref(string key) { SpecificationValue result = new SpecificationValue(); result.Values = new[] { key }; result.IsReference = true; return(result); }
public static bool TryFrom( string key, IReadOnlyDictionary <string, object> values, SpecificationValueSettings settings, out SpecificationValue result, out string error) { return(TryFrom(key, values, settings, new HashSet <SpecificationValue>(), out result, out error)); }
private static void SetType(Type type, SpecificationValue result, string paramName) { if (TypeHelper.Mapping.ContainsKey(type)) { result.ValueType = TypeHelper.Mapping[type]; } else { throw new ArgumentException( string.Format( SpecAbsRes.SpecificationValueTypeNotSupported, type, string.Join(", ", TypeHelper.Mapping.Keys)), paramName); } }
public static SpecificationValue Single(object value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } SpecificationValue result = new SpecificationValue(); result.ValueMultiplicity = Multiplicity.AllOf; result.Values = new[] { value }; SetType(value.GetType(), result, nameof(value)); return(result); }
public static string Serialize(this SpecificationValue value, int index = 0) { switch (value.ValueType) { case SpecificationValue.DataType.Int: return(value.Values.OfType <int>().ElementAt(index).ToString("D")); case SpecificationValue.DataType.Float: return(value.Values.OfType <float>().ElementAt(index).ToString("F")); case SpecificationValue.DataType.DateTime: return(value.Values.OfType <DateTime>().ElementAt(index).ToUniversalTime().ToString("u")); case SpecificationValue.DataType.String: return(value.Values.ElementAt(index).ToString()); default: throw new InvalidOperationException(); } }
private static Specification FromXmlValidated( XElement element, XmlSchema schema, XmlSchemaSet schemaSet, string ns) { if (element.Name.LocalName == Consts.And || element.Name.LocalName == Consts.Or) { List <Specification> inner = new List <Specification>(element.Elements().Count(el => el.Name.Namespace == ns)); foreach (XElement item in element.Elements().Where(el => el.Name.Namespace == ns)) { inner.Add(FromXmlValidated(item, schema, schemaSet, ns)); } if (element.Name.LocalName == Consts.And) { return(new AndSpecification(inner)); } if (element.Name.LocalName == Consts.Or) { return(new OrSpecification(inner)); } } if (element.Name.LocalName == Consts.Not) { Specification inner = FromXmlValidated(element.Elements().Single(), schema, schemaSet, ns); return(new NotSpecification(inner)); } if (element.Name.LocalName == Consts.HasValue) { return(new HasValueSpecification(GetKey(element, ns))); } if (element.Name.LocalName == Consts.Ref) { return(new ReferenceSpecification(GetKey(element, ns))); } if (element.Name.LocalName == Consts.True) { return(ConstantSpecification.True); } if (element.Name.LocalName == Consts.False) { return(ConstantSpecification.False); } if (Consts.CompareOperators.Contains(element.Name.LocalName)) { string key = GetKey(element, ns); SpecificationValue value = ParseSpecificationValue(element, schema, schemaSet, ns); if (element.Name.LocalName == Consts.Eq) { return(new EqualSpecification(key, value)); } if (element.Name.LocalName == Consts.Gt) { return(new GreaterSpecification(key, value)); } if (element.Name.LocalName == Consts.Ge) { return(new GreaterOrEqualSpecification(key, value)); } if (element.Name.LocalName == Consts.Lt) { return(new LessSpecification(key, value)); } if (element.Name.LocalName == Consts.Le) { return(new LessOrEqualSpecification(key, value)); } } throw new NotImplementedException(); }
private static void CollectionFromValidated( SpecificationsCollection collection, XElement element, XmlSchema schema, XmlSchemaSet schemaSet, string ns) { var values = element.Element(XName.Get(Consts.RefValuesCollection, ns)); if (values != null) { foreach (XElement add in values.Elements(XName.Get(Consts.Add, ns))) { string key = GetKey(add, ns); SpecificationValue value = ParseSpecificationValue(add, schema, schemaSet, ns); collection.ValuesForReference.Add(key, value); } foreach (XElement runtime in values.Elements(XName.Get(Consts.Runtime, ns))) { string key = GetKey(runtime, ns); collection.AllowedRuntimeValueReferenceKeys.Add(key); } } var definitions = element.Element(XName.Get(Consts.RefSpecCollection, ns)); if (definitions != null) { foreach (XElement add in definitions.Elements(XName.Get(Consts.Add, ns))) { string key = GetKey(add, ns); Specification spec = FromXmlValidated( add.Elements().First(e => e.Name.Namespace == ns), schema, schemaSet, ns); collection.SpecificationsForReference.Add(key, spec); } foreach (XElement runtime in definitions.Elements(XName.Get(Consts.Runtime, ns))) { string key = GetKey(runtime, ns); collection.AllowedRuntimeSpecificationReferenceKeys.Add(key); } } var specifications = element.Element(XName.Get(Consts.SpecCollection, ns)); if (specifications != null) { foreach (XElement add in specifications.Elements(XName.Get(Consts.Add, ns))) { string key = GetKey(add, ns); Specification spec = FromXmlValidated( add.Elements().First(e => e.Name.Namespace == ns), schema, schemaSet, ns); collection.Specifications.Add(key, spec); } } }
public static bool TryFrom(object value, SpecificationValueSettings settings, out SpecificationValue result, out string error) { error = null; result = null; if (value == null) { if (settings.IncludeDetails) { error = SpecAbsRes.SpecValueTryFromNull; } return(false); } Type type = value.GetType(); if (value is SpecificationValue sv) { result = sv; return(true); } if (TypeHelper.Mapping.ContainsKey(type)) { if (!settings.ExpectedType.HasValue || TypeHelper.Mapping[type] == settings.ExpectedType.Value) { result = Single(value); return(true); } if (TypeHelper.HasMappingOrCast(value, settings.ExpectedType.Value, settings, out object casted)) { result = Single(casted); return(true); } result = null; if (settings.IncludeDetails) { error = string.Format(SpecAbsRes.SpecValueAssumedTypeError, settings.ExpectedType.Value, value, type); } return(false); } if (value is IEnumerable en) { result = new SpecificationValue(); result.ValueMultiplicity = settings.DefaultMultiplicity; List <object> resultValues = new List <object>(5); int j = 0; foreach (object o in en) { if (o == null) { if (settings.IncludeDetails) { error = string.Format(SpecAbsRes.ValueSpecificationElementNull, j); } result = null; return(false); } j++; resultValues.Add(o); } if (resultValues.Count == 0) { if (settings.IncludeDetails) { error = SpecAbsRes.ValueSpecificationZeroCount; } result = null; return(false); } result.Values = resultValues; Type itemType = null; if (settings.ExpectedType.HasValue) { itemType = TypeHelper.Mapping.Single(p => p.Value == settings.ExpectedType.Value).Key; result.ValueType = settings.ExpectedType.Value; } for (int i = 0; i < resultValues.Count; i++) { Type currentType = resultValues[i].GetType(); if (itemType != null) { if (itemType != currentType) { if (TypeHelper.HasMappingOrCast(resultValues[i], result.ValueType, settings, out object casted)) { resultValues[i] = casted; currentType = casted.GetType(); } else { if (settings.IncludeDetails) { if (settings.ExpectedType.HasValue) { error = string.Format(SpecAbsRes.SpecValueAssumedTypeError, settings.ExpectedType.Value, resultValues[i], currentType); } else { error = SpecAbsRes.ValueSpecificationMixedTypes; } } result = null; return(false); } } } itemType = currentType; if (i == 0 && !settings.ExpectedType.HasValue) { if (TypeHelper.Mapping.ContainsKey(itemType)) { result.ValueType = TypeHelper.Mapping[itemType]; } else { if (settings.IncludeDetails) { error = string.Format( SpecAbsRes.SpecificationValueTypeNotSupportedElement, itemType, i, string.Join(", ", TypeHelper.Mapping.Keys)); } result = null; return(false); } } } return(true); } if (settings.IncludeDetails) { error = string.Format( SpecAbsRes.SpecificationValueTypeNotSupported, type, string.Join(", ", TypeHelper.Mapping.Keys)); } return(false); }
private static bool TryFrom( string key, IReadOnlyDictionary <string, object> values, SpecificationValueSettings settings, HashSet <SpecificationValue> processed, out SpecificationValue result, out string error) { result = null; error = null; if (key == null) { throw new ArgumentNullException(nameof(key)); } if (values == null) { throw new ArgumentNullException(nameof(values)); } if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (processed == null) { throw new ArgumentNullException(nameof(processed)); } if (values.ContainsKey(key)) { object value = values[key]; if (TryFrom(value, settings, out result, out error)) { if (result.IsReference) { if (processed.Contains(result)) { if (settings.IncludeDetails) { processed.Add(result); // Add to display correct message error = SpecAbsRes.SpecValueFromCircular + string.Format( SpecAbsRes.SpecValueFromProcessed, string.Join(", ", processed)); } result = null; return(false); } processed.Add(result); string next = result.Values.Single().ToString(); bool tryNext = TryFrom(next, values, settings, processed, out var nextResult, out error); if (tryNext) { result = nextResult; } return(tryNext); } return(true); } if (settings.IncludeDetails && processed.Any()) { error += string.Format(SpecAbsRes.SpecValueFromProcessed, string.Join(", ", processed)); } return(false); } if (settings.IncludeDetails) { error = string.Format(SpecAbsRes.KeyValueSpecificationMissingKey, key); if (processed.Any()) { error += string.Format( SpecAbsRes.SpecValueFromProcessed, string.Join(", ", processed)); } } return(false); }