Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ public String toModelName(final String name) {

// camelize the model name
// phone_number => PhoneNumber
final String camelizedName = camelize(nameWithPrefixSuffix);
String camelizedName = camelize(nameWithPrefixSuffix);

// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
Expand All @@ -1021,6 +1021,15 @@ public String toModelName(final String name) {
return modelName;
}

Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
if(!camelizedName.equals(origName)) {
int count = 0;
String augmentedName = camelizedName;
while(allDefinitions.containsKey(augmentedName) || schemaKeyToModelNameCache.containsValue(augmentedName)) {
augmentedName = camelizedName + count++;
}
camelizedName = augmentedName;
}
schemaKeyToModelNameCache.put(origName, camelizedName);

return camelizedName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,20 +172,20 @@ public void convertVarNameWithCaml() {
@Test
public void convertModelName() {
Assert.assertEquals(codegen.toModelName("name"), "Name");
Assert.assertEquals(codegen.toModelName("$name"), "Name");
Assert.assertEquals(codegen.toModelName("nam#e"), "Name");
Assert.assertEquals(codegen.toModelName("$name"), "Name0");
Assert.assertEquals(codegen.toModelName("nam#e"), "Name1");
Assert.assertEquals(codegen.toModelName("$another-fake?"), "AnotherFake");
Assert.assertEquals(codegen.toModelName("1a"), "Model1a");
Assert.assertEquals(codegen.toModelName("1A"), "Model1A");
Assert.assertEquals(codegen.toModelName("AAAb"), "AAAb");
Assert.assertEquals(codegen.toModelName("aBB"), "ABB");
Assert.assertEquals(codegen.toModelName("AaBBa"), "AaBBa");
Assert.assertEquals(codegen.toModelName("A_B"), "AB");
Assert.assertEquals(codegen.toModelName("A-B"), "AB");
Assert.assertEquals(codegen.toModelName("A-B"), "AB0");
Assert.assertEquals(codegen.toModelName("Aa_Bb"), "AaBb");
Assert.assertEquals(codegen.toModelName("Aa-Bb"), "AaBb");
Assert.assertEquals(codegen.toModelName("Aa_bb"), "AaBb");
Assert.assertEquals(codegen.toModelName("Aa-bb"), "AaBb");
Assert.assertEquals(codegen.toModelName("Aa-Bb"), "AaBb0");
Assert.assertEquals(codegen.toModelName("Aa_bb"), "AaBb1");
Assert.assertEquals(codegen.toModelName("Aa-bb"), "AaBb2");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3833,6 +3833,57 @@ public void queryParameterJsonSerialization(String library) {
);
}

@Test(description = "Issue #20889")
public void givenInlineSchemaConvertedNameClashesWithTopLevelSchemaNameWhenGenerateThenFilesDoNotOverwriteEachOther() throws Exception {
final Path output = newTempFolder();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName(JAVA_GENERATOR)
.setInputSpec("src/test/resources/bugs/issue_20889.json")
.setValidateSpec(false)
.setOutputDir(output.toString().replace("\\", "/"));
;
DefaultGenerator generator = new DefaultGenerator();
Map<String, File> files = generator.opts(configurator.toClientOptInput()).generate().stream()
.collect(Collectors.toMap(File::getName, Function.identity()));

JavaFileAssert.assertThat(files.get("OrgAttributes.java"))
.assertProperty("createdAt")
.withType("OffsetDateTime");

JavaFileAssert.assertThat(files.get("OrgAttributes0.java"))
.hasNoProperty("createdAt");

JavaFileAssert.assertThat(files.get("Org.java"))
.assertProperty("attributes")
.withType("OrgAttributes0")
.toType()
.assertProperty("branch")
.withType("OrgBranch0");

JavaFileAssert.assertThat(files.get("OrgBranch.java"))
.assertProperty("attributes")
.withType("OrgBranchAttributes0");

JavaFileAssert.assertThat(files.get("OrgBranch0.java"))
.assertProperty("attributes")
.withType("OrgBranchAttributes1");

JavaFileAssert.assertThat(files.get("OrgBranchAttributes1.java"))
.assertProperty("basicDescription")
.withType("String");

JavaFileAssert.assertThat(files.get("OrgBranchAttributes0.java"))
.assertProperty("uuid")
.withType("UUID");

JavaFileAssert.assertThat(files.get("OrgBranchAttributes.java"))
.assertProperty("detailedDescription")
.withType("String");

assertTrue(files.containsKey("OrgBranchAttributes0Test.java"));
assertTrue(files.containsKey("OrgBranchAttributes1Test.java"));
}

@DataProvider(name = "springClients")
public static Object[] springClients() {
return new Object[]{RESTCLIENT, WEBCLIENT};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,16 @@ public JavaFileAssert fileContainsPattern(final String pattern) {

return this;
}

public JavaFileAssert hasNoProperty(final String propertyName) {
Optional<FieldDeclaration> fieldOptional = actual.getType(0).getMembers().stream()
.filter(FieldDeclaration.class::isInstance)
.map(FieldDeclaration.class::cast)
.filter(field -> field.getVariables().getFirst().map(var -> var.getNameAsString().equals(propertyName)).orElse(Boolean.FALSE))
.findFirst();
Assertions.assertThat(fieldOptional)
.withFailMessage("Should not have property %s", propertyName)
.isNotPresent();
return this;
}
}
220 changes: 220 additions & 0 deletions modules/openapi-generator/src/test/resources/bugs/issue_20889.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"components": {
"schemas": {
"Org": {
"additionalProperties": false,
"properties": {
"attributes": {
"additionalProperties": false,
"properties": {
"group_id": {
"description": "The ID of a Group.",
"example": "59d6d97e-3106-4ebb-b608-352fad9c5b34",
"format": "uuid",
"type": "string"
},
"is_personal": {
"description": "Whether this organization belongs to an individual, rather than a Group.",
"example": true,
"type": "boolean"
},
"name": {
"description": "Friendly name of the organization.",
"example": "My Org",
"type": "string"
},
"slug": {
"description": "Unique URL sanitized name of the organization for accessing it in Snyk.",
"example": "my-org",
"type": "string"
}
},
"required": [
"name",
"slug",
"is_personal"
],
"type": "object"
},
"id": {
"description": "The Snyk ID corresponding to this org",
"example": "59d6d97e-3106-4ebb-b608-352fad9c5b34",
"format": "uuid",
"type": "string"
},
"type": {
"description": "Content type.",
"example": "org",
"type": "string"
},
"branch": {
"additionalProperties": false,
"type": "object",
"properties": {
"attributes": {
"type": "object",
"properties": {
"basicDescription": {
"type": "string"
}
}
}
}
}
},
"required": [
"type",
"id"
],
"type": "object"
},
"Org20230529": {
"additionalProperties": false,
"properties": {
"attributes": {
"$ref": "#/components/schemas/OrgAttributes20230529"
},
"id": {
"description": "The Snyk ID of the organization.",
"example": "59d6d97e-3106-4ebb-b608-352fad9c5b34",
"format": "uuid",
"type": "string"
},
"type": {
"$ref": "#/components/schemas/Types"
}
},
"required": [
"type",
"id",
"attributes"
],
"type": "object"
},
"OrgAttributes": {
"additionalProperties": false,
"properties": {
"access_requests_enabled": {
"description": "Whether the organization permits access requests from users who are not members of the organization.",
"example": false,
"type": "boolean"
},
"created_at": {
"description": "The time the organization was created.",
"example": "2022-03-16T00:00:00Z",
"format": "date-time",
"type": "string"
},
"group_id": {
"description": "The Snyk ID of the group to which the organization belongs.",
"example": "59d6d97e-3106-4ebb-b608-352fad9c5b34",
"format": "uuid",
"type": "string"
},
"is_personal": {
"description": "Whether the organization is independent (that is, not part of a group).",
"example": true,
"type": "boolean"
},
"name": {
"description": "The display name of the organization.",
"example": "My Org",
"type": "string"
},
"slug": {
"description": "The canonical (unique and URL-friendly) name of the organization.",
"example": "my-org",
"type": "string"
},
"updated_at": {
"description": "The time the organization was last modified.",
"example": "2022-03-16T00:00:00Z",
"format": "date-time",
"type": "string"
}
},
"required": [
"name",
"slug",
"is_personal"
],
"type": "object"
},
"OrgAttributes20230529": {
"additionalProperties": false,
"properties": {
"created_at": {
"description": "The time the organization was created.",
"example": "2022-03-16T00:00:00Z",
"format": "date-time",
"type": "string"
},
"group_id": {
"description": "The Snyk ID of the group to which the organization belongs.",
"example": "59d6d97e-3106-4ebb-b608-352fad9c5b34",
"format": "uuid",
"type": "string"
},
"is_personal": {
"description": "Whether the organization is independent (that is, not part of a group).",
"example": true,
"type": "boolean"
},
"name": {
"description": "The display name of the organization.",
"example": "My Org",
"type": "string"
},
"slug": {
"description": "The canonical (unique and URL-friendly) name of the organization.",
"example": "my-org",
"type": "string"
},
"updated_at": {
"description": "The time the organization was last modified.",
"example": "2022-03-16T00:00:00Z",
"format": "date-time",
"type": "string"
}
},
"required": [
"name",
"slug",
"is_personal"
],
"type": "object"
},
"OrgBranch": {
"additionalProperties": false,
"type": "object",
"properties": {
"attributes": {
"additionalProperties": false,
"type": "object",
"properties": {
"uuid": {
"type": "string",
"format": "uuid"
}
}
}
}
},
"OrgBranchAttributes": {
"additionalProperties": false,
"type": "object",
"properties": {
"detailedDescription": {
"type": "string"
}
}
}
}
},
"info": {
"title": "Snyk API",
"version": "REST"
},
"openapi": "3.0.3"

}
Loading