Esempio n. 1
0
        /// <summary>
        /// writes the given object to the StreamWriter
        ///
        /// throws
        /// - ArgumentException if the gedcomLine is a GedcomLine and no tagStr (gedcomLine.tagStr) is given
        /// </summary>
        /// <param name="gedcomLine">the gedcom line that should be written</param>
        /// <param name="tagStr"></param>
        /// <param name="streamWriter">the stream writer that the line should be written to</param>
        /// <param name="level">the level of the line</param>
        /// <param name="path">the path for the current object</param>
        private void WriteObject(object gedcomLine, string tagStr, StreamWriter streamWriter, int level, string path)
        {
            var lineV = new Line {
                Level = level, TagName = tagStr
            };

            if (gedcomLine is GedcomLine)
            {
                try
                {
                    var lineValueProperty = TagUtil.GetMember(gedcomLine, "", true, false);

                    var obj = lineValueProperty.GetValue(gedcomLine, null);

                    if (obj == null)
                    {
                        lineV.LineValue = "";
                    }
                    else
                    {
                        lineV.LineValue = obj.ToString();
                    }

                    if (lineV.LineValue.Length > LengthUtil.GetMaximumLength(lineValueProperty))
                    {
                        reporting.Warn("line-value too long");
                    }

                    if (lineV.LineValue.Length < LengthUtil.GetMinimumLength(lineValueProperty))
                    {
                        reporting.Warn("line-value too short");
                    }
                }
                catch (MemberNotFoundException)
                {
                    lineV.LineValue = "";
                }

                if (gedcomLine is Record record)
                {
                    lineV.XRefId = record.XRef;
                }
            }
            else if (gedcomLine.GetType().IsEnum)
            {
                lineV.LineValue = EnumTagUtil.GetFirstTagName(gedcomLine as ValueType);
            }
            else
            {
                lineV.LineValue = gedcomLine.ToString();
            }

            WriteLine(lineV, streamWriter);

            foreach (var type in TagUtil.GetTags(gedcomLine.GetType()))
            {
                var prop       = type.Key;
                var defaultTag = TagUtil.GetTagName(prop);

                if (!prop.CanRead)
                {
                    continue;
                }

                var minOccur = QuantityUtil.GetMinimum(prop);
                var maxOccur = QuantityUtil.GetMaximum(prop);

                var obj = prop.GetValue(gedcomLine, null);

                if (TagUtil.IsDefaultValue(prop, obj))
                {
                    if (minOccur > 0)
                    {
                        reporting.Warn(
                            $"object {prop.Name} in {path} must occur at least {minOccur} time(s), but was not set");
                    }

                    continue;
                }

                // use a loop, event its just a single object to avoid redundant code
                var tmpList     = ImplementsIList(prop.PropertyType) ? obj as IList : new[] { obj };
                var occurrences = 0;

                foreach (var o in tmpList)
                {
                    occurrences++;

                    string tag;
                    if (o is GedcomLine)
                    {
                        var line = o as GedcomLine;
                        line.Tag = GetTag(type.Value, line);

                        tag = line.Tag;
                    }
                    else
                    {
                        tag = defaultTag;
                    }

                    if (tag == "")
                    {
                        continue;
                    }

                    try
                    {
                        WriteObject(o, tag, streamWriter, level + 1, path + "/" + tag);
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }

                if (occurrences < minOccur)
                {
                    reporting.Warn(
                        $"object {prop.Name} in {path} must occur at least {minOccur} time(s), but occured only {occurrences} time(s)");
                }

                if (occurrences > maxOccur)
                {
                    reporting.Warn(
                        $"object {prop.Name} in {path} can only occur {maxOccur} time(s), but occured {occurrences} time(s)");
                }
            }
        }