Skip to content

Commit a741f4e

Browse files
authored
Merge pull request #725 from swagger-api/fix-relative-resolving
fixing relative refs resolving
2 parents 5ba0082 + 27995c7 commit a741f4e

File tree

27 files changed

+256
-71
lines changed

27 files changed

+256
-71
lines changed

modules/swagger-parser/src/main/java/io/swagger/parser/ResolverCache.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class ResolverCache {
4747
private final Swagger swagger;
4848
private final List<AuthorizationValue> auths;
4949
private final Path parentDirectory;
50+
private final String parentUrl;
5051
private final String rootPath;
5152
private Map<String, Object> resolutionCache = new HashMap<>();
5253
private Map<String, String> externalFileCache = new HashMap<>();
@@ -72,6 +73,7 @@ public ResolverCache(Swagger swagger, List<AuthorizationValue> auths, String par
7273
File file = new File(".");
7374
parentDirectory = file.toPath();
7475
}
76+
parentUrl = parentFileLocation;
7577

7678
}
7779

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ public String processRefToExternalDefinition(String $ref, RefFormat refFormat) {
107107
if (isAnExternalRefFormat(refModel.getRefFormat())) {
108108
String joinedRef = join(file, refModel.get$ref());
109109
refModel.set$ref(processRefToExternalDefinition(joinedRef, refModel.getRefFormat()));
110-
} else {
110+
}/*else if (isAnExternalRefFormat(refModel.getOriginalRefFormat())) {
111+
String joinedRef = join(file, refModel.getOriginalRef());
112+
refModel.set$ref(processRefToExternalDefinition(joinedRef, refModel.getOriginalRefFormat()));
113+
}*/else {
111114
processRefToExternalDefinition(file + refModel.get$ref(), RefFormat.RELATIVE);
112115
}
113116
} else if (allOfModel instanceof ModelImpl) {

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,21 @@ private void processRefModel(RefModel refModel) {
8787
2) shove it into the #/definitions
8888
3) update the RefModel to point to its location in #/definitions
8989
*/
90+
String newRef = null;
9091

9192
if (isAnExternalRefFormat(refModel.getRefFormat())) {
92-
final String newRef = externalRefProcessor.processRefToExternalDefinition(refModel.get$ref(), refModel.getRefFormat());
9393

94-
if (newRef != null) {
95-
refModel.set$ref(newRef);
96-
}
94+
newRef = externalRefProcessor.processRefToExternalDefinition(refModel.get$ref(), refModel.getRefFormat());
95+
96+
}
97+
98+
if (newRef != null) {
99+
refModel.set$ref(newRef);
97100
}
101+
98102
}
99103

100104

