1818
1919import com .fasterxml .jackson .databind .JsonNode ;
2020import com .fasterxml .jackson .databind .ObjectMapper ;
21+ import com .fasterxml .jackson .dataformat .yaml .YAMLMapper ;
2122import com .networknt .schema .uri .*;
2223import com .networknt .schema .urn .URNFactory ;
2324import org .slf4j .Logger ;
@@ -41,6 +42,7 @@ public class JsonSchemaFactory {
4142
4243 public static class Builder {
4344 private ObjectMapper objectMapper = new ObjectMapper ();
45+ private YAMLMapper yamlMapper = new YAMLMapper ();
4446 private String defaultMetaSchemaURI ;
4547 private final Map <String , URIFactory > uriFactoryMap = new HashMap <String , URIFactory >();
4648 private final Map <String , URIFetcher > uriFetcherMap = new HashMap <String , URIFetcher >();
@@ -77,6 +79,11 @@ public Builder objectMapper(final ObjectMapper objectMapper) {
7779 return this ;
7880 }
7981
82+ public Builder yamlMapper (final YAMLMapper yamlMapper ) {
83+ this .yamlMapper = yamlMapper ;
84+ return this ;
85+ }
86+
8087 public Builder defaultMetaSchemaURI (final String defaultMetaSchemaURI ) {
8188 this .defaultMetaSchemaURI = defaultMetaSchemaURI ;
8289 return this ;
@@ -154,6 +161,7 @@ public JsonSchemaFactory build() {
154161 // create builtin keywords with (custom) formats.
155162 return new JsonSchemaFactory (
156163 objectMapper == null ? new ObjectMapper () : objectMapper ,
164+ yamlMapper == null ? new YAMLMapper (): yamlMapper ,
157165 defaultMetaSchemaURI ,
158166 new URISchemeFactory (uriFactoryMap ),
159167 new URISchemeFetcher (uriFetcherMap ),
@@ -166,7 +174,8 @@ public JsonSchemaFactory build() {
166174 }
167175 }
168176
169- private final ObjectMapper mapper ;
177+ private final ObjectMapper jsonMapper ;
178+ private final YAMLMapper yamlMapper ;
170179 private final String defaultMetaSchemaURI ;
171180 private final URISchemeFactory uriFactory ;
172181 private final URISchemeFetcher uriFetcher ;
@@ -179,7 +188,8 @@ public JsonSchemaFactory build() {
179188
180189
181190 private JsonSchemaFactory (
182- final ObjectMapper mapper ,
191+ final ObjectMapper jsonMapper ,
192+ final YAMLMapper yamlMapper ,
183193 final String defaultMetaSchemaURI ,
184194 final URISchemeFactory uriFactory ,
185195 final URISchemeFetcher uriFetcher ,
@@ -188,8 +198,10 @@ private JsonSchemaFactory(
188198 final Map <String , String > uriMap ,
189199 final boolean forceHttps ,
190200 final boolean removeEmptyFragmentSuffix ) {
191- if (mapper == null ) {
201+ if (jsonMapper == null ) {
192202 throw new IllegalArgumentException ("ObjectMapper must not be null" );
203+ } else if (yamlMapper == null ) {
204+ throw new IllegalArgumentException ("YAMLMapper must not be null" );
193205 } else if (defaultMetaSchemaURI == null || defaultMetaSchemaURI .trim ().isEmpty ()) {
194206 throw new IllegalArgumentException ("defaultMetaSchemaURI must not be null or empty" );
195207 } else if (uriFactory == null ) {
@@ -203,7 +215,8 @@ private JsonSchemaFactory(
203215 } else if (uriMap == null ) {
204216 throw new IllegalArgumentException ("URL Mappings must not be null" );
205217 }
206- this .mapper = mapper ;
218+ this .jsonMapper = jsonMapper ;
219+ this .yamlMapper = yamlMapper ;
207220 this .defaultMetaSchemaURI = defaultMetaSchemaURI ;
208221 this .uriFactory = uriFactory ;
209222 this .uriFetcher = uriFetcher ;
@@ -274,7 +287,8 @@ public static Builder builder(final JsonSchemaFactory blueprint) {
274287 Builder builder = builder ()
275288 .addMetaSchemas (blueprint .jsonMetaSchemas .values ())
276289 .defaultMetaSchemaURI (blueprint .defaultMetaSchemaURI )
277- .objectMapper (blueprint .mapper )
290+ .objectMapper (blueprint .jsonMapper )
291+ .yamlMapper (blueprint .yamlMapper )
278292 .addUriMappings (blueprint .uriMap );
279293
280294 for (Map .Entry <String , URIFactory > entry : blueprint .uriFactory .getURIFactories ().entrySet ()) {
@@ -319,7 +333,7 @@ public URIFactory getUriFactory() {
319333
320334 public JsonSchema getSchema (final String schema , final SchemaValidatorsConfig config ) {
321335 try {
322- final JsonNode schemaNode = mapper .readTree (schema );
336+ final JsonNode schemaNode = jsonMapper .readTree (schema );
323337 return newJsonSchema (null , schemaNode , config );
324338 } catch (IOException ioe ) {
325339 logger .error ("Failed to load json schema!" , ioe );
@@ -333,7 +347,7 @@ public JsonSchema getSchema(final String schema) {
333347
334348 public JsonSchema getSchema (final InputStream schemaStream , final SchemaValidatorsConfig config ) {
335349 try {
336- final JsonNode schemaNode = mapper .readTree (schemaStream );
350+ final JsonNode schemaNode = jsonMapper .readTree (schemaStream );
337351 return newJsonSchema (null , schemaNode , config );
338352 } catch (IOException ioe ) {
339353 logger .error ("Failed to load json schema!" , ioe );
@@ -370,7 +384,14 @@ public JsonSchema getSchema(final URI schemaUri, final SchemaValidatorsConfig co
370384
371385 try {
372386 inputStream = this .uriFetcher .fetch (mappedUri );
373- final JsonNode schemaNode = mapper .readTree (inputStream );
387+
388+ final JsonNode schemaNode ;
389+ if (isYaml (mappedUri )) {
390+ schemaNode = yamlMapper .readTree (inputStream );
391+ } else {
392+ schemaNode = jsonMapper .readTree (inputStream );
393+ }
394+
374395 final JsonMetaSchema jsonMetaSchema = findMetaSchemaForSchema (schemaNode );
375396
376397 JsonSchema jsonSchema ;
@@ -428,6 +449,19 @@ private boolean idMatchesSourceUri(final JsonMetaSchema metaSchema, final JsonNo
428449 return result ;
429450 }
430451
452+ private boolean isYaml (final URI schemaUri ) {
453+ final String schemeSpecificPart = schemaUri .getSchemeSpecificPart ();
454+ final int idx = schemeSpecificPart .lastIndexOf ('.' );
455+
456+ if (idx == -1 ) {
457+ // no extension; assume json
458+ return false ;
459+ }
460+
461+ final String extension = schemeSpecificPart .substring (idx );
462+ return (".yml" .equals (extension ) || ".yaml" .equals (extension ));
463+ }
464+
431465 static protected String normalizeMetaSchemaUri (String u , boolean forceHttps , boolean removeEmptyFragmentSuffix ) {
432466 try {
433467 URI uri = new URI (u );
0 commit comments