public int GetLength(ITableParser tableParser, Type modelType, IEnumerable <ICell> primaryParts) { var parserState = new List <(IAtomicValueParser parser, ICell cell, Type itemType)>(); foreach (var primaryPart in primaryParts) { var childModelPath = ExcelTemplatePath.FromRawExpression(primaryPart.StringValue); var childModelType = ObjectPropertiesExtractor.ExtractChildObjectTypeFromPath(modelType, childModelPath); var parser = parserCollection.GetAtomicValueParser(); parserState.Add((parser, primaryPart, childModelType)); } for (var i = 0; i <= ParsingParameters.MaxEnumerableLength; i++) { var parsed = false; foreach (var(parser, cell, type) in parserState) { tableParser.PushState(cell.CellPosition.Add(new ObjectSize(0, i))); if (parser.TryParse(tableParser, type, out var result) && result != null) { parsed = true; } tableParser.PopState(); } if (!parsed) { return(i); } } throw new EnumerableTooLongException(ParsingParameters.MaxEnumerableLength); }
public void NullArrayExtractionTestWithBraces() { const string valueDesription = "Value::Bs[]"; var child = ObjectPropertiesExtractor.ExtractChildObject(new A(), ExcelTemplatePath.FromRawExpression(valueDesription)); child.Should().BeNull(); }
public static ImmutableArrayDictionary <string, object> WithObjectProperties <T>( this ImmutableArrayDictionary <string, object> properties, T @object, bool allowOverwrite, bool allowNullValues) { if (@object == null) { return(properties); } var pairs = @object is IReadOnlyDictionary <string, object> dictionary ? dictionary.Select(pair => (pair.Key, pair.Value)) : ObjectPropertiesExtractor.ExtractProperties(@object); foreach (var(name, value) in pairs) { if (!allowNullValues && value == null) { continue; } properties = properties.Set(name, value, allowOverwrite); } return(properties); }
public void AllNullValuesArrayExtractionTest() { const string valueDesription = "Value::Bs[]"; var localModel = new A { Bs = new B[] { null, null, null } }; var child = ObjectPropertiesExtractor.ExtractChildObject(localModel, ExcelTemplatePath.FromRawExpression(valueDesription)); var childArray = child as object[]; childArray.Should().BeEquivalentTo(localModel.Bs); }
public void ComplexObjectsArrayExtractionTest() { const string valueDesription = "Value::Bs[].Cs[]"; var child = ObjectPropertiesExtractor.ExtractChildObject(model, ExcelTemplatePath.FromRawExpression(valueDesription)); var childArray = child as object[]; childArray.Should().NotBeNull(); childArray.Length.Should().Be(2); childArray[0].Should().BeEquivalentTo(model.Bs[0].Cs); childArray[1].Should().BeEquivalentTo(model.Bs[1].Cs); }
private static object ExtractChildIfCorrectDescription(string expression, object model) { var excelTemplatePath = ExcelTemplatePath.FromRawExpression(expression); try { return(ObjectPropertiesExtractor.ExtractChildObject(model, excelTemplatePath)); } catch (ObjectPropertyExtractionException exception) { throw new InvalidOperationException($"Failed to extract child by path '{excelTemplatePath.RawPath}' in model of type {model.GetType()}", exception); } }
private void ParseCellularValue(ITableParser tableParser, Action <string, string> addFieldMapping, object model, ExcelTemplatePath path, Dictionary <ExcelTemplatePath, int> enumerablesLengths) { var leafSetter = ObjectPropertySettersExtractor.ExtractChildObjectSetter(model, path); var leafModelType = ObjectPropertiesExtractor.ExtractChildObjectTypeFromPath(model.GetType(), path); if (path.HasArrayAccess) { ParseEnumerableValue(tableParser, addFieldMapping, model, path, leafSetter, leafModelType, enumerablesLengths); } else { ParseSingleValue(tableParser, addFieldMapping, leafSetter, path, leafModelType); } }
private Dictionary <ExcelTemplatePath, int> GetEnumerablesLengths <TModel>([NotNull] ITableParser tableParser, [NotNull] RenderingTemplate template) { var enumerableCellsGroups = new Dictionary <ExcelTemplatePath, List <ICell> >(); foreach (var row in template.Content.Cells) { foreach (var cell in row) { var expression = cell.StringValue; if (TemplateDescriptionHelper.IsCorrectValueDescription(expression) && ExcelTemplatePath.FromRawExpression(expression).HasArrayAccess) { var cleanPathToEnumerable = ExcelTemplatePath.FromRawExpression(expression) .SplitForEnumerableExpansion() .pathToEnumerable .WithoutArrayAccess(); if (!enumerableCellsGroups.ContainsKey(cleanPathToEnumerable)) { enumerableCellsGroups[cleanPathToEnumerable] = new List <ICell>(); } enumerableCellsGroups[cleanPathToEnumerable].Add(cell); } } } var enumerablesLengths = new Dictionary <ExcelTemplatePath, int>(); foreach (var enumerableCells in enumerableCellsGroups) { var cleanPathToEnumerable = enumerableCells.Key; var childEnumerableType = ObjectPropertiesExtractor.ExtractChildObjectTypeFromPath(typeof(TModel), cleanPathToEnumerable); if (!TypeCheckingHelper.IsIList(childEnumerableType)) { throw new InvalidOperationException($"Only ILists are supported as collections, but tried to use '{childEnumerableType}'. (path: {cleanPathToEnumerable.RawPath})"); } var primaryParts = enumerableCells.Value.Where(x => ExcelTemplatePath.FromRawExpression(x.StringValue).HasPrimaryKeyArrayAccess).ToList(); if (primaryParts.Count == 0) { primaryParts = enumerableCells.Value.Take(1).ToList(); } var measurer = parserCollection.GetEnumerableMeasurer(); enumerablesLengths[cleanPathToEnumerable] = measurer.GetLength(tableParser, typeof(TModel), primaryParts); } return(enumerablesLengths); }
private void ParseFormValue(ITableParser tableParser, Action <string, string> addFieldMapping, object model, ICell cell, ExcelTemplatePath path) { var childSetter = ObjectPropertySettersExtractor.ExtractChildObjectSetter(model, path); var childModelType = ObjectPropertiesExtractor.ExtractChildObjectTypeFromPath(model.GetType(), path); var(childFormControlType, childFormControlName) = GetFormControlDescription(cell); if (path.HasArrayAccess) { throw new InvalidOperationException("Enumerables are not supported for form controls"); } var parser = parserCollection.GetFormValueParser(childFormControlType, childModelType); var parsedObject = parser.ParseOrDefault(tableParser, childFormControlName, childModelType); childSetter(parsedObject); addFieldMapping(path.RawPath, childFormControlName); }
public static LogEvent WithObjectProperties <T>(this LogEvent @event, T @object, bool allowOverwrite = true, bool allowNullValues = true) { if (@object == null) { return(@event); } foreach (var(name, value) in ObjectPropertiesExtractor.ExtractProperties(@object)) { if (!allowNullValues && value == null) { continue; } @event = @event.WithProperty(name, value, allowOverwrite); } return(@event); }
private void ParseEnumerableValue(ITableParser tableParser, Action <string, string> addFieldMapping, object model, ExcelTemplatePath path, Action <object> leafSetter, Type leafModelType, Dictionary <ExcelTemplatePath, int> enumerablesLengths) { var(rawPathToEnumerable, childPath) = path.SplitForEnumerableExpansion(); var cleanPathToEnumerable = rawPathToEnumerable.WithoutArrayAccess(); var enumerableType = ObjectPropertiesExtractor.ExtractChildObjectTypeFromPath(model.GetType(), cleanPathToEnumerable); if (!typeof(IList).IsAssignableFrom(enumerableType)) { throw new Exception($"Only ILists are supported as collections, but tried to use '{enumerableType}'. (path: {cleanPathToEnumerable.RawPath})"); } var parser = parserCollection.GetEnumerableParser(enumerableType); var count = enumerablesLengths[cleanPathToEnumerable]; var parsedList = parser.Parse(tableParser, leafModelType, count, (name, value) => addFieldMapping($"{cleanPathToEnumerable.RawPath}{name}.{childPath.RawPath}", value)); leafSetter(parsedList); }
private static void InnerSerialize(object obj, StringBuilder sb, string keyPrefix = null) { if (obj == null) { sb.AppendLine($"{keyPrefix ?? "value"} = "); return; } var type = obj.GetType(); if (TypeIsSimple(type)) { sb.AppendLine($"{keyPrefix ?? "value"} = " + obj); } else if (IsSimpleDictionary(type)) { foreach (var(key, value) in DictionaryInspector.EnumerateSimpleDictionary(obj)) { InnerSerialize(value, sb, keyPrefix == null ? key : $"{keyPrefix}.{key}"); } } else if (obj is IEnumerable) { InnerSerialize(null, sb, keyPrefix); } else if (HasCustomToString(type)) { InnerSerialize(obj.ToString(), sb, keyPrefix); } else if (HasPublicProperties(type)) { foreach (var(key, value) in ObjectPropertiesExtractor.ExtractProperties(obj)) { InnerSerialize(value, sb, keyPrefix == null ? key : $"{keyPrefix}.{key}"); } } else { sb.AppendLine($"{keyPrefix ?? "value"} = " + obj); } }
private static bool HasPublicProperties(Type type) => ObjectPropertiesExtractor.HasProperties(type);