Skip to content

Commit

Permalink
fix: adds support for all component types
Browse files Browse the repository at this point in the history
  • Loading branch information
baywet committed Jan 6, 2025
1 parent a231748 commit 8a73b54
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 20 deletions.
62 changes: 54 additions & 8 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -588,19 +588,65 @@ public static ReadResult Parse(string input,
return OpenApiModelFactory.Parse(input, format, settings);
}
/// <summary>
/// Adds a schema to the components object of the current document.
/// Adds a component to the components object of the current document and registers it to the underlying workspace.
/// </summary>
/// <param name="openApiSchema">The schema to add</param>
/// <param name="componentToRegister">The component to add</param>
/// <param name="id">The id for the component</param>
/// <returns>Whether the schema was added to the components.</returns>
public bool AddComponentSchema(string id, OpenApiSchema openApiSchema)
/// <typeparam name="T">The type of the component</typeparam>
/// <returns>Whether the component was added to the components.</returns>
/// <exception cref="ArgumentNullException">Thrown when the component is null.</exception>
/// <exception cref="ArgumentException">Thrown when the id is null or empty.</exception>
public bool AddComponent<T>(string id, T componentToRegister)
{
Utils.CheckArgumentNull(openApiSchema);
Utils.CheckArgumentNull(componentToRegister);
Utils.CheckArgumentNullOrEmpty(id);
Components ??= new();
Components.Schemas ??= new Dictionary<string, OpenApiSchema>();
Components.Schemas.Add(id, openApiSchema);
return Workspace?.RegisterSchemaForDocument(this, openApiSchema, id) ?? false;
switch (componentToRegister)
{
case OpenApiSchema openApiSchema:
Components.Schemas ??= new Dictionary<string, OpenApiSchema>();
Components.Schemas.Add(id, openApiSchema);
break;
case OpenApiParameter openApiParameter:
Components.Parameters ??= new Dictionary<string, OpenApiParameter>();
Components.Parameters.Add(id, openApiParameter);
break;
case OpenApiResponse openApiResponse:
Components.Responses ??= new Dictionary<string, OpenApiResponse>();
Components.Responses.Add(id, openApiResponse);
break;
case OpenApiRequestBody openApiRequestBody:
Components.RequestBodies ??= new Dictionary<string, OpenApiRequestBody>();
Components.RequestBodies.Add(id, openApiRequestBody);
break;
case OpenApiLink openApiLink:
Components.Links ??= new Dictionary<string, OpenApiLink>();
Components.Links.Add(id, openApiLink);
break;
case OpenApiCallback openApiCallback:
Components.Callbacks ??= new Dictionary<string, OpenApiCallback>();
Components.Callbacks.Add(id, openApiCallback);
break;
case OpenApiPathItem openApiPathItem:
Components.PathItems ??= new Dictionary<string, OpenApiPathItem>();
Components.PathItems.Add(id, openApiPathItem);
break;
case OpenApiExample openApiExample:
Components.Examples ??= new Dictionary<string, OpenApiExample>();
Components.Examples.Add(id, openApiExample);
break;
case OpenApiHeader openApiHeader:
Components.Headers ??= new Dictionary<string, OpenApiHeader>();
Components.Headers.Add(id, openApiHeader);
break;
case OpenApiSecurityScheme openApiSecurityScheme:
Components.SecuritySchemes ??= new Dictionary<string, OpenApiSecurityScheme>();
Components.SecuritySchemes.Add(id, openApiSecurityScheme);
break;
default:
throw new ArgumentException($"Component type {componentToRegister!.GetType().Name} is not supported.");
}
return Workspace?.RegisterComponentForDocument(this, componentToRegister, id) ?? false;
}
}

Expand Down
38 changes: 26 additions & 12 deletions src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,26 +145,40 @@ private string getBaseUri(OpenApiDocument openApiDocument)
}

/// <summary>
/// Registers a schema for a document in the workspace
/// Registers a component for a document in the workspace
/// </summary>
/// <param name="openApiDocument">The document to register the schema for.</param>
/// <param name="openApiSchema">The schema to register.</param>
/// <param name="id">The id of the schema.</param>
/// <returns>true if the schema is successfully registered; otherwise false.</returns>
/// <param name="openApiDocument">The document to register the component for.</param>
/// <param name="componentToRegister">The component to register.</param>
/// <param name="id">The id of the component.</param>
/// <typeparam name="T">The type of the component to register.</typeparam>
/// <returns>true if the component is successfully registered; otherwise false.</returns>
/// <exception cref="ArgumentNullException">openApiDocument is null</exception>
/// <exception cref="ArgumentNullException">openApiSchema is null</exception>
/// <exception cref="ArgumentNullException">componentToRegister is null</exception>
/// <exception cref="ArgumentNullException">id is null or empty</exception>
public bool RegisterSchemaForDocument(OpenApiDocument openApiDocument, OpenApiSchema openApiSchema, string id)
public bool RegisterComponentForDocument<T>(OpenApiDocument openApiDocument, T componentToRegister, string id)
{
Utils.CheckArgumentNull(openApiDocument);
Utils.CheckArgumentNull(openApiSchema);
Utils.CheckArgumentNull(componentToRegister);
Utils.CheckArgumentNullOrEmpty(id);

var baseUri = getBaseUri(openApiDocument);

var location = baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + id;

return RegisterComponent(location, openApiSchema);
var location = componentToRegister switch
{
OpenApiSchema => baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiParameter => baseUri + ReferenceType.Parameter.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiResponse => baseUri + ReferenceType.Response.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiRequestBody => baseUri + ReferenceType.RequestBody.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiLink => baseUri + ReferenceType.Link.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiCallback => baseUri + ReferenceType.Callback.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiPathItem => baseUri + ReferenceType.PathItem.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiExample => baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiHeader => baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + id,
OpenApiSecurityScheme => baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + id,
_ => throw new ArgumentException($"Invalid component type {componentToRegister.GetType().Name}"),
};

return RegisterComponent(location, componentToRegister);
}

/// <summary>
Expand All @@ -173,7 +187,7 @@ public bool RegisterSchemaForDocument(OpenApiDocument openApiDocument, OpenApiSc
/// <param name="location"></param>
/// <param name="component"></param>
/// <returns>true if the component is successfully registered; otherwise false.</returns>
public bool RegisterComponent<T>(string location, T component)
internal bool RegisterComponent<T>(string location, T component)
{
var uri = ToLocationUrl(location);
if (component is IOpenApiReferenceable referenceable)
Expand Down

0 comments on commit 8a73b54

Please sign in to comment.