1 /*
2 * SPDX-FileCopyrightText: none
3 * SPDX-License-Identifier: CC0-1.0
4 */
5
6 package dev.metaschema.schemagen;
7
8 import java.io.IOException;
9 import java.io.Writer;
10 import java.nio.charset.StandardCharsets;
11 import java.nio.file.Files;
12 import java.nio.file.Path;
13 import java.nio.file.StandardOpenOption;
14
15 import dev.metaschema.core.configuration.IConfiguration;
16 import dev.metaschema.core.model.IModule;
17 import dev.metaschema.schemagen.json.JsonSchemaGenerator;
18 import dev.metaschema.schemagen.xml.XmlSchemaGenerator;
19 import edu.umd.cs.findbugs.annotations.NonNull;
20
21 /**
22 * Provides the capability to generate a schema from a Metaschema module.
23 */
24 @FunctionalInterface
25 public interface ISchemaGenerator {
26 /**
27 * Generate and write a schema for the provided {@code metaschema} to the
28 * {@link Writer} provided by {@code writer} using the provided
29 * {@code configuration}.
30 *
31 * @param metaschema
32 * the Module to generate the schema for
33 * @param writer
34 * the writer to use to write the schema
35 * @param configuration
36 * the schema generation configuration
37 * @throws SchemaGenerationException
38 * if an error occurred while writing the schema
39 */
40 void generateFromModule(
41 @NonNull IModule metaschema,
42 @NonNull Writer writer,
43 @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration);
44
45 /**
46 * Generate a schema for the provided module and write it to the specified file
47 * path.
48 *
49 * @param module
50 * the Metaschema module to generate the schema for
51 * @param destination
52 * the file path to write the schema to
53 * @param asFormat
54 * the schema format to generate
55 * @param configuration
56 * the schema generation configuration
57 * @throws IOException
58 * if an I/O error occurs while writing the schema
59 */
60 static void generateSchema(
61 @NonNull IModule module,
62 @NonNull Path destination,
63 @NonNull SchemaFormat asFormat,
64 @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration)
65 throws IOException {
66 ISchemaGenerator schemaGenerator = asFormat.getSchemaGenerator();
67
68 try (Writer writer = Files.newBufferedWriter(
69 destination,
70 StandardCharsets.UTF_8,
71 StandardOpenOption.CREATE,
72 StandardOpenOption.WRITE,
73 StandardOpenOption.TRUNCATE_EXISTING)) {
74 assert writer != null;
75 schemaGenerator.generateFromModule(module, writer, configuration);
76 writer.flush();
77 }
78 }
79
80 /**
81 * Generate a schema for the provided module and write it to the specified
82 * writer.
83 * <p>
84 * The writer is not closed by this method, as the caller is responsible for
85 * managing its lifecycle.
86 *
87 * @param module
88 * the Metaschema module to generate the schema for
89 * @param writer
90 * the writer to output the schema to
91 * @param asFormat
92 * the schema format to generate
93 * @param configuration
94 * the schema generation configuration
95 * @throws IOException
96 * if an I/O error occurs while writing the schema
97 */
98 static void generateSchema(
99 @NonNull IModule module,
100 @NonNull Writer writer,
101 @NonNull SchemaFormat asFormat,
102 @NonNull IConfiguration<SchemaGenerationFeature<?>> configuration)
103 throws IOException {
104 ISchemaGenerator schemaGenerator = asFormat.getSchemaGenerator();
105
106 schemaGenerator.generateFromModule(module, writer, configuration);
107 writer.flush();
108 // we don't want to close os, since we do not own it
109 }
110
111 /**
112 * Identifies the supported schema generation formats.
113 */
114 enum SchemaFormat {
115 /**
116 * a JSON Schema.
117 */
118 JSON(new JsonSchemaGenerator()),
119 /**
120 * an XML Schema.
121 */
122 XML(new XmlSchemaGenerator());
123
124 @NonNull
125 private final ISchemaGenerator schemaGenerator;
126
127 SchemaFormat(@NonNull ISchemaGenerator schemaGenerator) {
128 this.schemaGenerator = schemaGenerator;
129 }
130
131 /**
132 * Get the schema generator implementation for this format.
133 *
134 * @return the schema generator
135 */
136 @NonNull
137 public ISchemaGenerator getSchemaGenerator() {
138 return schemaGenerator;
139 }
140 }
141 }