@@ -83,6 +83,47 @@ static SchemaRef getRefSchema(Schema parentSchema, SchemaContext schemaContext,
8383 }, schemaContext .getSchemaRegistryConfig ().isCacheRefs ()));
8484 }
8585
86+ static SchemaRef getRefSchema (Schema parentSchema , String refValue ,
87+ ExecutionContext executionContext ) {
88+ String ref = resolve (parentSchema , refValue );
89+ return new SchemaRef (getSupplier (() -> {
90+ SchemaContext schemaContext = parentSchema .getSchemaContext ();
91+ Schema refSchema = parentSchema .getSchemaContext ().getDynamicAnchors ().get (ref );
92+ if (refSchema == null ) { // This is a $dynamicRef without a matching $dynamicAnchor
93+ // A $dynamicRef without a matching $dynamicAnchor in the same schema resource
94+ // behaves like a normal $ref to $anchor
95+ // A $dynamicRef without anchor in fragment behaves identical to $ref
96+ SchemaRef r = RefValidator .getRefSchema (parentSchema , schemaContext , refValue , null );
97+ if (r != null ) {
98+ refSchema = r .getSchema ();
99+ }
100+ } else {
101+ // Check parents
102+ Schema base ;
103+ int index = ref .indexOf ("#" );
104+ String anchor = ref .substring (index );
105+ String absoluteIri = ref .substring (0 , index );
106+ for (Iterator <Schema > iter = executionContext .getEvaluationSchema ().descendingIterator (); iter .hasNext ();) {
107+ base = iter .next ();
108+ String baseAbsoluteIri = base .getSchemaLocation ().getAbsoluteIri () != null ? base .getSchemaLocation ().getAbsoluteIri ().toString () : "" ;
109+ if (!baseAbsoluteIri .equals (absoluteIri )) {
110+ absoluteIri = baseAbsoluteIri ;
111+ String parentRef = SchemaLocation .resolve (base .getSchemaLocation (), anchor );
112+ Schema parentRefSchema = schemaContext .getDynamicAnchors ().get (parentRef );
113+ if (parentRefSchema != null ) {
114+ refSchema = parentRefSchema ;
115+ }
116+ }
117+ }
118+ }
119+
120+ if (refSchema != null ) {
121+ refSchema = refSchema .fromRef (parentSchema , null );
122+ }
123+ return refSchema ;
124+ }, false ));
125+ }
126+
86127 static <T > Supplier <T > getSupplier (Supplier <T > supplier , boolean cache ) {
87128 return cache ? new ThreadSafeCachingSupplier <>(supplier ) : supplier ;
88129 }
0 commit comments