14
14
import io .swagger .v3 .oas .models .OpenAPI ;
15
15
import io .swagger .v3 .oas .models .Operation ;
16
16
import io .swagger .v3 .oas .models .PathItem ;
17
+ import io .swagger .v3 .oas .models .Paths ;
17
18
import io .swagger .v3 .oas .models .media .ArraySchema ;
18
19
import io .swagger .v3 .oas .models .media .IntegerSchema ;
19
20
import io .swagger .v3 .oas .models .media .MapSchema ;
21
+ import io .swagger .v3 .oas .models .media .MediaType ;
20
22
import io .swagger .v3 .oas .models .media .NumberSchema ;
21
23
import io .swagger .v3 .oas .models .media .ObjectSchema ;
22
24
import io .swagger .v3 .oas .models .media .Schema ;
23
25
import io .swagger .v3 .oas .models .media .StringSchema ;
26
+ import io .swagger .v3 .oas .models .parameters .RequestBody ;
24
27
import io .swagger .v3 .oas .models .responses .ApiResponse ;
25
28
import io .swagger .v3 .parser .util .SchemaTypeUtil ;
26
29
import org .apache .commons .lang3 .BooleanUtils ;
37
40
import java .util .ListIterator ;
38
41
import java .util .Map ;
39
42
import java .util .Objects ;
43
+ import java .util .Optional ;
40
44
import java .util .regex .Pattern ;
41
45
42
46
import static io .swagger .codegen .v3 .CodegenConstants .HAS_ENUMS_EXT_NAME ;
@@ -53,6 +57,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegenConfig {
53
57
public static final String WITH_XML = "withXml" ;
54
58
public static final String SUPPORT_JAVA6 = "supportJava6" ;
55
59
public static final String ERROR_ON_UNKNOWN_ENUM = "errorOnUnknownEnum" ;
60
+ public static final String CHECK_DUPLICATED_MODEL_NAME = "checkDuplicatedModelName" ;
56
61
57
62
protected String dateLibrary = "threetenbp" ;
58
63
protected boolean java8Mode = false ;
@@ -173,6 +178,7 @@ public AbstractJavaCodegen() {
173
178
java8ModeOptions .put ("false" , "Various third party libraries as needed" );
174
179
java8Mode .setEnum (java8ModeOptions );
175
180
cliOptions .add (java8Mode );
181
+ cliOptions .add (CliOption .newBoolean (CHECK_DUPLICATED_MODEL_NAME , "Check if there are duplicated model names (ignoring case)" ));
176
182
}
177
183
178
184
@ Override
@@ -1065,6 +1071,11 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
1065
1071
if (openAPI == null || openAPI .getPaths () == null ){
1066
1072
return ;
1067
1073
}
1074
+ boolean checkDuplicatedModelName = Boolean .parseBoolean (additionalProperties .get (CHECK_DUPLICATED_MODEL_NAME ) != null ? additionalProperties .get (CHECK_DUPLICATED_MODEL_NAME ).toString () : "" );
1075
+ if (checkDuplicatedModelName ) {
1076
+ this .checkDuplicatedModelNameIgnoringCase (openAPI );
1077
+ }
1078
+
1068
1079
for (String pathname : openAPI .getPaths ().keySet ()) {
1069
1080
PathItem pathItem = openAPI .getPaths ().get (pathname );
1070
1081
@@ -1123,6 +1134,103 @@ private static String getAccept(Operation operation) {
1123
1134
protected boolean needToImport (String type ) {
1124
1135
return super .needToImport (type ) && type .indexOf ("." ) < 0 ;
1125
1136
}
1137
+
1138
+ protected void checkDuplicatedModelNameIgnoringCase (OpenAPI openAPI ) {
1139
+ final Map <String , Schema > schemas = openAPI .getComponents ().getSchemas ();
1140
+ final Map <String , Map <String , Schema >> schemasRepeated = new HashMap <>();
1141
+
1142
+ for (String schemaKey : schemas .keySet ()) {
1143
+ final Schema schema = schemas .get (schemaKey );
1144
+ final String lowerKeyDefinition = schemaKey .toLowerCase ();
1145
+
1146
+ if (schemasRepeated .containsKey (lowerKeyDefinition )) {
1147
+ Map <String , Schema > modelMap = schemasRepeated .get (lowerKeyDefinition );
1148
+ if (modelMap == null ) {
1149
+ modelMap = new HashMap <>();
1150
+ schemasRepeated .put (lowerKeyDefinition , modelMap );
1151
+ }
1152
+ modelMap .put (schemaKey , schema );
1153
+ } else {
1154
+ schemasRepeated .put (lowerKeyDefinition , null );
1155
+ }
1156
+ }
1157
+ for (String lowerKeyDefinition : schemasRepeated .keySet ()) {
1158
+ final Map <String , Schema > modelMap = schemasRepeated .get (lowerKeyDefinition );
1159
+ if (modelMap == null ) {
1160
+ continue ;
1161
+ }
1162
+ int index = 1 ;
1163
+ for (String name : modelMap .keySet ()) {
1164
+ final Schema schema = modelMap .get (name );
1165
+ final String newModelName = name + index ;
1166
+ schemas .put (newModelName , schema );
1167
+ replaceDuplicatedInPaths (openAPI .getPaths (), name , newModelName );
1168
+ replaceDuplicatedInModelProperties (schemas , name , newModelName );
1169
+ schemas .remove (name );
1170
+ index ++;
1171
+ }
1172
+ }
1173
+ }
1174
+
1175
+ protected void replaceDuplicatedInPaths (Paths paths , String modelName , String newModelName ) {
1176
+ if (paths == null || paths .isEmpty ()) {
1177
+ return ;
1178
+ }
1179
+ paths .values ().stream ()
1180
+ .flatMap (pathItem -> pathItem .readOperations ().stream ())
1181
+ .filter (operation -> {
1182
+ final RequestBody requestBody = operation .getRequestBody ();
1183
+ if (requestBody == null || requestBody .getContent () == null || requestBody .getContent ().isEmpty ()) {
1184
+ return false ;
1185
+ }
1186
+ final Optional <MediaType > mediaTypeOptional = requestBody .getContent ().values ().stream ().findAny ();
1187
+ if (!mediaTypeOptional .isPresent ()) {
1188
+ return false ;
1189
+ }
1190
+ final MediaType mediaType = mediaTypeOptional .get ();
1191
+ final Schema schema = mediaType .getSchema ();
1192
+ if (schema .get$ref () != null ) {
1193
+ return true ;
1194
+ }
1195
+ return false ;
1196
+ })
1197
+ .forEach (operation -> {
1198
+ Schema schema = this .getSchemaFromBody (operation .getRequestBody ());
1199
+ schema .set$ref (schema .get$ref ().replace (modelName , newModelName ));
1200
+ });
1201
+ paths .values ().stream ()
1202
+ .flatMap (path -> path .readOperations ().stream ())
1203
+ .flatMap (operation -> operation .getResponses ().values ().stream ())
1204
+ .filter (response -> {
1205
+ if (response .getContent () == null || response .getContent ().isEmpty ()) {
1206
+ return false ;
1207
+ }
1208
+ final Optional <MediaType > mediaTypeOptional = response .getContent ().values ().stream ().findFirst ();
1209
+ if (!mediaTypeOptional .isPresent ()) {
1210
+ return false ;
1211
+ }
1212
+ final MediaType mediaType = mediaTypeOptional .get ();
1213
+ final Schema schema = mediaType .getSchema ();
1214
+ if (schema .get$ref () != null ) {
1215
+ return true ;
1216
+ }
1217
+ return false ;
1218
+ }).forEach (response -> {
1219
+ final Optional <MediaType > mediaTypeOptional = response .getContent ().values ().stream ().findFirst ();
1220
+ final Schema schema = mediaTypeOptional .get ().getSchema ();
1221
+ schema .set$ref (schema .get$ref ().replace (modelName , newModelName ));
1222
+ });
1223
+ }
1224
+
1225
+ protected void replaceDuplicatedInModelProperties (Map <String , Schema > definitions , String modelName , String newModelName ) {
1226
+ definitions .values ().stream ()
1227
+ .flatMap (model -> model .getProperties ().values ().stream ())
1228
+ .filter (property -> ((Schema ) property ).get$ref () != null )
1229
+ .forEach (property -> {
1230
+ final Schema schema = (Schema ) property ;
1231
+ schema .set$ref (schema .get$ref ().replace (modelName , newModelName ));
1232
+ });
1233
+ }
1126
1234
/*
1127
1235
@Override
1128
1236
public String findCommonPrefixOfVars(List<String> vars) {
0 commit comments