use of com.github.victools.jsonschema.generator.impl.SchemaGenerationContextImpl in project jsonschema-generator by victools.
the class SchemaBuilder method buildDefinitionsAndResolveReferences.
/**
* Finalisation Step: collect the entries for the generated schema's "definitions" and ensure that all references are either pointing to the
* appropriate definition or contain the respective (sub) schema directly inline.
*
* @param designatedDefinitionPath designated path to the returned definitions node (to be incorporated in {@link SchemaKeyword#TAG_REF} values)
* @param mainSchemaKey definition key identifying the main type for which createSchemaReference() was invoked
* @param generationContext context containing all definitions of (sub) schemas and the list of references to them
* @return node representing the main schema's "definitions" (may be empty)
*/
private ObjectNode buildDefinitionsAndResolveReferences(String designatedDefinitionPath, DefinitionKey mainSchemaKey, SchemaGenerationContextImpl generationContext) {
final ObjectNode definitionsNode = this.config.createObjectNode();
final boolean createDefinitionsForAll = this.config.shouldCreateDefinitionsForAllObjects();
final boolean inlineAllSchemas = this.config.shouldInlineAllSchemas();
final AtomicBoolean considerOnlyDirectReferences = new AtomicBoolean(false);
Predicate<DefinitionKey> shouldProduceDefinition = definitionKey -> {
if (inlineAllSchemas) {
return false;
}
if (definitionKey.equals(mainSchemaKey)) {
return true;
}
List<ObjectNode> references = generationContext.getReferences(definitionKey);
if (considerOnlyDirectReferences.get() && references.isEmpty()) {
return false;
}
List<ObjectNode> nullableReferences = generationContext.getNullableReferences(definitionKey);
return createDefinitionsForAll || (references.size() + nullableReferences.size()) > 1;
};
Map<DefinitionKey, String> baseReferenceKeys = this.getReferenceKeys(mainSchemaKey, shouldProduceDefinition, generationContext);
considerOnlyDirectReferences.set(true);
final boolean createDefinitionForMainSchema = this.config.shouldCreateDefinitionForMainSchema();
for (Map.Entry<DefinitionKey, String> entry : baseReferenceKeys.entrySet()) {
String definitionName = entry.getValue();
DefinitionKey definitionKey = entry.getKey();
List<ObjectNode> references = generationContext.getReferences(definitionKey);
List<ObjectNode> nullableReferences = generationContext.getNullableReferences(definitionKey);
final String referenceKey;
boolean referenceInline = !shouldProduceDefinition.test(definitionKey);
if (referenceInline) {
// it is a simple type, just in-line the sub-schema everywhere
ObjectNode definition = generationContext.getDefinition(definitionKey);
references.forEach(node -> AttributeCollector.mergeMissingAttributes(node, definition));
referenceKey = null;
} else {
// the same sub-schema is referenced in multiple places
if (createDefinitionForMainSchema || !definitionKey.equals(mainSchemaKey)) {
// add it to the definitions (unless it is the main schema that is not explicitly moved there via an Option)
definitionsNode.set(definitionName, generationContext.getDefinition(definitionKey));
referenceKey = this.config.getKeyword(SchemaKeyword.TAG_REF_MAIN) + '/' + designatedDefinitionPath + '/' + definitionName;
} else {
referenceKey = this.config.getKeyword(SchemaKeyword.TAG_REF_MAIN);
}
references.forEach(node -> node.put(this.config.getKeyword(SchemaKeyword.TAG_REF), referenceKey));
}
if (!nullableReferences.isEmpty()) {
ObjectNode definition;
if (referenceInline) {
definition = generationContext.getDefinition(definitionKey);
} else {
definition = this.config.createObjectNode().put(this.config.getKeyword(SchemaKeyword.TAG_REF), referenceKey);
}
generationContext.makeNullable(definition);
if (!inlineAllSchemas && (createDefinitionsForAll || nullableReferences.size() > 1)) {
String nullableDefinitionName = this.definitionNamingStrategy.adjustNullableName(definitionKey, definitionName, generationContext);
definitionsNode.set(nullableDefinitionName, definition);
nullableReferences.forEach(node -> node.put(this.config.getKeyword(SchemaKeyword.TAG_REF), this.config.getKeyword(SchemaKeyword.TAG_REF_MAIN) + '/' + designatedDefinitionPath + '/' + nullableDefinitionName));
} else {
nullableReferences.forEach(node -> AttributeCollector.mergeMissingAttributes(node, definition));
}
}
}
definitionsNode.forEach(node -> this.schemaNodes.add((ObjectNode) node));
return definitionsNode;
}
Aggregations