Exemple #1
0
        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);