Example #1
0
        public JsonSchemaObject FindDefinition(string definitionPath)
        {
            Match match = regexDefinitionPath.Match(definitionPath);

            JsonSchemaObject result = null;

            if (!match.Success || match.Groups.Count < 2 || !match.Groups[1].Success || !this.Definitions.TryGetValue(match.Groups[1].Value, out result))
            {
                return(null);
            }

            return(result);
        }
Example #2
0
        protected JsonSchemaObject Generate(JObject j)
        {
            JToken  tokenSchema = j["$schema"];
            JObject definitions = (JObject)j.SelectToken("definitions");

            if (tokenSchema != null)
            {
                this.Id = tokenSchema.ToString();
            }

            if (definitions != null)
            {
                foreach (JProperty child in definitions.Children())
                {
                    this.Definitions.Add(child.Name, JsonSchemaObject.Generate(this, child.Name, (JObject)definitions.SelectToken(child.Name)));
                }
            }

            return(JsonSchemaObject.Generate(this, "$", j));
        }
Example #3
0
        public void Parse(string source)
        {
            JObject j = JObject.Parse(source);

            _schema = this.Generate(j);
        }
        public static JsonSchemaObjectConstraint Generate(JsonSchema schema, JToken source)
        {
            JsonSchemaObjectConstraint constraint = new JsonSchemaObjectConstraint();

            JToken tokenType     = source["type"];
            JToken tokenRef      = source["$ref"];
            JToken tokenEnum     = source["enum"];
            JToken tokenRequired = source["required"];

            JToken tokenMinimum          = source["minimum"];
            JToken tokenExclusiveMinimum = source["exclusiveMinimum"];
            JToken tokenMaximum          = source["maximum"];
            JToken tokenExclusiveMaximum = source["exclusiveMaximum"];
            JToken tokenMultipleOf       = source["multipleOf"];
            JToken tokenMinLength        = source["minLength"];
            JToken tokenMaxLength        = source["maxLength"];
            JToken tokenPattern          = source["pattern"];
            JToken tokenAdditionalItems  = source["additionalItems"];
            JToken tokenItems            = source["items"];
            JToken tokenMinItems         = source["minItems"];
            JToken tokenMaxItems         = source["maxItems"];

            JsonSchemaObject schemaTypeReference = null;

            #region assertions
            if (tokenType == null && tokenRef == null && tokenEnum == null)
            {
                throw new SchemaException(String.Format("Could not find 'type', '$ref' or 'enum' property on schema object '{0}'", source.Path));
            }
            if (tokenType != null && tokenRef != null)
            {
                throw new SchemaException(String.Format("'$ref' and 'type' properties are not permitted at same level of schema object '{0}'", source.Path));
            }
            if (tokenRef != null)
            {
                schemaTypeReference = schema.FindDefinition(tokenRef.ToString());
                if (schemaTypeReference == null)
                {
                    throw new SchemaException(String.Format("Could not find definition of type with reference '{0}' on schema object '{1}'", tokenRef.ToString(), source.Path));
                }
            }

            if (tokenType != null)
            {
                JTokenType type;

                string typeValue = tokenType.Value <string>();
                if (typeValue.ToLower() == "number")
                {
                    type = JTokenType.Float;
                }
                else
                {
                    type = (JTokenType)Enum.Parse(typeof(JTokenType), tokenType.Value <string>(), true);
                }

                if (type != JTokenType.Integer && type != JTokenType.Float)
                {
                    if (tokenMinimum != null)
                    {
                        throw new SchemaException(String.Format("'minimum' not valid for anything other than a number type at {0}", source.Path));
                    }
                    if (tokenExclusiveMinimum != null)
                    {
                        throw new SchemaException(String.Format("'exclusiveMinimum' not valid for anything other than a number type at {0}", source.Path));
                    }
                    if (tokenMaximum != null)
                    {
                        throw new SchemaException(String.Format("'maximum' not valid for anything other than a number type at {0}", source.Path));
                    }
                    if (tokenExclusiveMaximum != null)
                    {
                        throw new SchemaException(String.Format("'exclusiveMaximum' not valid for anything other than a number type at {0}", source.Path));
                    }
                    if (tokenMultipleOf != null)
                    {
                        throw new SchemaException(String.Format("'multipleOf' not valid for anything other than a number type at {0}", source.Path));
                    }
                }

                if (type != JTokenType.String)
                {
                    if (tokenMinLength != null)
                    {
                        throw new SchemaException(String.Format("'minLength' not valid for anything other than a string type at {0}", source.Path));
                    }
                    if (tokenMaxLength != null)
                    {
                        throw new SchemaException(String.Format("'maxLength' not valid for anything other than a string type at {0}", source.Path));
                    }
                    if (tokenPattern != null)
                    {
                        throw new SchemaException(String.Format("'pattern' not valid for anything other than a string type at {0}", source.Path));
                    }
                }

                if (type != JTokenType.Array)
                {
                    if (tokenAdditionalItems != null)
                    {
                        throw new SchemaException(String.Format("'additionalItems' not valid for anything other than an array type at {0}", source.Path));
                    }
                    if (tokenMinItems != null)
                    {
                        throw new SchemaException(String.Format("'minItems' not valid for anything other than an array type at {0}", source.Path));
                    }
                    if (tokenMaxItems != null)
                    {
                        throw new SchemaException(String.Format("'maxItems' not valid for anything other than an array type at {0}", source.Path));
                    }
                }
            }
            #endregion

            if (tokenMinimum != null)
            {
                constraint.HasMinimum = true; constraint.Minimum = tokenMinimum.Value <int>();
            }
            if (tokenExclusiveMinimum != null)
            {
                constraint.ExclusiveMinimum = tokenExclusiveMinimum.Value <bool>();
            }
            if (tokenMaximum != null)
            {
                constraint.HasMaximum = true; constraint.Maximum = tokenMaximum.Value <int>();
            }
            if (tokenExclusiveMaximum != null)
            {
                constraint.ExclusiveMaximum = tokenExclusiveMaximum.Value <bool>();
            }
            if (tokenMultipleOf != null)
            {
                constraint.HasMultipleOf = true; constraint.MultipleOf = tokenMultipleOf.Value <int>();
            }
            if (tokenMinLength != null)
            {
                constraint.HasMinLength = true; constraint.MinLength = tokenMinLength.Value <int>();
            }
            if (tokenMaxLength != null)
            {
                constraint.HasMaxLength = true; constraint.MaxLength = tokenMaxLength.Value <int>();
            }
            if (tokenPattern != null)
            {
                constraint.HasPattern = true; constraint.Pattern = tokenPattern.Value <string>();
            }
            if (tokenAdditionalItems != null)
            {
                constraint.AdditionalItems = tokenAdditionalItems.Value <bool>();
            }
            if (tokenMinItems != null)
            {
                constraint.HasMinItems = true; constraint.MinItems = tokenMinItems.Value <int>();
            }
            if (tokenMaxItems != null)
            {
                constraint.HasMaxItems = true; constraint.MaxItems = tokenMaxItems.Value <int>();
            }

            if (tokenItems != null)
            {
                // this is a schema definition for items found in this array
                constraint.Items = JsonSchemaObject.Generate(schema, "items", (JObject)source.SelectToken("items"));
            }

            // $ref and type
            if (tokenRef == null && tokenType != null)
            {
                string tokenTypeName = tokenType.Value <string>();
                if (tokenTypeName.ToLower() == "number")
                {
                    constraint.Type = JTokenType.Float;
                }
                else
                {
                    constraint.Type = (JTokenType)Enum.Parse(typeof(JTokenType), tokenTypeName, true);
                }
            }
            else if (tokenRef != null && tokenType == null)
            {
                constraint.TypeReference = schemaTypeReference;
            }

            // required
            if (tokenRequired != null && tokenRequired.Type == JTokenType.Array)
            {
                constraint.Required.AddRange(tokenRequired.Children().Where(c => c.Type == JTokenType.String).Select(c => c.Value <string>()));
            }

            // enums
            if (tokenEnum != null)
            {
                constraint.Enums.AddRange(tokenEnum.Children().Where(c => c.Type == JTokenType.String).Select(c => c.Value <string>()));
            }

            return(constraint);
        }
