1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.schemagen.json.impl;
7   
8   import com.fasterxml.jackson.databind.node.ObjectNode;
9   
10  import java.util.Set;
11  import java.util.stream.Stream;
12  
13  import dev.metaschema.core.model.IAssemblyInstance;
14  import dev.metaschema.core.model.IAssemblyInstanceAbsolute;
15  import dev.metaschema.core.model.IFlagInstance;
16  import dev.metaschema.core.util.CollectionUtil;
17  import dev.metaschema.core.util.ObjectUtils;
18  import edu.umd.cs.findbugs.annotations.NonNull;
19  import nl.talsmasoftware.lazy4j.Lazy;
20  
21  /**
22   * Supports generation of a JSON schema based on a Metaschema
23   * {@link IAssemblyInstanceAbsolute}, which can be generated inline or as a JSON
24   * schema definition.
25   */
26  public class JsonSchemaPropertyAssembly
27      extends AbstractJsonSchemaPropertyNamed<IAssemblyInstanceAbsolute> {
28    @NonNull
29    private final Lazy<IJsonSchemaModelDefinition> definitionSchema;
30    private final IFlagInstance jsonKey;
31  
32    /**
33     * Construct a new JSON schema property.
34     *
35     * @param instance
36     *          the instance to construct the property for
37     * @param state
38     *          the JSON generation state used to get JSON schema information
39     */
40    public JsonSchemaPropertyAssembly(
41        @NonNull IAssemblyInstanceAbsolute instance,
42        @NonNull IJsonGenerationState state) {
43      super(instance, instance.getJsonName());
44      this.jsonKey = instance.getJsonKey();
45      this.definitionSchema = ObjectUtils.notNull(Lazy.of(() -> state.getAssemblyDefinition(
46          instance.getDefinition(),
47          jsonKey == null ? null : jsonKey.getQName())));
48    }
49  
50    @Override
51    public boolean isRequired() {
52      return getInstance().getMinOccurs() > 0;
53    }
54  
55    @NonNull
56    private IJsonSchemaModelDefinition getDefinitionSchema() {
57      return ObjectUtils.notNull(definitionSchema.get());
58    }
59  
60    @Override
61    protected void generateMetadata(ObjectNode obj, IJsonGenerationState state) {
62      IAssemblyInstance instance = getInstance();
63      JsonSchemaHelper.generateTitle(instance, obj);
64      JsonSchemaHelper.generateDescription(instance, obj);
65    }
66  
67    @Override
68    protected void generateBody(ObjectNode obj, IJsonGenerationState state) {
69      ICardinalityBehavior.behaviorFor(getInstance())
70          .generate(obj, getInstance(), CollectionUtil.singleton(getDefinitionSchema()), state);
71      assert !obj.isEmpty();
72    }
73  
74    @Override
75    public Stream<IJsonSchemaDefinable> collectDefinitions(
76        Set<IJsonSchemaDefinitionAssembly> visited,
77        IJsonGenerationState state) {
78      return getDefinitionSchema().collectDefinitions(visited, state);
79    }
80  }