66package io .openapiprocessor .jsonschema .schema ;
77
88import io .openapiprocessor .jsonschema .support .Types ;
9+ import io .openapiprocessor .jsonschema .support .Uris ;
910import org .checkerframework .checker .nullness .qual .Nullable ;
10- import org .checkerframework .checker .nullness .qual .PolyNull ;
1111import org .slf4j .Logger ;
1212import org .slf4j .LoggerFactory ;
1313
1414import java .net .URI ;
1515
16+ import static io .openapiprocessor .jsonschema .schema .SchemaVersionUtil .getSchemaVersion ;
17+
1618/**
1719 * loads the base document and resolves all internal and external $ref's. In case of an external
1820 * $ref it automatically downloads the referenced document if {@code autoLoadSchemas} is enabled.
@@ -26,8 +28,9 @@ public class Resolver {
2628 private static final Logger log = LoggerFactory .getLogger (Resolver .class );
2729
2830 public static class Settings {
29- private SchemaVersion version ;
31+ private final SchemaVersion version ;
3032 private boolean autoLoadSchemas = false ;
33+ private @ Nullable BaseUriCustomizer baseUriCustomizer ;
3134
3235 public Settings (SchemaVersion version ) {
3336 this .version = version ;
@@ -38,11 +41,26 @@ public Settings autoLoadSchemas (boolean load) {
3841 return this ;
3942 }
4043
44+ public Settings baseUriCustomizer (BaseUriCustomizer provider ) {
45+ this .baseUriCustomizer = provider ;
46+ return this ;
47+ }
48+
4149 public SchemaVersion getVersion () {
4250 return version ;
4351 }
4452 }
4553
54+ public interface BaseUriCustomizer {
55+ /**
56+ * get a base uri from a document if available.
57+ *
58+ * @param document the document
59+ * @return base uri or null
60+ */
61+ @ Nullable URI get (URI documentUri , Object document );
62+ }
63+
4664 private final DocumentStore documents ;
4765 private final DocumentLoader loader ;
4866
@@ -95,9 +113,9 @@ public ResolverResult resolve (String resourcePath, Settings settings) {
95113 public ResolverResult resolve (URI documentUri , Object document , Settings settings ) {
96114 ReferenceRegistry registry = new ReferenceRegistry ();
97115
98- documents . addId (documentUri , document );
99- Scope scope = Scope . createScope ( documentUri , document , settings . version );
100- Bucket bucket = toBucket (scope , document );
116+ Scope scope = createScope (documentUri , document , settings );
117+ documents . addId ( scope . getBaseUri () , document );
118+ Bucket bucket = Bucket . createBucket (scope , document );
101119
102120 if (bucket == null ) {
103121 return new ResolverResult (scope , document , registry , documents );
@@ -114,10 +132,23 @@ public ResolverResult resolve (URI documentUri, Object document, Settings settin
114132 return new ResolverResult (scope , document , registry , documents );
115133 }
116134
117- private @ Nullable Bucket toBucket (Scope scope , @ PolyNull Object source ) {
118- if (!Types .isObject (source )) {
119- return null ;
135+ Scope createScope (URI documentUri , Object document , Settings settings ) {
136+ SchemaVersion version = getSchemaVersion (documentUri , document , settings .version );
137+
138+ if (settings .baseUriCustomizer != null ) {
139+ @ Nullable URI baseUri = settings .baseUriCustomizer .get (documentUri , document );
140+ if (baseUri != null ) {
141+ return Scope .createScope (documentUri , Uris .resolve (documentUri , baseUri ), version );
142+ }
120143 }
121- return new Bucket (scope , Types .asObject (source ));
144+
145+ if (Types .isObject (document )) {
146+ String id = version .getIdProvider ().getId (Types .asObject (document ));
147+ if (id != null ) {
148+ return Scope .createScope (documentUri , Uris .resolve (documentUri , id ), version );
149+ }
150+ }
151+
152+ return Scope .createScope (documentUri , null , version );
122153 }
123154}
0 commit comments