Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.swagger.parser.v3.processors.ExternalRefProcessor Maven / Gradle / Ivy
package io.swagger.parser.v3.processors;
import io.swagger.oas.models.OpenAPI;
import io.swagger.oas.models.callbacks.Callback;
import io.swagger.oas.models.examples.Example;
import io.swagger.oas.models.headers.Header;
import io.swagger.oas.models.links.Link;
import io.swagger.oas.models.media.ArraySchema;
import io.swagger.oas.models.media.Schema;
import io.swagger.oas.models.parameters.Parameter;
import io.swagger.oas.models.parameters.RequestBody;
import io.swagger.oas.models.responses.ApiResponse;
import io.swagger.oas.models.security.SecurityScheme;
import io.swagger.parser.v3.ResolverCache;
import io.swagger.parser.v3.models.RefFormat;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import static io.swagger.parser.v3.util.RefUtils.computeDefinitionName;
import static io.swagger.parser.v3.util.RefUtils.computeRefFormat;
import static io.swagger.parser.v3.util.RefUtils.isAnExternalRefFormat;
public final class ExternalRefProcessor {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ExternalRefProcessor.class);
private final ResolverCache cache;
private final OpenAPI openAPI;
public ExternalRefProcessor(ResolverCache cache, OpenAPI openAPI) {
this.cache = cache;
this.openAPI = openAPI;
}
public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
final Schema schema = cache.loadRef($ref, refFormat, Schema.class);
if(schema == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map schemas = openAPI.getComponents().getSchemas();
if (schemas == null) {
schemas = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
Schema existingModel = schemas.get(possiblyConflictingDefinitionName);
if (existingModel != null) {
LOGGER.debug("A model for " + existingModel + " already exists");
if(existingModel.get$ref() != null) {
// use the new model
existingModel = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingModel == null) {
// don't overwrite existing model reference
openAPI.getComponents().addSchemas(newRef, schema);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (schema.get$ref() != null) {
RefFormat format = computeRefFormat(schema.get$ref());
if (isAnExternalRefFormat(format)) {
schema.set$ref(processRefToExternalSchema(schema.get$ref(), format));
} else {
processRefToExternalSchema(file + schema.get$ref(), RefFormat.RELATIVE);
}
}
//Loop the properties and recursively call this method;
Map subProps = schema.getProperties();
if (subProps != null) {
for (Map.Entry prop : subProps.entrySet()) {
if (prop.getValue().get$ref() != null) {
processRefProperty(prop.getValue(), file);
} else if (prop.getValue() instanceof ArraySchema) {
ArraySchema arrayProp = (ArraySchema) prop.getValue();
if (arrayProp.getItems().get$ref() != null) {
processRefProperty(arrayProp.getItems(), file);
}
} else if (prop.getValue().getAdditionalProperties() != null) {
Schema mapProp = prop.getValue();
if (mapProp.getAdditionalProperties().get$ref() != null) {
processRefProperty(mapProp.getAdditionalProperties(), file);
} else if (mapProp.getAdditionalProperties() instanceof ArraySchema &&
((ArraySchema) mapProp.getAdditionalProperties()).getItems().get$ref() != null) {
processRefProperty(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file);
}
}
}
}
if (schema instanceof ArraySchema && ((ArraySchema) schema).getItems().get$ref() != null) {
processRefProperty(((ArraySchema) schema).getItems(), file);
}
}
return newRef;
}
public String processRefToExternalResponse(String $ref, RefFormat refFormat) {
final ApiResponse response = cache.loadRef($ref, refFormat, ApiResponse.class);
if(response == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map responses = openAPI.getComponents().getResponses();
if (responses == null) {
responses = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
ApiResponse existingResponse = responses.get(possiblyConflictingDefinitionName);
if (existingResponse != null) {
LOGGER.debug("A model for " + existingResponse + " already exists");
if(existingResponse.get$ref() != null) {
// use the new model
existingResponse = null;
}
}
newRef = possiblyConflictingDefinitionName;
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)) {
response.set$ref(processRefToExternalResponse(response.get$ref(), format));
} else {
processRefToExternalResponse(file + response.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalRequestBody(String $ref, RefFormat refFormat) {
final RequestBody body = cache.loadRef($ref, refFormat, RequestBody.class);
if(body == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map bodies = openAPI.getComponents().getRequestBodies();
if (bodies == null) {
bodies = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
RequestBody existingBody= bodies.get(possiblyConflictingDefinitionName);
if (existingBody != null) {
LOGGER.debug("A model for " + existingBody + " already exists");
if(existingBody.get$ref() != null) {
// use the new model
existingBody = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingBody == null) {
// don't overwrite existing model reference
openAPI.getComponents().addRequestBodies(newRef, body);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (body.get$ref() != null) {
RefFormat format = computeRefFormat(body.get$ref());
if (isAnExternalRefFormat(format)) {
body.set$ref(processRefToExternalRequestBody(body.get$ref(), format));
} else {
processRefToExternalRequestBody(file + body.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalHeader(String $ref, RefFormat refFormat) {
final Header header = cache.loadRef($ref, refFormat, Header.class);
if(header == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map headers = openAPI.getComponents().getHeaders();
if (headers == null) {
headers = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
Header existingHeader = headers.get(possiblyConflictingDefinitionName);
if (existingHeader != null) {
LOGGER.debug("A model for " + existingHeader + " already exists");
if(existingHeader.get$ref() != null) {
// use the new model
existingHeader = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingHeader == null) {
// don't overwrite existing model reference
openAPI.getComponents().addHeaders(newRef, header);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (header.get$ref() != null) {
RefFormat format = computeRefFormat(header.get$ref());
if (isAnExternalRefFormat(format)) {
header.set$ref(processRefToExternalHeader(header.get$ref(), format));
} else {
processRefToExternalHeader(file + header.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalSecurityScheme(String $ref, RefFormat refFormat) {
final SecurityScheme securityScheme = cache.loadRef($ref, refFormat, SecurityScheme.class);
if(securityScheme == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map securitySchemeMap = openAPI.getComponents().getSecuritySchemes();
if (securitySchemeMap == null) {
securitySchemeMap = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
SecurityScheme existingSecurityScheme = securitySchemeMap.get(possiblyConflictingDefinitionName);
if (existingSecurityScheme != null) {
LOGGER.debug("A model for " + existingSecurityScheme + " already exists");
if(existingSecurityScheme.get$ref() != null) {
// use the new model
existingSecurityScheme = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingSecurityScheme == null) {
// don't overwrite existing model reference
openAPI.getComponents().addSecuritySchemes(newRef, securityScheme);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (securityScheme.get$ref() != null) {
RefFormat format = computeRefFormat(securityScheme.get$ref());
if (isAnExternalRefFormat(format)) {
securityScheme.set$ref(processRefToExternalSecurityScheme(securityScheme.get$ref(), format));
} else {
processRefToExternalSecurityScheme(file + securityScheme.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalLink(String $ref, RefFormat refFormat) {
final Link link = cache.loadRef($ref, refFormat, Link.class);
if(link == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map links = openAPI.getComponents().getLinks();
if (links == null) {
links = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
Link existingLink = links.get(possiblyConflictingDefinitionName);
if (existingLink != null) {
LOGGER.debug("A model for " + existingLink + " already exists");
if(existingLink.get$ref() != null) {
// use the new model
existingLink = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingLink == null) {
// don't overwrite existing model reference
openAPI.getComponents().addLinks(newRef, link);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (link.get$ref() != null) {
RefFormat format = computeRefFormat(link.get$ref());
if (isAnExternalRefFormat(format)) {
link.set$ref(processRefToExternalLink(link.get$ref(), format));
} else {
processRefToExternalLink(file + link.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalExample(String $ref, RefFormat refFormat) {
final Example example = cache.loadRef($ref, refFormat, Example.class);
if(example == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map examples = openAPI.getComponents().getExamples();
if (examples == null) {
examples = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
Example existingExample = examples.get(possiblyConflictingDefinitionName);
if (existingExample != null) {
LOGGER.debug("A model for " + existingExample + " already exists");
if(existingExample.get$ref() != null) {
// use the new model
existingExample = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingExample == null) {
// don't overwrite existing model reference
openAPI.getComponents().addExamples(newRef, example);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (example.get$ref() != null) {
RefFormat format = computeRefFormat(example.get$ref());
if (isAnExternalRefFormat(format)) {
example.set$ref(processRefToExternalExample(example.get$ref(), format));
} else {
processRefToExternalExample(file + example.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalParameter(String $ref, RefFormat refFormat) {
final Parameter parameter = cache.loadRef($ref, refFormat, Parameter.class);
if(parameter == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map parameters = openAPI.getComponents().getParameters();
if (parameters == null) {
parameters = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
Parameter existingParameters = parameters.get(possiblyConflictingDefinitionName);
if (existingParameters != null) {
LOGGER.debug("A model for " + existingParameters + " already exists");
if(existingParameters.get$ref() != null) {
// use the new model
existingParameters = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingParameters == null) {
// don't overwrite existing model reference
openAPI.getComponents().addParameters(newRef, parameter);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if (parameter.get$ref() != null) {
RefFormat format = computeRefFormat(parameter.get$ref());
if (isAnExternalRefFormat(format)) {
parameter.set$ref(processRefToExternalParameter(parameter.get$ref(), format));
} else {
processRefToExternalParameter(file + parameter.get$ref(), RefFormat.RELATIVE);
}
}
}
return newRef;
}
public String processRefToExternalCallback(String $ref, RefFormat refFormat) {
final Callback callback = cache.loadRef($ref, refFormat, Callback.class);
if(callback == null) {
// stop! There's a problem. retain the original ref
LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " +
"or the reference isn't a valid model schema");
return $ref;
}
String newRef;
Map callbacks = openAPI.getComponents().getCallbacks();
if (callbacks == null) {
callbacks = new LinkedHashMap<>();
}
final String possiblyConflictingDefinitionName = computeDefinitionName($ref);
Callback existingCallback = callbacks.get(possiblyConflictingDefinitionName);
if (existingCallback != null) {
LOGGER.debug("A model for " + existingCallback + " already exists");
if(existingCallback.get("$ref").get$ref() != null) {
// use the new model
existingCallback = null;
}
}
newRef = possiblyConflictingDefinitionName;
cache.putRenamedRef($ref, newRef);
if(existingCallback == null) {
// don't overwrite existing model reference
openAPI.getComponents().addCallbacks(newRef, callback);
cache.addReferencedKey(newRef);
String file = $ref.split("#/")[0];
if(callback.get("$ref") != null){
if (callback.get("$ref").get$ref() != null) {
RefFormat format = computeRefFormat(callback.get("$ref").get$ref());
if (isAnExternalRefFormat(format)) {
callback.get("$ref").set$ref(processRefToExternalCallback(callback.get("$ref").get$ref(), format));
} else {
processRefToExternalCallback(file + callback.get("$ref").get$ref(), RefFormat.RELATIVE);
}
}
}
}
return newRef;
}
private void processRefProperty(Schema subRef, String externalFile) {
RefFormat format = computeRefFormat(subRef.get$ref());
if (isAnExternalRefFormat(format)) {
String $ref = constructRef(subRef, externalFile);
subRef.set$ref($ref);
if($ref.startsWith("."))
processRefToExternalSchema($ref, RefFormat.RELATIVE);
else {
processRefToExternalSchema($ref, RefFormat.URL);
}
} else {
processRefToExternalSchema(externalFile + subRef.get$ref(), RefFormat.RELATIVE);
}
}
protected String constructRef(Schema refProperty, String rootLocation) {
String ref = refProperty.get$ref();
return join(rootLocation, ref);
}
public static String join(String source, String fragment) {
try {
boolean isRelative = false;
if(source.startsWith("/") || source.startsWith(".")) {
isRelative = true;
}
URI uri = new URI(source);
if(!source.endsWith("/") && (fragment.startsWith("./") && "".equals(uri.getPath()))) {
uri = new URI(source + "/");
}
else if("".equals(uri.getPath()) && !fragment.startsWith("/")) {
uri = new URI(source + "/");
}
URI f = new URI(fragment);
URI resolved = uri.resolve(f);
URI normalized = resolved.normalize();
if(Character.isAlphabetic(normalized.toString().charAt(0)) && isRelative) {
return "./" + normalized.toString();
}
return normalized.toString();
}
catch(Exception e) {
return source;
}
}
}