@@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
2525import com.networknt.schema.JsonSchema
2626import com.networknt.schema.JsonSchemaFactory
2727import com.networknt.schema.SpecVersion
28+ import com.networknt.schema.SpecVersionDetector
2829import com.networknt.schema.ValidationMessage
2930import groovy.transform.CompileStatic
3031import groovy.util.logging.Slf4j
@@ -54,31 +55,54 @@ class ModuleSchemaValidator {
5455 * @return List of validation error messages, empty if the spec is valid
5556 */
5657 static List<String > validate (Path metaYaml , String schemaLocation ) {
57- final schemaText = loadSchema(schemaLocation)
58- final factory = JsonSchemaFactory . getInstance(SpecVersion.VersionFlag . V202012 )
59- final JsonSchema schema
58+ final schemaNode = parseSchema(loadSchema(schemaLocation), schemaLocation)
59+ final specVersion = detectSpecVersion(schemaNode, schemaLocation)
60+ final schema = buildSchema(schemaNode, specVersion, schemaLocation)
61+ final metaNode = loadMeta(metaYaml)
62+ final Set<ValidationMessage > messages = schema. validate(metaNode)
63+ return messages. collect { it. message }. toList()
64+ }
65+
66+ static List<String > validate (Path metaYaml ) {
67+ return validate(metaYaml, DEFAULT_SCHEMA_URL )
68+ }
69+
70+ private static JsonNode parseSchema (String schemaText , String schemaLocation ) {
6071 try {
61- schema = factory . getSchema (schemaText)
72+ return JSON_MAPPER . readTree (schemaText)
6273 }
6374 catch ( Exception e ) {
6475 throw new AbortOperationException (" Invalid module schema at '${ schemaLocation} ': ${ e.message} " , e)
6576 }
77+ }
6678
67- Object yamlData
68- try ( final stream = Files . newInputStream(metaYaml) ) {
69- yamlData = new Yaml () . load(stream )
79+ private static SpecVersion.VersionFlag detectSpecVersion ( JsonNode schemaNode , String schemaLocation ) {
80+ try {
81+ return SpecVersionDetector . detect(schemaNode )
7082 }
7183 catch ( Exception e ) {
72- throw new AbortOperationException (" Failed to read module spec '${ metaYaml} ': ${ e.message} " , e)
84+ throw new AbortOperationException (
85+ " Cannot determine JSON Schema draft for '${ schemaLocation} ': ${ e.message} . " +
86+ " The schema must declare a supported \$ schema (e.g. https://json-schema.org/draft/2020-12/schema)." , e)
7387 }
88+ }
7489
75- final JsonNode node = JSON_MAPPER . valueToTree(yamlData)
76- final Set<ValidationMessage > messages = schema. validate(node)
77- return messages. collect { it. message }. toList()
90+ private static JsonSchema buildSchema (JsonNode schemaNode , SpecVersion.VersionFlag specVersion , String schemaLocation ) {
91+ try {
92+ return JsonSchemaFactory . getInstance(specVersion). getSchema(schemaNode)
93+ }
94+ catch ( Exception e ) {
95+ throw new AbortOperationException (" Invalid module schema at '${ schemaLocation} ': ${ e.message} " , e)
96+ }
7897 }
7998
80- static List<String > validate (Path metaYaml ) {
81- return validate(metaYaml, DEFAULT_SCHEMA_URL )
99+ private static JsonNode loadMeta (Path metaYaml ) {
100+ try ( final stream = Files . newInputStream(metaYaml) ) {
101+ return JSON_MAPPER . valueToTree(new Yaml (). load(stream))
102+ }
103+ catch ( Exception e ) {
104+ throw new AbortOperationException (" Failed to read module spec '${ metaYaml} ': ${ e.message} " , e)
105+ }
82106 }
83107
84108 /**
0 commit comments