11package io .swagger .v3 .parser .util ;
22
3+ import io .swagger .v3 .oas .models .Components ;
34import io .swagger .v3 .oas .models .OpenAPI ;
45import io .swagger .v3 .oas .models .Operation ;
56import io .swagger .v3 .oas .models .PathItem ;
7+ import io .swagger .v3 .oas .models .Paths ;
68import io .swagger .v3 .oas .models .callbacks .Callback ;
79import io .swagger .v3 .oas .models .examples .Example ;
810import io .swagger .v3 .oas .models .headers .Header ;
1921import io .swagger .v3 .parser .models .RefFormat ;
2022import org .slf4j .Logger ;
2123import org .slf4j .LoggerFactory ;
22-
2324import java .util .ArrayList ;
2425import java .util .HashMap ;
2526import java .util .HashSet ;
@@ -38,6 +39,8 @@ public class ResolverFully {
3839
3940 private boolean aggregateCombinators ;
4041
42+
43+
4144 public ResolverFully () {
4245 this (true );
4346 }
@@ -53,52 +56,54 @@ public ResolverFully(boolean aggregateCombinators) {
5356 private Map <String , RequestBody > requestBodies ;
5457 private Map <String , Header > headers ;
5558 private Map <String , Link > links ;
59+ private Map <String , Schema > resolvedProperties = new HashMap <>();
5660
5761 public void resolveFully (OpenAPI openAPI ) {
58- if (openAPI .getComponents () != null && openAPI .getComponents ().getRequestBodies () != null ) {
59- requestBodies = openAPI .getComponents ().getRequestBodies ();
62+ Components components = openAPI .getComponents ();
63+ if (components != null && components .getRequestBodies () != null ) {
64+ requestBodies = components .getRequestBodies ();
6065 if (requestBodies == null ) {
6166 requestBodies = new HashMap <>();
6267 }
6368 }
6469
65- if (openAPI . getComponents () != null && openAPI . getComponents () .getSchemas () != null ) {
66- schemas = openAPI . getComponents () .getSchemas ();
70+ if (components != null && components .getSchemas () != null ) {
71+ schemas = components .getSchemas ();
6772 if (schemas == null ) {
6873 schemas = new HashMap <>();
6974 }
7075 }
7176
72- if (openAPI . getComponents () != null && openAPI . getComponents () .getExamples () != null ) {
73- examples = openAPI . getComponents () .getExamples ();
77+ if (components != null && components .getExamples () != null ) {
78+ examples = components .getExamples ();
7479 if (examples == null ) {
7580 examples = new HashMap <>();
7681 }
7782 }
7883
79- if (openAPI . getComponents () != null && openAPI . getComponents () .getHeaders () != null ) {
80- headers = openAPI . getComponents () .getHeaders ();
84+ if (components != null && components .getHeaders () != null ) {
85+ headers = components .getHeaders ();
8186 if (headers == null ) {
8287 headers = new HashMap <>();
8388 }
8489 }
8590
86- if (openAPI . getComponents () != null && openAPI . getComponents () .getParameters () != null ) {
87- parameters = openAPI . getComponents () .getParameters ();
91+ if (components != null && components .getParameters () != null ) {
92+ parameters = components .getParameters ();
8893 if (parameters == null ) {
8994 parameters = new HashMap <>();
9095 }
9196 }
92- if (openAPI . getComponents () != null && openAPI . getComponents () .getLinks () != null ) {
93- links = openAPI . getComponents () .getLinks ();
97+ if (components != null && components .getLinks () != null ) {
98+ links = components .getLinks ();
9499 if (links == null ) {
95100 links = new HashMap <>();
96101 }
97102 }
98-
99- if (openAPI . getPaths () != null ) {
100- for (String pathname : openAPI . getPaths () .keySet ()) {
101- PathItem pathItem = openAPI . getPaths () .get (pathname );
103+ Paths paths = openAPI . getPaths ();
104+ if (paths != null ) {
105+ for (String pathname : paths .keySet ()) {
106+ PathItem pathItem = paths .get (pathname );
102107 resolvePath (pathItem );
103108 }
104109 }
@@ -262,21 +267,24 @@ public Schema resolveSchema(Schema schema) {
262267 String ref = schema .get$ref ();
263268 ref = ref .substring (ref .lastIndexOf ("/" ) + 1 );
264269 Schema resolved = schemas .get (ref );
265- if (resolved == null ) {
266- LOGGER .error ("unresolved model " + ref );
267- return schema ;
268- }
269- if (this .resolvedModels .containsKey (ref )) {
270- LOGGER .debug ("avoiding infinite loop" );
271- return this .resolvedModels .get (ref );
272- }
273- this .resolvedModels .put (ref , schema );
274270
275- Schema model = resolveSchema ( resolved );
271+ if ( resolved != null ) {
276272
277- // if we make it without a resolution loop, we can update the reference
278- this .resolvedModels .put (ref , model );
279- return model ;
273+ if (this .resolvedModels .containsKey (ref )) {
274+ LOGGER .debug ("avoiding infinite loop" );
275+ return resolvedModels .get (ref );
276+ }
277+ resolvedModels .put (ref , schema );
278+ Schema model = resolveSchema (resolved );
279+
280+ // if we make it without a resolution loop, we can update the reference
281+ resolvedModels .put (ref , model );
282+
283+ return model ;
284+
285+ }else {
286+ return schema ;
287+ }
280288 }
281289
282290 if (schema instanceof ArraySchema ) {
@@ -297,8 +305,14 @@ public Schema resolveSchema(Schema schema) {
297305 Schema innerProperty = obj .getProperties ().get (propertyName );
298306 // reference check
299307 if (schema != innerProperty ) {
300- Schema resolved = resolveSchema (innerProperty );
301- updated .put (propertyName , resolved );
308+ if (resolvedProperties .get (propertyName ) == null && resolvedProperties .get (propertyName ) != innerProperty ) {
309+ LOGGER .debug ("avoiding infinite loop" );
310+ Schema resolved = resolveSchema (innerProperty );
311+ updated .put (propertyName , resolved );
312+ resolvedProperties .put (propertyName , resolved );
313+ }else {
314+ updated .put (propertyName , resolvedProperties .get (propertyName ));
315+ }
302316 }
303317 }
304318 obj .setProperties (updated );
@@ -331,7 +345,14 @@ public Schema resolveSchema(Schema schema) {
331345 if (resolved .getProperties () != null ) {
332346 for (String key : properties .keySet ()) {
333347 Schema prop = (Schema ) resolved .getProperties ().get (key );
334- model .addProperties (key , resolveSchema (prop ));
348+ if (resolvedProperties .get (key ) == null && resolvedProperties .get (key ) != prop ) {
349+ LOGGER .debug ("avoiding infinite loop" );
350+ Schema resolvedProp = resolveSchema (prop );
351+ model .addProperties (key ,resolvedProp );
352+ resolvedProperties .put (key , resolvedProp );
353+ }else {
354+ model .addProperties (key ,resolvedProperties .get (key ));
355+ }
335356 }
336357 if (resolved .getRequired () != null ) {
337358 for (int i = 0 ; i < resolved .getRequired ().size (); i ++) {
@@ -372,7 +393,14 @@ public Schema resolveSchema(Schema schema) {
372393 if (resolved .getProperties () != null ) {
373394 for (String key : properties .keySet ()) {
374395 Schema prop = (Schema ) resolved .getProperties ().get (key );
375- model .addProperties (key , resolveSchema (prop ));
396+ if (resolvedProperties .get (key ) == null && resolvedProperties .get (key ) != prop ) {
397+ LOGGER .debug ("avoiding infinite loop" );
398+ Schema resolvedProp = resolveSchema (prop );
399+ model .addProperties (key ,resolvedProp );
400+ resolvedProperties .put (key , resolvedProp );
401+ }else {
402+ model .addProperties (key ,resolvedProperties .get (key ));
403+ }
376404 }
377405 if (resolved .getRequired () != null ) {
378406 for (int i = 0 ; i < resolved .getRequired ().size (); i ++) {
@@ -414,7 +442,14 @@ public Schema resolveSchema(Schema schema) {
414442 if (resolved .getProperties () != null ) {
415443 for (String key : properties .keySet ()) {
416444 Schema prop = (Schema ) resolved .getProperties ().get (key );
417- model .addProperties (key , resolveSchema (prop ));
445+ if (resolvedProperties .get (key ) == null && resolvedProperties .get (key ) != prop ) {
446+ LOGGER .debug ("avoiding infinite loop" );
447+ Schema resolvedProp = resolveSchema (prop );
448+ model .addProperties (key ,resolvedProp );
449+ resolvedProperties .put (key , resolvedProp );
450+ }else {
451+ model .addProperties (key ,resolvedProperties .get (key ));
452+ }
418453 }
419454 if (resolved .getRequired () != null ) {
420455 for (int i = 0 ; i < resolved .getRequired ().size (); i ++) {
@@ -463,8 +498,14 @@ public Schema resolveSchema(Schema schema) {
463498 Map <String , Schema > properties = model .getProperties ();
464499 for (String propertyName : properties .keySet ()) {
465500 Schema property = (Schema ) model .getProperties ().get (propertyName );
466- Schema resolved = resolveSchema (property );
467- updated .put (propertyName , resolved );
501+ if (resolvedProperties .get (propertyName ) == null && resolvedProperties .get (propertyName ) != property ) {
502+ LOGGER .debug ("avoiding infinite loop" );
503+ Schema resolved = resolveSchema (property );
504+ updated .put (propertyName , resolved );
505+ resolvedProperties .put (propertyName , resolved );
506+ }else {
507+ updated .put (propertyName , resolvedProperties .get (propertyName ));
508+ }
468509 }
469510
470511 for (String key : updated .keySet ()) {
0 commit comments