52
52
import java .net .URI ;
53
53
import java .net .URISyntaxException ;
54
54
import java .net .URL ;
55
- import java .util .ArrayList ;
56
- import java .util .Arrays ;
57
- import java .util .Iterator ;
58
- import java .util .LinkedHashMap ;
59
- import java .util .LinkedHashSet ;
60
- import java .util .List ;
61
- import java .util .Map ;
62
- import java .util .Optional ;
63
- import java .util .Set ;
55
+ import java .util .*;
64
56
import java .util .stream .Collectors ;
65
57
import java .util .stream .Stream ;
66
58
@@ -98,6 +90,7 @@ public class OpenAPIDeserializer {
98
90
private static final String PATH_PARAMETER = "path" ;
99
91
private static final String HEADER_PARAMETER = "header" ;
100
92
93
+ private final Set <String > operationIDs = new HashSet <>();
101
94
102
95
public SwaggerParseResult deserialize (JsonNode rootNode ) {
103
96
return deserialize (rootNode , null );
@@ -300,11 +293,18 @@ public List<Tag> getTagList(ArrayNode obj, String location, ParseResult result)
300
293
return null ;
301
294
}
302
295
List <Tag > tags = new ArrayList <>();
296
+ Set <String > tagsTracker = new HashSet <>();
303
297
for (JsonNode item : obj ) {
304
298
if (item .getNodeType ().equals (JsonNodeType .OBJECT )) {
305
299
Tag tag = getTag ((ObjectNode ) item , location , result );
306
300
if (tag != null ) {
307
301
tags .add (tag );
302
+
303
+ if (tagsTracker .contains ((String )tag .getName ())) {
304
+ result .uniqueTags (location ,tag .getName ());
305
+ }
306
+
307
+ tagsTracker .add (tag .getName ());
308
308
}
309
309
}
310
310
}
@@ -524,6 +524,9 @@ public Paths getPaths(ObjectNode obj, String location, ParseResult result) {
524
524
if (!pathValue .getNodeType ().equals (JsonNodeType .OBJECT )) {
525
525
result .invalidType (location , pathName , "object" , pathValue );
526
526
} else {
527
+ if (!pathName .startsWith ("/" )){
528
+ result .warning (location ," Resource " +pathName + " should start with /" );
529
+ }
527
530
ObjectNode path = (ObjectNode ) pathValue ;
528
531
PathItem pathObj = getPathItem (path ,String .format ("%s.'%s'" , location ,pathName ), result );
529
532
paths .put (pathName , pathObj );
@@ -687,7 +690,7 @@ public ExternalDocumentation getExternalDocs(ObjectNode node, String location, P
687
690
}
688
691
689
692
690
- public String getString (String key , ObjectNode node , boolean required , String location , ParseResult result ) {
693
+ public String getString (String key , ObjectNode node , boolean required , String location , ParseResult result , Set < String > uniqueValues ) {
691
694
String value = null ;
692
695
JsonNode v = node .get (key );
693
696
if (node == null || v == null ) {
@@ -699,10 +702,18 @@ public String getString(String key, ObjectNode node, boolean required, String lo
699
702
result .invalidType (location , key , "string" , node );
700
703
} else {
701
704
value = v .asText ();
705
+ if (uniqueValues != null && !uniqueValues .add (value )) {
706
+ result .unique (location , "operationId" );
707
+ result .invalid ();
708
+ }
702
709
}
703
710
return value ;
704
711
}
705
712
713
+ public String getString (String key , ObjectNode node , boolean required , String location , ParseResult result ) {
714
+ return getString (key , node , required , location , result , null );
715
+ }
716
+
706
717
public Set <String > getKeys (ObjectNode node ) {
707
718
Set <String > keys = new LinkedHashSet <>();
708
719
if (node == null ) {
@@ -802,6 +813,12 @@ public License getLicense(ObjectNode node, String location, ParseResult result)
802
813
803
814
value = getString ("url" , node , false , location , result );
804
815
if (StringUtils .isNotBlank (value )) {
816
+ try {
817
+ new URL (value );
818
+ }
819
+ catch (Exception e ) {
820
+ result .warning (location ,value );
821
+ }
805
822
license .setUrl (value );
806
823
}
807
824
@@ -833,6 +850,12 @@ public Contact getContact(ObjectNode node, String location, ParseResult result)
833
850
834
851
value = getString ("url" , node , false , location , result );
835
852
if (StringUtils .isNotBlank (value )) {
853
+ try {
854
+ new URL (value );
855
+ }
856
+ catch (Exception e ) {
857
+ result .warning (location ,value );
858
+ }
836
859
contact .setUrl (value );
837
860
}
838
861
@@ -1050,6 +1073,11 @@ public Link getLink(ObjectNode linkNode, String location, ParseResult result) {
1050
1073
link .setParameters (getLinkParameters (parametersObject , location , result ));
1051
1074
}
1052
1075
1076
+ String requestBody = getString ("requestBody" ,linkNode ,false ,location ,result );
1077
+ if (requestBody != null ) {
1078
+ link .setRequestBody (requestBody );
1079
+ }
1080
+
1053
1081
ObjectNode headerObject = getObject ("headers" ,linkNode ,false ,location ,result );
1054
1082
if (headerObject != null ) {
1055
1083
link .setHeaders (getHeaders (headerObject , location , result ));
@@ -1122,14 +1150,13 @@ public Callback getCallback(ObjectNode node,String location, ParseResult result)
1122
1150
JsonNode ref = node .get ("$ref" );
1123
1151
if (ref != null ) {
1124
1152
if (ref .getNodeType ().equals (JsonNodeType .STRING )) {
1125
- PathItem pathItem = new PathItem ();
1126
1153
String mungedRef = mungedRef (ref .textValue ());
1127
1154
if (mungedRef != null ) {
1128
- pathItem .set$ref (mungedRef );
1155
+ callback .set$ref (mungedRef );
1129
1156
}else {
1130
- pathItem .set$ref (ref .textValue ());
1157
+ callback .set$ref (ref .textValue ());
1131
1158
}
1132
- return callback . addPathItem ( name , pathItem ) ;
1159
+ return callback ;
1133
1160
} else {
1134
1161
result .invalidType (location , "$ref" , "string" , node );
1135
1162
return null ;
@@ -2455,7 +2482,7 @@ public Operation getOperation(ObjectNode obj, String location, ParseResult resul
2455
2482
if (docs != null ) {
2456
2483
operation .setExternalDocs (docs );
2457
2484
}
2458
- value = getString ("operationId" , obj , false , location , result );
2485
+ value = getString ("operationId" , obj , false , location , result , operationIDs );
2459
2486
if (StringUtils .isNotBlank (value )) {
2460
2487
operation .operationId (value );
2461
2488
}
@@ -2670,6 +2697,9 @@ protected static class ParseResult {
2670
2697
private Map <Location , JsonNode > unsupported = new LinkedHashMap <>();
2671
2698
private Map <Location , String > invalidType = new LinkedHashMap <>();
2672
2699
private List <Location > missing = new ArrayList <>();
2700
+ private List <Location > warnings = new ArrayList <>();
2701
+ private List <Location > unique = new ArrayList <>();
2702
+ private List <Location > uniqueTags = new ArrayList <>();
2673
2703
2674
2704
public ParseResult () {
2675
2705
}
@@ -2685,6 +2715,17 @@ public void extra(String location, String key, JsonNode value) {
2685
2715
public void missing (String location , String key ) {
2686
2716
missing .add (new Location (location , key ));
2687
2717
}
2718
+
2719
+ public void warning (String location , String key ) {
2720
+ warnings .add (new Location (location , key ));
2721
+ }
2722
+
2723
+ public void unique (String location , String key ) {
2724
+ unique .add (new Location (location , key ));
2725
+
2726
+ }
2727
+
2728
+ public void uniqueTags (String location , String key ) {uniqueTags .add (new Location (location ,key ));}
2688
2729
2689
2730
public void invalidType (String location , String key , String expectedType , JsonNode value ) {
2690
2731
invalidType .put (new Location (location , key ), expectedType );
@@ -2715,11 +2756,26 @@ public List<String> getMessages() {
2715
2756
String message = "attribute " + location + l .key + " is missing" ;
2716
2757
messages .add (message );
2717
2758
}
2759
+ for (Location l : warnings ) {
2760
+ String location = l .location .equals ("" ) ? "" : l .location + "." ;
2761
+ String message = "attribute " + location +l .key ;
2762
+ messages .add (message );
2763
+ }
2718
2764
for (Location l : unsupported .keySet ()) {
2719
2765
String location = l .location .equals ("" ) ? "" : l .location + "." ;
2720
2766
String message = "attribute " + location + l .key + " is unsupported" ;
2721
2767
messages .add (message );
2722
2768
}
2769
+ for (Location l : unique ) {
2770
+ String location = l .location .equals ("" ) ? "" : l .location + "." ;
2771
+ String message = "attribute " + location + l .key + " is repeated" ;
2772
+ messages .add (message );
2773
+ }
2774
+ for (Location l : uniqueTags ) {
2775
+ String location = l .location .equals ("" ) ? "" : l .location + "." ;
2776
+ String message = "attribute " + location + l .key + " is repeated" ;
2777
+ messages .add (message );
2778
+ }
2723
2779
return messages ;
2724
2780
}
2725
2781
}
0 commit comments