001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package gov.nist.secauto.metaschema.schemagen;
007
008import gov.nist.secauto.metaschema.core.configuration.IConfiguration;
009import gov.nist.secauto.metaschema.core.model.IModule;
010import gov.nist.secauto.metaschema.schemagen.json.JsonSchemaGenerator;
011import gov.nist.secauto.metaschema.schemagen.xml.XmlSchemaGenerator;
012
013import java.io.IOException;
014import java.io.Writer;
015import java.nio.charset.StandardCharsets;
016import java.nio.file.Files;
017import java.nio.file.Path;
018import java.nio.file.StandardOpenOption;
019
020import edu.umd.cs.findbugs.annotations.NonNull;
021
022@FunctionalInterface
023public interface ISchemaGenerator {
024  /**
025   * Generate and write a schema for the provided {@code metaschema} to the
026   * {@link Writer} provided by {@code writer} using the provided
027   * {@code configuration}.
028   *
029   * @param metaschema
030   *          the Module to generate the schema for
031   * @param writer
032   *          the writer to use to write the schema
033   * @param configuration
034   *          the schema generation configuration
035   * @throws SchemaGenerationException
036   *           if an error occurred while writing the schema
037   */
038  void generateFromModule(
039      @NonNull IModule metaschema,
040      @NonNull Writer writer,
041      @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration);
042
043  static void generateSchema(
044      @NonNull IModule module,
045      @NonNull Path destination,
046      @NonNull SchemaFormat asFormat,
047      @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration)
048      throws IOException {
049    ISchemaGenerator schemaGenerator = asFormat.getSchemaGenerator();
050
051    try (Writer writer = Files.newBufferedWriter(
052        destination,
053        StandardCharsets.UTF_8,
054        StandardOpenOption.CREATE,
055        StandardOpenOption.WRITE,
056        StandardOpenOption.TRUNCATE_EXISTING)) {
057      assert writer != null;
058      schemaGenerator.generateFromModule(module, writer, configuration);
059      writer.flush();
060    }
061  }
062
063  static void generateSchema(
064      @NonNull IModule module,
065      @NonNull Writer writer,
066      @NonNull SchemaFormat asFormat,
067      @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration)
068      throws IOException {
069    ISchemaGenerator schemaGenerator = asFormat.getSchemaGenerator();
070
071    schemaGenerator.generateFromModule(module, writer, configuration);
072    writer.flush();
073    // we don't want to close os, since we do not own it
074  }
075
076  /**
077   * Identifies the supported schema generation formats.
078   */
079  enum SchemaFormat {
080    /**
081     * a JSON Schema.
082     */
083    JSON(new JsonSchemaGenerator()),
084    /**
085     * an XML Schema.
086     */
087    XML(new XmlSchemaGenerator());
088
089    @NonNull
090    private final ISchemaGenerator schemaGenerator;
091
092    SchemaFormat(@NonNull ISchemaGenerator schemaGenerator) {
093      this.schemaGenerator = schemaGenerator;
094    }
095
096    @NonNull
097    public ISchemaGenerator getSchemaGenerator() {
098      return schemaGenerator;
099    }
100  }
101}