Example #1
0
        private static JsonSchema BuildJsonSchema(string name, JsonSchema?dataSchema)
        {
            var schema = new JsonSchema
            {
                Properties =
                {
                    [nameof(IContentEntity.Id).ToCamelCase()]             = SchemaBuilder.StringProperty($"The id of the {name} content.",                                       true),
                    [nameof(IContentEntity.Version).ToCamelCase()]        = SchemaBuilder.NumberProperty($"The version of the {name}.",                                          true),
                    [nameof(IContentEntity.Created).ToCamelCase()]        = SchemaBuilder.DateTimeProperty($"The date and time when the {name} content has been created.",       true),
                    [nameof(IContentEntity.CreatedBy).ToCamelCase()]      = SchemaBuilder.StringProperty($"The user that has created the {name} content.",                       true),
                    [nameof(IContentEntity.LastModified).ToCamelCase()]   = SchemaBuilder.DateTimeProperty($"The date and time when the {name} content has been modified last.", true),
                    [nameof(IContentEntity.LastModifiedBy).ToCamelCase()] = SchemaBuilder.StringProperty($"The user that has updated the {name} content last.",                  true),
                    [nameof(IContentEntity.NewStatus).ToCamelCase()]      = SchemaBuilder.StringProperty($"The new status of the content.",                                      false),
                    [nameof(IContentEntity.Status).ToCamelCase()]         = SchemaBuilder.StringProperty($"The status of the content.",                                          true)
                },
                Type = JsonObjectType.Object
            };

            if (dataSchema != null)
            {
                schema.Properties["data"]      = SchemaBuilder.ObjectProperty(dataSchema, $"The data of the {name}.", true);
                schema.Properties["dataDraft"] = SchemaBuilder.ObjectProperty(dataSchema, $"The draft data of the {name}.");
            }

            return(schema);
        }
Example #2
0
        public static JsonSchema BuildSchema(string name, JsonSchema?dataSchema, bool extended = false)
        {
            var jsonSchema = new JsonSchema
            {
                Properties =
                {
                    ["id"]             = SchemaBuilder.StringProperty($"The id of the {name} content.",                                       true),
                    ["created"]        = SchemaBuilder.DateTimeProperty($"The date and time when the {name} content has been created.",       true),
                    ["createdBy"]      = SchemaBuilder.StringProperty($"The user that has created the {name} content.",                       true),
                    ["lastModified"]   = SchemaBuilder.DateTimeProperty($"The date and time when the {name} content has been modified last.", true),
                    ["lastModifiedBy"] = SchemaBuilder.StringProperty($"The user that has updated the {name} content last.",                  true),
                    ["newStatus"]      = SchemaBuilder.StringProperty("The new status of the content."),
                    ["status"]         = SchemaBuilder.StringProperty("The status of the content.",                                           true),
                },
                Type = JsonObjectType.Object
            };

            if (extended)
            {
                jsonSchema.Properties["newStatusColor"] = SchemaBuilder.StringProperty("The color of the new status.", false);
                jsonSchema.Properties["schema"]         = SchemaBuilder.StringProperty("The name of the schema.", true);
                jsonSchema.Properties["SchemaName"]     = SchemaBuilder.StringProperty("The display name of the schema.", true);
                jsonSchema.Properties["statusColor"]    = SchemaBuilder.StringProperty("The color of the status.", true);
            }

            if (dataSchema != null)
            {
                jsonSchema.Properties["data"]      = SchemaBuilder.ObjectProperty(dataSchema, $"The data of the {name}.", true);
                jsonSchema.Properties["dataDraft"] = SchemaBuilder.ObjectProperty(dataSchema, $"The draft data of the {name}.");
            }

            return(jsonSchema);
        }
Example #3
0
        private static JsonSchema?_GetSchemaSlow(TypeInfo typeInfo)
        {
            var attribute = typeInfo.GetCustomAttribute <SchemaAttribute>();

            if (attribute == null)
            {
                return(null);
            }

            Exception? exception = null;
            JsonSchema?schema    = null;

            try
            {
                schema = _GetPropertySchema(typeInfo, attribute) ?? _GetFileSchema(attribute);
            }
            catch (FileNotFoundException e)
            {
                exception = e;
            }
            catch (UriFormatException e)
            {
                exception = e;
            }

            if (schema == null)
            {
                throw new JsonSerializationException($"The value '{attribute.Source}' could not be translated into a valid schema. " +
                                                     $"This value should represent either a public static property on the {typeInfo.Name} type " +
                                                     $"or a file with this name should exist at the execution path.", exception !);
            }

            return(schema);
        }
