Merge pull request #58 from Kabhal/separatedBody
fixed #53 : support for tags, paths and methods ordering
This commit is contained in:
@@ -36,6 +36,9 @@ tasks.withType(JavaCompile) {
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://oss.jfrog.org/artifactory/oss-snapshot-local"
|
||||
}
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
@@ -55,7 +58,7 @@ dependencies {
|
||||
|
||||
dependencyManagement {
|
||||
dependencies {
|
||||
dependency "io.github.robwin:markup-document-builder:0.1.5"
|
||||
dependency "io.github.robwin:markup-document-builder:0.1.6-SNAPSHOT"
|
||||
dependency "io.swagger:swagger-compat-spec-parser:1.0.16"
|
||||
dependency "commons-collections:commons-collections:3.2.1"
|
||||
dependency "commons-io:commons-io:2.4"
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
@Deprecated
|
||||
public enum OrderBy {
|
||||
AS_IS,
|
||||
NATURAL
|
||||
|
||||
@@ -18,12 +18,14 @@
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.builder.document.DefinitionsDocument;
|
||||
import io.github.robwin.swagger2markup.builder.document.OverviewDocument;
|
||||
import io.github.robwin.swagger2markup.builder.document.PathsDocument;
|
||||
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
|
||||
import io.github.robwin.swagger2markup.utils.Consumer;
|
||||
import io.swagger.models.HttpMethod;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
@@ -32,6 +34,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
@@ -44,6 +47,11 @@ public class Swagger2MarkupConverter {
|
||||
private static final String PATHS_DOCUMENT = "paths";
|
||||
private static final String DEFINITIONS_DOCUMENT = "definitions";
|
||||
|
||||
private static final Comparator<String> DEFAULT_TAG_ORDERING = Ordering.natural();
|
||||
private static final Comparator<String> DEFAULT_PATH_ORDERING = Ordering.natural();
|
||||
private static final Comparator<HttpMethod> DEFAULT_PATH_METHOD_ORDERING = Ordering.explicit(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS);
|
||||
private static final Comparator<String> DEFAULT_DEFINITION_ORDERING = Ordering.natural();
|
||||
|
||||
/**
|
||||
* @param swagger2MarkupConfig the configuration
|
||||
*/
|
||||
@@ -147,6 +155,10 @@ public class Swagger2MarkupConverter {
|
||||
private MarkupLanguage markupLanguage = MarkupLanguage.ASCIIDOC;
|
||||
private Language outputLanguage = Language.EN;
|
||||
private int inlineSchemaDepthLevel = 0;
|
||||
private Comparator<String> tagOrdering = DEFAULT_TAG_ORDERING;
|
||||
private Comparator<String> pathOrdering = DEFAULT_PATH_ORDERING;
|
||||
private Comparator<HttpMethod> pathMethodOrdering = DEFAULT_PATH_METHOD_ORDERING;
|
||||
private Comparator<String> definitionOrdering = DEFAULT_DEFINITION_ORDERING;
|
||||
|
||||
/**
|
||||
* Creates a Builder using a given Swagger source.
|
||||
@@ -172,7 +184,7 @@ public class Swagger2MarkupConverter {
|
||||
public Swagger2MarkupConverter build(){
|
||||
return new Swagger2MarkupConverter(new Swagger2MarkupConfig(swagger, markupLanguage, examplesFolderPath,
|
||||
schemasFolderPath, descriptionsFolderPath, separatedDefinitions, separatedPaths, pathsGroupedBy, definitionsOrderedBy,
|
||||
outputLanguage, inlineSchemaDepthLevel));
|
||||
outputLanguage, inlineSchemaDepthLevel, tagOrdering, pathOrdering, pathMethodOrdering, definitionOrdering));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,8 +277,10 @@ public class Swagger2MarkupConverter {
|
||||
* @param definitionsOrderedBy the OrderBy enum
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder withDefinitionsOrderedBy(OrderBy definitionsOrderedBy) {
|
||||
this.definitionsOrderedBy = definitionsOrderedBy;
|
||||
this.definitionOrdering = Ordering.natural();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -291,6 +305,59 @@ public class Swagger2MarkupConverter {
|
||||
this.inlineSchemaDepthLevel = inlineSchemaDepthLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order tags.
|
||||
* By default, natural ordering is applied.
|
||||
* Set ordering to null to keep swagger original order
|
||||
*
|
||||
* @param tagOrdering
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withTagOrdering(Comparator<String> tagOrdering) {
|
||||
this.tagOrdering = tagOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order paths.
|
||||
* By default, natural ordering is applied.
|
||||
* Set ordering to null to keep swagger original order
|
||||
*
|
||||
* @param pathOrdering
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withPathOrdering(Comparator<String> pathOrdering) {
|
||||
this.pathOrdering = pathOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order paths methods.
|
||||
* By default, explicit ordering is applied : GET, PUT, POST, DELETE, PATCH, HEAD, OPTIONS
|
||||
* Set ordering to null to keep swagger original order
|
||||
*
|
||||
* @param pathMethodOrdering
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withPathMethodOrdering(Comparator<HttpMethod> pathMethodOrdering) {
|
||||
this.pathMethodOrdering = pathMethodOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order definitions.
|
||||
* By default, natural ordering is applied.
|
||||
* Set ordering to null to keep swagger original order
|
||||
*
|
||||
* @param definitionOrdering
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withDefinitionOrdering(Comparator<String> definitionOrdering) {
|
||||
this.definitionOrdering = definitionOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,9 @@ package io.github.robwin.swagger2markup.builder.document;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilders;
|
||||
import io.github.robwin.swagger2markup.OrderBy;
|
||||
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
|
||||
import io.github.robwin.swagger2markup.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.type.Type;
|
||||
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
|
||||
import io.swagger.models.ComposedModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.RefModel;
|
||||
@@ -66,8 +64,8 @@ public class DefinitionsDocument extends MarkupDocument {
|
||||
private String descriptionsFolderPath;
|
||||
private boolean separatedDefinitionsEnabled;
|
||||
private String outputDirectory;
|
||||
private final OrderBy definitionsOrderedBy;
|
||||
private final int inlineSchemaDepthLevel;
|
||||
private final Comparator<String> definitionOrdering;
|
||||
|
||||
public DefinitionsDocument(Swagger2MarkupConfig swagger2MarkupConfig, String outputDirectory){
|
||||
super(swagger2MarkupConfig);
|
||||
@@ -79,7 +77,6 @@ public class DefinitionsDocument extends MarkupDocument {
|
||||
XML_SCHEMA = labels.getString("xml_schema");
|
||||
|
||||
this.inlineSchemaDepthLevel = swagger2MarkupConfig.getInlineSchemaDepthLevel();
|
||||
this.definitionsOrderedBy = swagger2MarkupConfig.getDefinitionsOrderedBy();
|
||||
if(isNotBlank(swagger2MarkupConfig.getSchemasFolderPath())){
|
||||
this.schemasEnabled = true;
|
||||
this.schemasFolderPath = swagger2MarkupConfig.getSchemasFolderPath();
|
||||
@@ -118,6 +115,7 @@ public class DefinitionsDocument extends MarkupDocument {
|
||||
}
|
||||
}
|
||||
this.outputDirectory = outputDirectory;
|
||||
this.definitionOrdering = swagger2MarkupConfig.getDefinitionOrdering();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,11 +133,11 @@ public class DefinitionsDocument extends MarkupDocument {
|
||||
if(MapUtils.isNotEmpty(definitions)){
|
||||
this.markupDocBuilder.sectionTitleLevel1(DEFINITIONS);
|
||||
Set<String> definitionNames;
|
||||
if(definitionsOrderedBy.equals(OrderBy.AS_IS)){
|
||||
definitionNames = definitions.keySet();
|
||||
}else{
|
||||
definitionNames = new TreeSet<>(definitions.keySet());
|
||||
}
|
||||
if (definitionOrdering == null)
|
||||
definitionNames = new LinkedHashSet<>();
|
||||
else
|
||||
definitionNames = new TreeSet<>(definitionOrdering);
|
||||
definitionNames.addAll(definitions.keySet());
|
||||
for(String definitionName : definitionNames){
|
||||
Model model = definitions.get(definitionName);
|
||||
if(isNotBlank(definitionName)) {
|
||||
@@ -354,13 +352,24 @@ public class DefinitionsDocument extends MarkupDocument {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inline definitions should never been referenced in TOC, so they are just text.
|
||||
*/
|
||||
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
docBuilder.anchor(anchor, null);
|
||||
docBuilder.newLine();
|
||||
docBuilder.boldTextLine(title);
|
||||
}
|
||||
|
||||
|
||||
private void inlineDefinitions(List<Type> definitions, int depth, MarkupDocBuilder docBuilder) {
|
||||
if(CollectionUtils.isNotEmpty(definitions)){
|
||||
for (Type definition: definitions) {
|
||||
MarkupDocBuilderUtils.sectionTitleLevel(5, definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
List<Type> localDefinitions = typeProperties(definition, depth, new DefinitionPropertyDescriptor(definition), docBuilder);
|
||||
for (Type localDefinition : localDefinitions)
|
||||
inlineDefinitions(Arrays.asList(localDefinition), depth - 1, docBuilder);
|
||||
inlineDefinitions(Collections.singletonList(localDefinition), depth - 1, docBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ package io.github.robwin.swagger2markup.builder.document;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilders;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupTableColumn;
|
||||
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
|
||||
import io.github.robwin.swagger2markup.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.type.RefType;
|
||||
import io.github.robwin.swagger2markup.type.Type;
|
||||
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
|
||||
import io.github.robwin.swagger2markup.utils.PropertyUtils;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.properties.Property;
|
||||
@@ -117,39 +117,43 @@ public abstract class MarkupDocument {
|
||||
if (type instanceof ObjectType) {
|
||||
ObjectType objectType = (ObjectType) type;
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
List<String> header = Arrays.asList(NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN);
|
||||
cells.add(header);
|
||||
List<MarkupTableColumn> cols = Arrays.asList(
|
||||
new MarkupTableColumn(NAME_COLUMN, 1),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 6),
|
||||
new MarkupTableColumn(REQUIRED_COLUMN, 1),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1),
|
||||
new MarkupTableColumn(DEFAULT_COLUMN, 1));
|
||||
if (MapUtils.isNotEmpty(objectType.getProperties())) {
|
||||
for (Map.Entry<String, Property> propertyEntry : objectType.getProperties().entrySet()) {
|
||||
Property property = propertyEntry.getValue();
|
||||
String propertyName = propertyEntry.getKey();
|
||||
Type propertyType = PropertyUtils.getType(property);
|
||||
if (depth > 0 && propertyType instanceof ObjectType) {
|
||||
propertyType.setName(propertyName);
|
||||
propertyType.setUniqueName(uniqueTypeName(propertyName));
|
||||
localDefinitions.add(propertyType);
|
||||
if (MapUtils.isNotEmpty(((ObjectType) propertyType).getProperties())) {
|
||||
propertyType.setName(propertyName);
|
||||
propertyType.setUniqueName(uniqueTypeName(propertyName));
|
||||
localDefinitions.add(propertyType);
|
||||
|
||||
propertyType = new RefType(propertyType);
|
||||
propertyType = new RefType(propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> content = Arrays.asList(
|
||||
propertyName,
|
||||
propertyDescriptor.getDescription(property, propertyName),
|
||||
Boolean.toString(property.getRequired()),
|
||||
propertyType.displaySchema(markupLanguage),
|
||||
propertyType.displaySchema(docBuilder),
|
||||
PropertyUtils.getDefaultValue(property));
|
||||
cells.add(content);
|
||||
}
|
||||
MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 6, 1, 1, 1), cells, docBuilder);
|
||||
docBuilder.tableWithColumnSpecs(cols, cells);
|
||||
}
|
||||
else {
|
||||
docBuilder.textLine(NO_CONTENT);
|
||||
docBuilder.newLine();
|
||||
}
|
||||
}
|
||||
else {
|
||||
docBuilder.textLine(NO_CONTENT);
|
||||
docBuilder.newLine();
|
||||
}
|
||||
|
||||
return localDefinitions;
|
||||
|
||||
@@ -87,12 +87,10 @@ public class OverviewDocument extends MarkupDocument {
|
||||
this.markupDocBuilder.sectionTitleLevel1(OVERVIEW);
|
||||
if(isNotBlank(info.getDescription())){
|
||||
this.markupDocBuilder.textLine(info.getDescription());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
if(isNotBlank(info.getVersion())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CURRENT_VERSION);
|
||||
this.markupDocBuilder.textLine(VERSION + info.getVersion());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
Contact contact = info.getContact();
|
||||
if(contact != null){
|
||||
@@ -103,7 +101,6 @@ public class OverviewDocument extends MarkupDocument {
|
||||
if(isNotBlank(contact.getEmail())){
|
||||
this.markupDocBuilder.textLine(CONTACT_EMAIL + contact.getEmail());
|
||||
}
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
License license = info.getLicense();
|
||||
@@ -115,11 +112,9 @@ public class OverviewDocument extends MarkupDocument {
|
||||
if (isNotBlank(license.getUrl())) {
|
||||
this.markupDocBuilder.textLine(LICENSE_URL + license.getUrl());
|
||||
}
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
if(isNotBlank(info.getTermsOfService())){
|
||||
this.markupDocBuilder.textLine(TERMS_OF_SERVICE + info.getTermsOfService());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
if(isNotBlank(swagger.getHost()) || isNotBlank(swagger.getBasePath()) || isNotEmpty(swagger.getSchemes())) {
|
||||
@@ -137,7 +132,6 @@ public class OverviewDocument extends MarkupDocument {
|
||||
}
|
||||
this.markupDocBuilder.textLine(SCHEMES + join(schemes, ", "));
|
||||
}
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
if(isNotEmpty(swagger.getTags())){
|
||||
@@ -153,19 +147,16 @@ public class OverviewDocument extends MarkupDocument {
|
||||
}
|
||||
}
|
||||
this.markupDocBuilder.unorderedList(tags);
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
if(isNotEmpty(swagger.getConsumes())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CONSUMES);
|
||||
this.markupDocBuilder.unorderedList(swagger.getConsumes());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
if(isNotEmpty(swagger.getProduces())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(PRODUCES);
|
||||
this.markupDocBuilder.unorderedList(swagger.getProduces());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,13 +22,14 @@ import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Multimap;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilders;
|
||||
import io.github.robwin.markup.builder.MarkupTableColumn;
|
||||
import io.github.robwin.swagger2markup.GroupBy;
|
||||
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
|
||||
import io.github.robwin.swagger2markup.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.type.RefType;
|
||||
import io.github.robwin.swagger2markup.type.Type;
|
||||
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
|
||||
import io.github.robwin.swagger2markup.utils.ParameterUtils;
|
||||
import io.github.robwin.swagger2markup.utils.PathUtils;
|
||||
import io.github.robwin.swagger2markup.utils.PropertyUtils;
|
||||
import io.swagger.models.*;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
@@ -81,6 +82,9 @@ public class PathsDocument extends MarkupDocument {
|
||||
private String descriptionsFolderPath;
|
||||
private final GroupBy pathsGroupedBy;
|
||||
private final int inlineSchemaDepthLevel;
|
||||
private final Comparator<String> tagOrdering;
|
||||
private final Comparator<String> pathOrdering;
|
||||
private final Comparator<HttpMethod> pathMethodOrdering;
|
||||
private boolean separatedPathsEnabled;
|
||||
private String outputDirectory;
|
||||
|
||||
@@ -143,6 +147,9 @@ public class PathsDocument extends MarkupDocument {
|
||||
}
|
||||
}
|
||||
this.outputDirectory = outputDirectory;
|
||||
tagOrdering = swagger2MarkupConfig.getTagOrdering();
|
||||
pathOrdering = swagger2MarkupConfig.getPathOrdering();
|
||||
pathMethodOrdering = swagger2MarkupConfig.getPathMethodOrdering();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,17 +169,24 @@ public class PathsDocument extends MarkupDocument {
|
||||
private void paths(){
|
||||
Map<String, Path> paths = swagger.getPaths();
|
||||
if(MapUtils.isNotEmpty(paths)) {
|
||||
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
|
||||
if(pathsGroupedBy == GroupBy.AS_IS){
|
||||
this.markupDocBuilder.sectionTitleLevel1(PATHS);
|
||||
for (Map.Entry<String, Path> pathEntry : paths.entrySet()) {
|
||||
Path path = pathEntry.getValue();
|
||||
if(path != null) {
|
||||
createPathSections(pathEntry.getKey(), path);
|
||||
}
|
||||
|
||||
Set<Pair<String, Path>> sortedPaths;
|
||||
if (this.pathOrdering == null)
|
||||
sortedPaths = new LinkedHashSet<>();
|
||||
else
|
||||
sortedPaths = new TreeSet<>(new PathUtils.PathPairComparator(this.pathOrdering));
|
||||
for (Map.Entry<String, Path> e : paths.entrySet()) {
|
||||
sortedPaths.add(Pair.of(e.getKey(), e.getValue()));
|
||||
}
|
||||
}else{
|
||||
|
||||
for (Pair<String, Path> pathEntry : sortedPaths) {
|
||||
createPathSections(pathEntry.getKey(), pathEntry.getValue());
|
||||
}
|
||||
} else {
|
||||
this.markupDocBuilder.sectionTitleLevel1(RESOURCES);
|
||||
Multimap<String, Pair<String, Path>> pathsGroupedByTag = groupPathsByTag(paths);
|
||||
Multimap<String, Pair<String, Path>> pathsGroupedByTag = groupPathsByTag(paths, tagOrdering, pathOrdering);
|
||||
Map<String, Tag> tagsMap = convertTagsListToMap(swagger.getTags());
|
||||
for(String tagName : pathsGroupedByTag.keySet()){
|
||||
this.markupDocBuilder.sectionTitleLevel2(WordUtils.capitalize(tagName));
|
||||
@@ -193,7 +207,15 @@ public class PathsDocument extends MarkupDocument {
|
||||
}
|
||||
|
||||
private void createPathSections(String pathUrl, Path path){
|
||||
for(Map.Entry<HttpMethod, Operation> operationEntry : path.getOperationMap().entrySet()){
|
||||
|
||||
Map<HttpMethod, Operation> operationsMap;
|
||||
if (pathMethodOrdering == null)
|
||||
operationsMap = new LinkedHashMap<>();
|
||||
else
|
||||
operationsMap = new TreeMap<>(pathMethodOrdering);
|
||||
operationsMap.putAll(path.getOperationMap());
|
||||
|
||||
for(Map.Entry<HttpMethod, Operation> operationEntry : operationsMap.entrySet()){
|
||||
String methodAndPath = operationEntry.getKey() + " " + pathUrl;
|
||||
processPath(methodAndPath, operationEntry.getValue());
|
||||
}
|
||||
@@ -270,7 +292,7 @@ public class PathsDocument extends MarkupDocument {
|
||||
* @param title the path title
|
||||
*/
|
||||
private void addPathTitle(String title, MarkupDocBuilder docBuilder) {
|
||||
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
|
||||
if(pathsGroupedBy == GroupBy.AS_IS){
|
||||
docBuilder.sectionTitleLevel2(title);
|
||||
}else{
|
||||
docBuilder.sectionTitleLevel3(title);
|
||||
@@ -283,7 +305,7 @@ public class PathsDocument extends MarkupDocument {
|
||||
* @param title the path title
|
||||
*/
|
||||
private void addPathSectionTitle(String title, MarkupDocBuilder docBuilder) {
|
||||
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
|
||||
if(pathsGroupedBy == GroupBy.AS_IS){
|
||||
docBuilder.sectionTitleLevel3(title);
|
||||
}else{
|
||||
docBuilder.sectionTitleLevel4(title);
|
||||
@@ -332,18 +354,24 @@ public class PathsDocument extends MarkupDocument {
|
||||
List<Type> localDefinitions = new ArrayList<>();
|
||||
if(CollectionUtils.isNotEmpty(parameters)){
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
// Table header row
|
||||
List<String> header = Arrays.asList(TYPE_COLUMN, NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN);
|
||||
cells.add(header);
|
||||
List<MarkupTableColumn> cols = Arrays.asList(
|
||||
new MarkupTableColumn(TYPE_COLUMN, 1),
|
||||
new MarkupTableColumn(NAME_COLUMN, 1),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 6),
|
||||
new MarkupTableColumn(REQUIRED_COLUMN, 1),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1),
|
||||
new MarkupTableColumn(DEFAULT_COLUMN, 1));
|
||||
for(Parameter parameter : parameters){
|
||||
Type type = ParameterUtils.getType(parameter);
|
||||
if (inlineSchemaDepthLevel > 0 && type instanceof ObjectType) {
|
||||
String localTypeName = parameter.getName();
|
||||
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
|
||||
String localTypeName = parameter.getName();
|
||||
|
||||
type.setName(localTypeName);
|
||||
type.setUniqueName(uniqueTypeName(localTypeName));
|
||||
localDefinitions.add(type);
|
||||
type = new RefType(type);
|
||||
type.setName(localTypeName);
|
||||
type.setUniqueName(uniqueTypeName(localTypeName));
|
||||
localDefinitions.add(type);
|
||||
type = new RefType(type);
|
||||
}
|
||||
}
|
||||
String parameterType = WordUtils.capitalize(parameter.getIn() + PARAMETER);
|
||||
// Table content row
|
||||
@@ -352,12 +380,12 @@ public class PathsDocument extends MarkupDocument {
|
||||
parameter.getName(),
|
||||
parameterDescription(operation, parameter, docBuilder),
|
||||
Boolean.toString(parameter.getRequired()),
|
||||
type.displaySchema(markupLanguage),
|
||||
type.displaySchema(markupDocBuilder),
|
||||
ParameterUtils.getDefaultValue(parameter));
|
||||
cells.add(content);
|
||||
}
|
||||
addPathSectionTitle(PARAMETERS, docBuilder);
|
||||
MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 1, 6, 1, 1, 1), cells, docBuilder);
|
||||
docBuilder.tableWithColumnSpecs(cols, cells);
|
||||
}
|
||||
|
||||
return localDefinitions;
|
||||
@@ -417,11 +445,17 @@ public class PathsDocument extends MarkupDocument {
|
||||
}
|
||||
|
||||
private void tagsSection(Operation operation, MarkupDocBuilder docBuilder) {
|
||||
if(pathsGroupedBy.equals(GroupBy.AS_IS)) {
|
||||
if(pathsGroupedBy == GroupBy.AS_IS) {
|
||||
List<String> tags = operation.getTags();
|
||||
if (CollectionUtils.isNotEmpty(tags)) {
|
||||
addPathSectionTitle(TAGS, docBuilder);
|
||||
docBuilder.unorderedList(tags);
|
||||
Set<String> sortedTags;
|
||||
if (tagOrdering == null)
|
||||
sortedTags = new LinkedHashSet<>();
|
||||
else
|
||||
sortedTags = new TreeSet<>(this.tagOrdering);
|
||||
sortedTags.addAll(tags);
|
||||
this.markupDocBuilder.unorderedList(new ArrayList<>(sortedTags));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,40 +567,50 @@ public class PathsDocument extends MarkupDocument {
|
||||
List<Type> localDefinitions = new ArrayList<>();
|
||||
if(MapUtils.isNotEmpty(responses)){
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
cells.add(Arrays.asList(HTTP_CODE_COLUMN, DESCRIPTION_COLUMN, SCHEMA_COLUMN));
|
||||
List<MarkupTableColumn> cols = Arrays.asList(
|
||||
new MarkupTableColumn(HTTP_CODE_COLUMN, 1),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 6),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1));
|
||||
for(Map.Entry<String, Response> entry : responses.entrySet()){
|
||||
Response response = entry.getValue();
|
||||
if(response.getSchema() != null){
|
||||
Property property = response.getSchema();
|
||||
Type type = PropertyUtils.getType(property);
|
||||
if (this.inlineSchemaDepthLevel > 0 && type instanceof ObjectType) {
|
||||
String localTypeName = RESPONSE + " " + entry.getKey();
|
||||
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
|
||||
String localTypeName = RESPONSE + " " + entry.getKey();
|
||||
|
||||
type.setName(localTypeName);
|
||||
type.setUniqueName(uniqueTypeName(localTypeName));
|
||||
localDefinitions.add(type);
|
||||
type = new RefType(type);
|
||||
type.setName(localTypeName);
|
||||
type.setUniqueName(uniqueTypeName(localTypeName));
|
||||
localDefinitions.add(type);
|
||||
type = new RefType(type);
|
||||
}
|
||||
}
|
||||
cells.add(Arrays.asList(entry.getKey(), response.getDescription(), type.displaySchema(markupLanguage)));
|
||||
cells.add(Arrays.asList(entry.getKey(), response.getDescription(), type.displaySchema(markupDocBuilder)));
|
||||
}else{
|
||||
cells.add(Arrays.asList(entry.getKey(), response.getDescription(), NO_CONTENT));
|
||||
}
|
||||
}
|
||||
addPathSectionTitle(RESPONSES, docBuilder);
|
||||
MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 6, 1), cells, docBuilder);
|
||||
docBuilder.tableWithColumnSpecs(cols, cells);
|
||||
}
|
||||
return localDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline definitions should never been referenced in TOC, so they are just text.
|
||||
*/
|
||||
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
docBuilder.anchor(anchor, null);
|
||||
docBuilder.newLine();
|
||||
docBuilder.boldTextLine(title);
|
||||
}
|
||||
|
||||
private void inlineDefinitions(List<Type> definitions, int depth, MarkupDocBuilder docBuilder) {
|
||||
if(CollectionUtils.isNotEmpty(definitions)){
|
||||
for (Type definition: definitions) {
|
||||
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
|
||||
MarkupDocBuilderUtils.sectionTitleLevel(4, definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
}else{
|
||||
MarkupDocBuilderUtils.sectionTitleLevel(5, definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
}
|
||||
List<Type> localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), docBuilder);
|
||||
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
List<Type> localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), this.markupDocBuilder);
|
||||
for (Type localDefinition : localDefinitions)
|
||||
inlineDefinitions(Collections.singletonList(localDefinition), depth - 1, docBuilder);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,11 @@ import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.GroupBy;
|
||||
import io.github.robwin.swagger2markup.Language;
|
||||
import io.github.robwin.swagger2markup.OrderBy;
|
||||
import io.swagger.models.HttpMethod;
|
||||
import io.swagger.models.Swagger;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class Swagger2MarkupConfig {
|
||||
|
||||
private final Swagger swagger;
|
||||
@@ -34,9 +37,14 @@ public class Swagger2MarkupConfig {
|
||||
private final boolean separatedDefinitions;
|
||||
private final boolean separatedPaths;
|
||||
private final GroupBy pathsGroupedBy;
|
||||
@Deprecated
|
||||
private final OrderBy definitionsOrderedBy;
|
||||
private final Language outputLanguage;
|
||||
private final int inlineSchemaDepthLevel;
|
||||
private final Comparator<String> tagOrdering;
|
||||
private final Comparator<String> pathOrdering;
|
||||
private final Comparator<HttpMethod> pathMethodOrdering;
|
||||
private final Comparator<String> definitionOrdering;
|
||||
|
||||
/**
|
||||
* @param swagger the Swagger source
|
||||
@@ -50,11 +58,16 @@ public class Swagger2MarkupConfig {
|
||||
* @param definitionsOrderedBy specifies if the definitions should be ordered by natural ordering or stay as-is
|
||||
* @param outputLanguage specifies language of labels in output files
|
||||
* @param inlineSchemaDepthLevel specifies the max depth for inline object schema display (0 = no inline schemas)
|
||||
* @param tagOrdering specifies a custom comparator function to order tags (null = as-is ordering)
|
||||
* @param pathOrdering specifies a custom comparator function to order paths (null = as-is ordering)
|
||||
* @param pathMethodOrdering specifies a custom comparator function to order paths methods (null = as-is ordering)
|
||||
* @param definitionOrdering specifies a custom comparator function to order definitions (null = as-is ordering)
|
||||
*/
|
||||
public Swagger2MarkupConfig(Swagger swagger, MarkupLanguage markupLanguage, String examplesFolderPath,
|
||||
String schemasFolderPath, String descriptionsFolderPath, boolean separatedDefinitions, boolean separatedPaths,
|
||||
GroupBy pathsGroupedBy, OrderBy definitionsOrderedBy, Language outputLanguage,
|
||||
int inlineSchemaDepthLevel) {
|
||||
int inlineSchemaDepthLevel, Comparator<String> tagOrdering, Comparator<String> pathOrdering,
|
||||
Comparator<HttpMethod> pathMethodOrdering, Comparator<String> definitionOrdering) {
|
||||
this.swagger = swagger;
|
||||
this.markupLanguage = markupLanguage;
|
||||
this.examplesFolderPath = examplesFolderPath;
|
||||
@@ -66,6 +79,10 @@ public class Swagger2MarkupConfig {
|
||||
this.definitionsOrderedBy = definitionsOrderedBy;
|
||||
this.outputLanguage = outputLanguage;
|
||||
this.inlineSchemaDepthLevel = inlineSchemaDepthLevel;
|
||||
this.tagOrdering = tagOrdering;
|
||||
this.pathOrdering = pathOrdering;
|
||||
this.pathMethodOrdering = pathMethodOrdering;
|
||||
this.definitionOrdering = definitionOrdering;
|
||||
}
|
||||
|
||||
public Swagger getSwagger() {
|
||||
@@ -111,4 +128,20 @@ public class Swagger2MarkupConfig {
|
||||
public int getInlineSchemaDepthLevel() {
|
||||
return inlineSchemaDepthLevel;
|
||||
}
|
||||
|
||||
public Comparator<String> getTagOrdering() {
|
||||
return tagOrdering;
|
||||
}
|
||||
|
||||
public Comparator<String> getPathOrdering() {
|
||||
return pathOrdering;
|
||||
}
|
||||
|
||||
public Comparator<HttpMethod> getPathMethodOrdering() {
|
||||
return pathMethodOrdering;
|
||||
}
|
||||
|
||||
public Comparator<String> getDefinitionOrdering() {
|
||||
return definitionOrdering;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.robwin.swagger2markup.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
public class ArrayType extends Type {
|
||||
|
||||
@@ -18,10 +18,10 @@ public class ArrayType extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupLanguage language) {
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
String collectionFormat = "";
|
||||
if (this.collectionFormat != null)
|
||||
collectionFormat = this.collectionFormat + " ";
|
||||
return collectionFormat + ofType.displaySchema(language) + " array";
|
||||
return collectionFormat + ofType.displaySchema(docBuilder) + " array";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.robwin.swagger2markup.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@@ -18,7 +18,7 @@ public class BasicType extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupLanguage language) {
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
if (isNotBlank(this.format))
|
||||
return this.name + "(" + this.format + ")";
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.robwin.swagger2markup.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -16,7 +16,7 @@ public class EnumType extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupLanguage language) {
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
return "enum" + " (" + join(values, ", ") + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package io.github.robwin.swagger2markup.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.swagger.models.properties.Property;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -15,8 +16,11 @@ public class ObjectType extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupLanguage language) {
|
||||
return "object";
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
if (MapUtils.isEmpty(properties))
|
||||
return "empty object";
|
||||
else
|
||||
return "object";
|
||||
}
|
||||
|
||||
public Map<String, Property> getProperties() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.github.robwin.swagger2markup.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
public class RefType extends Type {
|
||||
|
||||
@@ -14,7 +13,7 @@ public class RefType extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupLanguage language) {
|
||||
return MarkupDocBuilderUtils.crossReference(getName(), getUniqueName(), language);
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
return docBuilder.crossReferenceAsString(getUniqueName(), getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.robwin.swagger2markup.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public abstract class Type {
|
||||
@@ -35,5 +35,5 @@ public abstract class Type {
|
||||
this.uniqueName = uniqueName;
|
||||
}
|
||||
|
||||
public abstract String displaySchema(MarkupLanguage language);
|
||||
public abstract String displaySchema(MarkupDocBuilder docBuilder);
|
||||
}
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
package io.github.robwin.swagger2markup.utils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.asciidoc.AsciiDoc;
|
||||
import io.github.robwin.markup.builder.asciidoc.AsciiDocBuilder;
|
||||
import io.github.robwin.markup.builder.markdown.Markdown;
|
||||
import io.github.robwin.markup.builder.markdown.MarkdownBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.join;
|
||||
|
||||
/*
|
||||
* FIXME : this code should go to markup-document-builder project
|
||||
*/
|
||||
public class MarkupDocBuilderUtils {
|
||||
|
||||
public static String normalizeAsciiDocAnchor(String anchor) {
|
||||
return anchor.replaceAll("[^0-9a-zA-Z]", "_");
|
||||
}
|
||||
|
||||
public static void anchor(String text, MarkupDocBuilder docBuilder) {
|
||||
if (docBuilder instanceof AsciiDocBuilder) {
|
||||
docBuilder.textLine("[[" + normalizeAsciiDocAnchor(text) + "]]");
|
||||
}
|
||||
}
|
||||
|
||||
public static void crossReference(String text, String anchor, MarkupDocBuilder docBuilder) {
|
||||
if (docBuilder instanceof AsciiDocBuilder)
|
||||
docBuilder.textLine(crossReference(text, anchor, MarkupLanguage.ASCIIDOC));
|
||||
else if (docBuilder instanceof MarkdownBuilder)
|
||||
docBuilder.textLine(crossReference(text, anchor, MarkupLanguage.MARKDOWN));
|
||||
}
|
||||
|
||||
public static String crossReference(String text, String anchor, MarkupLanguage language) {
|
||||
if (language == MarkupLanguage.ASCIIDOC) {
|
||||
String normalizedAnchor = normalizeAsciiDocAnchor(anchor);
|
||||
if (text == null && !anchor.equals(normalizedAnchor))
|
||||
text = anchor;
|
||||
if (text == null)
|
||||
return AsciiDoc.CROSS_REFERENCE_START + normalizedAnchor + AsciiDoc.CROSS_REFERENCE_END;
|
||||
else
|
||||
return AsciiDoc.CROSS_REFERENCE_START + normalizedAnchor + "," + text + AsciiDoc.CROSS_REFERENCE_END;
|
||||
} else {
|
||||
if (text == null)
|
||||
return anchor;
|
||||
else
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sectionTitleLevel(int level, String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
if (anchor != null)
|
||||
MarkupDocBuilderUtils.anchor(anchor, docBuilder);
|
||||
|
||||
switch (level) {
|
||||
case 1:
|
||||
docBuilder.sectionTitleLevel1(title);
|
||||
break;
|
||||
case 2:
|
||||
docBuilder.sectionTitleLevel2(title);
|
||||
break;
|
||||
case 3:
|
||||
docBuilder.sectionTitleLevel3(title);
|
||||
break;
|
||||
case 4:
|
||||
docBuilder.sectionTitleLevel4(title);
|
||||
break;
|
||||
case 5:
|
||||
if (anchor == null)
|
||||
MarkupDocBuilderUtils.anchor(title, docBuilder);
|
||||
docBuilder.boldTextLine(title);
|
||||
break;
|
||||
case 6:
|
||||
if (anchor == null)
|
||||
MarkupDocBuilderUtils.anchor(title, docBuilder);
|
||||
docBuilder.textLine(title);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Illegal section level : " + level);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tableWithHeaderRow(List<Integer> columnWidthRatios, List<List<String>> cells, MarkupDocBuilder docBuilder) {
|
||||
if (docBuilder instanceof AsciiDocBuilder) {
|
||||
docBuilder.textLine("[options=\"header\",cols=\"" + join(columnWidthRatios, ",") + "\"]");
|
||||
docBuilder.textLine(AsciiDoc.TABLE.toString());
|
||||
|
||||
for (List<String> cols : cells) {
|
||||
String row = AsciiDoc.TABLE_COLUMN_DELIMITER + join(Collections2.transform(cols, new Function<String, String>() {
|
||||
public String apply(final String col) {
|
||||
return col.replace(AsciiDoc.TABLE_COLUMN_DELIMITER.toString(), "{vbar}");
|
||||
}
|
||||
}), AsciiDoc.TABLE_COLUMN_DELIMITER.toString());
|
||||
docBuilder.textLine(row);
|
||||
}
|
||||
docBuilder.textLine(AsciiDoc.TABLE.toString());
|
||||
} else if (docBuilder instanceof MarkdownBuilder) {
|
||||
List<String> rows = Lists.newArrayList(Collections2.transform(cells, new Function<List<String>, String>() {
|
||||
public String apply(List<String> cols) {
|
||||
return join(Collections2.transform(cols, new Function<String, String>() {
|
||||
public String apply(final String col) {
|
||||
return col.replace(Markdown.TABLE_COLUMN_DELIMITER.toString(), "|");
|
||||
}
|
||||
}), Markdown.TABLE_COLUMN_DELIMITER.toString());
|
||||
}
|
||||
}));
|
||||
|
||||
docBuilder.tableWithHeaderRow(rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.utils;
|
||||
|
||||
import io.swagger.models.Path;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class PathUtils {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(PathUtils.class);
|
||||
|
||||
public static class PathPairComparator implements Comparator<Pair<String, Path>> {
|
||||
|
||||
private Comparator<String> pathComparator;
|
||||
|
||||
public PathPairComparator(Comparator<String> pathComparator) {
|
||||
this.pathComparator = pathComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Pair<String, Path> o1, Pair<String, Path> o2) {
|
||||
return pathComparator.compare(o1.getKey(), o2.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,16 +18,16 @@
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.utils;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.type.*;
|
||||
import io.swagger.models.properties.*;
|
||||
import io.swagger.models.refs.RefFormat;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
public final class PropertyUtils {
|
||||
|
||||
@@ -42,7 +42,10 @@ public final class PropertyUtils {
|
||||
Type type;
|
||||
if(property instanceof RefProperty){
|
||||
RefProperty refProperty = (RefProperty)property;
|
||||
type = new RefType(refProperty.getSimpleRef());
|
||||
if (refProperty.getRefFormat() == RefFormat.RELATIVE)
|
||||
type = new ObjectType(null, null); // FIXME : Workaround for https://github.com/swagger-api/swagger-parser/issues/177
|
||||
else
|
||||
type = new RefType(refProperty.getSimpleRef());
|
||||
}else if(property instanceof ArrayProperty){
|
||||
ArrayProperty arrayProperty = (ArrayProperty)property;
|
||||
Property items = arrayProperty.getItems();
|
||||
|
||||
@@ -21,6 +21,7 @@ package io.github.robwin.swagger2markup.utils;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.swagger.models.HttpMethod;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.Path;
|
||||
@@ -30,10 +31,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class TagUtils {
|
||||
|
||||
@@ -77,8 +75,19 @@ public class TagUtils {
|
||||
* @param paths the Paths
|
||||
* @return Paths grouped by Tag
|
||||
*/
|
||||
public static Multimap<String, Pair<String, Path>> groupPathsByTag(Map<String, Path> paths) {
|
||||
Multimap<String, Pair<String, Path>> pathsGroupedByTag = MultimapBuilder.SortedSetMultimapBuilder.treeKeys().hashSetValues().build();
|
||||
public static Multimap<String, Pair<String, Path>> groupPathsByTag(Map<String, Path> paths, Comparator<String> tagComparator, Comparator<String> pathComparator) {
|
||||
MultimapBuilder.MultimapBuilderWithKeys<String> multimapBuilderWithKeys;
|
||||
if (tagComparator == null)
|
||||
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(Ordering.<String>natural()); // FIXME as-is when tagComparator not supported because of limitations in MultiMap::hashkeys()
|
||||
else
|
||||
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagComparator);
|
||||
|
||||
Multimap<String, Pair<String, Path>> pathsGroupedByTag;
|
||||
if (pathComparator == null)
|
||||
pathsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build();
|
||||
else
|
||||
pathsGroupedByTag = multimapBuilderWithKeys.treeSetValues(new PathUtils.PathPairComparator(pathComparator)).build();
|
||||
|
||||
for (Map.Entry<String, Path> pathEntry : paths.entrySet()) {
|
||||
String resourcePath = pathEntry.getKey();
|
||||
Path path = pathEntry.getValue();
|
||||
@@ -92,7 +101,7 @@ public class TagUtils {
|
||||
if (LOG.isInfoEnabled()) {
|
||||
LOG.info("Added path operation '{} {}' to tag '{}'", httpMethod, resourcePath, tag);
|
||||
}
|
||||
pathsGroupedByTag.put(tag, Pair.of(resourcePath, pathEntry.getValue()));
|
||||
pathsGroupedByTag.put(tag, Pair.of(resourcePath, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -178,7 +177,7 @@ public class Swagger2MarkupConverterTest {
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(3).containsAll(asList("definitions.adoc", "overview.adoc", "paths.adoc"));
|
||||
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "overview.adoc"))))
|
||||
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "overview.adoc").toPath())))
|
||||
.doesNotContain("=== URI scheme");
|
||||
}
|
||||
|
||||
@@ -197,7 +196,7 @@ public class Swagger2MarkupConverterTest {
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(3).containsAll(asList("definitions.adoc", "overview.adoc", "paths.adoc"));
|
||||
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "overview.adoc"))))
|
||||
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "overview.adoc").toPath())))
|
||||
.contains("=== URI scheme");
|
||||
}
|
||||
|
||||
@@ -251,8 +250,8 @@ public class Swagger2MarkupConverterTest {
|
||||
assertThat(directories).hasSize(4).containsAll(
|
||||
asList("definitions", "definitions.adoc", "overview.adoc", "paths.adoc"));
|
||||
File definitionsDirectory = new File(outputDirectory, "definitions");
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.adoc"))))
|
||||
.contains(new String(Files.readAllBytes(Paths.get(definitionsDirectory + File.separator + "user.adoc"))));
|
||||
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.adoc").toPath())))
|
||||
.contains(new String(Files.readAllBytes(new File(definitionsDirectory, "user.adoc").toPath())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -277,8 +276,8 @@ public class Swagger2MarkupConverterTest {
|
||||
assertThat(definitions).hasSize(6).containsAll(
|
||||
asList("identified.md", "user.md", "category.md", "pet.md", "tag.md", "order.md"));
|
||||
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.md"))))
|
||||
.contains(new String(Files.readAllBytes(Paths.get(definitionsDirectory + File.separator + "user.md"))));
|
||||
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.md").toPath())))
|
||||
.contains(new String(Files.readAllBytes(new File(definitionsDirectory, "user.md").toPath())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -298,7 +297,7 @@ public class Swagger2MarkupConverterTest {
|
||||
assertThat(directories).hasSize(4).containsAll(
|
||||
asList("definitions", "definitions.md", "overview.md", "paths.md"));
|
||||
verifyMarkdownContainsFieldsInTables(
|
||||
outputDirectory + File.separator + "definitions.md",
|
||||
new File(outputDirectory, "definitions.md"),
|
||||
ImmutableMap.<String, Set<String>>builder()
|
||||
.put("Identified", ImmutableSet.of("id"))
|
||||
.put("User", ImmutableSet.of("id", "username", "firstName",
|
||||
@@ -306,7 +305,7 @@ public class Swagger2MarkupConverterTest {
|
||||
.build());
|
||||
File definitionsDirectory = new File(outputDirectory, "definitions");
|
||||
verifyMarkdownContainsFieldsInTables(
|
||||
definitionsDirectory + File.separator + "user.md",
|
||||
new File(definitionsDirectory, "user.md"),
|
||||
ImmutableMap.<String, Set<String>>builder()
|
||||
.put("User", ImmutableSet.of("id", "username", "firstName",
|
||||
"lastName", "email", "password", "phone", "userStatus"))
|
||||
@@ -329,7 +328,7 @@ public class Swagger2MarkupConverterTest {
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.adoc"))))
|
||||
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.adoc").toPath())))
|
||||
.contains("== Определения");
|
||||
}
|
||||
|
||||
@@ -337,13 +336,13 @@ public class Swagger2MarkupConverterTest {
|
||||
* Given a markdown document to search, this checks to see if the specified tables
|
||||
* have all of the expected fields listed.
|
||||
*
|
||||
* @param doc path of markdown document to inspect
|
||||
* @param doc markdown document file to inspect
|
||||
* @param fieldsByTable map of table name (header) to field names expected
|
||||
* to be found in that table.
|
||||
* @throws IOException if the markdown document could not be read
|
||||
*/
|
||||
private static void verifyMarkdownContainsFieldsInTables(String doc, Map<String, Set<String>> fieldsByTable) throws IOException {
|
||||
final List<String> lines = Files.readAllLines(Paths.get(doc), Charset.defaultCharset());
|
||||
private static void verifyMarkdownContainsFieldsInTables(File doc, Map<String, Set<String>> fieldsByTable) throws IOException {
|
||||
final List<String> lines = Files.readAllLines(doc.toPath(), Charset.defaultCharset());
|
||||
final Map<String, Set<String>> fieldsLeftByTable = Maps.newHashMap();
|
||||
for(Map.Entry<String, Set<String>> entry : fieldsByTable.entrySet()) {
|
||||
fieldsLeftByTable.put(entry.getKey(), Sets.newHashSet(entry.getValue()));
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
swagger: "2.0"
|
||||
info:
|
||||
title: FCU API
|
||||
description: Outscale FCU service
|
||||
title: API
|
||||
description: Service API
|
||||
version: "2.18"
|
||||
host: fcu.eu-west-2.outscale.com
|
||||
host: service.host.com
|
||||
schemes:
|
||||
- https
|
||||
consumes:
|
||||
@@ -18,28 +18,6 @@ paths:
|
||||
tags:
|
||||
- All
|
||||
parameters:
|
||||
- $ref: "#/parameters/Version"
|
||||
- name: array
|
||||
in: query
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
- name: ref array
|
||||
in: query
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Simple'
|
||||
- name: csv
|
||||
in: query
|
||||
type: array
|
||||
collectionFormat: pipes
|
||||
items:
|
||||
type: boolean
|
||||
- name: FirstParameter
|
||||
description: <description>
|
||||
in: body
|
||||
schema:
|
||||
$ref: '#/definitions/Simple'
|
||||
- name: LaunchCommandRequest
|
||||
description: Launch something
|
||||
in: body
|
||||
@@ -51,10 +29,17 @@ paths:
|
||||
- MinCount
|
||||
- MaxCount
|
||||
properties:
|
||||
DryRun:
|
||||
Command:
|
||||
description: Dummy description
|
||||
type: boolean
|
||||
SecurityGroup.N:
|
||||
type: object
|
||||
properties:
|
||||
path:
|
||||
description: Command path
|
||||
type: string
|
||||
args:
|
||||
description: Command arguments
|
||||
type: string
|
||||
Options:
|
||||
description: Dummy description
|
||||
type: array
|
||||
items:
|
||||
@@ -63,12 +48,9 @@ paths:
|
||||
Location:
|
||||
description: Dummy description
|
||||
$ref: '#/definitions/Location'
|
||||
KernelId:
|
||||
description: Dummy description
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: Reservation
|
||||
description: Result
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
@@ -84,34 +66,29 @@ paths:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
|
||||
|
||||
parameters:
|
||||
Version:
|
||||
name: Version
|
||||
description: <description>
|
||||
in: query
|
||||
type: boolean
|
||||
|
||||
definitions:
|
||||
ExternalLocation:
|
||||
$ref: ./swagger_inlineSchema.yaml#/definitions/Location
|
||||
|
||||
Simple:
|
||||
description: simple def
|
||||
type: string
|
||||
|
||||
Error:
|
||||
type: integer
|
||||
type: object
|
||||
properties:
|
||||
error-code:
|
||||
description: Error code
|
||||
type: integer
|
||||
message:
|
||||
description: Error message
|
||||
type: string
|
||||
|
||||
Location:
|
||||
type: object
|
||||
properties:
|
||||
Loop:
|
||||
description: <description>
|
||||
description: Loop
|
||||
type:
|
||||
$ref: '#/definitions/Location'
|
||||
Affinity:
|
||||
description: <description>
|
||||
Place:
|
||||
description: Place
|
||||
type: string
|
||||
|
||||
InlineDepthSchema:
|
||||
@@ -120,16 +97,24 @@ definitions:
|
||||
Loop:
|
||||
type: object
|
||||
properties:
|
||||
P1:
|
||||
description: description P1
|
||||
p1:
|
||||
description: Description p1
|
||||
type: string
|
||||
p2:
|
||||
description: description P2
|
||||
description: Description p2
|
||||
type: object
|
||||
properties:
|
||||
pv1:
|
||||
description: pv1
|
||||
p2-1:
|
||||
description: Description p2-1
|
||||
type: string
|
||||
pv2:
|
||||
description: pv2
|
||||
type: boolean
|
||||
p2-2:
|
||||
description: Description p2-2
|
||||
type: object
|
||||
properties:
|
||||
p2-2-1:
|
||||
description: Description p2-2-1
|
||||
type: string
|
||||
p2-2-2:
|
||||
description: Description p2-2-2
|
||||
type: boolean
|
||||
|
||||
|
||||
38
src/test/resources/yaml/swagger_ordering.yaml
Normal file
38
src/test/resources/yaml/swagger_ordering.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
swagger: "2.0"
|
||||
info:
|
||||
title: API
|
||||
|
||||
paths:
|
||||
/C:
|
||||
post:
|
||||
tags:
|
||||
- C
|
||||
- B
|
||||
get:
|
||||
tags:
|
||||
- C
|
||||
- A
|
||||
/B:
|
||||
get:
|
||||
tags:
|
||||
- B
|
||||
/A:
|
||||
get:
|
||||
tags:
|
||||
- B
|
||||
- C
|
||||
delete:
|
||||
tags:
|
||||
- C
|
||||
- A
|
||||
|
||||
definitions:
|
||||
|
||||
C:
|
||||
type: string
|
||||
|
||||
B:
|
||||
type: string
|
||||
|
||||
A:
|
||||
type: string
|
||||
Reference in New Issue
Block a user