Example #1
0
        /// <summary>
        /// Declares 'field' members for a type.
        /// That is, all fields that apply to this type, either directly or through inheritance.
        /// </summary>
        /// <param name="entityType">The type entity.</param>
        /// <param name="memberGroup">The XSD container that will hold the members.</param>
        private void AddTypeFields(EffectiveType entityType, XmlSchemaGroupBase memberGroup)
        {
            // Example:
            // <xs:element minOccurs="0" maxOccurs="1" ref="firstName" />

            // Define fields applicable to type
            // This is defining that a given field can appear under a resource of a particular type
            var fields =
                from type in _schemaManager.GetAncestors(entityType.Type)
                from field in _schemaManager.GetDeclaredFields(type)
                select field;

            foreach (Entity field in fields)
            {
                if (field.Alias == null)
                {
                    continue;
                }
                var fieldElem = new XmlSchemaElement();
                fieldElem.RefName   = NameUsed(field.Alias.ToQualifiedName());
                fieldElem.MaxOccurs = 1;

                bool required =
                    (_schemaManager.GetBoolFieldValue(field, Aliases2.IsRequired) &&
                     _schemaManager.GetStringFieldValue(field, Aliases2.DefaultValue) == null
                    ) ||
                    field.Alias == Aliases.Alias;       // special case: alias is required in config, but not at runtime

                fieldElem.MinOccurs = required ? 1 : 0;
                memberGroup.Items.Add(fieldElem);
            }
        }