Example #5
0
        public static JsonSchemaObject Generate(JsonSchema schema, string name, JObject j)
        {
            JToken tokenId          = j["id"];
            JToken tokenTitle       = j["title"];
            JToken tokenDescription = j["description"];

            JToken tokenAllOf = j["allOf"];
            JToken tokenAnyOf = j["anyOf"];
            JToken tokenOneOf = j["oneOf"];
            JToken tokenNot   = j["not"];

            JsonSchemaObject schemaObject = new JsonSchemaObject
            {
                Id                         = tokenId != null?tokenId.ToString() : GenerateSchemaObjectId(schema, name, j),
                                     Title = tokenTitle != null?tokenTitle.ToString() : String.Empty,
                                                 Description = tokenDescription != null?tokenDescription.ToString() : String.Empty
            };

            if (tokenAllOf == null && tokenAnyOf == null && tokenOneOf == null && tokenNot == null)
            {
                schemaObject.Constraints.Add(JsonSchemaObjectConstraint.Generate(schema, j));
            }
            JToken tokenMultiConstraint = null;

            if (tokenAllOf != null)
            {
                tokenMultiConstraint = tokenAllOf;
                schemaObject.ConstraintMembership = JsonSchemaObjectConstraintMembership.AllOf;
            }
            if (tokenAnyOf != null)
            {
                if (tokenMultiConstraint != null)
                {
                    throw new SchemaException(String.Format("'anyOf' multi-constraint identifier cannot be used in conjunction with other multi-constraint identifiers at '{0}'", j.Path));
                }
                tokenMultiConstraint = tokenAnyOf;
                schemaObject.ConstraintMembership = JsonSchemaObjectConstraintMembership.AnyOf;
            }
            if (tokenOneOf != null)
            {
                if (tokenMultiConstraint != null)
                {
                    throw new SchemaException(String.Format("'oneOf' multi-constraint identifier cannot be used in conjunction with other multi-constraint identifiers at '{0}'", j.Path));
                }
                tokenMultiConstraint = tokenOneOf;
                schemaObject.ConstraintMembership = JsonSchemaObjectConstraintMembership.OneOf;
            }
            if (tokenNot != null)
            {
                if (tokenMultiConstraint != null)
                {
                    throw new SchemaException(String.Format("'not' multi-constraint identifier cannot be used in conjunction with other multi-constraint identifiers at '{0}'", j.Path));
                }
                tokenMultiConstraint = tokenNot;
                schemaObject.ConstraintMembership = JsonSchemaObjectConstraintMembership.Not;
            }

            if (tokenMultiConstraint != null)
            {
                foreach (JToken constraint in tokenMultiConstraint.Children())
                {
                    schemaObject.Constraints.Add(JsonSchemaObjectConstraint.Generate(schema, constraint));
                }
            }

            JObject properties = (JObject)j.SelectToken("properties");

            if (properties != null)
            {
                foreach (JProperty child in properties.Children())
                {
                    schemaObject.Properties.Add(child.Name, Generate(schema, child.Name, (JObject)properties.SelectToken(child.Name)));
                }
            }

            return(schemaObject);
        }