001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package gov.nist.secauto.metaschema.schemagen.json;
007
008import com.fasterxml.jackson.core.JsonFactory;
009import com.fasterxml.jackson.core.JsonGenerator;
010import com.fasterxml.jackson.core.JsonGenerator.Feature;
011import com.fasterxml.jackson.databind.ObjectMapper;
012import com.fasterxml.jackson.databind.node.ObjectNode;
013
014import gov.nist.secauto.metaschema.core.configuration.IConfiguration;
015import gov.nist.secauto.metaschema.core.model.IModule;
016import gov.nist.secauto.metaschema.core.util.ObjectUtils;
017import gov.nist.secauto.metaschema.schemagen.AbstractSchemaGenerator;
018import gov.nist.secauto.metaschema.schemagen.SchemaGenerationException;
019import gov.nist.secauto.metaschema.schemagen.SchemaGenerationFeature;
020import gov.nist.secauto.metaschema.schemagen.json.impl.IJsonSchema;
021import gov.nist.secauto.metaschema.schemagen.json.impl.JsonDatatypeManager;
022import gov.nist.secauto.metaschema.schemagen.json.impl.JsonGenerationState;
023import gov.nist.secauto.metaschema.schemagen.json.impl.JsonSchemaModule;
024
025import java.io.IOException;
026import java.io.Writer;
027
028import edu.umd.cs.findbugs.annotations.NonNull;
029
030public class JsonSchemaGenerator
031    extends AbstractSchemaGenerator<JsonGenerator, JsonDatatypeManager, JsonGenerationState> {
032  @NonNull
033  private final JsonFactory jsonFactory;
034
035  public JsonSchemaGenerator() {
036    this(new JsonFactory());
037  }
038
039  public JsonSchemaGenerator(@NonNull JsonFactory jsonFactory) {
040    this.jsonFactory = jsonFactory;
041  }
042
043  @NonNull
044  public JsonFactory getJsonFactory() {
045    return jsonFactory;
046  }
047
048  @SuppressWarnings("resource")
049  @Override
050  protected JsonGenerator newWriter(Writer out) {
051    try {
052      return ObjectUtils.notNull(getJsonFactory().createGenerator(out)
053          .setCodec(new ObjectMapper())
054          .useDefaultPrettyPrinter()
055          .disable(Feature.AUTO_CLOSE_TARGET));
056    } catch (IOException ex) {
057      throw new SchemaGenerationException(ex);
058    }
059  }
060
061  @Override
062  protected JsonGenerationState newGenerationState(
063      IModule module,
064      JsonGenerator schemaWriter,
065      IConfiguration<SchemaGenerationFeature<?>> configuration) {
066    return new JsonGenerationState(module, schemaWriter, configuration);
067  }
068
069  @Override
070  protected void generateSchema(JsonGenerationState state) {
071    IModule module = state.getModule();
072
073    IJsonSchema moduleSchema = new JsonSchemaModule(module, state);
074    ObjectNode schemaNode = ObjectUtils.notNull(state.getJsonNodeFactory().objectNode());
075    moduleSchema.generateInlineJsonSchema(schemaNode, state);
076
077    try {
078      state.writeObject(schemaNode);
079    } catch (IOException ex) {
080      throw new SchemaGenerationException(ex);
081    }
082  }
083}