use of io.swagger.v3.oas.models.media in project swagger-core by swagger-api.
the class DefaultParameterExtension method extractParameters.
@Override
public ResolvedParameter extractParameters(List<Annotation> annotations, Type type, Set<Type> typesToSkip, Components components, javax.ws.rs.Consumes classConsumes, javax.ws.rs.Consumes methodConsumes, boolean includeRequestBody, JsonView jsonViewAnnotation, Iterator<OpenAPIExtension> chain) {
if (shouldIgnoreType(type, typesToSkip)) {
return new ResolvedParameter();
}
Parameter parameter = null;
for (Annotation annotation : annotations) {
if (annotation instanceof QueryParam) {
QueryParam param = (QueryParam) annotation;
Parameter qp = new Parameter();
qp.setIn(QUERY_PARAM);
qp.setName(param.value());
parameter = qp;
} else if (annotation instanceof PathParam) {
PathParam param = (PathParam) annotation;
Parameter pp = new Parameter();
pp.setIn(PATH_PARAM);
pp.setName(param.value());
parameter = pp;
} else if (annotation instanceof MatrixParam) {
MatrixParam param = (MatrixParam) annotation;
Parameter pp = new Parameter();
pp.setIn(PATH_PARAM);
pp.setStyle(Parameter.StyleEnum.MATRIX);
pp.setName(param.value());
parameter = pp;
} else if (annotation instanceof HeaderParam) {
HeaderParam param = (HeaderParam) annotation;
Parameter pp = new Parameter();
pp.setIn(HEADER_PARAM);
pp.setName(param.value());
parameter = pp;
} else if (annotation instanceof CookieParam) {
CookieParam param = (CookieParam) annotation;
Parameter pp = new Parameter();
pp.setIn(COOKIE_PARAM);
pp.setName(param.value());
parameter = pp;
} else if (annotation instanceof io.swagger.v3.oas.annotations.Parameter) {
if (((io.swagger.v3.oas.annotations.Parameter) annotation).hidden()) {
return new ResolvedParameter();
}
if (parameter == null) {
parameter = new Parameter();
}
if (StringUtils.isNotBlank(((io.swagger.v3.oas.annotations.Parameter) annotation).ref())) {
parameter.$ref(((io.swagger.v3.oas.annotations.Parameter) annotation).ref());
}
} else {
List<Parameter> formParameters = new ArrayList<>();
List<Parameter> parameters = new ArrayList<>();
if (handleAdditionalAnnotation(parameters, formParameters, annotation, type, typesToSkip, classConsumes, methodConsumes, components, includeRequestBody, jsonViewAnnotation)) {
ResolvedParameter extractParametersResult = new ResolvedParameter();
extractParametersResult.parameters.addAll(parameters);
extractParametersResult.formParameters.addAll(formParameters);
return extractParametersResult;
}
}
}
List<Parameter> parameters = new ArrayList<>();
ResolvedParameter extractParametersResult = new ResolvedParameter();
if (parameter != null && (StringUtils.isNotBlank(parameter.getIn()) || StringUtils.isNotBlank(parameter.get$ref()))) {
parameters.add(parameter);
} else if (includeRequestBody) {
Parameter unknownParameter = ParameterProcessor.applyAnnotations(null, type, annotations, components, classConsumes == null ? new String[0] : classConsumes.value(), methodConsumes == null ? new String[0] : methodConsumes.value(), jsonViewAnnotation);
if (unknownParameter != null) {
if (StringUtils.isNotBlank(unknownParameter.getIn()) && !"form".equals(unknownParameter.getIn())) {
extractParametersResult.parameters.add(unknownParameter);
} else if ("form".equals(unknownParameter.getIn())) {
unknownParameter.setIn(null);
extractParametersResult.formParameters.add(unknownParameter);
} else {
// return as request body
extractParametersResult.requestBody = unknownParameter;
}
}
}
for (Parameter p : parameters) {
Parameter processedParameter = ParameterProcessor.applyAnnotations(p, type, annotations, components, classConsumes == null ? new String[0] : classConsumes.value(), methodConsumes == null ? new String[0] : methodConsumes.value(), jsonViewAnnotation);
if (processedParameter != null) {
extractParametersResult.parameters.add(processedParameter);
}
}
return extractParametersResult;
}
use of io.swagger.v3.oas.models.media in project swagger-core by swagger-api.
the class Reader method read.
public OpenAPI read(Class<?> cls, String parentPath, String parentMethod, boolean isSubresource, RequestBody parentRequestBody, ApiResponses parentResponses, Set<String> parentTags, List<Parameter> parentParameters, Set<Class<?>> scannedResources) {
Hidden hidden = cls.getAnnotation(Hidden.class);
// class path
final javax.ws.rs.Path apiPath = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Path.class);
if (hidden != null) {
// || (apiPath == null && !isSubresource)) {
return openAPI;
}
io.swagger.v3.oas.annotations.responses.ApiResponse[] classResponses = ReflectionUtils.getRepeatableAnnotationsArray(cls, io.swagger.v3.oas.annotations.responses.ApiResponse.class);
List<io.swagger.v3.oas.annotations.security.SecurityScheme> apiSecurityScheme = ReflectionUtils.getRepeatableAnnotations(cls, io.swagger.v3.oas.annotations.security.SecurityScheme.class);
List<io.swagger.v3.oas.annotations.security.SecurityRequirement> apiSecurityRequirements = ReflectionUtils.getRepeatableAnnotations(cls, io.swagger.v3.oas.annotations.security.SecurityRequirement.class);
ExternalDocumentation apiExternalDocs = ReflectionUtils.getAnnotation(cls, ExternalDocumentation.class);
io.swagger.v3.oas.annotations.tags.Tag[] apiTags = ReflectionUtils.getRepeatableAnnotationsArray(cls, io.swagger.v3.oas.annotations.tags.Tag.class);
io.swagger.v3.oas.annotations.servers.Server[] apiServers = ReflectionUtils.getRepeatableAnnotationsArray(cls, io.swagger.v3.oas.annotations.servers.Server.class);
javax.ws.rs.Consumes classConsumes = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Consumes.class);
javax.ws.rs.Produces classProduces = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Produces.class);
boolean classDeprecated = ReflectionUtils.getAnnotation(cls, Deprecated.class) != null;
// OpenApiDefinition
OpenAPIDefinition openAPIDefinition = ReflectionUtils.getAnnotation(cls, OpenAPIDefinition.class);
if (openAPIDefinition != null) {
// info
AnnotationsUtils.getInfo(openAPIDefinition.info()).ifPresent(info -> openAPI.setInfo(info));
// OpenApiDefinition security requirements
SecurityParser.getSecurityRequirements(openAPIDefinition.security()).ifPresent(s -> openAPI.setSecurity(s));
//
// OpenApiDefinition external docs
AnnotationsUtils.getExternalDocumentation(openAPIDefinition.externalDocs()).ifPresent(docs -> openAPI.setExternalDocs(docs));
// OpenApiDefinition tags
AnnotationsUtils.getTags(openAPIDefinition.tags(), false).ifPresent(tags -> openApiTags.addAll(tags));
// OpenApiDefinition servers
AnnotationsUtils.getServers(openAPIDefinition.servers()).ifPresent(servers -> openAPI.setServers(servers));
// OpenApiDefinition extensions
if (openAPIDefinition.extensions().length > 0) {
openAPI.setExtensions(AnnotationsUtils.getExtensions(openAPIDefinition.extensions()));
}
}
// class security schemes
if (apiSecurityScheme != null) {
for (io.swagger.v3.oas.annotations.security.SecurityScheme securitySchemeAnnotation : apiSecurityScheme) {
Optional<SecurityParser.SecuritySchemePair> securityScheme = SecurityParser.getSecurityScheme(securitySchemeAnnotation);
if (securityScheme.isPresent()) {
Map<String, SecurityScheme> securitySchemeMap = new HashMap<>();
if (StringUtils.isNotBlank(securityScheme.get().key)) {
securitySchemeMap.put(securityScheme.get().key, securityScheme.get().securityScheme);
if (components.getSecuritySchemes() != null && components.getSecuritySchemes().size() != 0) {
components.getSecuritySchemes().putAll(securitySchemeMap);
} else {
components.setSecuritySchemes(securitySchemeMap);
}
}
}
}
}
// class security requirements
List<SecurityRequirement> classSecurityRequirements = new ArrayList<>();
if (apiSecurityRequirements != null) {
Optional<List<SecurityRequirement>> requirementsObject = SecurityParser.getSecurityRequirements(apiSecurityRequirements.toArray(new io.swagger.v3.oas.annotations.security.SecurityRequirement[apiSecurityRequirements.size()]));
if (requirementsObject.isPresent()) {
classSecurityRequirements = requirementsObject.get();
}
}
// class tags, consider only name to add to class operations
final Set<String> classTags = new LinkedHashSet<>();
if (apiTags != null) {
AnnotationsUtils.getTags(apiTags, false).ifPresent(tags -> tags.stream().map(Tag::getName).forEach(classTags::add));
}
// parent tags
if (isSubresource) {
if (parentTags != null) {
classTags.addAll(parentTags);
}
}
// servers
final List<io.swagger.v3.oas.models.servers.Server> classServers = new ArrayList<>();
if (apiServers != null) {
AnnotationsUtils.getServers(apiServers).ifPresent(classServers::addAll);
}
// class external docs
Optional<io.swagger.v3.oas.models.ExternalDocumentation> classExternalDocumentation = AnnotationsUtils.getExternalDocumentation(apiExternalDocs);
JavaType classType = TypeFactory.defaultInstance().constructType(cls);
BeanDescription bd = Json.mapper().getSerializationConfig().introspect(classType);
final List<Parameter> globalParameters = new ArrayList<>();
// look for constructor-level annotated properties
globalParameters.addAll(ReaderUtils.collectConstructorParameters(cls, components, classConsumes, null));
// look for field-level annotated properties
globalParameters.addAll(ReaderUtils.collectFieldParameters(cls, components, classConsumes, null));
// Make sure that the class methods are sorted for deterministic order
// See https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getMethods--
final List<Method> methods = Arrays.stream(cls.getMethods()).sorted(new MethodComparator()).collect(Collectors.toList());
// iterate class methods
for (Method method : methods) {
if (isOperationHidden(method)) {
continue;
}
AnnotatedMethod annotatedMethod = bd.findMethod(method.getName(), method.getParameterTypes());
javax.ws.rs.Produces methodProduces = ReflectionUtils.getAnnotation(method, javax.ws.rs.Produces.class);
javax.ws.rs.Consumes methodConsumes = ReflectionUtils.getAnnotation(method, javax.ws.rs.Consumes.class);
if (isMethodOverridden(method, cls)) {
continue;
}
boolean methodDeprecated = ReflectionUtils.getAnnotation(method, Deprecated.class) != null;
javax.ws.rs.Path methodPath = ReflectionUtils.getAnnotation(method, javax.ws.rs.Path.class);
String operationPath = ReaderUtils.getPath(apiPath, methodPath, parentPath, isSubresource);
// extending resource config.
if (ignoreOperationPath(operationPath, parentPath) && !isSubresource) {
continue;
}
Map<String, String> regexMap = new LinkedHashMap<>();
operationPath = PathUtils.parsePath(operationPath, regexMap);
if (operationPath != null) {
if (config != null && ReaderUtils.isIgnored(operationPath, config)) {
continue;
}
final Class<?> subResource = getSubResourceWithJaxRsSubresourceLocatorSpecs(method);
String httpMethod = ReaderUtils.extractOperationMethod(method, OpenAPIExtensions.chain());
httpMethod = (httpMethod == null && isSubresource) ? parentMethod : httpMethod;
if (StringUtils.isBlank(httpMethod) && subResource == null) {
continue;
} else if (StringUtils.isBlank(httpMethod) && subResource != null) {
Type returnType = method.getGenericReturnType();
if (annotatedMethod != null && annotatedMethod.getType() != null) {
returnType = annotatedMethod.getType();
}
if (shouldIgnoreClass(returnType.getTypeName()) && !method.getGenericReturnType().equals(subResource)) {
continue;
}
}
io.swagger.v3.oas.annotations.Operation apiOperation = ReflectionUtils.getAnnotation(method, io.swagger.v3.oas.annotations.Operation.class);
JsonView jsonViewAnnotation;
JsonView jsonViewAnnotationForRequestBody;
if (apiOperation != null && apiOperation.ignoreJsonView()) {
jsonViewAnnotation = null;
jsonViewAnnotationForRequestBody = null;
} else {
jsonViewAnnotation = ReflectionUtils.getAnnotation(method, JsonView.class);
/* If one and only one exists, use the @JsonView annotation from the method parameter annotated
with @RequestBody. Otherwise fall back to the @JsonView annotation for the method itself. */
jsonViewAnnotationForRequestBody = (JsonView) Arrays.stream(ReflectionUtils.getParameterAnnotations(method)).filter(arr -> Arrays.stream(arr).anyMatch(annotation -> annotation.annotationType().equals(io.swagger.v3.oas.annotations.parameters.RequestBody.class))).flatMap(Arrays::stream).filter(annotation -> annotation.annotationType().equals(JsonView.class)).reduce((a, b) -> null).orElse(jsonViewAnnotation);
}
Operation operation = parseMethod(method, globalParameters, methodProduces, classProduces, methodConsumes, classConsumes, classSecurityRequirements, classExternalDocumentation, classTags, classServers, isSubresource, parentRequestBody, parentResponses, jsonViewAnnotation, classResponses, annotatedMethod);
if (operation != null) {
if (classDeprecated || methodDeprecated) {
operation.setDeprecated(true);
}
List<Parameter> operationParameters = new ArrayList<>();
List<Parameter> formParameters = new ArrayList<>();
Annotation[][] paramAnnotations = ReflectionUtils.getParameterAnnotations(method);
if (annotatedMethod == null) {
// annotatedMethod not null only when method with 0-2 parameters
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (int i = 0; i < genericParameterTypes.length; i++) {
final Type type = TypeFactory.defaultInstance().constructType(genericParameterTypes[i], cls);
io.swagger.v3.oas.annotations.Parameter paramAnnotation = AnnotationsUtils.getAnnotation(io.swagger.v3.oas.annotations.Parameter.class, paramAnnotations[i]);
Type paramType = ParameterProcessor.getParameterType(paramAnnotation, true);
if (paramType == null) {
paramType = type;
} else {
if (!(paramType instanceof Class)) {
paramType = type;
}
}
ResolvedParameter resolvedParameter = getParameters(paramType, Arrays.asList(paramAnnotations[i]), operation, classConsumes, methodConsumes, jsonViewAnnotation);
operationParameters.addAll(resolvedParameter.parameters);
// collect params to use together as request Body
formParameters.addAll(resolvedParameter.formParameters);
if (resolvedParameter.requestBody != null) {
processRequestBody(resolvedParameter.requestBody, operation, methodConsumes, classConsumes, operationParameters, paramAnnotations[i], type, jsonViewAnnotationForRequestBody, null);
}
}
} else {
for (int i = 0; i < annotatedMethod.getParameterCount(); i++) {
AnnotatedParameter param = annotatedMethod.getParameter(i);
final Type type = TypeFactory.defaultInstance().constructType(param.getParameterType(), cls);
io.swagger.v3.oas.annotations.Parameter paramAnnotation = AnnotationsUtils.getAnnotation(io.swagger.v3.oas.annotations.Parameter.class, paramAnnotations[i]);
Type paramType = ParameterProcessor.getParameterType(paramAnnotation, true);
if (paramType == null) {
paramType = type;
} else {
if (!(paramType instanceof Class)) {
paramType = type;
}
}
ResolvedParameter resolvedParameter = getParameters(paramType, Arrays.asList(paramAnnotations[i]), operation, classConsumes, methodConsumes, jsonViewAnnotation);
operationParameters.addAll(resolvedParameter.parameters);
// collect params to use together as request Body
formParameters.addAll(resolvedParameter.formParameters);
if (resolvedParameter.requestBody != null) {
processRequestBody(resolvedParameter.requestBody, operation, methodConsumes, classConsumes, operationParameters, paramAnnotations[i], type, jsonViewAnnotationForRequestBody, null);
}
}
}
// if we have form parameters, need to merge them into single schema and use as request body..
if (!formParameters.isEmpty()) {
Schema mergedSchema = new ObjectSchema();
Map<String, Encoding> encoding = new LinkedHashMap<>();
for (Parameter formParam : formParameters) {
if (formParam.getExplode() != null || (formParam.getStyle() != null) && Encoding.StyleEnum.fromString(formParam.getStyle().toString()) != null) {
Encoding e = new Encoding();
if (formParam.getExplode() != null) {
e.explode(formParam.getExplode());
}
if (formParam.getStyle() != null && Encoding.StyleEnum.fromString(formParam.getStyle().toString()) != null) {
e.style(Encoding.StyleEnum.fromString(formParam.getStyle().toString()));
}
encoding.put(formParam.getName(), e);
}
mergedSchema.addProperties(formParam.getName(), formParam.getSchema());
if (formParam.getSchema() != null && StringUtils.isNotBlank(formParam.getDescription()) && StringUtils.isBlank(formParam.getSchema().getDescription())) {
formParam.getSchema().description(formParam.getDescription());
}
if (null != formParam.getRequired() && formParam.getRequired()) {
mergedSchema.addRequiredItem(formParam.getName());
}
}
Parameter merged = new Parameter().schema(mergedSchema);
processRequestBody(merged, operation, methodConsumes, classConsumes, operationParameters, new Annotation[0], null, jsonViewAnnotationForRequestBody, encoding);
}
if (!operationParameters.isEmpty()) {
for (Parameter operationParameter : operationParameters) {
operation.addParametersItem(operationParameter);
}
}
// if subresource, merge parent parameters
if (parentParameters != null) {
for (Parameter parentParameter : parentParameters) {
operation.addParametersItem(parentParameter);
}
}
if (subResource != null && !scannedResources.contains(subResource)) {
scannedResources.add(subResource);
read(subResource, operationPath, httpMethod, true, operation.getRequestBody(), operation.getResponses(), classTags, operation.getParameters(), scannedResources);
// remove the sub resource so that it can visit it later in another path
// but we have a room for optimization in the future to reuse the scanned result
// by caching the scanned resources in the reader instance to avoid actual scanning
// the the resources again
scannedResources.remove(subResource);
// don't proceed with root resource operation, as it's handled by subresource
continue;
}
final Iterator<OpenAPIExtension> chain = OpenAPIExtensions.chain();
if (chain.hasNext()) {
final OpenAPIExtension extension = chain.next();
extension.decorateOperation(operation, method, chain);
}
PathItem pathItemObject;
if (openAPI.getPaths() != null && openAPI.getPaths().get(operationPath) != null) {
pathItemObject = openAPI.getPaths().get(operationPath);
} else {
pathItemObject = new PathItem();
}
if (StringUtils.isBlank(httpMethod)) {
continue;
}
setPathItemOperation(pathItemObject, httpMethod, operation);
paths.addPathItem(operationPath, pathItemObject);
if (openAPI.getPaths() != null) {
this.paths.putAll(openAPI.getPaths());
}
openAPI.setPaths(this.paths);
}
}
}
// if no components object is defined in openApi instance passed by client, set openAPI.components to resolved components (if not empty)
if (!isEmptyComponents(components) && openAPI.getComponents() == null) {
openAPI.setComponents(components);
}
// add tags from class to definition tags
AnnotationsUtils.getTags(apiTags, true).ifPresent(tags -> openApiTags.addAll(tags));
if (!openApiTags.isEmpty()) {
Set<Tag> tagsSet = new LinkedHashSet<>();
if (openAPI.getTags() != null) {
for (Tag tag : openAPI.getTags()) {
if (tagsSet.stream().noneMatch(t -> t.getName().equals(tag.getName()))) {
tagsSet.add(tag);
}
}
}
for (Tag tag : openApiTags) {
if (tagsSet.stream().noneMatch(t -> t.getName().equals(tag.getName()))) {
tagsSet.add(tag);
}
}
openAPI.setTags(new ArrayList<>(tagsSet));
}
return openAPI;
}
use of io.swagger.v3.oas.models.media in project swagger-core by swagger-api.
the class Reader method isOperationHidden.
protected boolean isOperationHidden(Method method) {
io.swagger.v3.oas.annotations.Operation apiOperation = ReflectionUtils.getAnnotation(method, io.swagger.v3.oas.annotations.Operation.class);
if (apiOperation != null && apiOperation.hidden()) {
return true;
}
Hidden hidden = method.getAnnotation(Hidden.class);
if (hidden != null) {
return true;
}
if (config != null && !Boolean.TRUE.equals(config.isReadAllResources()) && apiOperation == null) {
return true;
}
return false;
}
use of io.swagger.v3.oas.models.media in project swagger-core by swagger-api.
the class Reader method getCallbacks.
private Map<String, Callback> getCallbacks(io.swagger.v3.oas.annotations.callbacks.Callback apiCallback, Produces methodProduces, Produces classProduces, Consumes methodConsumes, Consumes classConsumes, JsonView jsonViewAnnotation) {
Map<String, Callback> callbackMap = new HashMap<>();
if (apiCallback == null) {
return callbackMap;
}
Callback callbackObject = new Callback();
if (StringUtils.isNotBlank(apiCallback.ref())) {
callbackObject.set$ref(apiCallback.ref());
callbackMap.put(apiCallback.name(), callbackObject);
return callbackMap;
}
PathItem pathItemObject = new PathItem();
for (io.swagger.v3.oas.annotations.Operation callbackOperation : apiCallback.operation()) {
Operation callbackNewOperation = new Operation();
setOperationObjectFromApiOperationAnnotation(callbackNewOperation, callbackOperation, methodProduces, classProduces, methodConsumes, classConsumes, jsonViewAnnotation);
setPathItemOperation(pathItemObject, callbackOperation.method(), callbackNewOperation);
}
callbackObject.addPathItem(apiCallback.callbackUrlExpression(), pathItemObject);
callbackMap.put(apiCallback.name(), callbackObject);
return callbackMap;
}
use of io.swagger.v3.oas.models.media in project swagger-core by swagger-api.
the class Reader method parseMethod.
protected Operation parseMethod(Class<?> cls, Method method, List<Parameter> globalParameters, Produces methodProduces, Produces classProduces, Consumes methodConsumes, Consumes classConsumes, List<SecurityRequirement> classSecurityRequirements, Optional<io.swagger.v3.oas.models.ExternalDocumentation> classExternalDocs, Set<String> classTags, List<io.swagger.v3.oas.models.servers.Server> classServers, boolean isSubresource, RequestBody parentRequestBody, ApiResponses parentResponses, JsonView jsonViewAnnotation, io.swagger.v3.oas.annotations.responses.ApiResponse[] classResponses, AnnotatedMethod annotatedMethod) {
Operation operation = new Operation();
io.swagger.v3.oas.annotations.Operation apiOperation = ReflectionUtils.getAnnotation(method, io.swagger.v3.oas.annotations.Operation.class);
List<io.swagger.v3.oas.annotations.security.SecurityRequirement> apiSecurity = ReflectionUtils.getRepeatableAnnotations(method, io.swagger.v3.oas.annotations.security.SecurityRequirement.class);
List<io.swagger.v3.oas.annotations.callbacks.Callback> apiCallbacks = ReflectionUtils.getRepeatableAnnotations(method, io.swagger.v3.oas.annotations.callbacks.Callback.class);
List<Server> apiServers = ReflectionUtils.getRepeatableAnnotations(method, Server.class);
List<io.swagger.v3.oas.annotations.tags.Tag> apiTags = ReflectionUtils.getRepeatableAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class);
List<io.swagger.v3.oas.annotations.Parameter> apiParameters = ReflectionUtils.getRepeatableAnnotations(method, io.swagger.v3.oas.annotations.Parameter.class);
List<io.swagger.v3.oas.annotations.responses.ApiResponse> apiResponses = ReflectionUtils.getRepeatableAnnotations(method, io.swagger.v3.oas.annotations.responses.ApiResponse.class);
io.swagger.v3.oas.annotations.parameters.RequestBody apiRequestBody = ReflectionUtils.getAnnotation(method, io.swagger.v3.oas.annotations.parameters.RequestBody.class);
ExternalDocumentation apiExternalDocumentation = ReflectionUtils.getAnnotation(method, ExternalDocumentation.class);
// callbacks
Map<String, Callback> callbacks = new LinkedHashMap<>();
if (apiCallbacks != null) {
for (io.swagger.v3.oas.annotations.callbacks.Callback methodCallback : apiCallbacks) {
Map<String, Callback> currentCallbacks = getCallbacks(methodCallback, methodProduces, classProduces, methodConsumes, classConsumes, jsonViewAnnotation);
callbacks.putAll(currentCallbacks);
}
}
if (callbacks.size() > 0) {
operation.setCallbacks(callbacks);
}
// security
classSecurityRequirements.forEach(operation::addSecurityItem);
if (apiSecurity != null) {
Optional<List<SecurityRequirement>> requirementsObject = SecurityParser.getSecurityRequirements(apiSecurity.toArray(new io.swagger.v3.oas.annotations.security.SecurityRequirement[apiSecurity.size()]));
if (requirementsObject.isPresent()) {
requirementsObject.get().stream().filter(r -> operation.getSecurity() == null || !operation.getSecurity().contains(r)).forEach(operation::addSecurityItem);
}
}
// servers
if (classServers != null) {
classServers.forEach(operation::addServersItem);
}
if (apiServers != null) {
AnnotationsUtils.getServers(apiServers.toArray(new Server[apiServers.size()])).ifPresent(servers -> servers.forEach(operation::addServersItem));
}
// external docs
AnnotationsUtils.getExternalDocumentation(apiExternalDocumentation).ifPresent(operation::setExternalDocs);
// method tags
if (apiTags != null) {
apiTags.stream().filter(t -> operation.getTags() == null || (operation.getTags() != null && !operation.getTags().contains(t.name()))).map(io.swagger.v3.oas.annotations.tags.Tag::name).forEach(operation::addTagsItem);
AnnotationsUtils.getTags(apiTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[apiTags.size()]), true).ifPresent(tags -> openApiTags.addAll(tags));
}
// parameters
if (globalParameters != null) {
for (Parameter globalParameter : globalParameters) {
operation.addParametersItem(globalParameter);
}
}
if (apiParameters != null) {
getParametersListFromAnnotation(apiParameters.toArray(new io.swagger.v3.oas.annotations.Parameter[apiParameters.size()]), classConsumes, methodConsumes, operation, jsonViewAnnotation).ifPresent(p -> p.forEach(operation::addParametersItem));
}
// RequestBody in Method
if (apiRequestBody != null && operation.getRequestBody() == null) {
OperationParser.getRequestBody(apiRequestBody, classConsumes, methodConsumes, components, jsonViewAnnotation).ifPresent(operation::setRequestBody);
}
// operation id
if (StringUtils.isBlank(operation.getOperationId())) {
operation.setOperationId(getOperationId(method.getName()));
}
// classResponses
if (classResponses != null && classResponses.length > 0) {
OperationParser.getApiResponses(classResponses, classProduces, methodProduces, components, jsonViewAnnotation).ifPresent(responses -> {
if (operation.getResponses() == null) {
operation.setResponses(responses);
} else {
responses.forEach(operation.getResponses()::addApiResponse);
}
});
}
if (apiOperation != null) {
setOperationObjectFromApiOperationAnnotation(operation, apiOperation, methodProduces, classProduces, methodConsumes, classConsumes, jsonViewAnnotation);
}
// apiResponses
if (apiResponses != null && !apiResponses.isEmpty()) {
OperationParser.getApiResponses(apiResponses.toArray(new io.swagger.v3.oas.annotations.responses.ApiResponse[apiResponses.size()]), classProduces, methodProduces, components, jsonViewAnnotation).ifPresent(responses -> {
if (operation.getResponses() == null) {
operation.setResponses(responses);
} else {
responses.forEach(operation.getResponses()::addApiResponse);
}
});
}
// class tags after tags defined as field of @Operation
if (classTags != null) {
classTags.stream().filter(t -> operation.getTags() == null || (operation.getTags() != null && !operation.getTags().contains(t))).forEach(operation::addTagsItem);
}
// external docs of class if not defined in annotation of method or as field of Operation annotation
if (operation.getExternalDocs() == null) {
classExternalDocs.ifPresent(operation::setExternalDocs);
}
// if subresource, merge parent requestBody
if (isSubresource && parentRequestBody != null) {
if (operation.getRequestBody() == null) {
operation.requestBody(parentRequestBody);
} else {
Content content = operation.getRequestBody().getContent();
if (content == null) {
content = parentRequestBody.getContent();
operation.getRequestBody().setContent(content);
} else if (parentRequestBody.getContent() != null) {
for (String parentMediaType : parentRequestBody.getContent().keySet()) {
if (content.get(parentMediaType) == null) {
content.addMediaType(parentMediaType, parentRequestBody.getContent().get(parentMediaType));
}
}
}
}
}
// handle return type, add as response in case.
Type returnType = method.getGenericReturnType();
if (annotatedMethod != null && annotatedMethod.getType() != null) {
returnType = annotatedMethod.getType();
}
final Class<?> subResource = getSubResourceWithJaxRsSubresourceLocatorSpecs(method);
Schema returnTypeSchema = null;
if (!shouldIgnoreClass(returnType.getTypeName()) && !method.getGenericReturnType().equals(subResource)) {
ResolvedSchema resolvedSchema = ModelConverters.getInstance().resolveAsResolvedSchema(new AnnotatedType(returnType).resolveAsRef(true).jsonViewAnnotation(jsonViewAnnotation));
if (resolvedSchema.schema != null) {
returnTypeSchema = resolvedSchema.schema;
Content content = new Content();
MediaType mediaType = new MediaType().schema(returnTypeSchema);
AnnotationsUtils.applyTypes(classProduces == null ? new String[0] : classProduces.value(), methodProduces == null ? new String[0] : methodProduces.value(), content, mediaType);
if (operation.getResponses() == null) {
operation.responses(new ApiResponses()._default(new ApiResponse().description(DEFAULT_DESCRIPTION).content(content)));
}
if (operation.getResponses().getDefault() != null && StringUtils.isBlank(operation.getResponses().getDefault().get$ref())) {
if (operation.getResponses().getDefault().getContent() == null) {
operation.getResponses().getDefault().content(content);
} else {
for (String key : operation.getResponses().getDefault().getContent().keySet()) {
if (operation.getResponses().getDefault().getContent().get(key).getSchema() == null) {
operation.getResponses().getDefault().getContent().get(key).setSchema(returnTypeSchema);
}
}
}
}
Map<String, Schema> schemaMap = resolvedSchema.referencedSchemas;
if (schemaMap != null) {
schemaMap.forEach((key, schema) -> components.addSchemas(key, schema));
}
}
}
if (operation.getResponses() == null || operation.getResponses().isEmpty()) {
Content content = resolveEmptyContent(classProduces, methodProduces);
ApiResponse apiResponseObject = new ApiResponse().description(DEFAULT_DESCRIPTION).content(content);
operation.setResponses(new ApiResponses()._default(apiResponseObject));
}
if (returnTypeSchema != null) {
resolveResponseSchemaFromReturnType(operation, classResponses, returnTypeSchema, classProduces, methodProduces);
if (apiResponses != null) {
resolveResponseSchemaFromReturnType(operation, apiResponses.stream().toArray(io.swagger.v3.oas.annotations.responses.ApiResponse[]::new), returnTypeSchema, classProduces, methodProduces);
}
}
return operation;
}
Aggregations