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