26
26
import io .swagger .v3 .oas .models .media .Schema ;
27
27
import io .swagger .v3 .oas .models .parameters .Parameter ;
28
28
import io .swagger .v3 .oas .models .responses .ApiResponse ;
29
+ import io .swagger .v3 .oas .models .security .SecurityRequirement ;
29
30
import j2html .rendering .FlatHtml ;
30
31
import j2html .tags .ContainerTag ;
31
32
import j2html .tags .specialized .DivTag ;
50
51
import org .openapitools .openapidiff .core .model .ChangedParameters ;
51
52
import org .openapitools .openapidiff .core .model .ChangedResponse ;
52
53
import org .openapitools .openapidiff .core .model .ChangedSchema ;
54
+ import org .openapitools .openapidiff .core .model .ChangedSecurityRequirement ;
55
+ import org .openapitools .openapidiff .core .model .ChangedSecurityRequirements ;
53
56
import org .openapitools .openapidiff .core .model .DiffContext ;
54
57
import org .openapitools .openapidiff .core .model .DiffResult ;
55
58
import org .openapitools .openapidiff .core .model .Endpoint ;
@@ -64,15 +67,27 @@ public class HtmlRender implements Render {
64
67
65
68
private final String title ;
66
69
private final String linkCss ;
70
+ private final boolean showAllChanges ;
67
71
protected ChangedOpenApi diff ;
68
72
69
73
public HtmlRender () {
70
74
this ("Api Change Log" , "http://deepoove.com/swagger-diff/stylesheets/demo.css" );
71
75
}
72
76
77
+ public HtmlRender (boolean showAllChanges ) {
78
+ this ("Api Change Log" , "http://deepoove.com/swagger-diff/stylesheets/demo.css" , showAllChanges );
79
+ }
80
+
73
81
public HtmlRender (String title , String linkCss ) {
74
82
this .title = title ;
75
83
this .linkCss = linkCss ;
84
+ this .showAllChanges = false ;
85
+ }
86
+
87
+ public HtmlRender (String title , String linkCss , boolean showAllChanges ) {
88
+ this .title = title ;
89
+ this .linkCss = linkCss ;
90
+ this .showAllChanges = showAllChanges ;
76
91
}
77
92
78
93
public void render (ChangedOpenApi diff , OutputStreamWriter outputStreamWriter ) {
@@ -200,6 +215,11 @@ private OlTag ol_changed(List<ChangedOperation> changedOperations) {
200
215
ul_detail .with (
201
216
li ().with (h3 ("Response" )).with (ul_response (changedOperation .getApiResponses ())));
202
217
}
218
+ if (showAllChanges && changedOperation .resultSecurityRequirements ().isDifferent ()) {
219
+ ul_detail .with (
220
+ li ().with (h3 ("Security Requirements" ))
221
+ .with (ul_securityRequirements (changedOperation .getSecurityRequirements ())));
222
+ }
203
223
ol .with (
204
224
li ().with (span (method ).withClass (method ))
205
225
.withText (pathUrl + " " )
@@ -209,6 +229,52 @@ private OlTag ol_changed(List<ChangedOperation> changedOperations) {
209
229
return ol ;
210
230
}
211
231
232
+ private UlTag ul_securityRequirements (ChangedSecurityRequirements changedSecurityRequirements ) {
233
+ List <SecurityRequirement > addRequirements = changedSecurityRequirements .getIncreased ();
234
+ List <SecurityRequirement > delRequirements = changedSecurityRequirements .getMissing ();
235
+ List <ChangedSecurityRequirement > changedRequirements = changedSecurityRequirements .getChanged ();
236
+ UlTag ul = ul ().withClass ("change security requirements" );
237
+ if (addRequirements != null ) {
238
+ for (SecurityRequirement addRequirement : addRequirements ) {
239
+ ul .with (li_addSecurityRequirement (addRequirement ));
240
+ }
241
+ }
242
+ if (delRequirements != null ) {
243
+ for (SecurityRequirement delRequirement : delRequirements ) {
244
+ ul .with (li_missingSecurityRequirement (delRequirement ));
245
+ }
246
+ }
247
+ if (changedRequirements != null ) {
248
+ for (ChangedSecurityRequirement changedRequirement : changedRequirements ) {
249
+ ul .with (li_changedSecurityRequirement (changedRequirement ));
250
+ }
251
+ }
252
+
253
+ return ul ;
254
+ }
255
+
256
+ private LiTag li_addSecurityRequirement (SecurityRequirement securityRequirement ) {
257
+ return li ().withText ("New security requirement : " )
258
+ .with (span (null == securityRequirement .toString () ? "" : (securityRequirement .toString ())));
259
+ }
260
+
261
+ private LiTag li_missingSecurityRequirement (SecurityRequirement securityRequirement ) {
262
+ return li ().withText ("Deleted security requirement : " )
263
+ .with (span (null == securityRequirement .toString () ? "" : (securityRequirement .toString ())));
264
+ }
265
+
266
+ private LiTag li_changedSecurityRequirement (
267
+ ChangedSecurityRequirement changedSecurityRequirement ) {
268
+ return li ().withText (String .format ("Changed security requirement : " ))
269
+ .with (
270
+ span (
271
+ (null == changedSecurityRequirement .getNewSecurityRequirement ()
272
+ || null
273
+ == changedSecurityRequirement .getNewSecurityRequirement ().toString ())
274
+ ? ""
275
+ : (changedSecurityRequirement .getNewSecurityRequirement ().toString ())));
276
+ }
277
+
212
278
private UlTag ul_response (ChangedApiResponse changedApiResponse ) {
213
279
Map <String , ApiResponse > addResponses = changedApiResponse .getIncreased ();
214
280
Map <String , ApiResponse > delResponses = changedApiResponse .getMissing ();
@@ -279,9 +345,12 @@ private LiTag li_changedRequest(String name, ChangedMediaType request) {
279
345
LiTag li =
280
346
li ().with (div_changedSchema (request .getSchema ()))
281
347
.withText (String .format ("Changed body: '%s'" , name ));
282
- if (request .isIncompatible ()) {
348
+ if (request .isIncompatible () && ! showAllChanges ) {
283
349
incompatibilities (li , request .getSchema ());
284
350
}
351
+ else if (showAllChanges ) {
352
+ allChanges (li , request .getSchema ());
353
+ }
285
354
return li ;
286
355
}
287
356
@@ -291,6 +360,28 @@ private DivTag div_changedSchema(ChangedSchema schema) {
291
360
return div ;
292
361
}
293
362
363
+ private void allChanges (final LiTag output , final ChangedSchema schema ) {
364
+ allChanges (output , "" , schema );
365
+ }
366
+
367
+ private void allChanges (
368
+ final ContainerTag <?> output , String propName , final ChangedSchema schema ) {
369
+ String prefix = propName .isEmpty () ? "" : propName + "." ;
370
+ properties (
371
+ output , prefix , "Missing property" , schema .getMissingProperties (), schema .getContext ());
372
+ properties (
373
+ output , prefix , "Added property" , schema .getIncreasedProperties (), schema .getContext ());
374
+
375
+ propertiesChanged (
376
+ output , prefix , "Changed property" , schema .getChangedProperties (), schema .getContext ());
377
+ if (schema .getItems () != null ) {
378
+ itemsAllChanges (output , propName , schema .getItems ());
379
+ }
380
+ schema
381
+ .getChangedProperties ()
382
+ .forEach ((name , property ) -> allChanges (output , prefix + name , property ));
383
+ }
384
+
294
385
private void incompatibilities (final LiTag output , final ChangedSchema schema ) {
295
386
incompatibilities (output , "" , schema );
296
387
}
@@ -316,6 +407,10 @@ private void items(ContainerTag<?> output, String propName, ChangedSchema schema
316
407
incompatibilities (output , propName + "[n]" , schema );
317
408
}
318
409
410
+ private void itemsAllChanges (ContainerTag <?> output , String propName , ChangedSchema schema ) {
411
+ allChanges (output , propName + "[n]" , schema );
412
+ }
413
+
319
414
private void properties (
320
415
ContainerTag <?> output ,
321
416
String propPrefix ,
@@ -327,6 +422,17 @@ private void properties(
327
422
}
328
423
}
329
424
425
+ private void propertiesChanged (
426
+ ContainerTag <?> output ,
427
+ String propPrefix ,
428
+ String title ,
429
+ Map <String , ChangedSchema > properties ,
430
+ DiffContext context ) {
431
+ if (properties != null ) {
432
+ properties .forEach ((key , value ) -> resolveProperty (output , propPrefix , key , value , title ));
433
+ }
434
+ }
435
+
330
436
private void resolveProperty (
331
437
ContainerTag <?> output , String propPrefix , String key , Schema <?> value , String title ) {
332
438
try {
@@ -336,6 +442,15 @@ private void resolveProperty(
336
442
}
337
443
}
338
444
445
+ private void resolveProperty (
446
+ ContainerTag <?> output , String propPrefix , String key , ChangedSchema value , String title ) {
447
+ try {
448
+ property (output , propPrefix + key , title , resolve (value ));
449
+ } catch (Exception e ) {
450
+ property (output , propPrefix + key , title , type (value ));
451
+ }
452
+ }
453
+
339
454
protected void property (ContainerTag <?> output , String name , String title , Schema <?> schema ) {
340
455
property (output , name , title , type (schema ));
341
456
}
@@ -349,6 +464,13 @@ protected Schema<?> resolve(Schema<?> schema) {
349
464
diff .getNewSpecOpenApi ().getComponents (), schema , schema .get$ref ());
350
465
}
351
466
467
+ protected Schema <?> resolve (ChangedSchema schema ) {
468
+ return refPointer .resolveRef (
469
+ diff .getNewSpecOpenApi ().getComponents (),
470
+ schema .getNewSchema (),
471
+ schema .getNewSchema ().get$ref ());
472
+ }
473
+
352
474
protected String type (Schema <?> schema ) {
353
475
String result = "object" ;
354
476
if (schema == null ) {
@@ -361,6 +483,10 @@ protected String type(Schema<?> schema) {
361
483
return result ;
362
484
}
363
485
486
+ protected String type (ChangedSchema schema ) {
487
+ return type (schema .getNewSchema ());
488
+ }
489
+
364
490
private UlTag ul_param (ChangedParameters changedParameters ) {
365
491
List <Parameter > addParameters = changedParameters .getIncreased ();
366
492
List <Parameter > delParameters = changedParameters .getMissing ();
0 commit comments