Search in sources :

Example 1 with SchemaGenerationContextImpl

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;
}
Also used : Predicate(java.util.function.Predicate) DefinitionKey(com.github.victools.jsonschema.generator.impl.DefinitionKey) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CleanSchemaDefinitionNamingStrategy(com.github.victools.jsonschema.generator.naming.CleanSchemaDefinitionNamingStrategy) ResolvedType(com.fasterxml.classmate.ResolvedType) AttributeCollector(com.github.victools.jsonschema.generator.impl.AttributeCollector) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) SchemaGenerationContextImpl(com.github.victools.jsonschema.generator.impl.SchemaGenerationContextImpl) DefaultSchemaDefinitionNamingStrategy(com.github.victools.jsonschema.generator.naming.DefaultSchemaDefinitionNamingStrategy) List(java.util.List) SchemaCleanUpUtils(com.github.victools.jsonschema.generator.impl.SchemaCleanUpUtils) TreeMap(java.util.TreeMap) Type(java.lang.reflect.Type) Map(java.util.Map) SchemaDefinitionNamingStrategy(com.github.victools.jsonschema.generator.naming.SchemaDefinitionNamingStrategy) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) DefinitionKey(com.github.victools.jsonschema.generator.impl.DefinitionKey) ArrayList(java.util.ArrayList) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap) Map(java.util.Map)

Aggregations

ResolvedType (com.fasterxml.classmate.ResolvedType)1 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)1 AttributeCollector (com.github.victools.jsonschema.generator.impl.AttributeCollector)1 DefinitionKey (com.github.victools.jsonschema.generator.impl.DefinitionKey)1 SchemaCleanUpUtils (com.github.victools.jsonschema.generator.impl.SchemaCleanUpUtils)1 SchemaGenerationContextImpl (com.github.victools.jsonschema.generator.impl.SchemaGenerationContextImpl)1 CleanSchemaDefinitionNamingStrategy (com.github.victools.jsonschema.generator.naming.CleanSchemaDefinitionNamingStrategy)1 DefaultSchemaDefinitionNamingStrategy (com.github.victools.jsonschema.generator.naming.DefaultSchemaDefinitionNamingStrategy)1 SchemaDefinitionNamingStrategy (com.github.victools.jsonschema.generator.naming.SchemaDefinitionNamingStrategy)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Function (java.util.function.Function)1 Predicate (java.util.function.Predicate)1 Collectors (java.util.stream.Collectors)1