/// <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);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyMapperCustomBase{TEntity, TProperty}"/> class.
        /// </summary>
        /// <param name="srcePropertyExpression">The <see cref="LambdaExpression"/> to reference the source entity property.</param>
        /// <param name="destPropertyName">The name of the destination property (defaults to <see cref="SrcePropertyName"/> where null).</param>
        /// <param name="operationTypes">The <see cref="Mapper.OperationTypes"/> selection to enable inclusion or exclusion of property (default to <see cref="OperationTypes.Any"/>).</param>
        protected PropertyMapperCustomBase(Expression <Func <TSrce, TSrceProperty> > srcePropertyExpression, string destPropertyName, OperationTypes operationTypes = OperationTypes.Any)
        {
            SrcePropertyExpression = PropertyExpression.Create(srcePropertyExpression ?? throw new ArgumentNullException(nameof(srcePropertyExpression)));
            SrcePropertyInfo       = TypeReflector.GetPropertyInfo(typeof(TSrce), SrcePropertyName);
            DestPropertyName       = string.IsNullOrEmpty(destPropertyName) ? SrcePropertyExpression.Name : destPropertyName;
            OperationTypes         = operationTypes;

            if (SrcePropertyInfo.PropertyType.IsClass && SrcePropertyInfo.PropertyType != typeof(string))
            {
                SrceComplexTypeReflector = ComplexTypeReflector.Create(SrcePropertyInfo);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Recursively find all types (definitions).
        /// </summary>
        private static void FindAllTypes(List <Type> types, Type type)
        {
            foreach (var pi in type.GetProperties())
            {
                var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>();
                if (pcsa != null)
                {
                    if (pi.PropertyType == typeof(List <string>))
                    {
                        continue;
                    }

                    var t = ComplexTypeReflector.GetItemType(pi.PropertyType);
                    if (types.Contains(t))
                    {
                        continue;
                    }

                    types.Add(t);
                    FindAllTypes(types, t);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Writes the schema for the object.
        /// </summary>
        private static void WriteObject(ConfigType ct, Type type, XNamespace ns, XElement xe, bool isRoot)
        {
            var csa = type.GetCustomAttribute <ClassSchemaAttribute>();

            if (csa == null)
            {
                throw new InvalidOperationException($"Type '{type.Name}' does not have a required ClassSchemaAttribute.");
            }

            if (!Enum.TryParse <ConfigurationEntity>(csa.Name, out var ce))
            {
                ce = ConfigurationEntity.CodeGen;
            }

            var xml = new XElement(ns + "element");

            xml.Add(new XAttribute("name", csa.Name));
            if (!isRoot)
            {
                xml.Add(new XAttribute("minOccurs", "0"));
                xml.Add(new XAttribute("maxOccurs", "unbounded"));
            }

            xml.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", csa.Title)));
            var xct = new XElement(ns + "complexType");

            // Add sub-collections within xs:choice element.
            var hasSeq = false;
            var xs     = new XElement(ns + "choice");

            xs.Add(new XAttribute("maxOccurs", "unbounded"));
            foreach (var pi in type.GetProperties())
            {
                var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>();
                if (pcsa == null)
                {
                    continue;
                }

                // Properties with List<string> are not compatible with XML and should be picked up as comma separated strings.
                if (pi.PropertyType == typeof(List <string>))
                {
                    continue;
                }

                WriteObject(ct, ComplexTypeReflector.GetItemType(pi.PropertyType), ns, xs, false);
                hasSeq = true;
            }

            if (hasSeq)
            {
                xct.Add(xs);
            }

            // Add properties as xs:attribute's.
            foreach (var pi in type.GetProperties())
            {
                var jpa = pi.GetCustomAttribute <JsonPropertyAttribute>();
                if (jpa == null)
                {
                    continue;
                }

                var name        = jpa.PropertyName ?? StringConversion.ToCamelCase(pi.Name) !;
                var xmlName     = XmlYamlTranslate.GetXmlName(ct, ce, name);
                var xmlOverride = XmlYamlTranslate.GetXmlPropertySchemaAttribute(ct, ce, xmlName);

                var psa = xmlOverride.Attribute ?? pi.GetCustomAttribute <PropertySchemaAttribute>();
                if (psa == null)
                {
                    // Properties with List<string> are not compatible with XML and should be picked up as comma separated strings.
                    if (pi.PropertyType == typeof(List <string>))
                    {
                        var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>();
                        if (pcsa == null)
                        {
                            continue;
                        }

                        var xpx = new XElement(ns + "attribute",
                                               new XAttribute("name", xmlName),
                                               new XAttribute("use", pcsa.IsMandatory ? "required" : "optional"));

                        xpx.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", GetDocumentation(name, pcsa))));
                        xct.Add(xpx);
                    }

                    continue;
                }

                var xp = new XElement(ns + "attribute",
                                      new XAttribute("name", xmlName),
                                      new XAttribute("use", psa.IsMandatory ? "required" : "optional"));

                xp.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", GetDocumentation(name, psa))));

                if (psa.Options == null)
                {
                    xp.Add(new XAttribute("type", GetXmlType(pi, xmlOverride.Type)));
                }
                else
                {
                    var xr = new XElement(ns + "restriction", new XAttribute("base", GetXmlType(pi, xmlOverride.Type)));
                    foreach (var opt in psa.Options)
                    {
                        xr.Add(new XElement(ns + "enumeration", new XAttribute("value", opt)));
                    }

                    xp.Add(new XElement(ns + "simpleType", xr));
                }

                xct.Add(xp);
            }

            // Add this type into the overall document.
            xml.Add(xct);
            xe.Add(xml);
        }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DictionaryRule{TEntity, TProperty}"/> class.
 /// </summary>
 public DictionaryRule()
 {
     var(kt, vt) = ComplexTypeReflector.GetDictionaryType(typeof(TProperty));
     _keyType    = kt !;
     _valueType  = vt !;
 }
Beispiel #6
0
        /// <summary>
        /// Writes the schema for the object.
        /// </summary>
        private static void WriteObject(Type type, XNamespace ns, XElement xe, bool isRoot)
        {
            var csa = type.GetCustomAttribute <ClassSchemaAttribute>();

            if (csa == null)
            {
                throw new InvalidOperationException($"Type '{type.Name}' does not have a required ClassSchemaAttribute.");
            }

            if (!Enum.TryParse <ConfigurationEntity>(csa.Name, out var ce))
            {
                ce = ConfigurationEntity.CodeGen;
            }

            var xml = new XElement(ns + "element");

            xml.Add(new XAttribute("name", csa.Name));
            if (!isRoot)
            {
                xml.Add(new XAttribute("minOccurs", "0"));
                xml.Add(new XAttribute("maxOccurs", "unbounded"));
            }

            xml.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", csa.Title)));
            var xct = new XElement(ns + "complexType");

            // Add sub-collections within xs:sequence element.
            var hasSeq = false;
            var xs     = new XElement(ns + "sequence");

            foreach (var pi in type.GetProperties())
            {
                var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>();
                if (pcsa == null)
                {
                    continue;
                }

                WriteObject(ComplexTypeReflector.GetItemType(pi.PropertyType), ns, xs, false);
                hasSeq = true;
            }

            if (hasSeq)
            {
                xct.Add(xs);
            }

            // Add properties as xs:attribute's.
            foreach (var pi in type.GetProperties())
            {
                var jpa = pi.GetCustomAttribute <JsonPropertyAttribute>();
                if (jpa == null)
                {
                    continue;
                }

                var psa = pi.GetCustomAttribute <PropertySchemaAttribute>();
                if (psa == null)
                {
                    continue;
                }

                var name = jpa.PropertyName ?? Beef.CodeGen.CodeGenerator.ToCamelCase(pi.Name) !;
                var xp   = new XElement(ns + "attribute",
                                        new XAttribute("name", XmlJsonRename.GetXmlName(ce, name)),
                                        new XAttribute("use", psa.IsMandatory ? "required" : "optional"));

                xp.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", GetDocumentation(name, psa))));

                if (psa.Options == null)
                {
                    xp.Add(new XAttribute("type", GetXmlType(pi)));
                }
                else
                {
                    var xr = new XElement(ns + "restriction", new XAttribute("base", GetXmlType(pi)));
                    foreach (var opt in psa.Options)
                    {
                        xr.Add(new XElement(ns + "enumeration", new XAttribute("value", opt)));
                    }

                    xp.Add(new XElement(ns + "simpleType", xr));
                }

                xct.Add(xp);
            }

            // Add this type into the overall document.
            xml.Add(xct);
            xe.Add(xml);
        }
Beispiel #7
0
        /// <summary>
        /// Writes the object definition.
        /// </summary>
        private static void WriteDefinition(Type type, JsonTextWriter jtw)
        {
            var csa = type.GetCustomAttribute <ClassSchemaAttribute>();

            if (csa == null)
            {
                throw new InvalidOperationException($"Type {type.Name} does not have required ClassSchemaAttribute defined.");
            }

            jtw.WritePropertyName(csa.Name);


            jtw.WriteStartObject();
            jtw.WritePropertyName("type");
            jtw.WriteValue("object");
            jtw.WritePropertyName("title");
            jtw.WriteValue(CleanString(csa.Title) ?? StringConversion.ToSentenceCase(csa.Name) !);
            if (csa.Description != null)
            {
                jtw.WritePropertyName("description");
                jtw.WriteValue(CleanString(csa.Description));
            }

            jtw.WritePropertyName("properties");
            jtw.WriteStartObject();

            var rqd = new List <string>();

            foreach (var pi in type.GetProperties())
            {
                var jpa = pi.GetCustomAttribute <JsonPropertyAttribute>();
                if (jpa == null)
                {
                    continue;
                }

                var name = jpa.PropertyName ?? StringConversion.ToCamelCase(pi.Name) !;
                jtw.WritePropertyName(name);
                jtw.WriteStartObject();

                var psa = pi.GetCustomAttribute <PropertySchemaAttribute>();
                if (psa != null)
                {
                    jtw.WritePropertyName("type");
                    jtw.WriteValue(GetJsonType(pi));
                    jtw.WritePropertyName("title");
                    jtw.WriteValue(CleanString(psa.Title) ?? StringConversion.ToSentenceCase(name) !);
                    if (psa.Description != null)
                    {
                        jtw.WritePropertyName("description");
                        jtw.WriteValue(CleanString(psa.Description));
                    }

                    if (psa.IsMandatory)
                    {
                        rqd.Add(name);
                    }

                    if (psa.Options != null)
                    {
                        jtw.WritePropertyName("enum");
                        jtw.WriteStartArray();

                        foreach (var opt in psa.Options)
                        {
                            jtw.WriteValue(opt);
                        }

                        jtw.WriteEndArray();
                    }
                }
                else
                {
                    var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>();
                    if (pcsa == null)
                    {
                        throw new InvalidOperationException($"Type '{type.Name}' Property '{pi.Name}' does not have a required PropertySchemaAttribute or PropertyCollectionSchemaAttribute.");
                    }

                    jtw.WritePropertyName("type");
                    jtw.WriteValue("array");
                    jtw.WritePropertyName("title");
                    jtw.WriteValue(CleanString(pcsa.Title) ?? StringConversion.ToSentenceCase(name) !);
                    if (pcsa.Description != null)
                    {
                        jtw.WritePropertyName("description");
                        jtw.WriteValue(CleanString(pcsa.Description));
                    }

                    jtw.WritePropertyName("items");

                    if (pi.PropertyType == typeof(List <string>))
                    {
                        jtw.WriteStartObject();
                        jtw.WritePropertyName("type");
                        jtw.WriteValue("string");
                        jtw.WriteEndObject();
                    }
                    else
                    {
                        var t = ComplexTypeReflector.GetItemType(pi.PropertyType);

                        jtw.WriteStartObject();
                        jtw.WritePropertyName("$ref");
                        jtw.WriteValue($"#/definitions/{t.GetCustomAttribute<ClassSchemaAttribute>()!.Name}");
                        jtw.WriteEndObject();
                    }
                }

                jtw.WriteEndObject();
            }

            jtw.WriteEndObject();

            if (rqd.Count > 0)
            {
                jtw.WritePropertyName("required");
                jtw.WriteStartArray();

                foreach (var name in rqd)
                {
                    jtw.WriteValue(name);
                }

                jtw.WriteEndArray();
            }

            jtw.WriteEndObject();
        }
Beispiel #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CollectionRule{TEntity, TProperty}"/> class.
 /// </summary>
 public CollectionRule()
 {
     _itemType = ComplexTypeReflector.GetItemType(typeof(TProperty));
 }
Beispiel #9
0
        /// <summary>
        /// Writes the schema for the object.
        /// </summary>
        private static void WriteObject(Type type, JsonTextWriter jtw, Action?additional = null)
        {
            jtw.WriteStartObject();
            additional?.Invoke();

            jtw.WritePropertyName("type");
            jtw.WriteValue("object");
            jtw.WritePropertyName("properties");
            jtw.WriteStartObject();

            var rqd = new List <string>();

            foreach (var pi in type.GetProperties())
            {
                var jpa = pi.GetCustomAttribute <JsonPropertyAttribute>();
                if (jpa == null)
                {
                    continue;
                }

                var name = jpa.PropertyName ?? Beef.CodeGen.CodeGenerator.ToCamelCase(pi.Name) !;
                jtw.WritePropertyName(name);
                jtw.WriteStartObject();

                var psa = pi.GetCustomAttribute <PropertySchemaAttribute>();
                if (psa != null)
                {
                    jtw.WritePropertyName("type");
                    jtw.WriteValue(GetJsonType(pi));
                    jtw.WritePropertyName("title");
                    jtw.WriteValue(psa.Title ?? Beef.CodeGen.CodeGenerator.ToSentenceCase(name) !);
                    if (psa.Description != null)
                    {
                        jtw.WritePropertyName("description");
                        jtw.WriteValue(psa.Description);
                    }

                    if (psa.IsMandatory)
                    {
                        rqd.Add(name);
                    }

                    if (psa.Options != null)
                    {
                        jtw.WritePropertyName("enum");
                        jtw.WriteStartArray();

                        foreach (var opt in psa.Options)
                        {
                            jtw.WriteValue(opt);
                        }

                        jtw.WriteEndArray();
                    }
                }
                else
                {
                    var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>();
                    if (pcsa == null)
                    {
                        throw new InvalidOperationException($"Type '{type.Name}' Property '{pi.Name}' does not have a required PropertySchemaAttribute or PropertyCollectionSchemaAttribute.");
                    }

                    jtw.WritePropertyName("type");
                    jtw.WriteValue("array");
                    jtw.WritePropertyName("title");
                    jtw.WriteValue(pcsa.Title ?? Beef.CodeGen.CodeGenerator.ToSentenceCase(name) !);
                    if (pcsa.Description != null)
                    {
                        jtw.WritePropertyName("description");
                        jtw.WriteValue(pcsa.Description);
                    }

                    jtw.WritePropertyName("items");
                    jtw.WriteStartArray();

                    WriteObject(ComplexTypeReflector.GetItemType(pi.PropertyType), jtw);

                    jtw.WriteEndArray();
                }

                jtw.WriteEndObject();
            }

            jtw.WriteEndObject();

            if (rqd.Count > 0)
            {
                jtw.WritePropertyName("required");
                jtw.WriteStartArray();

                foreach (var name in rqd)
                {
                    jtw.WriteValue(name);
                }

                jtw.WriteEndArray();
            }

            jtw.WriteEndObject();
        }