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.
com.github.kongchen.swagger.docgen.reader.AbstractReader Maven / Gradle / Ivy
Go to download
A maven build plugin which helps you generate API document during build phase
package com.github.kongchen.swagger.docgen.reader;
import com.github.kongchen.swagger.docgen.jaxrs.BeanParamInjectParamExtention;
import com.github.kongchen.swagger.docgen.jaxrs.JaxrsParameterExtension;
import com.github.kongchen.swagger.docgen.spring.SpringSwaggerExtension;
import com.sun.jersey.api.core.InjectParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.AuthorizationScope;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.ResponseHeader;
import io.swagger.converter.ModelConverters;
import io.swagger.jaxrs.ext.SwaggerExtension;
import io.swagger.jaxrs.ext.SwaggerExtensions;
import io.swagger.jersey.SwaggerJerseyJaxrs;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Response;
import io.swagger.models.Scheme;
import io.swagger.models.SecurityRequirement;
import io.swagger.models.Swagger;
import io.swagger.models.Tag;
import io.swagger.models.parameters.AbstractSerializableParameter;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.FormParameter;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.PathParameter;
import io.swagger.models.parameters.QueryParameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.util.ParameterProcessor;
import io.swagger.util.PathUtils;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.apache.maven.plugin.logging.Log;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import javax.ws.rs.BeanParam;
import javax.ws.rs.FormParam;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author chekong on 15/4/28.
*/
public abstract class AbstractReader {
protected final Log LOG;
protected Swagger swagger;
private Set typesToSkip = new HashSet();
public Set getTypesToSkip() {
return typesToSkip;
}
public void setTypesToSkip(List typesToSkip) {
this.typesToSkip = new HashSet(typesToSkip);
}
public void setTypesToSkip(Set typesToSkip) {
this.typesToSkip = typesToSkip;
}
public void addTypeToSkippedTypes(Type type) {
this.typesToSkip.add(type);
}
public AbstractReader(Swagger swagger, Log LOG) {
this.swagger = swagger;
this.LOG = LOG;
updateExtensionChain();
}
private void updateExtensionChain() {
List extensions = new ArrayList();
Class extends AbstractReader> clazz = this.getClass();
if (clazz == SpringMvcApiReader.class || SpringMvcApiReader.class.isAssignableFrom(clazz)) {
extensions.add(new SpringSwaggerExtension());
} else {
extensions.add(new BeanParamInjectParamExtention());
extensions.add(new SwaggerJerseyJaxrs());
extensions.add(new JaxrsParameterExtension());
}
SwaggerExtensions.setExtensions(extensions);
}
protected List getSecurityRequirements(Api api) {
List securities = new ArrayList();
for (Authorization auth : api.authorizations()) {
if (auth.value().isEmpty()) {
continue;
}
SecurityRequirement security = new SecurityRequirement();
security.setName(auth.value());
for (AuthorizationScope scope : auth.scopes()) {
if (!scope.scope().isEmpty()) {
security.addScope(scope.scope());
}
}
securities.add(security);
}
return securities;
}
protected String parseOperationPath(String operationPath, Map regexMap) {
return PathUtils.parsePath(operationPath, regexMap);
}
protected void updateOperationParameters(List parentParameters, Map regexMap, Operation operation) {
if (parentParameters != null) {
for (Parameter param : parentParameters) {
operation.parameter(param);
}
}
for (Parameter param : operation.getParameters()) {
String pattern = regexMap.get(param.getName());
if (pattern != null) {
param.setPattern(pattern);
}
}
}
protected Map parseResponseHeaders(ResponseHeader[] headers) {
if (headers == null) {
return null;
}
Map responseHeaders = null;
for (ResponseHeader header : headers) {
if (header.name().isEmpty()) {
continue;
}
if (responseHeaders == null) {
responseHeaders = new HashMap();
}
Class> cls = header.response();
if (!cls.equals(Void.class) && !cls.equals(void.class)) {
Property property = ModelConverters.getInstance().readAsProperty(cls);
if (property != null) {
Property responseProperty;
if (header.responseContainer().equalsIgnoreCase("list")) {
responseProperty = new ArrayProperty(property);
} else if (header.responseContainer().equalsIgnoreCase("map")) {
responseProperty = new MapProperty(property);
} else {
responseProperty = property;
}
responseProperty.setDescription(header.description());
responseHeaders.put(header.name(), responseProperty);
}
}
}
return responseHeaders;
}
protected Set> parseCustomExtensions(Extension[] extensions) {
if (extensions == null) {
return Collections.emptySet();
}
Set> resultSet = new HashSet>();
for (Extension extension : extensions) {
if (extension == null) {
continue;
}
Map extensionProperties = new HashMap();
for (ExtensionProperty extensionProperty : extension.properties()) {
String name = extensionProperty.name();
if (!name.isEmpty()) {
String value = extensionProperty.value();
extensionProperties.put(name, value);
}
}
if (!extension.name().isEmpty()) {
Map wrapper = new HashMap();
wrapper.put(extension.name(), extensionProperties);
resultSet.add(wrapper);
} else {
resultSet.add(extensionProperties);
}
}
return resultSet;
}
protected void updatePath(String operationPath, String httpMethod, Operation operation) {
if (httpMethod == null) {
return;
}
Path path = swagger.getPath(operationPath);
if (path == null) {
path = new Path();
swagger.path(operationPath, path);
}
path.set(httpMethod, operation);
}
protected void updateTagsForOperation(Operation operation, ApiOperation apiOperation) {
if (apiOperation == null) {
return;
}
for (String tag : apiOperation.tags()) {
if (!tag.isEmpty()) {
operation.tag(tag);
swagger.tag(new Tag().name(tag));
}
}
}
protected boolean canReadApi(boolean readHidden, Api api) {
return (api != null && readHidden) || (api != null && !api.hidden());
}
protected Set extractTags(Api api) {
Set output = new LinkedHashSet();
boolean hasExplicitTags = false;
for (String tag : api.tags()) {
if (!tag.isEmpty()) {
hasExplicitTags = true;
output.add(new Tag().name(tag));
}
}
if (!hasExplicitTags) {
// derive tag from api path + description
String tagString = api.value().replace("/", "");
if (!tagString.isEmpty()) {
Tag tag = new Tag().name(tagString);
if (!api.description().isEmpty()) {
tag.description(api.description());
}
output.add(tag);
}
}
return output;
}
protected void updateOperationProtocols(ApiOperation apiOperation, Operation operation) {
String[] protocols = apiOperation.protocols().split(",");
for (String protocol : protocols) {
String trimmed = protocol.trim();
if (!trimmed.isEmpty()) {
operation.scheme(Scheme.forValue(trimmed));
}
}
}
protected Map updateTagsForApi(Map parentTags, Api api) {
// the value will be used as a tag for 2.0 UNLESS a Tags annotation is present
Map tagsMap = new HashMap();
for (Tag tag : extractTags(api)) {
tagsMap.put(tag.getName(), tag);
}
if (parentTags != null) {
tagsMap.putAll(parentTags);
}
for (Tag tag : tagsMap.values()) {
swagger.tag(tag);
}
return tagsMap;
}
protected boolean isPrimitive(Type cls) {
boolean isPrimitive = false;
Property property = ModelConverters.getInstance().readAsProperty(cls);
if (property == null) {
isPrimitive = false;
} else if ("integer".equals(property.getType())) {
isPrimitive = true;
} else if ("string".equals(property.getType())) {
isPrimitive = true;
} else if ("number".equals(property.getType())) {
isPrimitive = true;
} else if ("boolean".equals(property.getType())) {
isPrimitive = true;
} else if ("array".equals(property.getType())) {
isPrimitive = true;
} else if ("file".equals(property.getType())) {
isPrimitive = true;
}
return isPrimitive;
}
protected void updateOperation(String[] apiConsumes, String[] apiProduces, Map tags, List securities, Operation operation) {
if (operation == null) {
return;
}
if (operation.getConsumes() == null) {
for (String mediaType : apiConsumes) {
operation.consumes(mediaType);
}
}
if (operation.getProduces() == null) {
for (String mediaType : apiProduces) {
operation.produces(mediaType);
}
}
if (operation.getTags() == null) {
for (String tagString : tags.keySet()) {
operation.tag(tagString);
}
}
for (SecurityRequirement security : securities) {
operation.security(security);
}
}
private boolean isApiParamHidden(List parameterAnnotations) {
for (Annotation parameterAnnotation : parameterAnnotations) {
if (parameterAnnotation instanceof ApiParam) {
return ((ApiParam) parameterAnnotation).hidden();
}
}
return false;
}
private boolean hasValidAnnotations(List parameterAnnotations) {
// Because method parameters can contain parameters that are valid, but
// not part of the API contract, first check to make sure the parameter
// has at lease one annotation before processing it. Also, check a
// whitelist to make sure that the annotation of the parameter is
// compatible with spring-maven-plugin
List validParameterAnnotations = new ArrayList();
validParameterAnnotations.add(ModelAttribute.class);
validParameterAnnotations.add(BeanParam.class);
validParameterAnnotations.add(InjectParam.class);
validParameterAnnotations.add(ApiParam.class);
validParameterAnnotations.add(PathParam.class);
validParameterAnnotations.add(QueryParam.class);
validParameterAnnotations.add(HeaderParam.class);
validParameterAnnotations.add(FormParam.class);
validParameterAnnotations.add(RequestParam.class);
validParameterAnnotations.add(RequestBody.class);
validParameterAnnotations.add(PathVariable.class);
validParameterAnnotations.add(RequestHeader.class);
validParameterAnnotations.add(RequestPart.class);
boolean hasValidAnnotation = false;
for (Annotation potentialAnnotation : parameterAnnotations) {
if (validParameterAnnotations.contains(potentialAnnotation.annotationType())) {
hasValidAnnotation = true;
break;
}
}
return hasValidAnnotation;
}
protected List getParameters(Type type, List annotations) {
if (!hasValidAnnotations(annotations) || isApiParamHidden(annotations)) {
return Collections.emptyList();
}
Iterator chain = SwaggerExtensions.chain();
List parameters = new ArrayList();
Class> cls = TypeUtils.getRawType(type, type);
LOG.debug("Looking for path/query/header/form/cookie params in " + cls);
if (chain.hasNext()) {
SwaggerExtension extension = chain.next();
LOG.debug("trying extension " + extension);
parameters = extension.extractParameters(annotations, type, typesToSkip, chain);
}
if (!parameters.isEmpty()) {
for (Parameter parameter : parameters) {
ParameterProcessor.applyAnnotations(swagger, parameter, type, annotations);
}
} else {
LOG.debug("Looking for body params in " + cls);
if (!typesToSkip.contains(type)) {
Parameter param = ParameterProcessor.applyAnnotations(swagger, null, type, annotations);
if (param != null) {
parameters.add(param);
}
}
}
return parameters;
}
protected void updateApiResponse(Operation operation, ApiResponses responseAnnotation) {
for (ApiResponse apiResponse : responseAnnotation.value()) {
Map responseHeaders = parseResponseHeaders(apiResponse.responseHeaders());
Class> responseClass = apiResponse.response();
Response response = new Response()
.description(apiResponse.message())
.headers(responseHeaders);
if (responseClass.equals(Void.class)) {
if (operation.getResponses() != null) {
Response apiOperationResponse = operation.getResponses().get(String.valueOf(apiResponse.code()));
if (apiOperationResponse != null) {
response.setSchema(apiOperationResponse.getSchema());
}
}
} else {
Map models = ModelConverters.getInstance().read(responseClass);
for (String key : models.keySet()) {
final Property schema = new RefProperty().asDefault(key);
if (apiResponse.responseContainer().equals("List")) {
response.schema(new ArrayProperty(schema));
} else {
response.schema(schema);
}
swagger.model(key, models.get(key));
}
models = ModelConverters.getInstance().readAll(responseClass);
for (Map.Entry entry : models.entrySet()) {
swagger.model(entry.getKey(), entry.getValue());
}
if (response.getSchema() == null) {
Map responses = operation.getResponses();
if (responses != null) {
Response apiOperationResponse = responses.get(String.valueOf(apiResponse.code()));
if (apiOperationResponse != null) {
response.setSchema(apiOperationResponse.getSchema());
}
}
}
}
if (apiResponse.code() == 0) {
operation.defaultResponse(response);
} else {
operation.response(apiResponse.code(), response);
}
}
}
protected String[] updateOperationProduces(String[] parentProduces, String[] apiProduces, Operation operation) {
if (parentProduces != null) {
Set both = new LinkedHashSet(Arrays.asList(apiProduces));
both.addAll(Arrays.asList(parentProduces));
if (operation.getProduces() != null) {
both.addAll(operation.getProduces());
}
apiProduces = both.toArray(new String[both.size()]);
}
return apiProduces;
}
protected String[] updateOperationConsumes(String[] parentConsumes, String[] apiConsumes, Operation operation) {
if (parentConsumes != null) {
Set both = new LinkedHashSet(Arrays.asList(apiConsumes));
both.addAll(Arrays.asList(parentConsumes));
if (operation.getConsumes() != null) {
both.addAll(operation.getConsumes());
}
apiConsumes = both.toArray(new String[both.size()]);
}
return apiConsumes;
}
protected void readImplicitParameters(Method method, Operation operation) {
ApiImplicitParams implicitParams = AnnotationUtils.findAnnotation(method, ApiImplicitParams.class);
if (implicitParams == null) {
return;
}
for (ApiImplicitParam param : implicitParams.value()) {
Class> cls;
try {
cls = Class.forName(param.dataType());
} catch (ClassNotFoundException e) {
cls = method.getDeclaringClass();
}
Parameter p = readImplicitParam(param, cls);
if (p != null) {
operation.addParameter(p);
}
}
}
protected Parameter readImplicitParam(ApiImplicitParam param, Class> apiClass) {
Parameter parameter;
if (param.paramType().equalsIgnoreCase("path")) {
parameter = new PathParameter();
} else if (param.paramType().equalsIgnoreCase("query")) {
parameter = new QueryParameter();
} else if (param.paramType().equalsIgnoreCase("form") || param.paramType().equalsIgnoreCase("formData")) {
parameter = new FormParameter();
} else if (param.paramType().equalsIgnoreCase("body")) {
parameter = new BodyParameter();
} else if (param.paramType().equalsIgnoreCase("header")) {
parameter = new HeaderParameter();
} else {
return null;
}
return ParameterProcessor.applyAnnotations(swagger, parameter, apiClass, Arrays.asList(new Annotation[]{param}));
}
void processOperationDecorator(Operation operation, Method method) {
final Iterator chain = SwaggerExtensions.chain();
if (chain.hasNext()) {
SwaggerExtension extension = chain.next();
extension.decorateOperation(operation, method, chain);
}
}
}