Example #4
0
 public static JsonSchemaProperty ObjectProperty(JsonSchema?value = null, string?description = null, bool isRequired = false)
 {
     return(new JsonSchemaProperty {
         Type = JsonObjectType.Object, AdditionalPropertiesSchema = value
     }
            .SetDescription(description)
            .SetRequired(isRequired));
 }
Example #5
0
        public OperationBuilder Responds(int statusCode, string description, JsonSchema?schema = null)
        {
            var response = new OpenApiResponse {
                Description = description, Schema = schema
            };

            operation.Responses.Add(statusCode.ToString(), response);

            return(this);
        }
Example #6
0
        /// <summary>
        /// Provides validation for the keyword.
        /// </summary>
        /// <param name="context">Contextual details for the validation process.</param>
        public void Validate(ValidationContext context)
        {
            context.EnterKeyword(Name);
            var parts    = Reference.OriginalString.Split(new[] { '#' }, StringSplitOptions.None);
            var baseUri  = parts[0];
            var fragment = parts.Length > 1 ? parts[1] : null;

            Uri?       newUri;
            JsonSchema?baseSchema = null;

            if (!string.IsNullOrEmpty(baseUri))
            {
                if (Uri.TryCreate(baseUri, UriKind.Absolute, out newUri))
                {
                    baseSchema = context.Options.SchemaRegistry.Get(newUri);
                }
                else if (context.CurrentUri != null)
                {
                    var uriFolder = context.CurrentUri.OriginalString.EndsWith("/")
                                                ? context.CurrentUri
                                                : context.CurrentUri.GetParentUri();
                    newUri = uriFolder;
                    var newBaseUri = new Uri(uriFolder, baseUri);
                    if (!string.IsNullOrEmpty(fragment))
                    {
                        newUri = newBaseUri;
                    }
                    baseSchema = context.Options.SchemaRegistry.Get(newBaseUri);
                }
            }
            else
            {
                newUri     = context.CurrentUri;
                baseSchema = context.CurrentAnchor ?? context.Options.SchemaRegistry.Get(newUri) ?? context.SchemaRoot;
            }

            var refFragment       = string.IsNullOrEmpty(fragment) ? $"__{nameof(RecursiveRefKeyword)}__" : fragment;
            var absoluteReference = SchemaRegistry.GetFullReference(newUri, refFragment);

            if (context.NavigatedReferences.Contains(absoluteReference))
            {
                context.IsValid = false;
                context.Message = "Encountered recursive reference";
                context.ExitKeyword(Name, context.IsValid);
                return;
            }

            context.NavigatedReferences.Add(absoluteReference);

            JsonSchema?schema;

            if (!string.IsNullOrEmpty(fragment) && AnchorKeyword.AnchorPattern.IsMatch(fragment !))
            {
                schema = context.Options.SchemaRegistry.Get(newUri, fragment);
            }
Example #7
0
        private void _ResolveLocalReference(Uri baseUri)
        {
            if (!_resolvedFragment.Any())
            {
                Resolved = _resolvedRoot;
                return;
            }

            Log.Schema($"Resolving local reference {_resolvedFragment}");
            Resolved = _resolvedRoot !.ResolveSubschema(_resolvedFragment !, baseUri);
        }
        private void _ResolveLocalReference(Uri baseUri, JsonSchemaVersion supportedVersions)
        {
            if (!_resolvedFragment.Any())
            {
                Resolved = _resolvedRoot;
                return;
            }

            Log.Schema(() => $"Resolving local reference {_resolvedFragment}");
            Resolved = _resolvedRoot !.ResolveSubschema(_resolvedFragment !, baseUri, supportedVersions);
        }
        /// <summary>
        /// Provides validation for the keyword.
        /// </summary>
        /// <param name="context">Contextual details for the validation process.</param>
        public void Validate(ValidationContext context)
        {
            var parts    = Reference.OriginalString.Split(new [] { '#' }, StringSplitOptions.None);
            var baseUri  = parts[0];
            var fragment = parts.Length > 1 ? parts[1] : null;

            Uri?       newUri;
            JsonSchema?baseSchema = null;

            if (!string.IsNullOrEmpty(baseUri))
            {
                if (Uri.TryCreate(baseUri, UriKind.Absolute, out newUri))
                {
                    baseSchema = context.Options.SchemaRegistry.Get(newUri);
                }
                else if (context.CurrentUri != null)
                {
                    var uriFolder = context.CurrentUri.OriginalString.EndsWith("/")
                                                ? context.CurrentUri
                                                : context.CurrentUri.GetParentUri();
                    newUri = uriFolder;
                    var newBaseUri = new Uri(uriFolder, baseUri);
                    if (!string.IsNullOrEmpty(fragment))
                    {
                        newUri = newBaseUri;
                    }
                    baseSchema = context.Options.SchemaRegistry.Get(newBaseUri);
                }
            }
            else
            {
                newUri = context.CurrentUri;
                if (fragment != null && context.DynamicAnchors.TryGetValue(fragment, out var dynamicSchema))
                {
                    baseSchema = dynamicSchema;
                }
                baseSchema ??= context.Options.SchemaRegistry.Get(newUri, fragment) ?? context.SchemaRoot;
            }

            JsonSchema?schema;

            if (!string.IsNullOrEmpty(fragment) && AnchorKeyword.AnchorPattern.IsMatch(fragment !))
            {
                schema = baseSchema ?? context.Options.SchemaRegistry.Get(newUri, fragment);
            }
Example #10
0
        public static JsonSchema Build(JsonSchema?dataSchema, bool extended = false, bool withDeleted = false)
        {
            var jsonSchema = new JsonSchema
            {
                AllowAdditionalProperties = false,
                Properties =
                {
                    ["id"]             = JsonTypeBuilder.StringProperty(FieldDescriptions.EntityId,             true),
                    ["created"]        = JsonTypeBuilder.DateTimeProperty(FieldDescriptions.EntityCreated,      true),
                    ["createdBy"]      = JsonTypeBuilder.StringProperty(FieldDescriptions.EntityCreatedBy,      true),
                    ["lastModified"]   = JsonTypeBuilder.DateTimeProperty(FieldDescriptions.EntityLastModified, true),
                    ["lastModifiedBy"] = JsonTypeBuilder.StringProperty(FieldDescriptions.EntityLastModifiedBy, true),
                    ["newStatus"]      = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentNewStatus),
                    ["status"]         = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentStatus,        true)
                },
                Type = JsonObjectType.Object
            };

            if (withDeleted)
            {
                jsonSchema.Properties["isDeleted"] = JsonTypeBuilder.BooleanProperty(FieldDescriptions.EntityIsDeleted, false);
            }

            if (extended)
            {
                jsonSchema.Properties["newStatusColor"]    = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentNewStatusColor, false);
                jsonSchema.Properties["schemaId"]          = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentSchemaId, true);
                jsonSchema.Properties["schemaName"]        = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentSchemaName, true);
                jsonSchema.Properties["schemaDisplayName"] = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentSchemaDisplayName, true);
                jsonSchema.Properties["statusColor"]       = JsonTypeBuilder.StringProperty(FieldDescriptions.ContentStatusColor, true);
            }

            if (dataSchema != null)
            {
                jsonSchema.Properties["data"] = JsonTypeBuilder.ReferenceProperty(dataSchema, FieldDescriptions.ContentData, true);
            }

            return(jsonSchema);
        }
