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.IFieldInstance;
14  import dev.metaschema.core.model.IFieldInstanceAbsolute;
15  import dev.metaschema.core.model.IFlagInstance;
16  import dev.metaschema.core.util.CollectionUtil;
17  import edu.umd.cs.findbugs.annotations.NonNull;
18  
19  /**
20   * Supports generation of a JSON schema based on a Metaschema
21   * {@link IFieldInstanceAbsolute}, which can be generated inline or as a JSON
22   * schema definition.
23   */
24  public class JsonSchemaPropertyField
25      extends AbstractJsonSchemaPropertyNamed<IFieldInstanceAbsolute> {
26    @NonNull
27    private final IJsonSchemaModelDefinition definitionSchema;
28    private final IFlagInstance jsonKey;
29  
30    /**
31     * Construct a new JSON schema property.
32     *
33     * @param instance
34     *          the instance to construct the property for
35     * @param state
36     *          the JSON generation state used to get JSON schema information
37     */
38    public JsonSchemaPropertyField(
39        @NonNull IFieldInstanceAbsolute instance,
40        @NonNull IJsonGenerationState state) {
41      super(instance, instance.getJsonName());
42      this.jsonKey = instance.getJsonKey();
43      this.definitionSchema = state.getFieldDefinition(
44          instance.getDefinition(),
45          jsonKey == null ? null : jsonKey.getQName());
46    }
47  
48    @Override
49    public boolean isRequired() {
50      return getInstance().getMinOccurs() > 0;
51    }
52  
53    @Override
54    public Stream<IJsonSchemaDefinable> collectDefinitions(
55        Set<IJsonSchemaDefinitionAssembly> visited,
56        IJsonGenerationState state) {
57      return definitionSchema.collectDefinitions(visited, state);
58    }
59  
60    @Override
61    protected void generateMetadata(ObjectNode obj, IJsonGenerationState state) {
62      IFieldInstance instance = getInstance();
63      JsonSchemaHelper.generateTitle(instance, obj);
64      JsonSchemaHelper.generateDescription(instance, obj);
65      // TODO: handle complex case?
66      JsonSchemaHelper.generateDefault(instance, obj);
67    }
68  
69    @Override
70    protected void generateBody(ObjectNode obj, IJsonGenerationState state) {
71      ICardinalityBehavior.behaviorFor(getInstance())
72          .generate(obj, getInstance(), CollectionUtil.singleton(definitionSchema), state);
73      assert !obj.isEmpty();
74    }
75  }