Skip to content

Commit 6be4df3

Browse files
authored
Merge pull request #590 from joeljons/ref-name-conflicts
$ref name conflicts for Swagger 2
2 parents c419941 + d3df699 commit 6be4df3

File tree

9 files changed

+94
-8
lines changed

9 files changed

+94
-8
lines changed

modules/swagger-parser/src/main/java/io/swagger/parser/processors/ExternalRefProcessor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public ExternalRefProcessor(ResolverCache cache, Swagger swagger) {
2929
}
3030

3131
public String processRefToExternalDefinition(String $ref, RefFormat refFormat) {
32+
String renamedRef = cache.getRenamedRef($ref);
33+
if(renamedRef != null) {
34+
return renamedRef;
35+
}
36+
3237
final Model model = cache.loadRef($ref, refFormat, Model.class);
3338

3439
if(model == null) {
@@ -45,7 +50,7 @@ public String processRefToExternalDefinition(String $ref, RefFormat refFormat) {
4550
definitions = new LinkedHashMap<>();
4651
}
4752

48-
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
53+
final String possiblyConflictingDefinitionName = computeDefinitionName($ref, definitions.keySet());
4954

5055
Model existingModel = definitions.get(possiblyConflictingDefinitionName);
5156

modules/swagger-parser/src/main/java/io/swagger/parser/util/RefUtils.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
import java.nio.file.Files;
1010
import java.nio.file.Path;
1111
import java.util.List;
12+
import java.util.Set;
1213

1314
public class RefUtils {
1415

15-
public static String computeDefinitionName(String ref) {
16+
public static String computeDefinitionName(String ref, Set<String> reserved) {
1617

1718
final String[] refParts = ref.split("#/");
1819

@@ -36,8 +37,13 @@ public static String computeDefinitionName(String ref) {
3637
final String[] split = plausibleName.split("\\.");
3738
plausibleName = split[0];
3839
}
40+
String tryName = plausibleName;
3941

40-
return plausibleName;
42+
for (int i = 2; reserved.contains(tryName); i++) {
43+
tryName = plausibleName + "_" + i;
44+
}
45+
46+
return tryName;
4147
}
4248

4349
public static boolean isAnExternalRefFormat(RefFormat refFormat) {

modules/swagger-parser/src/test/java/io/swagger/parser/JsonToYamlFileDuplicator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ private static void processFile(File next, Path inputDirectory, Path outputDirec
4242

4343
final JsonNode jsonNode = DeserializationUtils.deserializeIntoTree(fileContents, next.toString());
4444

45-
final String yamlOutput = Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
46-
45+
final String yamlOutput = Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode)
46+
.replaceAll("\\n", System.getProperty("line.separator"));
4747

4848
final String relativePath = "./" + next.toString().replace(inputDirectory.toString(), "").replace(".json", ".yaml");
4949

modules/swagger-parser/src/test/java/io/swagger/parser/SwaggerParserTest.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,9 @@ public void testLoadExternalNestedDefinitions() throws Exception {
220220
assertTrue(definitions.containsKey("x"));
221221
assertTrue(definitions.containsKey("y"));
222222
assertTrue(definitions.containsKey("z"));
223-
assertEquals(((RefModel) definitions.get("i")).get$ref(), "#/definitions/k");
223+
assertEquals("#/definitions/k_2", ((RefModel) definitions.get("i")).get$ref());
224+
assertEquals("k-definition", definitions.get("k").getTitle());
225+
assertEquals("k-definition", definitions.get("k_2").getTitle());
224226
}
225227

226228
@Test
@@ -613,7 +615,7 @@ private Swagger doRelativeFileTest(String location) {
613615

614616
assertEquals(composedCat.getInterfaces().size(), 2);
615617
assertEquals(composedCat.getInterfaces().get(0).get$ref(), "#/definitions/pet");
616-
assertEquals(composedCat.getInterfaces().get(1).get$ref(), "#/definitions/foo");
618+
assertEquals(composedCat.getInterfaces().get(1).get$ref(), "#/definitions/foo_2");
617619

618620
return swagger;
619621
}
@@ -1013,4 +1015,15 @@ public void readingSpecNodeShouldNotOverQuotingStringExample() throws Exception
10131015
Map<String, Model> definitions = swagger.getDefinitions();
10141016
assertEquals("NoQuotePlease", definitions.get("CustomerType").getExample());
10151017
}
1018+
1019+
@Test
1020+
public void testRefNameConflicts() throws Exception {
1021+
Swagger swagger = new SwaggerParser().read("./refs-name-conflict/a.yaml");
1022+
1023+
assertEquals("#/definitions/PersonObj", ((RefProperty) swagger.getPath("/newPerson").getPost().getResponses().get("200").getSchema()).get$ref());
1024+
assertEquals("#/definitions/PersonObj_2", ((RefProperty) swagger.getPath("/oldPerson").getPost().getResponses().get("200").getSchema()).get$ref());
1025+
assertEquals("#/definitions/PersonObj_2", ((RefProperty) swagger.getPath("/yetAnotherPerson").getPost().getResponses().get("200").getSchema()).get$ref());
1026+
assertEquals("local", swagger.getDefinitions().get("PersonObj").getProperties().get("location").getExample());
1027+
assertEquals("referred", swagger.getDefinitions().get("PersonObj_2").getProperties().get("location").getExample());
1028+
}
10161029
}

modules/swagger-parser/src/test/java/io/swagger/parser/processors/ExternalRefProcessorTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public void testProcessRefToExternalDefinition_NoNameConflict(
3636
final RefFormat refFormat = RefFormat.URL;
3737

3838
new StrictExpectations() {{
39+
cache.getRenamedRef(ref);
40+
times = 1;
41+
result = null;
42+
3943
cache.loadRef(ref, refFormat, Model.class);
4044
times = 1;
4145
result = mockedModel;

modules/swagger-parser/src/test/java/io/swagger/parser/util/RefUtilsTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@
1616
import java.io.IOException;
1717
import java.nio.file.Files;
1818
import java.nio.file.Path;
19+
import java.util.Collections;
1920
import java.util.HashMap;
21+
import java.util.HashSet;
2022
import java.util.List;
2123
import java.util.Map;
2224

25+
import static java.util.Arrays.asList;
26+
import static java.util.Collections.singleton;
2327
import static org.testng.Assert.assertEquals;
2428
import static org.testng.Assert.assertFalse;
2529
import static org.testng.Assert.assertTrue;
@@ -61,10 +65,13 @@ public void testComputeDefinitionName() throws Exception {
6165
doComputeDefinitionNameTestCase("./path/to/file#/foo/bar", "bar");
6266
doComputeDefinitionNameTestCase("./path/to/file#/foo/bar/hello", "hello");
6367

68+
// Name conflicts resolved by adding _number
69+
assertEquals("file_2", RefUtils.computeDefinitionName("http://my.company.com/path/to/file.json", singleton("file")));
70+
assertEquals("file_3", RefUtils.computeDefinitionName("http://my.company.com/path/to/file.json", new HashSet<>(asList("file", "file_2"))));
6471
}
6572

6673
private void doComputeDefinitionNameTestCase(String ref, String expectedDefinitionName) {
67-
assertEquals(expectedDefinitionName, RefUtils.computeDefinitionName(ref));
74+
assertEquals(expectedDefinitionName, RefUtils.computeDefinitionName(ref, Collections.<String>emptySet()));
6875
}
6976

7077
private Map<String, Model> createMap(String... keys) {

modules/swagger-parser/src/test/resources/nested-references/b.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ definitions:
1111
$ref: "./a.yaml#/definitions/j"
1212
k:
1313
type: object
14+
title: k-definition
1415
properties:
1516
name:
1617
type: string
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
swagger: '2.0'
2+
info:
3+
version: 1.0.0
4+
title: Person
5+
description: Maintain Person data
6+
paths:
7+
/newPerson:
8+
post:
9+
summary: Create new person
10+
description: Create new person
11+
parameters: []
12+
responses:
13+
200:
14+
description: OK
15+
schema:
16+
$ref: '#/definitions/PersonObj'
17+
/oldPerson:
18+
post:
19+
summary: Create old person
20+
description: Create old person
21+
parameters: []
22+
responses:
23+
200:
24+
description: OK
25+
schema:
26+
$ref: "./refs-name-conflict/b.yaml#/definitions/PersonObj"
27+
/yetAnotherPerson:
28+
post:
29+
summary: Create yet another person
30+
description: Create yet another person
31+
parameters: []
32+
responses:
33+
200:
34+
description: OK
35+
schema:
36+
$ref: "./refs-name-conflict/b.yaml#/definitions/PersonObj"
37+
38+
definitions:
39+
PersonObj:
40+
properties:
41+
location:
42+
type: string
43+
example: local
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
definitions:
3+
PersonObj:
4+
properties:
5+
location:
6+
type: string
7+
example: referred

0 commit comments

Comments
 (0)