16
16
17
17
using System ;
18
18
using System . Collections . Generic ;
19
+ using System . IO ;
20
+ using System . Text . RegularExpressions ;
21
+ using System . Threading ;
19
22
using System . Threading . Tasks ;
20
23
using NJsonSchema ;
24
+ using NJsonSchema . References ;
21
25
using Newtonsoft . Json . Linq ;
22
26
#if NET8_0_OR_GREATER
23
27
using NewtonsoftJsonSchemaGeneratorSettings = NJsonSchema . NewtonsoftJson . Generation . NewtonsoftJsonSchemaGeneratorSettings ;
@@ -81,20 +85,17 @@ public async Task<JsonSchema> GetResolvedSchema(){
81
85
return resolvedJsonSchema ;
82
86
}
83
87
84
- private async Task CreateSchemaDictUtil ( Schema root )
88
+ private async Task CreateSchemaDictUtil ( Schema root , string referenceName = null )
85
89
{
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 ) ;
91
92
92
93
if ( root . References != null )
93
94
{
94
95
foreach ( var reference in root . References )
95
96
{
96
97
Schema refSchemaRes = await schemaRegistryClient . GetRegisteredSchemaAsync ( reference . Subject , reference . Version , false ) ;
97
- await CreateSchemaDictUtil ( refSchemaRes ) ;
98
+ await CreateSchemaDictUtil ( refSchemaRes , reference . Name ) ;
98
99
}
99
100
}
100
101
}
@@ -118,21 +119,78 @@ private async Task<JsonSchema> GetSchemaUtil(Schema root)
118
119
new NJsonSchema . Generation . JsonSchemaResolver ( rootObject , this . jsonSchemaGeneratorSettings ??
119
120
new NewtonsoftJsonSchemaGeneratorSettings ( ) ) ;
120
121
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 ) ;
130
123
} ;
131
124
132
125
string rootStr = root . SchemaString ;
133
126
JObject schema = JObject . Parse ( rootStr ) ;
134
- string schemaId = ( string ) schema [ "$id" ] ;
127
+ string schemaId = ( string ) schema [ "$id" ] ?? "" ;
135
128
return await JsonSchema . FromJsonAsync ( rootStr , schemaId , factory ) ;
136
129
}
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
+ }
137
195
}
138
196
}
0 commit comments