public void Render(ITableBuilder tableBuilder, object model, RenderingTemplate template)
        {
            var lastRow = template.Content.Cells.LastOrDefault();

            foreach (var row in template.Content.Cells)
            {
                foreach (var cell in row)
                {
                    tableBuilder.PushState(new Style(cell));

                    if (TemplateDescriptionHelper.IsCorrectFormValueDescription(cell.StringValue))
                    {
                        RenderFormControl(tableBuilder, model, cell);
                    }
                    else
                    {
                        RenderCellularValue(tableBuilder, model, cell);
                    }

                    tableBuilder.PopState();
                }
                if (!row.Equals(lastRow))
                {
                    tableBuilder.MoveToNextLayer();
                }
            }
            MergeCells(tableBuilder, template);
            ResizeColumns(tableBuilder, template);
        }
        public TModel Parse <TModel>([NotNull] ITableParser tableParser, [NotNull] RenderingTemplate template, Action <string, string> addFieldMapping)
            where TModel : new()
        {
            var model = new TModel();

            var enumerablesLengths = GetEnumerablesLengths <TModel>(tableParser, template);

            foreach (var row in template.Content.Cells)
            {
                foreach (var cell in row)
                {
                    tableParser.PushState(cell.CellPosition);

                    var expression = cell.StringValue;

                    if (TemplateDescriptionHelper.IsCorrectValueDescription(expression))
                    {
                        ParseCellularValue(tableParser, addFieldMapping, model, ExcelTemplatePath.FromRawExpression(expression), enumerablesLengths);
                        continue;
                    }
                    if (TemplateDescriptionHelper.IsCorrectFormValueDescription(expression))
                    {
                        ParseFormValue(tableParser, addFieldMapping, model, cell, ExcelTemplatePath.FromRawExpression(expression));
                        continue;
                    }

                    tableParser.PopState();
                }
            }

            return(model);
        }
 public void TemplateCoordinatesTest()
 {
     TemplateDescriptionHelper.TryExtractCoordinates("Template:qwe:QWE123:ASD987", out var range).Should().BeTrue();
     range.UpperLeft.ColumnIndex.Should().Be(26 * 26 + 19 * 26 + 4);
     range.UpperLeft.RowIndex.Should().Be(123);
     range.LowerRight.ColumnIndex.Should().Be(17 * 26 * 26 + 23 * 26 + 5);
     range.LowerRight.RowIndex.Should().Be(987);
 }
        private static object ExtractChildModel(object model, ICell cell)
        {
            var expression = cell.StringValue;

            if (!TemplateDescriptionHelper.IsCorrectValueDescription(expression))
            {
                return(expression ?? "");
            }
            return(ExtractChildIfCorrectDescription(expression, model) ?? "");
        }
        private static (string formControlType, string formControlName) GetFormControlDescription([NotNull] ICell cell)
        {
            var formControlDescription = TemplateDescriptionHelper.TryGetFormControlFromValueDescription(cell.StringValue);

            if (string.IsNullOrEmpty(formControlDescription.formControlType) || formControlDescription.formControlName == null)
            {
                throw new InvalidOperationException($"Invalid xlsx template. '{cell.StringValue}' is not a valid form control description.");
            }
            return(formControlDescription);
        }
        private void RenderFormControl(ITableBuilder tableBuilder, object model, ICell cell)
        {
            var childModel = StrictExtractChildModel(model, cell);

            if (childModel != null)
            {
                var(controlType, controlName) = TemplateDescriptionHelper.TryGetFormControlFromValueDescription(cell.StringValue);
                var renderer = rendererCollection.GetFormControlRenderer(controlType, childModel.GetType());
                renderer.Render(tableBuilder, controlName, childModel);
            }
            tableBuilder.SetCurrentStyle();
            tableBuilder.MoveToNextColumn();
        }
        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 AddNewTemplateIntoCache(string templateName)
        {
            cache.Add(templateName, null);

            var cell = SearchTemplateDescription(templateName);

            if (cell == null)
            {
                return;
            }

            if (!TemplateDescriptionHelper.TryExtractCoordinates(cell.StringValue, out var range))
            {
                return;
            }

            var newTemplate = BuildNewRenderingTemplate(range);

            if (newTemplate.IsValid())
            {
                cache[templateName] = newTemplate;
            }
        }
 private static string ExtractTemplateName(ICell cell)
 {
     return(TemplateDescriptionHelper.GetTemplateNameFromValueDescription(cell.StringValue));
 }
 public void TestIsCollectionAccessPathPartReturnsFalse(string pathPart)
 {
     TemplateDescriptionHelper.IsCollectionAccessPathPart(pathPart).Should().BeFalse();
 }
 public void TestIsCorrectFormValueDescriptionReturnsFalse(string description)
 {
     TemplateDescriptionHelper.IsCorrectFormValueDescription(description).Should().BeFalse();
 }
 public void ValueDescriptionCorrectnessTest(string expression, bool isCorrect)
 {
     TemplateDescriptionHelper.IsCorrectValueDescription(expression).Should().Be(isCorrect);
 }
 public void TestIsIsArrayPathPartReturnsTrue(string pathPart)
 {
     TemplateDescriptionHelper.IsArrayPathPart(pathPart).Should().BeTrue();
 }