/// <summary> /// Gets the underlying hierarchy for an item. /// </summary> private static void Get(FileFormatBase fileFormat, Dictionary <string, FileRecordHierarchyItem> dict, FileRecordHierarchyItem item, PropertyInfo pi) { if (dict.ContainsKey(item.RecordIdentifier)) { throw new InvalidOperationException(string.Format("Type '{0}' property '{1}' FileHierarchyAttribute has a duplicate Record Identifier '{2}'; must be unique within hierarchy).", pi.DeclaringType.Name, pi.Name, item.RecordIdentifier)); } if (fileFormat.HeaderRecordIdentifier != null && item.RecordIdentifier == fileFormat.HeaderRecordIdentifier) { throw new InvalidOperationException(string.Format("Type '{0}' property '{1}' FileHierarchyAttribute has a duplicate Record Identifier '{2}'; must be different to the Header Record Identifier).", pi.DeclaringType.Name, pi.Name, item.RecordIdentifier)); } if (fileFormat.TrailerRecordIdentifier != null && item.RecordIdentifier == fileFormat.TrailerRecordIdentifier) { throw new InvalidOperationException(string.Format("Type '{0}' property '{1}' FileHierarchyAttribute has a duplicate Record Identifier '{2}'; must be different to the Trailer Record Identifier).", pi.DeclaringType.Name, pi.Name, item.RecordIdentifier)); } dict.Add(item.RecordIdentifier, item); if (item.RecordReflector.Children == null || item.RecordReflector.Children.Length == 0) { return; } foreach (var fhr in item.RecordReflector.Children) { var frhh = new FileRecordHierarchyItem { RecordIdentifier = fhr.RecordIdentifier, Level = item.Level + 1, Parent = item, RecordReflector = fileFormat.GetFileRecordReflector(fhr.PropertyType), HierarchyReflector = fhr }; Get(fileFormat, dict, frhh, fhr.PropertyInfo); item.Children.Add(frhh.RecordIdentifier, frhh); } }
/// <summary> /// Initializes a new instance of the <see cref="FileHierarchyReflector"/> class. /// </summary> /// <param name="index">The <see cref="Index"/>.</param> /// <param name="fh">The <see cref="FileHierarchy"/>.</param> /// <param name="pi">The <see cref="PropertyInfo"/>.</param> /// <param name="ff">The <see cref="FileFormat"/>.</param> internal FileHierarchyReflector(int index, FileHierarchyAttribute fh, PropertyInfo pi, FileFormatBase ff) { Index = index; Order = fh.Order < 0 ? int.MaxValue : fh.Order; FileHierarchy = fh; PropertyInfo = pi; FileFormat = ff; // Where an intrinsic type then we have an issue. if (FileColumnReflector.GetTypeCode(PropertyInfo.PropertyType) != TypeCode.Object) { throw new ArgumentException($"Type '{PropertyInfo.DeclaringType.Name}' Property '{PropertyInfo.Name}' must be a class or collection (FileHierarchyAttribute).", nameof(pi)); } // Determine the collection type. _collTypeReflector = ComplexTypeReflector.Create(PropertyInfo); // Load/cache the corresponding property type. var frr = (_collTypeReflector.ComplexTypeCode == ComplexTypeCode.Object) ? FileFormat.GetFileRecordReflector(PropertyInfo.PropertyType) : FileFormat.GetFileRecordReflector(_collTypeReflector.ItemType); if (fh.ValidationType != null) { frr.SetValidatorType(fh.ValidationType); } }
/// <summary> /// Gets the underlying hierarchy for the specified <see cref="FileFormatBase"/>. /// </summary> /// <param name="fileFormat">The <see cref="FileFormatBase"/>.</param> /// <returns>A dictionary containing the full hierarchy.</returns> public static Dictionary <string, FileRecordHierarchyItem> GetHierarchy(FileFormatBase fileFormat) { var dict = new Dictionary <string, FileRecordHierarchyItem>(); Get(fileFormat, dict, new FileRecordHierarchyItem { RecordIdentifier = fileFormat.ContentRecordIdentifier, Level = 0, Parent = null, RecordReflector = fileFormat.GetFileRecordReflector(fileFormat.ContentRowType) }, null); return(dict); }