private ReferenceContext(string segment, ReferenceContext parent, TableStore store, ClassMapping cMapping)
        {
            Store    = store;
            CMapping = cMapping;

            //init lists
            Children      = new List <ReferenceContext>();
            ParentContext = parent;

            //try to extract TypeOf part of the path
            var parts = segment.Split('\\');

            segment = parts[0];
            var typeHint = parts.Length > 1 ? parts[1] : null;

            Segment = segment;

            //set up path type hint if it is defined
            if (!string.IsNullOrWhiteSpace(typeHint))
            {
                PathTypeHint = Store.MetaData.ExpressType(typeHint.ToUpper());
            }

            if (segment == "parent")
            {
                PathTypeHint = Store.MetaData.ExpressType(CMapping.ParentClass.ToUpper());
                ContextType  = ReferenceContextType.Parent;
                return;
            }

            Index        = TableStore.GetPropertyIndex(ref segment);
            PropertyInfo = Store.GetPropertyInfo(segment, parent.SegmentType, Index);
            MetaProperty = Store.GetProperty(parent.SegmentType, segment);
            var info = PropertyInfo != null
                    ? PropertyInfo.PropertyType
                    : (MetaProperty != null
                        ? MetaProperty.EnumerableType ?? MetaProperty.PropertyInfo.PropertyType
                        : null);

            if (info == null)
            {
                Store.Log.WriteLine("Type {0} doesn't have a property {1}.", parent.PathTypeHint.ExpressName, segment);
                return;
            }

            PropertyTypeHint = Store.MetaData.ExpressType(MetaProperty != null ?
                                                          MetaProperty.EnumerableType ?? MetaProperty.PropertyInfo.PropertyType :
                                                          (PropertyInfo != null ? PropertyInfo.PropertyType : null)
                                                          );


            //set up type of the context
            var isEnumerable = MetaProperty != null && MetaProperty.EnumerableType != null;

            if (isEnumerable)
            {
                if (MetaProperty.EnumerableType.IsValueType ||
                    MetaProperty.EnumerableType == typeof(string) ||
                    typeof(IExpressValueType).IsAssignableFrom(MetaProperty.EnumerableType))
                {
                    ContextType = ReferenceContextType.ScalarList;
                }
                else
                {
                    ContextType = ReferenceContextType.EntityList;
                }
            }
            else
            {
                if (info.IsValueType ||
                    info == typeof(string) ||
                    typeof(IExpressValueType).IsAssignableFrom(info))
                {
                    ContextType = ReferenceContextType.Scalar;
                }
                else
                {
                    ContextType = ReferenceContextType.Entity;
                }
            }
        }
Example #2
0
        private void Store(ISheet sheet, IPersistEntity entity, ClassMapping mapping, ExpressType expType, EntityContext context)
        {
            var             multiRow     = -1;
            List <string>   multiValues  = null;
            PropertyMapping multiMapping = null;
            var             row          = GetRow(sheet);

            //fix on "Special Case" Assembly Row to Entity mapping
            if ((context?.RootEntity != null) && (expType?.ExpressNameUpper == "TYPEORCOMPONENT"))  //without CobieExpress reference and not using reflection this is as good as it gets to ID Assembly
            {
                RowNoToEntityLabelLookup[sheet.SheetName].Add(row.RowNum, context.RootEntity.EntityLabel);
            }
            else
            {
                RowNoToEntityLabelLookup[sheet.SheetName].Add(row.RowNum, entity.EntityLabel);
            }

            foreach (var propertyMapping in mapping.PropertyMappings)
            {
                object value = null;
                foreach (var path in propertyMapping.Paths)
                {
                    value = GetValue(entity, expType, path, context);
                    if (value != null)
                    {
                        break;
                    }
                }
                if (value == null && propertyMapping.Status == DataStatus.Required)
                {
                    value = propertyMapping.DefaultValue ?? "n/a";
                }

                var isMultiRow = IsMultiRow(value, propertyMapping);
                if (isMultiRow)
                {
                    multiRow = row.RowNum;
                    var values     = new List <string>();
                    var enumerable = value as IEnumerable <string>;
                    if (enumerable != null)
                    {
                        values.AddRange(enumerable);
                    }

                    //get only first value and store it
                    var first = values.First();
                    Store(row, first, propertyMapping);

                    //set the rest for the processing as multiValue
                    values.Remove(first);
                    multiValues  = values;
                    multiMapping = propertyMapping;
                }
                else
                {
                    Store(row, value, propertyMapping);
                }
            }

            //adjust width of the columns after the first and the eight row
            //adjusting fully populated workbook takes ages. This should be almost all right
            if (row.RowNum == 1 || row.RowNum == 8)
            {
                AdjustAllColumns(sheet, mapping);
            }

            //it is not a multi row so return
            if (multiRow <= 0 || multiValues == null || !multiValues.Any())
            {
                return;
            }

            //add repeated rows if necessary
            foreach (var value in multiValues)
            {
                var rowNum = GetNextRowNum(sheet);
                var copy   = sheet.CopyRow(multiRow, rowNum);
                Store(copy, value, multiMapping);
                RowNoToEntityLabelLookup[sheet.SheetName].Add(rowNum, entity.EntityLabel);
            }
        }