105+
106+
101107
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public List<Parameter> processParameters(List<Parameter> parameters) {
3434
for (Parameter parameter : parameters) {
3535
if (parameter instanceof RefParameter) {
3636
RefParameter refParameter = (RefParameter) parameter;
37-
final Parameter resolvedParameter = cache.loadRef(refParameter.get$ref(), refParameter.getRefFormat(), Parameter.class);
37+
Parameter resolvedParameter = cache.loadRef(refParameter.get$ref(), refParameter.getRefFormat(), Parameter.class);
3838

3939
if(resolvedParameter == null) {
4040
// can't resolve it!

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ public void processPaths() {
8181
// TODO: update references to the parent location
8282

8383
String pathRef = refPath.get$ref().split("#")[0];
84-
updateLocalRefs(resolvedPath, pathRef);
84+
8585

8686
if (resolvedPath != null) {
87+
updateLocalRefs(resolvedPath, pathRef);
8788
//we need to put the resolved path into swagger object
8889
swagger.path(pathStr, resolvedPath);
8990
path = resolvedPath;
@@ -145,7 +146,9 @@ protected void updateLocalRefs(Model model, String pathRef) {
145146
RefModel refModel = (RefModel) model;
146147
if(isLocalRef(refModel.get$ref())) {
147148
refModel.set$ref(computeLocalRef(refModel.get$ref(), pathRef));
148-
}
149+
}/*else if(isLocalRef(refModel.getOriginalRef())) {
150+
refModel.set$ref(computeLocalRef(refModel.getOriginalRef(), pathRef));
151+
}*/
149152
}
150153
else if(model instanceof ModelImpl) {
151154
// process properties
@@ -175,7 +178,9 @@ protected void updateLocalRefs(Property property, String pathRef) {
175178
RefProperty ref = (RefProperty) property;
176179
if(isLocalRef(ref.get$ref())) {
177180
ref.set$ref(computeLocalRef(ref.get$ref(), pathRef));
178-
}
181+
}/*else if(isLocalRef(ref.getOriginalRef())) {
182+
ref.set$ref(computeLocalRef(ref.getOriginalRef(), pathRef));
183+
}*/
179184
}
180185
}
181186

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package io.swagger.parser.util;
22

33
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import io.swagger.models.Swagger;
46
import io.swagger.util.Json;
57
import io.swagger.util.Yaml;
8+
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
9+
import org.apache.commons.lang3.builder.ToStringStyle;
610
import org.yaml.snakeyaml.constructor.SafeConstructor;
711

812
import java.io.IOException;
Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
package io.swagger.parser.util;
22

33
import java.net.URI;
4+
import java.net.URL;
5+
import java.nio.file.Files;
46
import java.nio.file.Path;
57
import java.nio.file.Paths;
68

79
public class PathUtils {
810

11+
public static Path getParentDirectoryOfFile(String location) {
12+
Path file = null;
13+
try {
14+
location = location.replaceAll("\\\\","/");
15+
final String fileScheme = "file:";
16+
if (location.toLowerCase().startsWith(fileScheme)) {
17+
file = Paths.get(URI.create(location)).toAbsolutePath();
18+
} else {
19+
file = Paths.get(location).toAbsolutePath();
20+
}
21+
if (!Files.exists(file)) {
22+
URL url = PathUtils.class.getClassLoader().getResource(location);
23+
file = Paths.get((URI.create(url.toExternalForm())));
24+
return file.getParent();
25+
}
926

10-
public static Path getParentDirectoryOfFile(String fileStr) {
11-
final String fileScheme = "file:";
12-
Path file;
13-
fileStr = fileStr.replaceAll("\\\\","/");
14-
if (fileStr.toLowerCase().startsWith(fileScheme)) {
15-
file = Paths.get(URI.create(fileStr)).toAbsolutePath();
16-
} else {
17-
file = Paths.get(fileStr).toAbsolutePath();
27+
28+
29+
} catch (Exception e) {
30+
e.getMessage();
1831
}
32+
1933
return file.toAbsolutePath().getParent();
2034
}
2135
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public static String readExternalRef(String file, RefFormat refFormat, List<Auth
121121
throw new RuntimeException("Ref is not external");
122122
}
123123

124-
String result;
124+
String result = null;
125125

126126
try {
127127
if (refFormat == RefFormat.URL) {
@@ -133,9 +133,23 @@ public static String readExternalRef(String file, RefFormat refFormat, List<Auth
133133
if(Files.exists(pathToUse)) {
134134
result = IOUtils.toString(new FileInputStream(pathToUse.toFile()), "UTF-8");
135135
} else {
136+
String url = file;
137+
if(url.contains("..")) {
138+
url = parentDirectory + url.substring(url.indexOf(".") + 2);
139+
}else{
140+
url = parentDirectory + url.substring(url.indexOf(".") + 1);
141+
}
142+
final Path pathToUse2 = parentDirectory.resolve(url).normalize();
143+
144+
if(Files.exists(pathToUse2)) {
145+
result = IOUtils.toString(new FileInputStream(pathToUse2.toFile()), "UTF-8");
146+
}
147+
}
148+
if (result == null){
136149
result = ClasspathHelper.loadFileFromClasspath(file);
137150
}
138151

152+
139153
}
140154
} catch (Exception e) {
141155
throw new RuntimeException("Unable to load " + refFormat + " ref: " + file + " path: "+parentDirectory, e);

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

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ public Path path(ObjectNode obj, String location, ParseResult result) {
199199
if(obj.get("$ref") != null) {
200200
JsonNode ref = obj.get("$ref");
201201
if(ref.getNodeType().equals(JsonNodeType.STRING)) {
202+
202203
return pathRef((TextNode)ref, location, result);
203204
}
204205

@@ -425,21 +426,6 @@ public List<Parameter> parameters(ArrayNode obj, String location, ParseResult re
425426
return output;
426427
}
427428

428-
// Refs may need to be massaged slightly to ensure that swagger-core (specifically GenericRef) recognizes
429-
// relative refs properly. This should be done anywhere refs could appear (properties, parameters, schema, etc),
430-
// so we have this function to ensure it is done consistently (and hopefully correctly) for all these occurrences.
431-
//
432-
// Returns a new ref string is change is needed, else returns null
433-
public String mungedRef(String refString) {
434-
// Ref: IETF RFC 3966, Section 5.2.2
435-
if (!refString.contains(":") && // No scheme
436-
!refString.startsWith("#") && // Path is not empty
437-
!refString.startsWith("/") && // Path is not absolute
438-
refString.indexOf(".") > 0) { // Path does not start with dot but contains "." (file extension)
439-
return "./" + refString;
440-
}
441-
return null;
442-
}
443429

444430
public Parameter parameter(ObjectNode obj, String location, ParseResult result) {
445431
if(obj == null) {
@@ -450,12 +436,6 @@ public Parameter parameter(ObjectNode obj, String location, ParseResult result)
450436
JsonNode ref = obj.get("$ref");
451437
if(ref != null) {
452438
if(ref.getNodeType().equals(JsonNodeType.STRING)) {
453-
// work-around for https://github.com/swagger-api/swagger-core/issues/2138
454-
String mungedRef = mungedRef(ref.textValue());
455-
if (mungedRef != null) {
456-
obj.put("$ref", mungedRef);
457-
ref = obj.get("$ref");
458-
}
459439
return refParameter((TextNode) ref, location, result);
460440
}
461441
else {
@@ -691,6 +671,7 @@ public RefResponse refResponse(TextNode obj, String location, ParseResult result
691671

692672
public Path pathRef(TextNode ref, String location, ParseResult result) {
693673
RefPath output = new RefPath();
674+
694675
output.set$ref(ref.textValue());
695676
return output;
696677
}
@@ -1023,14 +1004,6 @@ public Property property(ObjectNode node, String location, ParseResult result) {
10231004
}
10241005
}
10251006

1026-
// work-around for https://github.com/swagger-api/swagger-core/issues/1977
1027-
if(node.get("$ref") != null && node.get("$ref").isTextual()) {
1028-
// check if it's a relative ref
1029-
String mungedRef = mungedRef(node.get("$ref").textValue());
1030-
if(mungedRef != null) {
1031-
node.put("$ref", mungedRef);
1032-
}
1033-
}
10341007
return Json.mapper().convertValue(node, Property.class);
10351008
}
10361009

@@ -1118,6 +1091,7 @@ public Response response(ObjectNode node, String location, ParseResult result) {
11181091
JsonNode ref = node.get("$ref");
11191092
if(ref != null) {
11201093
if(ref.getNodeType().equals(JsonNodeType.STRING)) {
1094+
11211095
return refResponse((TextNode) ref, location, result);
11221096
}
11231097
else {
@@ -1134,14 +1108,6 @@ public Response response(ObjectNode node, String location, ParseResult result) {
11341108
JsonNode schemaRef = schema.get("$ref");
11351109
if (schemaRef != null) {
11361110
if (schemaRef.getNodeType().equals(JsonNodeType.STRING)) {
1137-
1138-
// work-around for https://github.com/swagger-api/swagger-core/issues/2138
1139-
String mungedRef = mungedRef(schemaRef.textValue());
1140-
if (mungedRef != null) {
1141-
schema.put("$ref", mungedRef);
1142-
schemaRef = schema.get("$ref");
1143-
}
1144-
11451111
Model schemaProp = new RefModel(schemaRef.textValue());
11461112
output.responseSchema(schemaProp);
11471113
} else {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void testIssue306() {
2828

2929
Swagger swagger = result.getSwagger();
3030

31-
assertTrue(swagger.getDefinitions().size() == 5);
31+
assertTrue(swagger.getDefinitions().size() == 6);
3232
// resolved from `$ref: './book.yaml'`
3333
assertNotNull(swagger.getDefinitions().get("Inventory"));
3434
// resolved from `$ref: 'book.yaml'`

0 commit comments

Comments
 (0)