package com.ajah.swagger.out; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.TreeMap; import lombok.extern.java.Log; import com.ajah.http.HttpMethod; import com.ajah.swagger.api.SwaggerApi; import com.ajah.swagger.api.SwaggerDefinition; import com.ajah.swagger.api.SwaggerOperation; import com.ajah.swagger.api.SwaggerParameter; import com.ajah.swagger.api.SwaggerParameterType; import com.ajah.swagger.api.SwaggerProperty; import com.ajah.swagger.api.SwaggerPropertyType; import com.ajah.swagger.api.SwaggerResponse; import com.ajah.swagger.api.SwaggerResponseType; import com.ajah.util.CollectionUtils; import com.ajah.util.StringUtils; @Log public class SwaggerWriter { public SwaggerOut write(SwaggerApi api, List<SwaggerOperation> operations, List<SwaggerDefinition> definitions) { SwaggerOut out = new SwaggerOut(); out.swagger = "2.0"; out.basePath = api.getBasePath(); out.host = api.getHost(); out.info = new SwaggerInfoOut(); out.info.description = api.getDescription(); out.info.title = api.getName(); out.info.version = api.getVersion(); if (api.isHttp()) { if (api.isHttps()) { out.schemes = new String[] { "http", "https" }; } else { out.schemes = new String[] { "http" }; } } else { if (api.isHttps()) { out.schemes = new String[] { "https" }; } else { out.schemes = null; } } if (api.isJson()) { if (api.isXml()) { out.produces = new String[] { "application/xml", "application/json" }; } else { out.produces = new String[] { "application/json" }; } } else { if (api.isXml()) { out.produces = new String[] { "application/xml" }; } else { out.produces = null; } } out.paths = new TreeMap<String, SwaggerPathOut>(); for (SwaggerOperation operation : operations) { SwaggerPathOut path = out.paths.get(operation.getPath()); if (path == null) { path = new SwaggerPathOut(); out.paths.put(operation.getPath(), path); } if (operation.getMethod() == HttpMethod.POST) { path.post = createPath(operation); } else if (operation.getMethod() == HttpMethod.GET) { path.get = createPath(operation); } } out.definitions = new TreeMap<String, SwaggerDefinitionOut>(); for (SwaggerDefinition definition : definitions) { if (CollectionUtils.isEmpty(definition.getSwaggerProperties())) { log.warning("No properties defined for " + definition.getName()); } out.definitions.put(definition.getName(), getDefOut(definition)); } return out; } private SwaggerDefinitionOut getDefOut(SwaggerDefinition definition) { SwaggerDefinitionOut out = new SwaggerDefinitionOut(); for (SwaggerProperty property : definition.getSwaggerProperties()) { if (out.properties == null) { out.properties = new TreeMap<>(); } out.properties.put(property.getName(), getPropertyOut(property)); } if (!CollectionUtils.isEmpty(definition.getSwaggerProperties())) { for (SwaggerProperty property : definition.getSwaggerProperties()) { if (property.isRequired()) { if (out.required == null) { out.required = new ArrayList<>(); } out.required.add(property.getName()); } } } return out; } private SwaggerPropertyOut getPropertyOut(SwaggerProperty property) { SwaggerPropertyOut out = new SwaggerPropertyOut(); if (property.getType() == SwaggerPropertyType.DEFINITION) { out.ref = "#/definitions/" + property.getSwaggerDefinition().getName(); } else if (property.getType() == SwaggerPropertyType.DOUBLE) { out.type = "number"; out.format = "double"; } else if (property.getType() == SwaggerPropertyType.DATE_TIME) { out.type = "string"; out.format = "date-time"; } else if (property.getType() == SwaggerPropertyType.DATE) { out.type = "string"; out.format = "date"; } else if (property.getType() == SwaggerPropertyType.INTEGER) { out.type = "integer"; out.format = "int32"; } else if (property.getType() == SwaggerPropertyType.LONG) { out.type = "integer"; out.format = "int64"; } else if (property.getType() == SwaggerPropertyType.FLOAT) { out.type = "number"; out.format = "float"; } else if (property.getType() == SwaggerPropertyType.LIST) { out.type = "array"; out.items = new SwaggerItemsOut(); out.items.ref = "#/definitions/" + property.getSwaggerDefinition().getName(); } else if (property.getType() == SwaggerPropertyType.SET) { out.type = "array"; out.uniqueItems = true; out.items = new SwaggerItemsOut(); out.items.ref = "#/definitions/" + property.getSwaggerDefinition().getName(); } else { out.type = property.getType().getCode(); } out.description = property.getDescription(); if (!StringUtils.isBlank(property.getFormat())) { out.format = property.getFormat(); } return out; } private SwaggerPathMethodOut createPath(SwaggerOperation operation) { if (CollectionUtils.isEmpty(operation.getResponses())) { log.warning("No responses configured for " + operation.getName()); // return null; } SwaggerPathMethodOut path = new SwaggerPathMethodOut(); path.description = operation.getDescription(); path.consumes = new String[] { operation.getConsumes() }; path.produces = operation.getProduces() == null ? null : new String[] { operation.getProduces() }; path.operationId = operation.getOperationId(); path.summary = operation.getSummary(); path.tags = operation.getTagArray(); path.responses = new HashMap<>(); for (SwaggerResponse response : operation.getResponses()) { path.responses.put(response.getCode(), getResponseOut(response)); } if (!CollectionUtils.isEmpty(operation.getParameters())) { path.parameters = new ArrayList<>(); for (SwaggerParameter parameter : operation.getParameters()) { path.parameters.add(getParameterOut(parameter)); } } return path; } private SwaggerParameterOut getParameterOut(SwaggerParameter parameter) { SwaggerParameterOut out = new SwaggerParameterOut(); out.description = parameter.getDescription(); out.in = parameter.getIn(); out.name = parameter.getName(); out.required = parameter.isRequired(); if (parameter.getType() == SwaggerParameterType.DEFINITION) { out.schema = new SwaggerSchemaOut(); if (parameter.getSwaggerDefinition() != null) { out.schema.ref = "#/definitions/" + parameter.getSwaggerDefinition().getName(); } } else { out.type = parameter.getType().getCode(); } return out; } private SwaggerResponseOut getResponseOut(SwaggerResponse response) { SwaggerResponseOut out = new SwaggerResponseOut(); out.description = response.getDescription(); out.schema = new SwaggerSchemaOut(); if (response.getType() == SwaggerResponseType.DEFINITION) { if (response.getSwaggerDefinition() != null) { out.schema.ref = "#/definitions/" + response.getSwaggerDefinition().getName(); } } else { out.schema.type = response.getType().getCode(); } return out; } }