diff --git a/.editorconfig b/.editorconfig
index fa9a24871d..fba6473b28 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,6 +15,7 @@ charset = utf-8
[modules/swagger-parser-v3/src/test/resources/**/*.json]
trim_trailing_whitespace = false
-
+insert_final_newline = false
[modules/swagger-parser-v3/src/test/resources/**/*.yaml]
trim_trailing_whitespace = false
+insert_final_newline = false
diff --git a/modules/swagger-parser-core/pom.xml b/modules/swagger-parser-core/pom.xml
index 9e2242ee11..e544649f2b 100644
--- a/modules/swagger-parser-core/pom.xml
+++ b/modules/swagger-parser-core/pom.xml
@@ -3,7 +3,7 @@
io.swagger.parser.v3
swagger-parser-project
- 2.0.34-SNAPSHOT
+ 2.1.0-SNAPSHOT
../..
4.0.0
diff --git a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java
index 7b478ef9b9..2ed2dd6f80 100644
--- a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java
+++ b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java
@@ -13,7 +13,10 @@ public class ParseOptions {
private boolean validateInternalRefs = true;
private boolean legacyYamlDeserialization = false;
private boolean resolveRequestBody = false;
-
+
+ private boolean oaiAuthor;
+ private boolean defaultSchemaTypeObject = true;
+
public boolean isResolve() {
return resolve;
}
@@ -37,7 +40,7 @@ public boolean isResolveFully() {
public void setResolveFully(boolean resolveFully) {
this.resolveFully = resolveFully;
}
-
+
public boolean isResolveRequestBody() {
return resolveRequestBody;
}
@@ -105,6 +108,14 @@ public void setLegacyYamlDeserialization(boolean legacyYamlDeserialization) {
this.legacyYamlDeserialization = legacyYamlDeserialization;
}
+ public void setOaiAuthor(boolean oaiAuthor) {
+ this.oaiAuthor = oaiAuthor;
+ }
+
+ public boolean isOaiAuthor() {
+ return oaiAuthor;
+ }
+
public void setValidateInternalRefs(boolean validateInternalRefs) {
this.validateInternalRefs = validateInternalRefs;
}
@@ -112,4 +123,12 @@ public void setValidateInternalRefs(boolean validateInternalRefs) {
public boolean isValidateInternalRefs() {
return validateInternalRefs;
}
+
+ public boolean isDefaultSchemaTypeObject() {
+ return defaultSchemaTypeObject;
+ }
+
+ public void setDefaultSchemaTypeObject(boolean defaultSchemaTypeObject) {
+ this.defaultSchemaTypeObject = defaultSchemaTypeObject;
+ }
}
diff --git a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/SwaggerParseResult.java b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/SwaggerParseResult.java
index eddcce9323..badc207d8a 100644
--- a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/SwaggerParseResult.java
+++ b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/SwaggerParseResult.java
@@ -9,6 +9,7 @@
public class SwaggerParseResult {
private List messages = null;
private OpenAPI openAPI;
+ private boolean openapi31;
public SwaggerParseResult messages(List messages) {
this.messages = messages;
@@ -52,4 +53,17 @@ public static SwaggerParseResult ofError(String message){
result.setMessages(Collections.singletonList(message));
return result;
}
+
+ public void setOpenapi31(boolean openapi31) {
+ this.openapi31 = openapi31;
+ }
+
+ public SwaggerParseResult openapi31(boolean openapi31) {
+ this.openapi31 = openapi31;
+ return this;
+ }
+
+ public boolean isOpenapi31() {
+ return this.openapi31;
+ }
}
diff --git a/modules/swagger-parser-v2-converter/pom.xml b/modules/swagger-parser-v2-converter/pom.xml
index 84dc2a940e..2a0f981a9b 100644
--- a/modules/swagger-parser-v2-converter/pom.xml
+++ b/modules/swagger-parser-v2-converter/pom.xml
@@ -3,7 +3,7 @@
io.swagger.parser.v3
swagger-parser-project
- 2.0.34-SNAPSHOT
+ 2.1.0-SNAPSHOT
../..
4.0.0
diff --git a/modules/swagger-parser-v3/pom.xml b/modules/swagger-parser-v3/pom.xml
index 5f31632697..805c8987af 100644
--- a/modules/swagger-parser-v3/pom.xml
+++ b/modules/swagger-parser-v3/pom.xml
@@ -3,7 +3,7 @@
io.swagger.parser.v3
swagger-parser-project
- 2.0.34-SNAPSHOT
+ 2.1.0-SNAPSHOT
../..
4.0.0
@@ -64,7 +64,6 @@
org.slf4j
slf4j-simple
${slf4j-version}
- test
com.github.tomakehurst
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java
index 8de614c4b7..c377e9bd2a 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java
@@ -10,6 +10,9 @@
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import io.swagger.v3.parser.exception.EncodingNotSupportedException;
import io.swagger.v3.parser.exception.ReadContentException;
+import io.swagger.v3.parser.reference.DereferencerContext;
+import io.swagger.v3.parser.reference.DereferencersFactory;
+import io.swagger.v3.parser.reference.OpenAPIDereferencer;
import io.swagger.v3.parser.util.ClasspathHelper;
import io.swagger.v3.parser.util.DeserializationUtils;
import io.swagger.v3.parser.util.InlineModelResolver;
@@ -136,7 +139,7 @@ public SwaggerParseResult parseJsonNode(String path, JsonNode node) {
return new OpenAPIDeserializer().deserialize(node, path,new ParseOptions());
}
public SwaggerParseResult parseJsonNode(String path, JsonNode node, ParseOptions options) {
- return new OpenAPIDeserializer().deserialize(node, path, options);
+ return new OpenAPIDeserializer().deserialize(node, path, options, options.isOaiAuthor());
}
public SwaggerParseResult readContents(String yaml) {
@@ -145,7 +148,7 @@ public SwaggerParseResult readContents(String yaml) {
return readContents(yaml, null, options);
}
- private SwaggerParseResult readContents(String swaggerAsString, List auth, ParseOptions options,
+ public SwaggerParseResult readContents(String swaggerAsString, List auth, ParseOptions options,
String location) {
if (swaggerAsString == null || swaggerAsString.trim().isEmpty()) {
return SwaggerParseResult.ofError("Null or empty definition");
@@ -180,6 +183,7 @@ private SwaggerParseResult readContents(String swaggerAsString, List dereferencers = DereferencersFactory.getInstance().getDereferencers();
+ if (dereferencers.iterator().hasNext()) {
+ OpenAPIDereferencer dereferencer = dereferencers.iterator().next();
+ dereferencer.dereference(dereferencerContext, dereferencers.iterator());
+ }
+ } else {
+ OpenAPIResolver resolver = new OpenAPIResolver(result.getOpenAPI(), emptyListIfNull(auth),
+ location, null, options);
+ resolver.resolve(result);
+ }
if (options.isResolveFully()) {
new ResolverFully(options.isResolveCombinators()).resolveFully(result.getOpenAPI());
}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java
index f143ae85cc..c5e08fe0ab 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java
@@ -69,7 +69,7 @@ public class ResolverCache {
private List referencedModelKeys = new ArrayList<>();
private Set resolveValidationMessages;
private final ParseOptions parseOptions;
-
+ protected boolean openapi31;
/*
* a map that stores original external references, and their associated renamed
@@ -86,6 +86,7 @@ public ResolverCache(OpenAPI openApi, List auths, String par
}
public ResolverCache(OpenAPI openApi, List auths, String parentFileLocation, Set resolveValidationMessages, ParseOptions parseOptions) {
+ this.openapi31 = openApi != null && openApi.getOpenapi() != null && openApi.getOpenapi().startsWith("3.1");
this.openApi = openApi;
this.auths = auths;
this.rootPath = parentFileLocation;
@@ -165,7 +166,7 @@ else if (rootPath != null) {
if (parseOptions.isValidateExternalRefs()) {
result = deserializeFragment(tree, expectedType, file, "/");
} else {
- result = DeserializationUtils.deserialize(contents, file, expectedType);
+ result = DeserializationUtils.deserialize(contents, file, expectedType, openapi31);
}
resolutionCache.put(ref, result);
if (deserializationUtilResult.getMessages() != null) {
@@ -191,9 +192,9 @@ else if (rootPath != null) {
} else {
if (expectedType.equals(Schema.class)) {
OpenAPIDeserializer deserializer = new OpenAPIDeserializer();
- result = (T) deserializer.getSchema((ObjectNode) tree, definitionPath.replace("/", "."), null);
+ result = (T) deserializer.getSchema((ObjectNode) tree, definitionPath.replace("/", "."), new OpenAPIDeserializer.ParseResult().openapi31(openapi31));
} else {
- result = DeserializationUtils.deserialize(tree, file, expectedType);
+ result = DeserializationUtils.deserialize(tree, file, expectedType, openapi31);
}
}
updateLocalRefs(file, result);
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/extensions/JsonSchemaParserExtension.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/extensions/JsonSchemaParserExtension.java
new file mode 100644
index 0000000000..eeab9768ea
--- /dev/null
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/extensions/JsonSchemaParserExtension.java
@@ -0,0 +1,18 @@
+package io.swagger.v3.parser.extensions;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.parser.ResolverCache;
+import io.swagger.v3.parser.util.OpenAPIDeserializer;
+
+import java.util.Map;
+
+public interface JsonSchemaParserExtension {
+
+ Schema getSchema(ObjectNode node, String location, OpenAPIDeserializer.ParseResult result, Map rootMap, String basePath);
+
+
+ boolean resolveSchema(Schema schema, ResolverCache cache, OpenAPI openAPI, boolean openapi31);
+
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/CallbackProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/CallbackProcessor.java
index 9719eca176..0c412ca2e9 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/CallbackProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/CallbackProcessor.java
@@ -26,9 +26,12 @@ public class CallbackProcessor {
private final ExternalRefProcessor externalRefProcessor;
public CallbackProcessor(ResolverCache cache, OpenAPI openAPI) {
+ this(cache, openAPI, false);
+ }
+ public CallbackProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
this.cache = cache;
- this.operationProcessor = new OperationProcessor(cache, openAPI);
- this.parameterProcessor = new ParameterProcessor(cache,openAPI);
+ this.operationProcessor = new OperationProcessor(cache, openAPI, openapi31);
+ this.parameterProcessor = new ParameterProcessor(cache,openAPI, openapi31);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
this.openAPI = openAPI;
}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java
index 6e7ba3c0a4..392dafaa68 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java
@@ -35,21 +35,26 @@ public class ComponentsProcessor {
private final SecuritySchemeProcessor securitySchemeProcessor;
public ComponentsProcessor(OpenAPI openApi,ResolverCache cache){
+ this(openApi, cache, false);
+
+ }
+ public ComponentsProcessor(OpenAPI openApi,ResolverCache cache, boolean openapi31){
this.cache = cache;
this.openApi = openApi;
- this.schemaProcessor = new SchemaProcessor(cache,openApi);
- this.responseProcessor = new ResponseProcessor(cache, openApi);
- this.requestBodyProcessor = new RequestBodyProcessor(cache, openApi);
- this.parameterProcessor = new ParameterProcessor(cache, openApi);
- this.headerProcessor = new HeaderProcessor(cache, openApi);
+ this.schemaProcessor = new SchemaProcessor(cache,openApi, openapi31);
+ this.responseProcessor = new ResponseProcessor(cache, openApi, openapi31);
+ this.requestBodyProcessor = new RequestBodyProcessor(cache, openApi, openapi31);
+ this.parameterProcessor = new ParameterProcessor(cache, openApi, openapi31);
+ this.headerProcessor = new HeaderProcessor(cache, openApi, openapi31);
this.exampleProcessor = new ExampleProcessor(cache,openApi);
- this.linkProcessor = new LinkProcessor(cache,openApi);
- this.callbackProcessor = new CallbackProcessor(cache,openApi);
+ this.linkProcessor = new LinkProcessor(cache,openApi, openapi31);
+ this.callbackProcessor = new CallbackProcessor(cache,openApi, openapi31);
this.securitySchemeProcessor = new SecuritySchemeProcessor(cache,openApi);
}
+
public void processComponents() {
if (openApi.getComponents() == null){
return;
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java
index 466b09cfe0..6388d95b42 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java
@@ -1,7 +1,6 @@
package io.swagger.v3.parser.processors;
-import java.io.File;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Collection;
@@ -391,9 +390,39 @@ public String processRefToExternalResponse(String $ref, RefFormat refFormat) {
}
}
newRef = possiblyConflictingDefinitionName;
- openAPI.getComponents().addResponses(newRef, response);
cache.putRenamedRef($ref, newRef);
+ if(existingResponse == null) {
+ // don't overwrite existing model reference
+ openAPI.getComponents().addResponses(newRef, response);
+ cache.addReferencedKey(newRef);
+
+ String file = $ref.split("#/")[0];
+ if (response.get$ref() != null) {
+ RefFormat format = computeRefFormat(response.get$ref());
+ if (isAnExternalRefFormat(format)) {
+ String fullRef = response.get$ref();
+ if (!format.equals(RefFormat.URL)) {
+ String parent = file.substring(0, file.lastIndexOf('/'));
+ if (!parent.isEmpty()) {
+ if (fullRef.contains("#/")) {
+ String[] parts = fullRef.split("#/");
+ String fullRefFilePart = parts[0];
+ String fullRefInternalRefPart = parts[1];
+ fullRef = Paths.get(parent, fullRefFilePart).normalize().toString() + "#/" + fullRefInternalRefPart;
+ } else {
+ fullRef = Paths.get(parent, fullRef).normalize().toString();
+ }
+ }
+
+ }
+ response.set$ref(processRefToExternalResponse(fullRef, format));
+ } else {
+ processRefToExternalResponse(file + response.get$ref(), RefFormat.RELATIVE);
+ }
+ }
+ }
+
if(response != null) {
if(response.getContent() != null){
processRefContent(response.getContent(), $ref);
@@ -759,7 +788,22 @@ public String processRefToExternalParameter(String $ref, RefFormat refFormat) {
if (parameter.get$ref() != null) {
RefFormat format = computeRefFormat(parameter.get$ref());
if (isAnExternalRefFormat(format)) {
- parameter.set$ref(processRefToExternalParameter(parameter.get$ref(), format));
+ String fullRef = parameter.get$ref();
+ if (!format.equals(RefFormat.URL)) {
+ String parent = file.substring(0, file.lastIndexOf('/'));
+ if (!parent.isEmpty()) {
+ if (fullRef.contains("#/")) {
+ String[] parts = fullRef.split("#/");
+ String fullRefFilePart = parts[0];
+ String fullRefInternalRefPart = parts[1];
+ fullRef = Paths.get(parent, fullRefFilePart).normalize().toString() + "#/" + fullRefInternalRefPart;
+ } else {
+ fullRef = Paths.get(parent, fullRef).normalize().toString();
+ }
+ }
+
+ }
+ parameter.set$ref(processRefToExternalParameter(fullRef, format));
} else {
processRefToExternalParameter(file + parameter.get$ref(), RefFormat.RELATIVE);
}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/HeaderProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/HeaderProcessor.java
index f9cfafac26..33dda6cff4 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/HeaderProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/HeaderProcessor.java
@@ -26,13 +26,17 @@ public class HeaderProcessor {
public HeaderProcessor(ResolverCache cache, OpenAPI openAPI) {
+ this(cache, openAPI, false);
+ }
+ public HeaderProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
this.cache = cache;
this.openAPI = openAPI;
- this.schemaProcessor = new SchemaProcessor(cache,openAPI);
+ this.schemaProcessor = new SchemaProcessor(cache,openAPI, openapi31);
this.exampleProcessor = new ExampleProcessor(cache,openAPI);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
}
+
public void processHeader(Header header) {
if(header.get$ref() != null){
@@ -72,4 +76,4 @@ public void processHeader(Header header) {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/LinkProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/LinkProcessor.java
index 59b29049e6..d96e79b9d9 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/LinkProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/LinkProcessor.java
@@ -22,11 +22,13 @@ public class LinkProcessor {
private final HeaderProcessor headerProcessor;
private final ExternalRefProcessor externalRefProcessor;
-
public LinkProcessor(ResolverCache cache, OpenAPI openAPI){
+ this (cache, openAPI, false);
+ }
+ public LinkProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31){
this.cache = cache;
this.openAPI = openAPI;
- this.headerProcessor = new HeaderProcessor(cache,openAPI);
+ this.headerProcessor = new HeaderProcessor(cache,openAPI, openapi31);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java
index d24a3b1b81..e07c2dfe50 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java
@@ -25,16 +25,24 @@ public class OperationProcessor {
private final ExternalRefProcessor externalRefProcessor;
private final ResolverCache cache;
-
public OperationProcessor(ResolverCache cache, OpenAPI openAPI) {
- this.parameterProcessor = new ParameterProcessor(cache, openAPI);
- this.responseProcessor = new ResponseProcessor(cache,openAPI);
- this.requestBodyProcessor = new RequestBodyProcessor(cache,openAPI);
+ this(cache, openAPI, false);
+ }
+
+ public OperationProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
+ this.parameterProcessor = new ParameterProcessor(cache, openAPI, openapi31);
+ this.responseProcessor = new ResponseProcessor(cache,openAPI, openapi31);
+ this.requestBodyProcessor = new RequestBodyProcessor(cache,openAPI, openapi31);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
this.cache = cache;
}
public void processOperation(Operation operation) {
+ if (operation.getParameters() != null) {
+ for (Parameter parameter : operation.getParameters()) {
+ parameterProcessor.processParameter(parameter);
+ }
+ }
final List processedOperationParameters = parameterProcessor.processParameters(operation.getParameters());
if(processedOperationParameters != null) {
operation.setParameters(processedOperationParameters);
@@ -115,4 +123,4 @@ public void processOperation(Operation operation) {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java
index b49b9ec0d4..100846e7c2 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java
@@ -26,11 +26,14 @@ public class ParameterProcessor {
private final OpenAPI openAPI;
private final ExternalRefProcessor externalRefProcessor;
-
public ParameterProcessor(ResolverCache cache, OpenAPI openAPI) {
+ this(cache, openAPI, false);
+ }
+
+ public ParameterProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
this.cache = cache;
this.openAPI = openAPI;
- this.schemaProcessor = new SchemaProcessor(cache,openAPI);
+ this.schemaProcessor = new SchemaProcessor(cache,openAPI, openapi31);
this.exampleProcessor = new ExampleProcessor(cache,openAPI);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java
index bac9fffdb7..370bc6a63e 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java
@@ -37,12 +37,16 @@ public class PathsProcessor {
public PathsProcessor(ResolverCache cache, OpenAPI openAPI) {
this(cache, openAPI, new OpenAPIResolver.Settings());
}
+
public PathsProcessor(ResolverCache cache, OpenAPI openAPI, OpenAPIResolver.Settings settings) {
+ this(cache, openAPI, settings, false);
+ }
+ public PathsProcessor(ResolverCache cache, OpenAPI openAPI, OpenAPIResolver.Settings settings, boolean openapi31) {
this.openAPI = openAPI;
this.cache = cache;
this.settings = settings;
- parameterProcessor = new ParameterProcessor(cache, openAPI);
- operationProcessor = new OperationProcessor(cache, openAPI);
+ parameterProcessor = new ParameterProcessor(cache, openAPI, openapi31);
+ operationProcessor = new OperationProcessor(cache, openAPI, openapi31);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
}
@@ -277,20 +281,20 @@ protected boolean isLocalRef(String ref) {
}
return false;
}
-
+
protected boolean isAbsoluteRef(String ref) {
if(!ref.startsWith(".")) {
return true;
}
return false;
}
-
+
protected String computeRef(String ref, String prefix) {
if(isLocalRef(ref)) return computeLocalRef(ref, prefix);
if(isAbsoluteRef(ref)) return ref;
return computeRelativeRef(ref, prefix);
}
-
+
protected String computeRelativeRef(String ref, String prefix) {
if(ref.startsWith("./")) {
return ref;
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/RequestBodyProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/RequestBodyProcessor.java
index ce1caa02ee..a8062eb155 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/RequestBodyProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/RequestBodyProcessor.java
@@ -24,7 +24,11 @@ public class RequestBodyProcessor {
private final OpenAPI openAPI;
public RequestBodyProcessor(ResolverCache cache, OpenAPI openAPI) {
- schemaProcessor = new SchemaProcessor(cache,openAPI);
+ this(cache, openAPI, false);
+ }
+
+ public RequestBodyProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
+ schemaProcessor = new SchemaProcessor(cache,openAPI, openapi31);
exampleProcessor = new ExampleProcessor(cache,openAPI);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
this.cache = cache;
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ResponseProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ResponseProcessor.java
index 959026de7f..d0538b24e6 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ResponseProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ResponseProcessor.java
@@ -26,9 +26,13 @@ public class ResponseProcessor {
private final OpenAPI openAPI;
public ResponseProcessor(ResolverCache cache, OpenAPI openAPI) {
- schemaProcessor = new SchemaProcessor(cache,openAPI);
- headerProcessor = new HeaderProcessor(cache,openAPI);
- linkProcessor = new LinkProcessor(cache,openAPI);
+ this(cache, openAPI, false);
+ }
+
+ public ResponseProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
+ schemaProcessor = new SchemaProcessor(cache,openAPI, openapi31);
+ headerProcessor = new HeaderProcessor(cache,openAPI, openapi31);
+ linkProcessor = new LinkProcessor(cache,openAPI, openapi31);
exampleProcessor = new ExampleProcessor(cache,openAPI);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
this.cache = cache;
@@ -88,4 +92,4 @@ public void processReferenceResponse(ApiResponse response){
}
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java
index 1ed583a2b8..3a9901b8f9 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java
@@ -8,8 +8,10 @@
import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.ResolverCache;
+import io.swagger.v3.parser.extensions.JsonSchemaParserExtension;
import io.swagger.v3.parser.models.RefFormat;
import io.swagger.v3.parser.models.RefType;
+import io.swagger.v3.parser.util.OpenAPIDeserializer;
import io.swagger.v3.parser.util.RefUtils;
import java.util.HashMap;
@@ -22,17 +24,38 @@
public class SchemaProcessor {
private final ExternalRefProcessor externalRefProcessor;
+ private boolean openapi31;
+ private final ResolverCache cache;
+ private OpenAPI openAPI;
public SchemaProcessor(ResolverCache cache, OpenAPI openAPI) {
+ this(cache,openAPI, false);
+ }
+
+ public SchemaProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
+ this.openapi31 = openapi31;
+ this.cache = cache;
+ this.openAPI = openAPI;
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
}
public void processSchema(Schema schema) {
+
if (schema == null) {
return;
}
+ if (openapi31) {
+ // TODO use as singleton somewhere loaded as static used by both here and deserializer
+ List jsonschemaExtensions = OpenAPIDeserializer.getJsonSchemaParserExtensions();
+ for (JsonSchemaParserExtension jsonschemaExtension: jsonschemaExtensions) {
+ if (jsonschemaExtension.resolveSchema(schema, cache, openAPI, openapi31)) {
+ return;
+ }
+ }
+ }
+
if (schema.get$ref() != null) {
processReferenceSchema(schema);
} else {
@@ -59,7 +82,7 @@ public void processSchemaType(Schema schema){
}
if(schema.getAdditionalProperties() != null){
processAdditionalProperties(schema);
-
+
}
if (schema.getDiscriminator() != null) {
processDiscriminatorSchema(schema);
@@ -218,4 +241,4 @@ private void processReferenceSchema(Schema schema) {
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/AbstractVisitor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/AbstractVisitor.java
new file mode 100644
index 0000000000..918141264c
--- /dev/null
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/AbstractVisitor.java
@@ -0,0 +1,102 @@
+package io.swagger.v3.parser.reference;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.examples.Example;
+import io.swagger.v3.oas.models.headers.Header;
+import io.swagger.v3.oas.models.links.Link;
+import io.swagger.v3.oas.models.media.Encoding;
+import io.swagger.v3.oas.models.media.MediaType;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.parameters.RequestBody;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+
+import java.util.List;
+
+public abstract class AbstractVisitor implements Visitor {
+
+ @Override
+ public OpenAPI visitOpenApi(OpenAPI openAPI){
+ return null;
+ }
+ @Override
+ public Paths visitPaths(Paths paths){
+ return null;
+ }
+
+ @Override
+ public Components visitComponents(Components components){
+ return null;
+ }
+
+ @Override
+ public PathItem visitPathItem(PathItem pathItem){
+ return null;
+ }
+
+ @Override
+ public Parameter visitParameter(Parameter parameter){
+ return null;
+ }
+
+ @Override
+ public Operation visitOperation(Operation operation){
+ return null;
+ }
+
+ @Override
+ public Schema visitSchema(Schema schema, List inheritedIds){
+ return null;
+ }
+
+ @Override
+ public ApiResponse visitResponse(ApiResponse response){
+ return null;
+ }
+
+ @Override
+ public RequestBody visitRequestBody(RequestBody requestBody){
+ return null;
+ }
+
+ @Override
+ public Link visitLink(Link link){
+ return null;
+ }
+
+ @Override
+ public SecurityScheme visitSecurityScheme(SecurityScheme securityScheme){
+ return null;
+ }
+
+ @Override
+ public ApiResponses visitResponses(ApiResponses responses){
+ return null;
+ }
+
+ @Override
+ public MediaType visitMediaType(MediaType mediaType){
+ return null;
+ }
+
+ @Override
+ public Encoding visitEncoding(Encoding encoding){
+ return null;
+ }
+
+ @Override
+ public Header visitHeader(Header header){
+ return null;
+ }
+
+ @Override
+ public Example visitExample(Example example){
+ return null;
+ }
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java
new file mode 100644
index 0000000000..1a4e23ef35
--- /dev/null
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java
@@ -0,0 +1,117 @@
+package io.swagger.v3.parser.reference;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.parser.core.models.AuthorizationValue;
+import io.swagger.v3.parser.core.models.ParseOptions;
+import io.swagger.v3.parser.core.models.SwaggerParseResult;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DereferencerContext {
+
+ protected final OpenAPI openApi;
+
+ protected final List auths;
+ protected final String rootUri;
+ protected final ParseOptions parseOptions;
+ protected String providedBaseUri;
+ protected SwaggerParseResult swaggerParseResult;
+ protected boolean addParametersToEachOperation = true;
+ protected String currentUri;
+
+ private Map referenceSet = new LinkedHashMap<>();
+
+ public DereferencerContext(
+ SwaggerParseResult swaggerParseResult,
+ List auths,
+ String rootUri,
+ ParseOptions parseOptions,
+ String providedBaseUri,
+ Map referenceSet,
+ Boolean addParametersToEachOperation) {
+ this.swaggerParseResult = swaggerParseResult;
+ this.openApi = swaggerParseResult.getOpenAPI();
+ this.auths = auths;
+ this.rootUri = rootUri;
+ this.currentUri = rootUri;
+ this.parseOptions = parseOptions;
+ this.providedBaseUri = providedBaseUri;
+ this.addParametersToEachOperation = addParametersToEachOperation != null ? addParametersToEachOperation : true;
+ this.referenceSet = referenceSet != null ? referenceSet : new LinkedHashMap<>();
+ }
+
+ public OpenAPI getOpenApi() {
+ return openApi;
+ }
+
+ public List getAuths() {
+ return auths;
+ }
+
+ public String getRootUri() {
+ return rootUri;
+ }
+
+ public ParseOptions getParseOptions() {
+ return parseOptions;
+ }
+
+ public String getProvidedBaseUri() {
+ return providedBaseUri;
+ }
+
+ public SwaggerParseResult getSwaggerParseResult() {
+ return swaggerParseResult;
+ }
+
+ public boolean isAddParametersToEachOperation() {
+ return addParametersToEachOperation;
+ }
+
+ public void setAddParametersToEachOperation(boolean addParametersToEachOperation) {
+ this.addParametersToEachOperation = addParametersToEachOperation;
+ }
+
+ public String getCurrentUri() {
+ return currentUri;
+ }
+
+ public void setCurrentUri(String currentUri) {
+ this.currentUri = currentUri;
+ }
+
+ public DereferencerContext providedBaseUri(String providedBaseUri) {
+ this.providedBaseUri = providedBaseUri;
+ return this;
+ }
+
+ public DereferencerContext swaggerParseResult(SwaggerParseResult swaggerParseResult) {
+ this.swaggerParseResult = swaggerParseResult;
+ return this;
+ }
+
+ public DereferencerContext addParametersToEachOperation(boolean addParametersToEachOperation) {
+ this.addParametersToEachOperation = addParametersToEachOperation;
+ return this;
+ }
+
+ public DereferencerContext currentUri(String currentUri) {
+ this.currentUri = currentUri;
+ return this;
+ }
+
+ public Map getReferenceSet() {
+ return referenceSet;
+ }
+
+ public void setReferenceSet(Map referenceSet) {
+ this.referenceSet = referenceSet;
+ }
+
+ public DereferencerContext referenceSet(Map referenceSet) {
+ this.referenceSet = referenceSet;
+ return this;
+ }
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencersFactory.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencersFactory.java
new file mode 100644
index 0000000000..17eb5ea689
--- /dev/null
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencersFactory.java
@@ -0,0 +1,55 @@
+package io.swagger.v3.parser.reference;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class DereferencersFactory {
+
+ private static DereferencersFactory instance;
+ static Logger LOGGER = LoggerFactory.getLogger(DereferencersFactory.class);
+ private final List dereferencers;
+
+ private DereferencersFactory() {
+ dereferencers = new CopyOnWriteArrayList<>();
+ dereferencers.add(new OpenAPIDereferencer31());
+ }
+
+ public static DereferencersFactory getInstance() {
+ if (instance == null) {
+ instance = new DereferencersFactory();
+ }
+ return instance;
+ }
+
+ public void addDereferencer(OpenAPIDereferencer dereferencer) {
+ dereferencers.add(0, dereferencer);
+ }
+
+ public void removeDereferencer(OpenAPIDereferencer dereferencer) {
+ dereferencers.remove(dereferencer);
+ }
+
+ public List getDereferencers() {
+ return Collections.unmodifiableList(dereferencers);
+ }
+
+ static {
+ ServiceLoader loader = ServiceLoader.load(OpenAPIDereferencer.class);
+ Iterator itr = loader.iterator();
+ while (itr.hasNext()) {
+ OpenAPIDereferencer ext = itr.next();
+ if (ext == null) {
+ LOGGER.error("failed to load extension {}", ext);
+ } else {
+ instance.addDereferencer(ext);
+ LOGGER.debug("adding OpenAPIDereferencer: {}", ext);
+ }
+ }
+ }
+}
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java
new file mode 100644
index 0000000000..67c3403344
--- /dev/null
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java
@@ -0,0 +1,1139 @@
+package io.swagger.v3.parser.reference;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json31;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.callbacks.Callback;
+import io.swagger.v3.oas.models.examples.Example;
+import io.swagger.v3.oas.models.headers.Header;
+import io.swagger.v3.oas.models.links.Link;
+import io.swagger.v3.oas.models.media.Encoding;
+import io.swagger.v3.oas.models.media.MediaType;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.parameters.RequestBody;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.parser.util.DeserializationUtils;
+import io.swagger.v3.parser.util.OpenAPIDeserializer;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+public class OpenAPI31Traverser implements Traverser {
+
+ private DereferencerContext context;
+
+ public OpenAPI31Traverser(DereferencerContext context) {
+ this.context = context;
+ }
+
+ public DereferencerContext getContext() {
+ return context;
+ }
+
+ public void setContext(DereferencerContext context) {
+ this.context = context;
+ }
+
+ public OpenAPI31Traverser context(DereferencerContext context) {
+ this.context = context;
+ return this;
+ }
+
+ public Set