1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.schemagen.json.schema;
28
29 import com.fasterxml.jackson.databind.node.ArrayNode;
30 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
31 import com.fasterxml.jackson.databind.node.ObjectNode;
32
33 import gov.nist.secauto.metaschema.core.model.IFieldDefinition;
34 import gov.nist.secauto.metaschema.core.model.IFlagInstance;
35 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
36 import gov.nist.secauto.metaschema.schemagen.FlagInstanceFilter;
37 import gov.nist.secauto.metaschema.schemagen.json.impl.JsonGenerationState;
38 import gov.nist.secauto.metaschema.schemagen.json.property.FlagInstanceJsonProperty;
39 import gov.nist.secauto.metaschema.schemagen.json.property.IJsonProperty.PropertyCollection;
40
41 import java.io.IOException;
42 import java.util.Collection;
43
44 import edu.umd.cs.findbugs.annotations.NonNull;
45
46 public class FieldDefinitionJsonSchema
47 extends AbstractDefinitionJsonSchema<IFieldDefinition> {
48
49 public FieldDefinitionJsonSchema(
50 @NonNull IFieldDefinition definition) {
51 super(definition);
52 }
53
54 @Override
55 public void resolveSubSchemas(JsonGenerationState state) {
56 state.getDataTypeSchemaForDefinition(getDefinition());
57
58 for (IFlagInstance instance : getDefinition().getFlagInstances()) {
59 state.getSchema(instance.getDefinition());
60 }
61 }
62
63 @SuppressWarnings("PMD.CognitiveComplexity")
64 @Override
65 protected void generateBody(JsonGenerationState state, ObjectNode obj) throws IOException {
66 IFieldDefinition definition = getDefinition();
67
68 Collection<? extends IFlagInstance> flags = definition.getFlagInstances();
69 IFlagInstance jsonKeyFlag = definition.getJsonKeyFlagInstance();
70 if (flags.isEmpty() || (jsonKeyFlag != null && flags.size() == 1)) {
71
72
73 state.getDataTypeSchemaForDefinition(definition).generateSchemaOrRef(state, obj);
74 } else {
75 obj.put("type", "object");
76
77
78 IFlagInstance jsonValueKeyFlag = definition.getJsonValueKeyFlagInstance();
79 flags = FlagInstanceFilter.filterFlags(flags, jsonKeyFlag, jsonValueKeyFlag);
80
81 PropertyCollection properties = new PropertyCollection();
82
83
84 for (IFlagInstance flag : flags) {
85 assert flag != null;
86 new FlagInstanceJsonProperty(flag).generateProperty(properties, state);
87 }
88
89
90 if (jsonValueKeyFlag == null) {
91 generateSimpleFieldValueInstance(properties, state);
92 }
93
94 properties.generate(obj);
95
96 if (jsonValueKeyFlag == null) {
97 obj.put("additionalProperties", false);
98 } else {
99 ObjectNode additionalPropertiesTypeNode;
100
101 additionalPropertiesTypeNode = ObjectUtils.notNull(JsonNodeFactory.instance.objectNode());
102
103 state.getDataTypeSchemaForDefinition(definition).generateSchemaOrRef(state, additionalPropertiesTypeNode);
104
105 ObjectNode additionalPropertiesNode = ObjectUtils.notNull(JsonNodeFactory.instance.objectNode());
106 ArrayNode allOf = additionalPropertiesNode.putArray("allOf");
107 allOf.add(additionalPropertiesTypeNode);
108 allOf.addObject()
109 .put("minProperties", properties.getRequired().size() + 1)
110 .put("maxProperties", properties.getProperties().size() + 1);
111
112 obj.set("additionalProperties", additionalPropertiesNode);
113 }
114 }
115 }
116
117 public void generateSimpleFieldValueInstance(
118 @NonNull PropertyCollection properties,
119 @NonNull JsonGenerationState state) {
120
121 IFieldDefinition definition = getDefinition();
122
123 String propertyName = definition.getJsonValueKeyName();
124
125 ObjectNode propertyObject = ObjectUtils.notNull(JsonNodeFactory.instance.objectNode());
126 state.getDataTypeSchemaForDefinition(definition).generateSchemaOrRef(state, propertyObject);
127
128 properties.addProperty(propertyName, propertyObject);
129 properties.addRequired(propertyName);
130 }
131 }