Example #2
0
        private bool TryParseToPredicateType(string s, out object value)
        {
            value = null;
            if (ValueIsNull(s))
            {
                return(!IsNullable);
            }

            if (EffectiveType.Is <string>())
            {
                value = s;
                return(true);
            }
            else if (DataType == PredicateDataType.Number)
            {
                var r = TryParseNumber(s, typeof(decimal), out value);
                value = NumericTypeHelper.NarrowNumber(value);
                return(r);
            }
            else if (DataType == PredicateDataType.Boolean)
            {
                var r = TryParseBool(s, out var b); value = b; return(r);
            }
            else if (DataType == PredicateDataType.DateTime)
            {
                var r = TryParseDateTime(s, out var d); value = d; return(r);
            }
            else if (DataType == PredicateDataType.TimeSpan)
            {
                var r = TryParseTimeSpan(s, out var t); value = t; return(r);
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Declares the element type for this entity. Refers to the the complex type that describes the members.
        /// Is referred to by the 'is a' groups.
        /// </summary>
        /// <param name="entityType">The type entity.</param>
        private void AddTypeElement(EffectiveType entityType, XmlSchema xsd)
        {
            // Example:
            //<xs:element name="person" type="type_person" />

            var typeElement = new XmlSchemaElement();

            typeElement.Name           = NameDeclared(entityType.Alias.Value, entityType.Alias.Namespace);
            typeElement.SchemaTypeName = entityType.Alias.ToQualifiedName(prefix: "type_");
            xsd.Items.Add(typeElement);
        }
Example #4
0
        /// <summary>
        /// Creates a group that contains all of the types that inherit from a given type,
        /// as well as the type itself. Reference this group when any inherited type is suitable.
        /// </summary>
        private void AddTypeDescendents(EffectiveType entityType, XmlSchema xsd)
        {
            // Example of inheritance declaration
            //<xs:group name="is_person">
            //  <xs:choice>
            //    <xs:element ref="person" />
            //    <xs:element ref="employee" />
            //    <xs:element ref="manager" />
            //  </xs:choice>
            //</xs:group>

            // Create a group, named "is_%typename%"
            var isType = new XmlSchemaGroup();

            isType.Name     = NameDeclared("is_" + entityType.Alias.Value, entityType.Alias.Namespace);
            isType.Particle = new XmlSchemaChoice();

            // Determine valid descendents
            IEnumerable <Entity> descendents;
            bool isSealed = _schemaManager.GetBoolFieldValue(entityType.Type, Aliases2.IsSealed);

            if (isSealed)
            {
                descendents = new List <Entity> {
                    entityType.Type
                }
            }
            ;
            else
            {
                descendents = _schemaManager.GetDecendants(entityType.Type);
            }

            // Render each type
            foreach (EffectiveType desc in EffectiveTypes(descendents))
            {
                bool isAbstract = _schemaManager.GetBoolFieldValue(desc.Type, Aliases2.IsAbstract);
                if (isAbstract)
                {
                    continue;
                }

                var derivedType = new XmlSchemaElement();
                derivedType.RefName = NameUsed(desc.Alias.ToQualifiedName());
                isType.Particle.Items.Add(derivedType);
            }
            xsd.Items.Add(isType);
        }
Example #5
0
        /// <summary>
        /// Given a stream of types, returns a stream of types where any 'relationship' types are duplicated so that their
        /// reverse alias also appears in the output stream.
        /// Caution: remember to invert the from/to types, and the cardinality, as applicable.
        /// </summary>
        /// <param name="types"></param>
        /// <returns></returns>
        IEnumerable <EffectiveType> EffectiveTypes(IEnumerable <Entity> types)
        {
            foreach (var type in types)
            {
                bool isRelationship = _schemaManager.IsInstance(type, A(Aliases.Relationship));
                if (isRelationship)
                {
                    continue;
                }

                var et = new EffectiveType()
                {
                    Type = type, Alias = type.Alias
                };
                yield return(et);
            }
        }
Example #6
0
        /// <summary>
        /// Declares 'field' members for a type.
        /// That is, all fields that apply to this type, either directly or through inheritance.
        /// </summary>
        /// <param name="entityType">The type entity.</param>
        private void AddTypeMembers(EffectiveType entityType, XmlSchema xsd)
        {
            // Example of member declaration
            // This contains both fields and relationships (and reverse relationships)
            //<xs:complexType name="type_person">
            //  <xs:all>
            //    <!-- fields -->
            //    <xs:element minOccurs="0" maxOccurs="1" ref="name" />
            //    <xs:element minOccurs="0" maxOccurs="1" ref="description" />
            //    <xs:element minOccurs="0" maxOccurs="1" ref="alias" />
            //    <xs:element minOccurs="0" maxOccurs="1" ref="firstName" />
            //    <xs:element minOccurs="0" maxOccurs="1" ref="lastName" />
            //    <!-- relationships -->
            //    <xs:element minOccurs="0" maxOccurs="1" ref="worksFor" />
            //  </xs:all>
            //</xs:complexType>

            // Create a complex type, named "type_%typename%"
            var typeMembers = new XmlSchemaComplexType();

            typeMembers.Name = NameDeclared("type_" + entityType.Alias.Value, entityType.Alias.Namespace);

            // Create a group to hold the members
            var memberGroup = new XmlSchemaAll();

            typeMembers.Particle = memberGroup;

            // Add members
            AddTypeFields(entityType, memberGroup);
            AddTypeRelationships(entityType, memberGroup);

            // Add 'source' attribute for file types
            Entity file = _aliasResolver[Aliases2.File];

            if (_schemaManager.IsSameOrDerivedType(entityType.Type, file))
            {
                XmlSchemaAttribute sourceAttrib = new XmlSchemaAttribute();
                sourceAttrib.Name           = "source";
                sourceAttrib.SchemaTypeName = XmlSchemaSimpleType.GetBuiltInSimpleType(XmlTypeCode.String).QualifiedName;
                typeMembers.Attributes.Add(sourceAttrib);
            }

            xsd.Items.Add(typeMembers);
        }
Example #7
0
        /// <summary>
        /// Declares 'relationship' members for a type.
        /// That is, all forward or reverse relationships that can connect to this type at one end or the other.
        /// </summary>
        /// <param name="entityType">The type entity.</param>
        /// <param name="memberGroup">The XSD container that will hold the members.</param>
        private void AddTypeRelationships(EffectiveType entityType, XmlSchemaGroupBase memberGroup)
        {
            // Define relationships applicable to type
            // This is defining that a given relationship container can appear under a resource of a particular type
            // e.g. <xs:element ref="worksFor" minOccurs="0" maxOccurs="1"/>
            // Note: maxOccurs refers to the relationship container, not the cardinality of the relationship itself.

            var relationships =
                from type in _schemaManager.GetAncestors(entityType.Type)
                from relationshipDefn in _schemaManager.GetRelationshipsToEntity(type, A(Aliases.FromType))
                select new { Relationship = relationshipDefn, Alias = relationshipDefn.Alias };

            var relationshipsRev =
                from type in _schemaManager.GetAncestors(entityType.Type)
                from relationshipDefn in _schemaManager.GetRelationshipsToEntity(type, A(Aliases.ToType))
                select new { Relationship = relationshipDefn, Alias = relationshipDefn.ReverseAlias };

            HashSet <XmlQualifiedName> hash = new HashSet <XmlQualifiedName>();

            foreach (var rel in relationships.Concat(relationshipsRev))
            {
                if (rel.Alias == null || string.IsNullOrEmpty(rel.Alias.Value))
                {
                    continue;
                }
                var fieldElem = new XmlSchemaElement();
                fieldElem.MaxOccurs = 1;    // the relationship container, not the relationships themselves
                fieldElem.MinOccurs = 0;
                fieldElem.RefName   = NameUsed(rel.Alias.ToQualifiedName());
                if (hash.Contains(fieldElem.RefName))
                {
                    throw new Exception("Already used: " + fieldElem.RefName.ToString());   // note: this can also get triggered if an inline-relationship defines a fromType node.
                }
                hash.Add(fieldElem.RefName);
                memberGroup.Items.Add(fieldElem);
            }
        }