Example #1
0
        private SchemaTypeEntry GenerateForType(StructuredType structuredType)
        {
            string extends          = null;
            var    resourceTypeSpec = structuredType as ResourceType;
            IEnumerable <StructuredProperty> properties = structuredType.Properties;

            if (resourceTypeSpec == null || !resourceTypeSpec.IsUriBaseType)
            {
                if (structuredType.BaseType != null && structuredType.BaseType != typeof(object))
                {
                    extends = structuredType.BaseType.Name;
                    var propsOfBaseType = new HashSet <string>(structuredType.BaseType.Properties.Select(x => x.Name));
                    properties = properties.Where(x => !propsOfBaseType.Contains(x.Name));
                }
            }

            var typeName = structuredType.Name;

            var schemaTypeEntry = new SchemaTypeEntry
            {
                Extends    = extends,
                Name       = typeName,
                Properties = new SortedDictionary <string, SchemaPropertyEntry>(properties
                                                                                .Select(GenerateForProperty)
                                                                                .ToDictionary(x => x.Name, x => x)),
                // TODO: Expose IsAbstract on TypeSpec
                Abstract       = structuredType.Type != null && structuredType.Type.IsAbstract,
                AllowedMethods = structuredType.AllowedMethods
            };

            if (resourceTypeSpec != null)
            {
                schemaTypeEntry.Uri = resourceTypeSpec.UrlRelativePath;
            }

            return(schemaTypeEntry);
        }
Example #2
0
        private static void PropertiesAreBackwardsCompatible(TextWriter errorLog,
                                                             SchemaTypeEntry oldType,
                                                             SchemaTypeEntry newType,
                                                             ref bool isBackwardsCompatible,
                                                             string typeName)
        {
            var propertyNames =
                oldType.Properties.Select(x => x.Key).Concat(newType.Properties.Select(x => x.Key)).Distinct();

            foreach (var propName in propertyNames)
            {
                SchemaPropertyEntry oldPropEntry, newPropEntry;

                oldType.Properties.TryGetValue(propName, out oldPropEntry);
                newType.Properties.TryGetValue(propName, out newPropEntry);

                if (oldPropEntry == null && newPropEntry == null)
                {
                    throw new InvalidOperationException("Should have found a property named " + propName +
                                                        " on either old or new type. WTF?");
                }

                if (newPropEntry == null)
                {
                    // Removal of property, not allowed!
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "Removal of property {0} from type {1} breaks backwards compability.\r\n", propName,
                        typeName);
                    continue;
                }
                if (oldPropEntry == null)
                {
                    if (newPropEntry.Required)
                    {
                        isBackwardsCompatible = false;
                        errorLog.Write(
                            "Introducing a new required property {0} to type {1} breaks backwards compability.\r\n",
                            propName, typeName);
                    }
                    continue;
                }

                var lostRights = oldPropEntry.Access ^ (newPropEntry.Access & oldPropEntry.Access);

                if (lostRights != 0)
                {
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "The property access rights {0} has been removed from property, which breaks backwards compatibility.",
                        lostRights);
                }

                if (!oldPropEntry.Required && newPropEntry.Required)
                {
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "Making previosly optional property {0} of type {1} required breaks compability.\r\n",
                        propName, typeName);
                }

                if (newPropEntry.Type != oldPropEntry.Type)
                {
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "Changing type of property {0} declared by {1} from type {2} to type {3} breaks compability\r\n",
                        propName, typeName, oldPropEntry.Type, newPropEntry.Type);
                }
            }
        }
Example #3
0
        private static void PropertiesAreBackwardsCompatible(TextWriter errorLog,
                                                             SchemaTypeEntry oldType,
                                                             SchemaTypeEntry newType,
                                                             ref bool isBackwardsCompatible,
                                                             string typeName)
        {
            var propertyNames =
                oldType.Properties.Select(x => x.Key).Concat(newType.Properties.Select(x => x.Key)).Distinct();

            foreach (var propName in propertyNames)
            {
                SchemaPropertyEntry oldPropEntry, newPropEntry;

                oldType.Properties.TryGetValue(propName, out oldPropEntry);
                newType.Properties.TryGetValue(propName, out newPropEntry);

                if (oldPropEntry == null && newPropEntry == null)
                {
                    throw new InvalidOperationException("Should have found a property named " + propName +
                                                        " on either old or new type. WTF?");
                }

                if (newPropEntry == null)
                {
                    // Removal of property, not allowed!
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "Removal of property {0} from type {1} breaks backwards compability.\r\n", propName,
                        typeName);
                    continue;
                }
                if (oldPropEntry == null)
                {
                    if (newPropEntry.Required)
                    {
                        isBackwardsCompatible = false;
                        errorLog.Write(
                            "Introducing a new required property {0} to type {1} breaks backwards compability.\r\n",
                            propName, typeName);
                    }
                    continue;
                }

                var lostRights = oldPropEntry.Access ^ (newPropEntry.Access & oldPropEntry.Access);

                if (lostRights != 0)
                {
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "The property access rights {0} has been removed from property, which breaks backwards compatibility.",
                        lostRights);
                }

                if (!oldPropEntry.Required && newPropEntry.Required)
                {
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "Making previosly optional property {0} of type {1} required breaks compability.\r\n",
                        propName, typeName);
                }

                if (newPropEntry.Type != oldPropEntry.Type)
                {
                    isBackwardsCompatible = false;
                    errorLog.Write(
                        "Changing type of property {0} declared by {1} from type {2} to type {3} breaks compability\r\n",
                        propName, typeName, oldPropEntry.Type, newPropEntry.Type);
                }
            }
        }
Example #4
0
        private SchemaTypeEntry GenerateForType(TransformedType transformedType)
        {
            string extends = null;
            var resourceTypeSpec = transformedType as ResourceType;
            IEnumerable<PropertyMapping> properties = transformedType.Properties;
            if (resourceTypeSpec == null || !resourceTypeSpec.IsUriBaseType)
            {
                extends = transformedType.BaseType.Name;
                var propsOfBaseType = new HashSet<string>(transformedType.BaseType.Properties.Select(x => x.Name));
                properties = properties.Where(x => !propsOfBaseType.Contains(x.Name));
            }

            var typeName = transformedType.Name;

            var schemaTypeEntry = new SchemaTypeEntry
            {
                Extends = extends,
                Name = typeName,
                Properties = new SortedDictionary<string, SchemaPropertyEntry>(properties
                    .Select(GenerateForProperty)
                    .ToDictionary(x => x.Name, x => x)),
                // TODO: Expose IsAbstract on TypeSpec
                Abstract = transformedType.Type != null && transformedType.Type.IsAbstract,
                AllowedMethods = transformedType.AllowedMethods
            };

            if (resourceTypeSpec != null)
            {
                schemaTypeEntry.Uri = resourceTypeSpec.UriRelativePath;
            }

            return schemaTypeEntry;
        }