added handling for relative ref rooting
@@ -3,14 +3,20 @@ package io.swagger.parser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.RefModel;
+import io.swagger.models.Response;
import io.swagger.models.Swagger;
import io.swagger.models.auth.AuthorizationValue;
+import io.swagger.models.properties.Property;
+import io.swagger.models.properties.RefProperty;
import io.swagger.models.refs.RefFormat;
import io.swagger.models.refs.RefType;
import io.swagger.parser.util.DeserializationUtils;
import io.swagger.parser.util.PathUtils;
import io.swagger.parser.util.RefUtils;
import io.swagger.parser.util.SwaggerDeserializer;
+import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.nio.file.Path;
@@ -136,11 +142,70 @@ public class ResolverCache {
} else {
result = DeserializationUtils.deserialize(tree, file, expectedType);
}
+
+ updateLocalRefs(file, result);
+
resolutionCache.put(ref, result);
return result;
}
+ protected <T> void updateLocalRefs(String file, T result) {
+ if(result instanceof Response) {
+ Response response = (Response) result;
+ updateLocalRefs(file, response.getSchema());
+ }
+ else if(result instanceof RefProperty) {
+ RefProperty prop = (RefProperty) result;
+ updateLocalRefs(file, prop);
+ }
+ }
+
+ protected <T> void updateLocalRefs(String file, Model schema) {
+ if(schema instanceof RefModel) {
+ RefModel ref = (RefModel) schema;
+ String updatedLocation = merge(file, ref.get$ref());
+ ref.set$ref(updatedLocation);
+ }
+ else if(schema instanceof ModelImpl) {
+ ModelImpl impl = (ModelImpl) schema;
+ if(impl.getProperties() != null) {
+ for(Property property : schema.getProperties().values()) {
+ updateLocalRefs(file, property);
+ }
+ }
+ }
+ }
+
+ protected <T> void updateLocalRefs(String file, Property schema) {
+ if(schema instanceof RefProperty) {
+ RefProperty ref = (RefProperty) schema;
+ String updatedLocation = merge(file, ref.get$ref());
+ ref.set$ref(updatedLocation);
+ }
+ }
+
+ protected String merge(String host, String ref) {
+ if(StringUtils.isBlank(host)) {
+ return ref;
+ }
+ if(ref.startsWith("http:") || ref.startsWith("https:")) {
+ // already an absolute ref
+ return ref;
+ }
+ if(!host.startsWith("http:") || !host.startsWith("https:")) {
+ return ref;
+ }
+ if(ref.startsWith(".")) {
+ // relative ref, leave alone
+ return ref;
+ }
+ if(host.endsWith("/") && ref.startsWith("/")) {
+ return host + ref.substring(1);
+ }
+ return host + ref;
+ }
+
private String unescapePointer(String jsonPathElement) {
// Unescape the JSON Pointer segment using the algorithm described in RFC 6901, section 4:
// https://tools.ietf.org/html/rfc6901#section-4
