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