Example #11
0
        /// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>true if the current object is equal to the <paramref name="other">other</paramref> parameter; otherwise, false.</returns>
        public bool Equals(JsonSchema?other)
        {
            if (ReferenceEquals(null, other))
            {
                return(false);
            }
            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            if (BoolValue.HasValue)
            {
                return(BoolValue == other.BoolValue);
            }
            if (other.BoolValue.HasValue)
            {
                return(false);
            }
            if (Keywords !.Count != other.Keywords !.Count)
            {
                return(false);
            }
            if (OtherData?.Count != other.OtherData?.Count)
            {
                return(false);
            }

            if (Keywords != null)
            {
                var byKeyword = Keywords.Join(other.Keywords,
                                              tk => tk.Keyword(),
                                              ok => ok.Keyword(),
                                              (tk, ok) => new { ThisKeyword = tk, OtherKeyword = ok })
                                .ToList();
                if (byKeyword.Count != Keywords.Count)
                {
                    return(false);
                }
                if (!byKeyword.All(k => k.ThisKeyword.Equals(k.OtherKeyword)))
                {
                    return(false);
                }
            }

            if (OtherData != null)
            {
                var byKey = OtherData.Join(other.OtherData !,
                                           td => td.Key,
                                           od => od.Key,
                                           (td, od) => new { ThisData = td.Value, OtherData = od.Value })
                            .ToList();
                if (byKey.Count != OtherData.Count)
                {
                    return(false);
                }
                if (!byKey.All(k => k.ThisData.IsEquivalentTo(k.OtherData)))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #12
0
        private void _ResolveReference(SchemaValidationContext context)
        {
            Log.Schema($"Resolving `{Reference}`");

            if (context.RecursiveAnchor != null)
            {
                Log.Schema("Finding anchor of root schema");
                if (context.BaseUri == null)
                {
                    throw new InvalidOperationException("BaseUri not set");
                }
                var baseDocument = JsonSchemaRegistry.Get(context.BaseUri.OriginalString);
                if (baseDocument?.Get <RecursiveAnchorKeyword>() != null)
                {
                    _resolvedRoot = context.RecursiveAnchor;
                }
            }

            if (Reference.IsLocalSchemaId())
            {
                Log.Schema("Reference recognized as anchor or local ID");
                Resolved = context.LocalRegistry.GetLocal(Reference);
                if (Resolved != null)
                {
                    return;
                }

                Log.Schema($"`{Reference}` is an unknown anchor");
            }

            var documentPath   = _resolvedRoot?.DocumentPath ?? context.BaseUri;
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? documentPath?.OriginalString : referenceParts[0];

            _resolvedFragment = referenceParts.Length > 1 ? JsonPointer.Parse(referenceParts[1]) : new JsonPointer();
            if (_resolvedRoot == null)
            {
                if (!string.IsNullOrWhiteSpace(address))
                {
                    if (!Uri.TryCreate(address, UriKind.Absolute, out _))
                    {
                        address = context.Local.Id + address;
                    }

                    if (documentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out _))
                    {
                        var uriFolder = documentPath.OriginalString.EndsWith("/") ? documentPath : documentPath.GetParentUri();
                        var absolute  = new Uri(uriFolder, address);
                        address = absolute.OriginalString;
                    }

                    _resolvedRoot = JsonSchemaRegistry.Get(address);
                }
                else
                {
                    _resolvedRoot = context.Root;
                }
            }

            if (_resolvedRoot == null)
            {
                Log.Schema("Could not resolve root of reference");
                return;
            }

            var wellKnown = JsonSchemaRegistry.GetWellKnown(Reference);

            if (wellKnown != null)
            {
                Log.Schema("Well known reference found");
                Resolved = wellKnown;
                return;
            }

            _ResolveLocalReference(_resolvedRoot?.DocumentPath ?? context.BaseUri !);
        }
Example #13
0
        private void _ResolveReference(SchemaValidationContext context)
        {
            Log.Schema($"Resolving `{Reference}`");

            if (Reference.IsLocalSchemaId())
            {
                Log.Schema("Reference recognized as anchor or local ID");
                Resolved = context.LocalRegistry.GetLocal(Reference);
                if (Resolved != null)
                {
                    return;
                }

                Log.Schema($"`{Reference}` is an unknown anchor");
            }

            var documentPath   = context.BaseUri;
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? documentPath?.OriginalString.Split('#')[0] : referenceParts[0];

            _resolvedFragment = referenceParts.Length > 1 ? JsonPointer.Parse(referenceParts[1]) : new JsonPointer();
            if (!string.IsNullOrWhiteSpace(address))
            {
                if (!Uri.TryCreate(address, UriKind.Absolute, out var absolute) &&
                    (JsonSchemaOptions.RefResolution == RefResolutionStrategy.ProcessSiblingId ||
                     context.Root.SupportedVersions == JsonSchemaVersion.Draft2019_09))
                {
                    address = context.Local.Id + address;
                }

                if (documentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out absolute))
                {
                    var uriFolder = documentPath.OriginalString.EndsWith("/") ? documentPath : documentPath.GetParentUri();
                    absolute = new Uri(uriFolder, address);
                    address  = absolute.OriginalString;
                }

                _resolvedRoot = JsonSchemaRegistry.Get(address);
            }
            else
            {
                _resolvedRoot = context.Root;
            }

            if (_resolvedRoot == null)
            {
                Log.Schema("Could not resolve root of reference");
                return;
            }

            var wellKnown = JsonSchemaRegistry.GetWellKnown(Reference);

            if (wellKnown != null)
            {
                Log.Schema("Well known reference found");
                Resolved = wellKnown;
                return;
            }

            _ResolveLocalReference(_resolvedRoot?.DocumentPath ?? context.BaseUri !);
        }
Example #14
0
        public static void AddResponse(this OpenApiOperation operation, string statusCode, string description, JsonSchema?schema = null)
        {
            var response = new OpenApiResponse {
                Description = description, Schema = schema
            };

            operation.Responses.Add(statusCode, response);
        }