From 78eec39fec5cdfa4df4b54a5987ca4e2e22a8195 Mon Sep 17 00:00:00 2001 From: Eric Wittmann Date: Tue, 7 Jan 2025 08:31:45 -0500 Subject: [PATCH] Implemented DeleteAllServersCommand and DeleteAllTagsCommand --- .../datamodels/cmd/CommandFactory.java | 17 ++ .../cmd/commands/DeleteAllServersCommand.java | 286 ++++++++++++++++++ .../cmd/commands/DeleteAllTagsCommand.java | 65 ++++ .../apicurio/datamodels/util/CommandUtil.ts | 4 + src/test/resources/fixtures/cmd/tests.json | 7 +- 5 files changed, 378 insertions(+), 1 deletion(-) create mode 100755 src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllServersCommand.java create mode 100755 src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllTagsCommand.java diff --git a/src/main/java/io/apicurio/datamodels/cmd/CommandFactory.java b/src/main/java/io/apicurio/datamodels/cmd/CommandFactory.java index 484ac5a4..e2690a16 100644 --- a/src/main/java/io/apicurio/datamodels/cmd/CommandFactory.java +++ b/src/main/java/io/apicurio/datamodels/cmd/CommandFactory.java @@ -17,6 +17,8 @@ import io.apicurio.datamodels.cmd.commands.DeleteAllResponsesCommand; import io.apicurio.datamodels.cmd.commands.DeleteAllSecurityRequirementsCommand; import io.apicurio.datamodels.cmd.commands.DeleteAllSecuritySchemesCommand; +import io.apicurio.datamodels.cmd.commands.DeleteAllServersCommand; +import io.apicurio.datamodels.cmd.commands.DeleteAllTagsCommand; import io.apicurio.datamodels.cmd.commands.DeleteContactCommand; import io.apicurio.datamodels.cmd.commands.DeleteExtensionCommand; import io.apicurio.datamodels.cmd.commands.DeleteLicenseCommand; @@ -143,4 +145,19 @@ public static final ICommand createDeleteAllSecuritySchemesCommand() { return new DeleteAllSecuritySchemesCommand(); } + public static final ICommand createDeleteAllTagsCommand() { + return new DeleteAllTagsCommand(); + } + + public static final ICommand createDeleteAllDocumentServersCommand(OpenApiDocument document) { + return new DeleteAllServersCommand(document); + } + public static final ICommand createDeleteAllPathItemServersCommand(OpenApiPathItem pathItem) { + return new DeleteAllServersCommand(pathItem); + } + public static final ICommand createDeleteAllOperationServersCommand(OpenApiOperation operation) { + return new DeleteAllServersCommand(operation); + } + + } diff --git a/src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllServersCommand.java b/src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllServersCommand.java new file mode 100755 index 00000000..be051558 --- /dev/null +++ b/src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllServersCommand.java @@ -0,0 +1,286 @@ +package io.apicurio.datamodels.cmd.commands; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.apicurio.datamodels.Library; +import io.apicurio.datamodels.cmd.AbstractCommand; +import io.apicurio.datamodels.models.Document; +import io.apicurio.datamodels.models.Node; +import io.apicurio.datamodels.models.Operation; +import io.apicurio.datamodels.models.Server; +import io.apicurio.datamodels.models.openapi.OpenApiPathItem; +import io.apicurio.datamodels.models.openapi.OpenApiServer; +import io.apicurio.datamodels.models.openapi.v30.OpenApi30Document; +import io.apicurio.datamodels.models.openapi.v30.OpenApi30Operation; +import io.apicurio.datamodels.models.openapi.v30.OpenApi30PathItem; +import io.apicurio.datamodels.models.openapi.v30.OpenApi30Server; +import io.apicurio.datamodels.models.openapi.v31.OpenApi31Document; +import io.apicurio.datamodels.models.openapi.v31.OpenApi31Operation; +import io.apicurio.datamodels.models.openapi.v31.OpenApi31PathItem; +import io.apicurio.datamodels.models.openapi.v31.OpenApi31Server; +import io.apicurio.datamodels.models.visitors.CombinedVisitorAdapter; +import io.apicurio.datamodels.paths.NodePath; +import io.apicurio.datamodels.paths.NodePathUtil; +import io.apicurio.datamodels.util.LoggerUtil; +import io.apicurio.datamodels.util.ModelTypeUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * A command used to delete all servers from a document. + * + * @author eric.wittmann@gmail.com + */ +public class DeleteAllServersCommand extends AbstractCommand { + + public NodePath _parentPath; + public List _oldServers; + + public DeleteAllServersCommand() { + } + + public DeleteAllServersCommand(Node parent) { + this._parentPath = Library.createNodePath(parent); + } + + /** + * @see io.apicurio.datamodels.cmd.ICommand#execute(Document) + */ + @Override + public void execute(Document document) { + LoggerUtil.info("[DeleteAllServersCommand] Executing."); + this._oldServers = new ArrayList<>(); + + Node parent = NodePathUtil.resolveNodePath(this._parentPath, document); + if (this.isNullOrUndefined(parent)) { + return; + } + + // Save the old servers (if any) + List servers = getServers(parent); + if (!this.isNullOrUndefined(servers)) { + servers.forEach( server -> { + this._oldServers.add(Library.writeNode(server)); + }); + } + clearServers(parent); + } + + private List getServers(Node parent) { + GetServersVisitor viz = new GetServersVisitor(); + parent.accept(viz); + return viz._servers; + } + + private void clearServers(Node parent) { + ClearServersVisitor viz = new ClearServersVisitor(); + parent.accept(viz); + } + + /** + * @see io.apicurio.datamodels.cmd.ICommand#undo(Document) + */ + @Override + public void undo(Document document) { + LoggerUtil.info("[DeleteAllServersCommand] Reverting."); + if (this._oldServers.isEmpty()) { + return; + } + + Node parent = NodePathUtil.resolveNodePath(this._parentPath, document); + if (this.isNullOrUndefined(parent)) { + return; + } + + for (ObjectNode oldServer : this._oldServers) { + OpenApiServer server = createServer(parent); + Library.readNode(oldServer, server); + addServer(parent, server); + } + } + + private OpenApiServer createServer(Node parent) { + CreateServerVisitor viz = new CreateServerVisitor(); + parent.accept(viz); + return (OpenApiServer) viz._server; + } + + private void addServer(Node parent, OpenApiServer server) { + AddServerVisitor viz = new AddServerVisitor(server); + parent.accept(viz); + } + + private abstract class ServersParentVisitor extends CombinedVisitorAdapter { + @Override + public void visitDocument(Document node) { + if (ModelTypeUtil.isOpenApi30Model(node)) { + visitOpenApi30Document((OpenApi30Document) node); + } else if (ModelTypeUtil.isOpenApi31Model(node)) { + visitOpenApi31Document((OpenApi31Document) node); + } + } + + @Override + public void visitPathItem(OpenApiPathItem node) { + if (ModelTypeUtil.isOpenApi30Model(node)) { + visitOpenApi30PathItem((OpenApi30PathItem) node); + } else if (ModelTypeUtil.isOpenApi31Model(node)) { + visitOpenApi31PathItem((OpenApi31PathItem) node); + } + } + + @Override + public void visitOperation(Operation node) { + if (ModelTypeUtil.isOpenApi30Model(node)) { + visitOpenApi30Operation((OpenApi30Operation) node); + } else if (ModelTypeUtil.isOpenApi31Model(node)) { + visitOpenApi31Operation((OpenApi31Operation) node); + } + } + + abstract void visitOpenApi31Document(OpenApi31Document node); + abstract void visitOpenApi30Document(OpenApi30Document node); + abstract void visitOpenApi31PathItem(OpenApi31PathItem node); + abstract void visitOpenApi30PathItem(OpenApi30PathItem node); + abstract void visitOpenApi31Operation(OpenApi31Operation node); + abstract void visitOpenApi30Operation(OpenApi30Operation node); + } + + private class GetServersVisitor extends ServersParentVisitor { + List _servers; + + @Override + void visitOpenApi31Document(OpenApi31Document node) { + this._servers = node.getServers(); + } + + @Override + void visitOpenApi30Document(OpenApi30Document node) { + this._servers = node.getServers(); + } + + @Override + void visitOpenApi31PathItem(OpenApi31PathItem node) { + this._servers = node.getServers(); + } + + @Override + void visitOpenApi30PathItem(OpenApi30PathItem node) { + this._servers = node.getServers(); + } + + @Override + void visitOpenApi31Operation(OpenApi31Operation node) { + this._servers = node.getServers(); + } + + @Override + void visitOpenApi30Operation(OpenApi30Operation node) { + this._servers = node.getServers(); + } + } + + private class ClearServersVisitor extends ServersParentVisitor { + @Override + void visitOpenApi31Document(OpenApi31Document node) { + node.clearServers(); + } + + @Override + void visitOpenApi30Document(OpenApi30Document node) { + node.clearServers(); + } + + @Override + void visitOpenApi31PathItem(OpenApi31PathItem node) { + node.clearServers(); + } + + @Override + void visitOpenApi30PathItem(OpenApi30PathItem node) { + node.clearServers(); + } + + @Override + void visitOpenApi31Operation(OpenApi31Operation node) { + node.clearServers(); + } + + @Override + void visitOpenApi30Operation(OpenApi30Operation node) { + node.clearServers(); + } + } + + private class CreateServerVisitor extends ServersParentVisitor { + Server _server; + + @Override + void visitOpenApi31Document(OpenApi31Document node) { + this._server = node.createServer(); + } + + @Override + void visitOpenApi30Document(OpenApi30Document node) { + this._server = node.createServer(); + } + + @Override + void visitOpenApi31PathItem(OpenApi31PathItem node) { + this._server = node.createServer(); + } + + @Override + void visitOpenApi30PathItem(OpenApi30PathItem node) { + this._server = node.createServer(); + } + + @Override + void visitOpenApi31Operation(OpenApi31Operation node) { + this._server = node.createServer(); + } + + @Override + void visitOpenApi30Operation(OpenApi30Operation node) { + this._server = node.createServer(); + } + } + + private class AddServerVisitor extends ServersParentVisitor { + private final OpenApiServer _server; + + public AddServerVisitor(OpenApiServer server) { + this._server = server; + } + + @Override + void visitOpenApi31Document(OpenApi31Document node) { + node.addServer((OpenApi31Server) this._server); + } + + @Override + void visitOpenApi30Document(OpenApi30Document node) { + node.addServer((OpenApi30Server) this._server); + } + + @Override + void visitOpenApi31PathItem(OpenApi31PathItem node) { + node.addServer((OpenApi31Server) this._server); + } + + @Override + void visitOpenApi30PathItem(OpenApi30PathItem node) { + node.addServer((OpenApi30Server) this._server); + } + + @Override + void visitOpenApi31Operation(OpenApi31Operation node) { + node.addServer((OpenApi31Server) this._server); + } + + @Override + void visitOpenApi30Operation(OpenApi30Operation node) { + node.addServer((OpenApi30Server) this._server); + } + } +} diff --git a/src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllTagsCommand.java b/src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllTagsCommand.java new file mode 100755 index 00000000..1058dbcd --- /dev/null +++ b/src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllTagsCommand.java @@ -0,0 +1,65 @@ +package io.apicurio.datamodels.cmd.commands; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.apicurio.datamodels.Library; +import io.apicurio.datamodels.cmd.AbstractCommand; +import io.apicurio.datamodels.models.Document; +import io.apicurio.datamodels.models.Tag; +import io.apicurio.datamodels.models.openapi.OpenApiDocument; +import io.apicurio.datamodels.models.openapi.OpenApiTag; +import io.apicurio.datamodels.util.LoggerUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * A command used to delete all tags from a document. + * @author eric.wittmann@gmail.com + */ +public class DeleteAllTagsCommand extends AbstractCommand { + + public List _oldTags; + + public DeleteAllTagsCommand() { + } + + /** + * @see io.apicurio.datamodels.cmd.ICommand#execute(Document) + */ + @Override + public void execute(Document document) { + LoggerUtil.info("[DeleteAllTagsCommand] Executing."); + + OpenApiDocument doc = (OpenApiDocument) document; + + this._oldTags = new ArrayList<>(); + // Save the old tags (if any) + List tags = doc.getTags(); + if (!this.isNullOrUndefined(tags)) { + tags.forEach( tag -> { + this._oldTags.add(Library.writeNode(tag)); + }); + } + doc.clearTags(); + } + + /** + * @see io.apicurio.datamodels.cmd.ICommand#undo(Document) + */ + @Override + public void undo(Document document) { + LoggerUtil.info("[DeleteAllTagsCommand] Reverting."); + if (this._oldTags.isEmpty()) { + return; + } + + OpenApiDocument doc = (OpenApiDocument) document; + + this._oldTags.forEach( oldTag -> { + OpenApiTag tag = doc.createTag(); + Library.readNode(oldTag, tag); + doc.addTag(tag); + }); + } + +} diff --git a/src/main/ts/src/io/apicurio/datamodels/util/CommandUtil.ts b/src/main/ts/src/io/apicurio/datamodels/util/CommandUtil.ts index f9143897..b2b0712c 100644 --- a/src/main/ts/src/io/apicurio/datamodels/util/CommandUtil.ts +++ b/src/main/ts/src/io/apicurio/datamodels/util/CommandUtil.ts @@ -21,6 +21,8 @@ import {DeleteAllPropertiesCommand} from "../cmd/commands/DeleteAllPropertiesCom import {DeleteAllResponsesCommand} from "../cmd/commands/DeleteAllResponsesCommand"; import {DeleteAllSecurityRequirementsCommand} from "../cmd/commands/DeleteAllSecurityRequirementsCommand"; import {DeleteAllSecuritySchemesCommand} from "../cmd/commands/DeleteAllSecuritySchemesCommand"; +import {DeleteAllServersCommand} from "../cmd/commands/DeleteAllServersCommand"; +import {DeleteAllTagsCommand} from "../cmd/commands/DeleteAllTagsCommand"; import {DeleteContactCommand} from "../cmd/commands/DeleteContactCommand"; import {DeleteExtensionCommand} from "../cmd/commands/DeleteExtensionCommand"; import {DeleteLicenseCommand} from "../cmd/commands/DeleteLicenseCommand"; @@ -58,6 +60,8 @@ const commandSuppliers: { [key: string]: Supplier } = { "DeleteAllResponsesCommand": () => { return new DeleteAllResponsesCommand(); }, "DeleteAllSecurityRequirementsCommand": () => { return new DeleteAllSecurityRequirementsCommand(); }, "DeleteAllSecuritySchemesCommand": () => { return new DeleteAllSecuritySchemesCommand(); }, + "DeleteAllServersCommand": () => { return new DeleteAllServersCommand(); }, + "DeleteAllTagsCommand": () => { return new DeleteAllTagsCommand(); }, "DeleteContactCommand": () => { return new DeleteContactCommand(); }, "DeleteExtensionCommand": () => { return new DeleteExtensionCommand(); }, "DeleteLicenseCommand": () => { return new DeleteLicenseCommand(); }, diff --git a/src/test/resources/fixtures/cmd/tests.json b/src/test/resources/fixtures/cmd/tests.json index 7f8bba36..c684685f 100755 --- a/src/test/resources/fixtures/cmd/tests.json +++ b/src/test/resources/fixtures/cmd/tests.json @@ -52,5 +52,10 @@ { "name": "[AsyncAPI 2] {Delete All Security Requirements} - Delete All Security Requirements", "test": "commands/delete-all-security-requirements/asyncapi-2/delete-all-security-requirements" }, { "name": "[OpenAPI 2] {Delete All Security Schemes} - Delete All Security Schemes", "test": "commands/delete-all-security-schemes/openapi-2/delete-all-security-schemes" }, { "name": "[OpenAPI 3] {Delete All Security Schemes} - Delete All Security Schemes", "test": "commands/delete-all-security-schemes/openapi-3/delete-all-security-schemes" }, - { "name": "[AsyncAPI 2] {Delete All Security Schemes} - Delete All Security Schemes", "test": "commands/delete-all-security-schemes/asyncapi-2/delete-all-security-schemes" } + { "name": "[AsyncAPI 2] {Delete All Security Schemes} - Delete All Security Schemes", "test": "commands/delete-all-security-schemes/asyncapi-2/delete-all-security-schemes" }, + { "name": "[OpenAPI 2] {Delete All Tags} - Delete All Tags", "test": "commands/delete-all-tags/openapi-2/delete-all-tags" }, + { "name": "[OpenAPI 3] {Delete All Tags} - Delete All Tags", "test": "commands/delete-all-tags/openapi-3/delete-all-tags" }, + { "name": "[OpenAPI 3] {Delete All Servers} - Delete All Servers Document", "test": "commands/delete-all-servers/openapi-3/delete-all-servers-document" }, + { "name": "[OpenAPI 3] {Delete All Servers} - Delete All Servers Operation", "test": "commands/delete-all-servers/openapi-3/delete-all-servers-operation" }, + { "name": "[OpenAPI 3] {Delete All Servers} - Delete All Servers Path Item", "test": "commands/delete-all-servers/openapi-3/delete-all-servers-pathItem" } ] \ No newline at end of file