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); }
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); }
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); }