1616
1717using System ;
1818using System . Collections . Generic ;
19+ using System . IO ;
20+ using System . Text . RegularExpressions ;
21+ using System . Threading ;
1922using System . Threading . Tasks ;
2023using NJsonSchema ;
24+ using NJsonSchema . References ;
2125using Newtonsoft . Json . Linq ;
2226#if NET8_0_OR_GREATER
2327using NewtonsoftJsonSchemaGeneratorSettings = NJsonSchema . NewtonsoftJson . Generation . NewtonsoftJsonSchemaGeneratorSettings ;
@@ -81,20 +85,17 @@ public async Task<JsonSchema> GetResolvedSchema(){
8185 return resolvedJsonSchema ;
8286 }
8387
84- private async Task CreateSchemaDictUtil ( Schema root )
88+ private async Task CreateSchemaDictUtil ( Schema root , string referenceName = null )
8589 {
86- string rootStr = root . SchemaString ;
87- JObject schema = JObject . Parse ( rootStr ) ;
88- string schemaId = ( string ) schema [ "$id" ] ;
89- if ( schemaId != null && ! dictSchemaNameToSchema . ContainsKey ( schemaId ) )
90- this . dictSchemaNameToSchema . Add ( schemaId , root ) ;
90+ if ( referenceName != null && ! dictSchemaNameToSchema . ContainsKey ( referenceName ) )
91+ this . dictSchemaNameToSchema . Add ( referenceName , root ) ;
9192
9293 if ( root . References != null )
9394 {
9495 foreach ( var reference in root . References )
9596 {
9697 Schema refSchemaRes = await schemaRegistryClient . GetRegisteredSchemaAsync ( reference . Subject , reference . Version , false ) ;
97- await CreateSchemaDictUtil ( refSchemaRes ) ;
98+ await CreateSchemaDictUtil ( refSchemaRes , reference . Name ) ;
9899 }
99100 }
100101 }
@@ -118,21 +119,78 @@ private async Task<JsonSchema> GetSchemaUtil(Schema root)
118119 new NJsonSchema . Generation . JsonSchemaResolver ( rootObject , this . jsonSchemaGeneratorSettings ??
119120 new NewtonsoftJsonSchemaGeneratorSettings ( ) ) ;
120121
121- JsonReferenceResolver referenceResolver =
122- new JsonReferenceResolver ( schemaResolver ) ;
123- foreach ( var reference in refers )
124- {
125- JsonSchema jschema =
126- dictSchemaNameToJsonSchema [ reference . Name ] ;
127- referenceResolver . AddDocumentReference ( reference . Name , jschema ) ;
128- }
129- return referenceResolver ;
122+ return new CustomJsonReferenceResolver ( schemaResolver , rootObject , dictSchemaNameToJsonSchema ) ;
130123 } ;
131124
132125 string rootStr = root . SchemaString ;
133126 JObject schema = JObject . Parse ( rootStr ) ;
134- string schemaId = ( string ) schema [ "$id" ] ;
127+ string schemaId = ( string ) schema [ "$id" ] ?? "" ;
135128 return await JsonSchema . FromJsonAsync ( rootStr , schemaId , factory ) ;
136129 }
130+
131+ private class CustomJsonReferenceResolver : JsonReferenceResolver
132+ {
133+ private JsonSchema rootObject ;
134+ private Dictionary < string , JsonSchema > refs ;
135+
136+ public CustomJsonReferenceResolver ( JsonSchemaAppender schemaAppender ,
137+ JsonSchema rootObject , Dictionary < string , JsonSchema > refs )
138+ : base ( schemaAppender )
139+ {
140+ this . rootObject = rootObject ;
141+ this . refs = refs ;
142+ }
143+
144+ public override string ResolveFilePath ( string documentPath , string jsonPath )
145+ {
146+ // override the default behavior to not prepend the documentPath
147+ var arr = Regex . Split ( jsonPath , @"(?=#)" ) ;
148+ return arr [ 0 ] ;
149+ }
150+
151+ public override async Task < IJsonReference > ResolveFileReferenceAsync ( string filePath , CancellationToken cancellationToken = default )
152+ {
153+ JsonSchema schema ;
154+ if ( refs . TryGetValue ( filePath , out schema ) )
155+ {
156+ return schema ;
157+ }
158+
159+ // remove the documentPath and look for the reference
160+ var fileName = Path . GetFileName ( filePath ) ;
161+ if ( refs . TryGetValue ( fileName , out schema ) )
162+ {
163+ return schema ;
164+ }
165+
166+ return await base . ResolveFileReferenceAsync ( filePath , cancellationToken ) ;
167+ }
168+
169+ public override async Task < IJsonReference > ResolveUrlReferenceAsync ( string url , CancellationToken cancellationToken = default )
170+ {
171+ JsonSchema schema ;
172+ if ( refs . TryGetValue ( url , out schema ) )
173+ {
174+ return schema ;
175+ }
176+
177+ var documentPathProvider = rootObject as IDocumentPathProvider ;
178+ var documentPath = documentPathProvider ? . DocumentPath ;
179+ if ( documentPath != null )
180+ {
181+ var documentUri = new Uri ( documentPath ) ;
182+ var uri = new Uri ( url ) ;
183+ var relativeUrl = documentUri . MakeRelativeUri ( uri ) ;
184+
185+ // remove the documentPath and look for the reference
186+ if ( refs . TryGetValue ( relativeUrl . ToString ( ) , out schema ) )
187+ {
188+ return schema ;
189+ }
190+ }
191+
192+ return await base . ResolveUrlReferenceAsync ( url , cancellationToken ) ;
193+ }
194+ }
137195 }
138196}
0 commit comments