Skip to content

Commit 471a6c9

Browse files
committed
Correctly resolve externalRefs that point to the root path
Previously, if OpenAPI v3 document A loads document B, and B refers to schemas in document A, swagger-parser would not resolve references to schemas in A as internal refs, even though they refer to the root OpenAPI v3 document (document A). This would result in the creation of duplicate schemas for those schemas in document A. Now, we resolve these "external" refs as internal refs, preventing the duplication of these schemas by the ExternalRefProcessor.
1 parent 258ed4b commit 471a6c9

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

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

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.io.UnsupportedEncodingException;
2929
import java.net.URLDecoder;
3030
import java.nio.file.Path;
31+
import java.nio.file.Paths;
3132
import java.util.ArrayList;
3233
import java.util.Collections;
3334
import java.util.HashMap;
@@ -106,17 +107,25 @@ public ResolverCache(OpenAPI openApi, List<AuthorizationValue> auths, String par
106107

107108
}
108109

110+
private <T> T loadSchemaForInternalRef(String ref, Class<T> expectedType) {
111+
Object loadedRef = loadInternalRef(ref);
112+
113+
try{
114+
return expectedType.cast(loadedRef);
115+
}
116+
catch (Exception e) {
117+
return null;
118+
}
119+
}
120+
121+
private boolean fileIsRootPath(Path file) {
122+
return this.rootPath != null && file.normalize().equals(Paths.get(this.rootPath).toAbsolutePath().normalize());
123+
}
124+
109125
public <T> T loadRef(String ref, RefFormat refFormat, Class<T> expectedType) {
110126
if (refFormat == RefFormat.INTERNAL) {
111127
//we don't need to go get anything for internal refs
112-
Object loadedRef = loadInternalRef(ref);
113-
114-
try{
115-
return expectedType.cast(loadedRef);
116-
}
117-
catch (Exception e) {
118-
return null;
119-
}
128+
return loadSchemaForInternalRef(ref, expectedType);
120129
}
121130

122131
final String[] refParts = ref.split("#/");
@@ -128,6 +137,12 @@ public <T> T loadRef(String ref, RefFormat refFormat, Class<T> expectedType) {
128137
final String file = refParts[0];
129138
final String definitionPath = refParts.length == 2 ? refParts[1] : null;
130139

140+
if (this.parentDirectory != null && fileIsRootPath(this.parentDirectory.resolve(file))) {
141+
// If the file part of this external ref refers to the same file as the root path, we can treat it like an
142+
// internal ref.
143+
return loadSchemaForInternalRef("#/" + definitionPath, expectedType);
144+
}
145+
131146
//we might have already resolved this ref, so check the resolutionCache
132147
Object previouslyResolvedEntity = resolutionCache.get(ref);
133148

0 commit comments

Comments
 (0)