4
4
import static j2html .TagCreator .*;
5
5
6
6
import com .qdesrame .openapi .diff .model .*;
7
+ import com .qdesrame .openapi .diff .utils .RefPointer ;
8
+ import com .qdesrame .openapi .diff .utils .RefType ;
9
+ import io .swagger .v3 .oas .models .media .ArraySchema ;
7
10
import io .swagger .v3 .oas .models .media .MediaType ;
11
+ import io .swagger .v3 .oas .models .media .Schema ;
8
12
import io .swagger .v3 .oas .models .parameters .Parameter ;
9
13
import io .swagger .v3 .oas .models .responses .ApiResponse ;
10
14
import j2html .tags .ContainerTag ;
@@ -16,6 +20,8 @@ public class HtmlRender implements Render {
16
20
17
21
private String title ;
18
22
private String linkCss ;
23
+ protected static RefPointer <Schema > refPointer = new RefPointer <>(RefType .SCHEMAS );
24
+ protected ChangedOpenApi diff ;
19
25
20
26
public HtmlRender () {
21
27
this ("Api Change Log" , "http://deepoove.com/swagger-diff/stylesheets/demo.css" );
@@ -27,6 +33,8 @@ public HtmlRender(String title, String linkCss) {
27
33
}
28
34
29
35
public String render (ChangedOpenApi diff ) {
36
+ this .diff = diff ;
37
+
30
38
List <Endpoint > newEndpoints = diff .getNewEndpoints ();
31
39
ContainerTag ol_newEndpoint = ol_newEndpoint (newEndpoints );
32
40
@@ -218,7 +226,7 @@ private ContainerTag li_changedRequest(String name, ChangedMediaType request) {
218
226
li ().with (div_changedSchema (request .getSchema ()))
219
227
.withText (String .format ("Changed body: '%s'" , name ));
220
228
if (request .isIncompatible ()) {
221
- li = incompatibility (li , request , "" );
229
+ incompatibilities (li , request . getSchema () );
222
230
}
223
231
return li ;
224
232
}
@@ -229,55 +237,63 @@ private ContainerTag div_changedSchema(ChangedSchema schema) {
229
237
return div ;
230
238
}
231
239
232
- private ContainerTag incompatibility (
233
- final ContainerTag output , final ComposedChanged changed , final String propPrefix ) {
234
- if (changed .isCoreChanged () == DiffResult .INCOMPATIBLE ) {
235
- if (changed instanceof ChangedSchema ) {
236
- ChangedSchema cs = (ChangedSchema ) changed ;
237
-
238
- cs .getMissingProperties ().keySet ().stream ()
239
- .forEach (
240
- (propName ) -> {
241
- output .with (
242
- p (String .format (
243
- "Missing property: %s%s%s" ,
244
- propPrefix , propPrefix .isEmpty () ? "" : "." , propName ))
245
- .withClass ("missing" ));
246
- });
247
-
248
- if (cs .isChangedType ()) {
249
- output .with (p ("Changed property type: " + propPrefix ).withClass ("missing" ));
250
- }
251
- }
240
+ private void incompatibilities (final ContainerTag output , final ChangedSchema schema ) {
241
+ incompatibilities (output , "" , schema );
242
+ }
243
+
244
+ private void incompatibilities (
245
+ final ContainerTag output , String propName , final ChangedSchema schema ) {
246
+ if (schema .getItems () != null ) {
247
+ items (output , propName , schema .getItems ());
248
+ }
249
+ if (schema .isCoreChanged () == DiffResult .INCOMPATIBLE && schema .isChangedType ()) {
250
+ String type = type (schema .getOldSchema ()) + " -> " + type (schema .getNewSchema ());
251
+ property (output , propName , "Changed property type" , type );
252
252
}
253
+ String prefix = propName .isEmpty () ? "" : propName + "." ;
254
+ properties (
255
+ output , prefix , "Missing property" , schema .getMissingProperties (), schema .getContext ());
256
+ schema
257
+ .getChangedProperties ()
258
+ .forEach ((name , property ) -> incompatibilities (output , prefix + name , property ));
259
+ }
253
260
254
- if (changed instanceof ChangedSchema ) {
255
- ChangedSchema cs = (ChangedSchema ) changed ;
256
-
257
- String description = null ;
258
- if (!cs .getChangedProperties ().isEmpty ()) {
259
- cs .getChangedProperties ().entrySet ().stream ()
260
- .forEach (
261
- (entry ) -> {
262
- incompatibility (
263
- output ,
264
- entry .getValue (),
265
- propPrefix + (propPrefix .isEmpty () ? "" : "." ) + entry .getKey ());
266
- });
267
- } else if (cs .getItems () != null ) {
268
- incompatibility (output , cs .getItems (), propPrefix + "[n]" );
269
- }
261
+ private void items (ContainerTag output , String propName , ChangedSchema schema ) {
262
+ incompatibilities (output , propName + "[n]" , schema );
263
+ }
270
264
271
- return output ;
265
+ private void properties (
266
+ ContainerTag output ,
267
+ String propPrefix ,
268
+ String title ,
269
+ Map <String , Schema > properties ,
270
+ DiffContext context ) {
271
+ if (properties != null ) {
272
+ properties .forEach ((key , value ) -> property (output , propPrefix + key , title , resolve (value )));
272
273
}
274
+ }
273
275
274
- for (Changed child : changed .getChangedElements ()) {
275
- if (child instanceof ComposedChanged ) {
276
- incompatibility (output , (ComposedChanged ) child , "" );
277
- }
278
- }
276
+ protected void property (ContainerTag output , String name , String title , Schema schema ) {
277
+ property (output , name , title , type (schema ));
278
+ }
279
+
280
+ protected void property (ContainerTag output , String name , String title , String type ) {
281
+ output .with (p (String .format ("%s: %s (%s)" , title , name , type )).withClass ("missing" ));
282
+ }
283
+
284
+ protected Schema resolve (Schema schema ) {
285
+ return refPointer .resolveRef (
286
+ diff .getNewSpecOpenApi ().getComponents (), schema , schema .get$ref ());
287
+ }
279
288
280
- return output ;
289
+ protected String type (Schema schema ) {
290
+ String result = "object" ;
291
+ if (schema instanceof ArraySchema ) {
292
+ result = "array" ;
293
+ } else if (schema .getType () != null ) {
294
+ result = schema .getType ();
295
+ }
296
+ return result ;
281
297
}
282
298
283
299
private ContainerTag ul_param (ChangedParameters changedParameters ) {
0 commit comments