001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.metaschema.databind.io.json; 007 008import com.fasterxml.jackson.core.JsonFactory; 009import com.fasterxml.jackson.core.JsonGenerator; 010import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; 011 012import gov.nist.secauto.metaschema.core.configuration.IMutableConfiguration; 013import gov.nist.secauto.metaschema.core.model.IBoundObject; 014import gov.nist.secauto.metaschema.core.util.ObjectUtils; 015import gov.nist.secauto.metaschema.databind.io.AbstractSerializer; 016import gov.nist.secauto.metaschema.databind.io.SerializationFeature; 017import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly; 018 019import java.io.IOException; 020import java.io.Writer; 021 022import edu.umd.cs.findbugs.annotations.NonNull; 023 024public class DefaultJsonSerializer<CLASS extends IBoundObject> 025 extends AbstractSerializer<CLASS> { 026 private JsonFactory jsonFactory; 027 028 /** 029 * Construct a new Module binding-based deserializer that reads JSON-based 030 * Module content. 031 * 032 * @param definition 033 * the assembly class binding describing the Java objects this 034 * deserializer parses data into 035 */ 036 public DefaultJsonSerializer(@NonNull IBoundDefinitionModelAssembly definition) { 037 super(definition); 038 } 039 040 /** 041 * Constructs a new JSON factory. 042 * <p> 043 * Subclasses can override this method to create a JSON factory with a specific 044 * configuration. 045 * 046 * @return the factory 047 */ 048 @NonNull 049 protected JsonFactory getJsonFactoryInstance() { 050 return JsonFactoryFactory.instance(); 051 } 052 053 @SuppressWarnings("PMD.NullAssignment") 054 @Override 055 protected void configurationChanged(IMutableConfiguration<SerializationFeature<?>> config) { 056 synchronized (this) { 057 jsonFactory = null; 058 } 059 } 060 061 @NonNull 062 private JsonFactory getJsonFactory() { 063 synchronized (this) { 064 if (jsonFactory == null) { 065 jsonFactory = getJsonFactoryInstance(); 066 } 067 assert jsonFactory != null; 068 return jsonFactory; 069 } 070 } 071 072 @SuppressWarnings("resource") 073 @NonNull 074 private JsonGenerator newJsonGenerator(@NonNull Writer writer) throws IOException { 075 JsonFactory factory = getJsonFactory(); 076 return ObjectUtils.notNull(factory.createGenerator(writer) 077 .setPrettyPrinter(new DefaultPrettyPrinter())); 078 } 079 080 @Override 081 public void serialize(IBoundObject data, Writer writer) throws IOException { 082 try (JsonGenerator generator = newJsonGenerator(writer)) { 083 IBoundDefinitionModelAssembly definition = getDefinition(); 084 085 boolean serializeRoot = get(SerializationFeature.SERIALIZE_ROOT); 086 if (serializeRoot) { 087 // first write the initial START_OBJECT 088 generator.writeStartObject(); 089 090 generator.writeFieldName(definition.getRootJsonName()); 091 } 092 093 MetaschemaJsonWriter jsonWriter = new MetaschemaJsonWriter(generator); 094 jsonWriter.write(definition, data); 095 096 if (serializeRoot) { 097 generator.writeEndObject(); 098 } 099 } 100 } 101}