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.databind.io.json;
28
29 import com.fasterxml.jackson.core.JsonGenerator;
30
31 import gov.nist.secauto.metaschema.databind.model.IAssemblyClassBinding;
32 import gov.nist.secauto.metaschema.databind.model.IBoundFieldValueInstance;
33 import gov.nist.secauto.metaschema.databind.model.IBoundFlagInstance;
34 import gov.nist.secauto.metaschema.databind.model.IBoundNamedInstance;
35 import gov.nist.secauto.metaschema.databind.model.IBoundNamedModelInstance;
36 import gov.nist.secauto.metaschema.databind.model.IClassBinding;
37 import gov.nist.secauto.metaschema.databind.model.IFieldClassBinding;
38 import gov.nist.secauto.metaschema.databind.model.info.IDataTypeHandler;
39 import gov.nist.secauto.metaschema.databind.model.info.IModelPropertyInfo;
40
41 import org.apache.logging.log4j.LogManager;
42 import org.apache.logging.log4j.Logger;
43
44 import java.io.IOException;
45 import java.util.Map;
46
47 import edu.umd.cs.findbugs.annotations.NonNull;
48
49 public class MetaschemaJsonWriter implements IJsonWritingContext {
50 private static final Logger LOGGER = LogManager.getLogger(MetaschemaJsonWriter.class);
51
52 @NonNull
53 private final JsonGenerator writer;
54
55
56
57
58
59
60
61
62 public MetaschemaJsonWriter(
63 @NonNull JsonGenerator generator) {
64 this.writer = generator;
65 }
66
67 @Override
68 public JsonGenerator getWriter() {
69 return writer;
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public void write(
85 @NonNull IAssemblyClassBinding targetDefinition,
86 @NonNull Object targetObject) throws IOException {
87 if (!targetDefinition.isRoot()) {
88 throw new UnsupportedOperationException(
89 String.format("The assembly '%s' is not a root assembly.", targetDefinition.getBoundClass().getName()));
90 }
91
92 writer.writeStartObject();
93
94 writer.writeFieldName(targetDefinition.getRootJsonName());
95
96
97 IDataTypeHandler dataTypeHandler = IDataTypeHandler.newDataTypeHandler(targetDefinition);
98 dataTypeHandler.writeItem(targetObject, this);
99
100
101 writer.writeEndObject();
102 }
103
104 @Override
105 public void writeDefinitionValue(
106 IClassBinding targetDefinition,
107 Object targetObject,
108 Map<String, ? extends IBoundNamedInstance> instances) throws IOException {
109 for (IBoundNamedInstance property : instances.values()) {
110 assert property != null;
111 writeInstance(property, targetObject);
112 }
113
114 if (targetDefinition instanceof IFieldClassBinding) {
115 IFieldClassBinding fieldDefinition = (IFieldClassBinding) targetDefinition;
116 IBoundFieldValueInstance fieldValueInstance = fieldDefinition.getFieldValueInstance();
117 Object fieldValue = fieldValueInstance.getValue(targetObject);
118 if (fieldValue != null) {
119 String valueKeyName;
120 IBoundFlagInstance jsonValueKey = fieldDefinition.getJsonValueKeyFlagInstance();
121 if (jsonValueKey != null) {
122 valueKeyName = jsonValueKey.getValueAsString(jsonValueKey.getValue(targetObject));
123 } else {
124 valueKeyName = fieldValueInstance.getJsonValueKeyName();
125 }
126 writer.writeFieldName(valueKeyName);
127 fieldValueInstance.getJavaTypeAdapter().writeJsonValue(fieldValue, writer);
128 }
129 }
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143 protected void writeInstance(
144 @NonNull IBoundNamedInstance targetInstance,
145 @NonNull Object parentObject)
146 throws IOException {
147 if (targetInstance instanceof IBoundFlagInstance) {
148 writeFlagInstanceValue((IBoundFlagInstance) targetInstance, parentObject);
149 } else if (targetInstance instanceof IBoundNamedModelInstance) {
150 writeModelInstanceValues((IBoundNamedModelInstance) targetInstance, parentObject);
151 } else if (targetInstance instanceof IBoundFieldValueInstance) {
152 writeFieldValueInstanceValue((IBoundFieldValueInstance) targetInstance, parentObject);
153 } else {
154 throw new UnsupportedOperationException(
155 String.format("Unsupported class binding type: %s", targetInstance.getClass().getName()));
156 }
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170 protected void writeFlagInstanceValue(
171 @NonNull IBoundFlagInstance targetInstance,
172 @NonNull Object parentObject) throws IOException {
173 Object value = targetInstance.getValue(parentObject);
174 if (value != null) {
175
176 writer.writeFieldName(targetInstance.getJsonName());
177
178
179 targetInstance.getDefinition().getJavaTypeAdapter().writeJsonValue(value, writer);
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194 protected void writeModelInstanceValues(
195 @NonNull IBoundNamedModelInstance targetInstance,
196 @NonNull Object parentObject) throws IOException {
197 IModelPropertyInfo propertyInfo = targetInstance.getPropertyInfo();
198 if (propertyInfo.isValueSet(parentObject)) {
199
200 writer.writeFieldName(targetInstance.getJsonName());
201
202
203 propertyInfo.writeValues(parentObject, this);
204 }
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 protected void writeFieldValueInstanceValue(
219 @NonNull IBoundFieldValueInstance targetInstance,
220 @NonNull Object parentObject) throws IOException {
221 Object value = targetInstance.getValue(parentObject);
222 if (value != null) {
223
224
225
226 IBoundFlagInstance jsonValueKey = targetInstance.getParentClassBinding().getJsonValueKeyFlagInstance();
227
228 String valueKeyName;
229 if (jsonValueKey != null) {
230
231 valueKeyName = jsonValueKey.getValue(parentObject).toString();
232 } else {
233 valueKeyName = targetInstance.getJsonValueKeyName();
234 }
235 writer.writeFieldName(valueKeyName);
236 LOGGER.info("FIELD: {}", valueKeyName);
237 targetInstance.getJavaTypeAdapter().writeJsonValue(value, writer);
238 }
239 }
240 }