Exemple #1
0
 private void ReferenceOrWriteSchema(JsonSchema schema)
 {
     if (schema.Id != null && _resolver.GetSchema(schema.Id) != null)
     {
         _writer.WriteStartObject();
         _writer.WritePropertyName(JsonSchemaConstants.ReferencePropertyName);
         _writer.WriteValue(schema.Id);
         _writer.WriteEndObject();
     }
     else
     {
         WriteSchema(schema);
     }
 }
Exemple #2
0
        private JsonSchema BuildSchema()
        {
            if (_reader.TokenType != JsonToken.StartObject)
            {
                throw new Exception("Expected StartObject while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
            }

            _reader.Read();
            // empty schema object
            if (_reader.TokenType == JsonToken.EndObject)
            {
                Push(new JsonSchema());
                return(Pop());
            }

            string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);

            _reader.Read();

            // schema reference
            if (propertyName == JsonSchemaConstants.ReferencePropertyName)
            {
                string id = (string)_reader.Value;
                _reader.Read();
                JsonSchema referencedSchema = _resolver.GetSchema(id);
                if (referencedSchema == null)
                {
                    throw new Exception("Could not resolve schema reference for Id '{0}'.".FormatWith(CultureInfo.InvariantCulture, id));
                }

                return(referencedSchema);
            }

            // regular ol' schema object
            Push(new JsonSchema());

            ProcessSchemaProperty(propertyName);

            while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
            {
                propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
                _reader.Read();

                ProcessSchemaProperty(propertyName);
            }

            return(Pop());
        }
        private JsonSchema GenerateInternal(Type type, bool valueRequired)
        {
            ValidationUtils.ArgumentNotNull(type, "type");

            string resolvedId = GetTypeId(type, false);
            string explicitId = GetTypeId(type, true);

            if (!string.IsNullOrEmpty(resolvedId))
            {
                JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
                if (resolvedSchema != null)
                {
                    return(resolvedSchema);
                }
            }

            // test for unresolved circular reference
            if (_stack.Any(tc => tc.Type == type))
            {
                throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }

            Push(new TypeSchema(type, new JsonSchema()));

            if (explicitId != null)
            {
                CurrentSchema.Id = explicitId;
            }

            CurrentSchema.Title       = GetTitle(type);
            CurrentSchema.Description = GetDescription(type);

            if (CollectionUtils.IsDictionaryType(type))
            {
                CurrentSchema.Type = JsonSchemaType.Object;

                Type keyType;
                Type valueType;
                ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);

                if (keyType != null)
                {
                    // can be converted to a string
                    if (typeof(IConvertible).IsAssignableFrom(keyType))
                    {
                        CurrentSchema.AdditionalProperties = GenerateInternal(valueType, false);
                    }
                }
            }
            else if (CollectionUtils.IsCollectionType(type))
            {
                CurrentSchema.Type = JsonSchemaType.Array;

                JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : false;

                Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                if (collectionItemType != null)
                {
                    CurrentSchema.Items = new List <JsonSchema>();
                    CurrentSchema.Items.Add(GenerateInternal(collectionItemType, !allowNullItem));
                }
            }
            else
            {
                CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);

                if (HasFlag(CurrentSchema.Type, JsonSchemaType.Object))
                {
                    CurrentSchema.Id = GetTypeId(type, false);

                    JsonObjectContract contract = ContractResolver.ResolveContract(type) as JsonObjectContract;

                    if (contract == null)
                    {
                        throw new Exception("Could not resolve contract for '{0}'.".FormatWith(CultureInfo.InvariantCulture, type));
                    }

                    CurrentSchema.Properties = new Dictionary <string, JsonSchema>();
                    foreach (JsonProperty property in contract.Properties)
                    {
                        if (!property.Ignored)
                        {
                            Type       propertyMemberType = ReflectionUtils.GetMemberUnderlyingType(property.Member);
                            JsonSchema propertySchema     = GenerateInternal(propertyMemberType, property.Required);

                            if (property.DefaultValue != null)
                            {
                                propertySchema.Default = JToken.FromObject(property.DefaultValue);
                            }

                            CurrentSchema.Properties.Add(property.PropertyName, propertySchema);
                        }
                    }

                    if (type.IsSealed)
                    {
                        CurrentSchema.AllowAdditionalProperties = false;
                    }
                }
                else if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
                {
                    CurrentSchema.Enum    = new List <JToken>();
                    CurrentSchema.Options = new Dictionary <JToken, string>();

                    EnumValues <ulong> enumValues = EnumUtils.GetNamesAndValues <ulong>(type);
                    foreach (EnumValue <ulong> enumValue in enumValues)
                    {
                        JToken value = JToken.FromObject(enumValue.Value);

                        CurrentSchema.Enum.Add(value);
                        CurrentSchema.Options.Add(value, enumValue.Name);
                    }
                }
            }

            return(Pop().Schema);
        }