-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented DeleteAllChildSchemasCommand
- Loading branch information
1 parent
cbeaeff
commit 95dbbd1
Showing
5 changed files
with
359 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
162 changes: 162 additions & 0 deletions
162
src/main/java/io/apicurio/datamodels/cmd/commands/AbstractSchemaInhCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/* | ||
* Copyright 2019 JBoss Inc | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
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.Node; | ||
import io.apicurio.datamodels.models.Referenceable; | ||
import io.apicurio.datamodels.models.Schema; | ||
import io.apicurio.datamodels.models.asyncapi.AsyncApiSchema; | ||
import io.apicurio.datamodels.models.openapi.v30.OpenApi30Schema; | ||
import io.apicurio.datamodels.models.openapi.v31.OpenApi31Schema; | ||
import io.apicurio.datamodels.util.ModelTypeUtil; | ||
import io.apicurio.datamodels.util.NodeUtil; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* @author [email protected] | ||
*/ | ||
public abstract class AbstractSchemaInhCommand extends AbstractCommand { | ||
|
||
public static final String TYPE_NONE = "none"; | ||
public static final String TYPE_ALL_OF = "allOf"; | ||
public static final String TYPE_ONE_OF = "oneOf"; | ||
public static final String TYPE_ANY_OF = "anyOf"; | ||
|
||
/** | ||
* Determines the current inheritance type for the given schema. | ||
* @param schema | ||
*/ | ||
static String getInheritanceType(Schema schema) { | ||
if (ModelTypeUtil.isOpenApiModel(schema)) { | ||
if (NodeUtil.isDefined(schema.getAllOf())) { | ||
return TYPE_ALL_OF; | ||
} | ||
if (ModelTypeUtil.isOpenApi3Model(schema)) { | ||
if (NodeUtil.isDefined(NodeUtil.getNodeProperty(schema, TYPE_ANY_OF))) { | ||
return TYPE_ANY_OF; | ||
} | ||
if (NodeUtil.isDefined(NodeUtil.getNodeProperty(schema, TYPE_ONE_OF))) { | ||
return TYPE_ONE_OF; | ||
} | ||
} | ||
} else if (ModelTypeUtil.isAsyncApiModel(schema)) { | ||
if (NodeUtil.isDefined(((AsyncApiSchema) schema).getAllOf())) { | ||
return TYPE_ALL_OF; | ||
} | ||
if (NodeUtil.isDefined(((AsyncApiSchema) schema).getAnyOf())) { | ||
return TYPE_ANY_OF; | ||
} | ||
if (NodeUtil.isDefined(((AsyncApiSchema) schema).getOneOf())) { | ||
return TYPE_ONE_OF; | ||
} | ||
} | ||
|
||
return TYPE_NONE; | ||
} | ||
|
||
/** | ||
* Creates a schema of a particular type (allOf, anyOf, etc). | ||
* @param parentSchema | ||
* @param inheritanceType | ||
*/ | ||
protected Schema createSchema(Schema parentSchema, String inheritanceType) { | ||
if (NodeUtil.equals(TYPE_ALL_OF, inheritanceType)) { | ||
return createAllOfSchema(parentSchema); | ||
} | ||
if (NodeUtil.equals(TYPE_ANY_OF, inheritanceType)) { | ||
return createAnyOfSchema(parentSchema); | ||
} | ||
if (NodeUtil.equals(TYPE_ONE_OF, inheritanceType)) { | ||
return createOneOfSchema(parentSchema); | ||
} | ||
// TODO is it possible to get here? if so what should we do? | ||
return createAllOfSchema(parentSchema); | ||
} | ||
|
||
/** | ||
* Copies the given list of schemas to the appropriate property on the model | ||
* @param schemas | ||
* @param targetSchema | ||
* @param inheritanceType | ||
*/ | ||
protected void copySchemaJsTo(List<ObjectNode> schemas, Schema targetSchema, String inheritanceType) { | ||
if (NodeUtil.equals(TYPE_ALL_OF, inheritanceType)) { | ||
schemas.forEach(ser -> { | ||
addAllOfSchema(targetSchema, (Schema) Library.readNode(ser, createAllOfSchema(targetSchema))); | ||
}); | ||
} | ||
if (NodeUtil.equals(TYPE_ANY_OF, inheritanceType)) { | ||
schemas.forEach(ser -> { | ||
addAnyOfSchema(targetSchema, (Schema) Library.readNode(ser, createAnyOfSchema(targetSchema))); | ||
}); | ||
} | ||
if (NodeUtil.equals(TYPE_ONE_OF, inheritanceType)) { | ||
schemas.forEach(ser -> { | ||
addOneOfSchema(targetSchema, (Schema) Library.readNode(ser, createOneOfSchema(targetSchema))); | ||
}); | ||
} | ||
} | ||
|
||
private static void addAllOfSchema(Schema to, Schema from) { | ||
to.addAllOf(from); | ||
} | ||
|
||
private static Schema createAllOfSchema(Schema schema) { | ||
return schema.createSchema(); | ||
} | ||
|
||
private static void addAnyOfSchema(Schema to, Schema from) { | ||
if (ModelTypeUtil.isOpenApi30Model(to)) { | ||
((OpenApi30Schema) to).addAnyOf((OpenApi30Schema) from); | ||
} else if (ModelTypeUtil.isOpenApi31Model(to)) { | ||
((OpenApi31Schema) to).addAnyOf((OpenApi31Schema) from); | ||
} else if (ModelTypeUtil.isAsyncApiModel(to)) { | ||
((AsyncApiSchema) to).addAnyOf((AsyncApiSchema) from); | ||
} | ||
} | ||
|
||
private static Schema createAnyOfSchema(Schema schema) { | ||
return schema.createSchema(); | ||
} | ||
|
||
private static void addOneOfSchema(Schema to, Schema from) { | ||
if (ModelTypeUtil.isOpenApi30Model(to)) { | ||
((OpenApi30Schema) to).addOneOf((OpenApi30Schema) from); | ||
} else if (ModelTypeUtil.isOpenApi31Model(to)) { | ||
((OpenApi31Schema) to).addOneOf((OpenApi31Schema) from); | ||
} else if (ModelTypeUtil.isAsyncApiModel(to)) { | ||
((AsyncApiSchema) to).addOneOf((AsyncApiSchema) from); | ||
} | ||
} | ||
|
||
private static Schema createOneOfSchema(Schema schema) { | ||
return schema.createSchema(); | ||
} | ||
|
||
protected boolean has$Ref(Node node) { | ||
if (node != null && node instanceof Referenceable) { | ||
String ref = ((Referenceable) node).get$ref(); | ||
return !NodeUtil.isNullOrUndefined(ref); | ||
} | ||
return false; | ||
} | ||
|
||
} |
187 changes: 187 additions & 0 deletions
187
src/main/java/io/apicurio/datamodels/cmd/commands/DeleteAllChildSchemasCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* Copyright 2019 Red Hat | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.apicurio.datamodels.cmd.commands; | ||
|
||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
import io.apicurio.datamodels.Library; | ||
import io.apicurio.datamodels.models.Document; | ||
import io.apicurio.datamodels.models.Node; | ||
import io.apicurio.datamodels.models.Schema; | ||
import io.apicurio.datamodels.models.asyncapi.AsyncApiSchema; | ||
import io.apicurio.datamodels.models.openapi.v30.OpenApi30Schema; | ||
import io.apicurio.datamodels.models.openapi.v31.OpenApi31Schema; | ||
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 io.apicurio.datamodels.util.NodeUtil; | ||
|
||
import java.util.ArrayList; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
|
||
/** | ||
* A command used to delete all child schemas from a schema. | ||
* @author [email protected] | ||
*/ | ||
public class DeleteAllChildSchemasCommand extends AbstractSchemaInhCommand { | ||
|
||
public NodePath _schemaPath; | ||
public String _childSchemaType; | ||
|
||
public List<ObjectNode> _oldSchemas; | ||
|
||
public DeleteAllChildSchemasCommand() { | ||
} | ||
|
||
public DeleteAllChildSchemasCommand(Schema parent, String type) { | ||
this._schemaPath = Library.createNodePath((Node) parent); | ||
this._childSchemaType = type; | ||
} | ||
|
||
@Override | ||
public void execute(Document document) { | ||
LoggerUtil.info("[DeleteAllChildSchemasCommand] Executing."); | ||
this._oldSchemas = new ArrayList<>(); | ||
|
||
Schema schema = (Schema) NodePathUtil.resolveNodePath(this._schemaPath, document); | ||
if (this.isNullOrUndefined(schema)) { | ||
return; | ||
} | ||
|
||
// Pull the schemas out (if allOf, anyOf, or oneOf) | ||
List<? extends Schema> schemas = new ArrayList<>(); | ||
if (NodeUtil.equals(TYPE_ALL_OF, this._childSchemaType)) { | ||
schemas = new LinkedList<>(schema.getAllOf()); | ||
for (int i = 0; i < schemas.size(); i++) { | ||
Schema s = schemas.get(i); | ||
if (has$Ref(s)) { | ||
schema.removeAllOf(s); | ||
addOldSchema(s); | ||
} | ||
} | ||
if (schema.getAllOf().isEmpty()) { | ||
NodeUtil.setProperty(schema, TYPE_ALL_OF, null); | ||
} | ||
} | ||
if (NodeUtil.equals(TYPE_ANY_OF, this._childSchemaType)) { | ||
schemas = new LinkedList<>(getAnyOfSchemas(schema)); | ||
for (int i = 0; i < schemas.size(); i++) { | ||
Schema s = schemas.get(i); | ||
if (has$Ref(s)) { | ||
removeAnyOfSchema(schema, s); | ||
addOldSchema(s); | ||
} | ||
} | ||
if (getAnyOfSchemas(schema).isEmpty()) { | ||
NodeUtil.setProperty(schema, TYPE_ANY_OF, null); | ||
} | ||
} | ||
if (NodeUtil.equals(TYPE_ONE_OF, this._childSchemaType)) { | ||
schemas = new LinkedList<>(getOneOfSchemas(schema)); | ||
for (int i = 0; i < schemas.size(); i++) { | ||
Schema s = schemas.get(i); | ||
if (has$Ref(s)) { | ||
removeOneOfSchema(schema, s); | ||
addOldSchema(s); | ||
} | ||
} | ||
if (getOneOfSchemas(schema).isEmpty()) { | ||
NodeUtil.setProperty(schema, TYPE_ONE_OF, null); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void undo(Document document) { | ||
LoggerUtil.info("[DeleteAllChildSchemasCommand] Reverting."); | ||
|
||
if (this.isNullOrUndefined(this._oldSchemas) || this._oldSchemas.size() == 0) { | ||
return; | ||
} | ||
|
||
Schema schema = (Schema) NodePathUtil.resolveNodePath (this._schemaPath, document); | ||
if (this.isNullOrUndefined(schema)) { | ||
return; | ||
} | ||
|
||
// TODO: remember the index of each schema so we can restore them to the right positions. | ||
this.copySchemaJsTo(_oldSchemas, schema, _childSchemaType); | ||
} | ||
|
||
private void addOldSchema(Schema schema) { | ||
if (this.isNullOrUndefined(schema)) { | ||
return; | ||
} | ||
this._oldSchemas.add(Library.writeNode(schema)); | ||
} | ||
|
||
private List<? extends Schema> getAnyOfSchemas(Schema schema) { | ||
if (ModelTypeUtil.isOpenApi30Model(schema)) { | ||
OpenApi30Schema schema30 = (OpenApi30Schema) schema; | ||
return schema30.getAnyOf(); | ||
} else if (ModelTypeUtil.isOpenApi31Model(schema)) { | ||
OpenApi31Schema schema31 = (OpenApi31Schema) schema; | ||
return schema31.getAnyOf(); | ||
} else if (ModelTypeUtil.isAsyncApiModel(schema)) { | ||
AsyncApiSchema s = (AsyncApiSchema) schema; | ||
return s.getAnyOf(); | ||
} | ||
return null; | ||
} | ||
|
||
private List<? extends Schema> getOneOfSchemas(Schema schema) { | ||
if (ModelTypeUtil.isOpenApi30Model(schema)) { | ||
OpenApi30Schema schema30 = (OpenApi30Schema) schema; | ||
return schema30.getOneOf(); | ||
} else if (ModelTypeUtil.isOpenApi31Model(schema)) { | ||
OpenApi31Schema schema31 = (OpenApi31Schema) schema; | ||
return schema31.getOneOf(); | ||
} else if (ModelTypeUtil.isAsyncApiModel(schema)) { | ||
AsyncApiSchema s = (AsyncApiSchema) schema; | ||
return s.getOneOf(); | ||
} | ||
return null; | ||
} | ||
|
||
private static void removeAnyOfSchema(Schema parent, Schema child) { | ||
if (ModelTypeUtil.isOpenApi30Model(parent)) { | ||
OpenApi30Schema schema30 = (OpenApi30Schema) parent; | ||
schema30.removeAnyOf((OpenApi30Schema) child); | ||
} else if (ModelTypeUtil.isOpenApi31Model(parent)) { | ||
OpenApi31Schema schema31 = (OpenApi31Schema) parent; | ||
schema31.removeAnyOf((OpenApi31Schema) child); | ||
} else if (ModelTypeUtil.isAsyncApiModel(parent)) { | ||
AsyncApiSchema schema = (AsyncApiSchema) parent; | ||
schema.removeAnyOf((AsyncApiSchema) child); | ||
} | ||
} | ||
|
||
private static void removeOneOfSchema(Schema parent, Schema child) { | ||
if (ModelTypeUtil.isOpenApi30Model(parent)) { | ||
OpenApi30Schema schema30 = (OpenApi30Schema) parent; | ||
schema30.removeOneOf((OpenApi30Schema) child); | ||
} else if (ModelTypeUtil.isOpenApi31Model(parent)) { | ||
OpenApi31Schema schema31 = (OpenApi31Schema) parent; | ||
schema31.removeOneOf((OpenApi31Schema) child); | ||
} else if (ModelTypeUtil.isAsyncApiModel(parent)) { | ||
AsyncApiSchema schema = (AsyncApiSchema) parent; | ||
schema.removeOneOf((AsyncApiSchema) child); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.