diff --git a/build.gradle b/build.gradle index 3507259b..5509bf95 100644 --- a/build.gradle +++ b/build.gradle @@ -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" diff --git a/src/main/java/io/github/robwin/swagger2markup/OrderBy.java b/src/main/java/io/github/robwin/swagger2markup/OrderBy.java index 412393fa..d8332233 100644 --- a/src/main/java/io/github/robwin/swagger2markup/OrderBy.java +++ b/src/main/java/io/github/robwin/swagger2markup/OrderBy.java @@ -17,6 +17,8 @@ * */ package io.github.robwin.swagger2markup; + +@Deprecated public enum OrderBy { AS_IS, NATURAL diff --git a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java index 3cf9c264..24727cc4 100644 --- a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java +++ b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java @@ -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 DEFAULT_TAG_ORDERING = Ordering.natural(); + private static final Comparator DEFAULT_PATH_ORDERING = Ordering.natural(); + private static final Comparator DEFAULT_PATH_METHOD_ORDERING = Ordering.explicit(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS); + private static final Comparator 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 tagOrdering = DEFAULT_TAG_ORDERING; + private Comparator pathOrdering = DEFAULT_PATH_ORDERING; + private Comparator pathMethodOrdering = DEFAULT_PATH_METHOD_ORDERING; + private Comparator 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 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 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 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 definitionOrdering) { + this.definitionOrdering = definitionOrdering; + return this; + } + } } diff --git a/src/main/java/io/github/robwin/swagger2markup/builder/document/DefinitionsDocument.java b/src/main/java/io/github/robwin/swagger2markup/builder/document/DefinitionsDocument.java index 4a73d4ff..9c9fe4ca 100644 --- a/src/main/java/io/github/robwin/swagger2markup/builder/document/DefinitionsDocument.java +++ b/src/main/java/io/github/robwin/swagger2markup/builder/document/DefinitionsDocument.java @@ -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 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 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 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 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); } } diff --git a/src/main/java/io/github/robwin/swagger2markup/builder/document/MarkupDocument.java b/src/main/java/io/github/robwin/swagger2markup/builder/document/MarkupDocument.java index e9f1e558..78105fa6 100644 --- a/src/main/java/io/github/robwin/swagger2markup/builder/document/MarkupDocument.java +++ b/src/main/java/io/github/robwin/swagger2markup/builder/document/MarkupDocument.java @@ -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> cells = new ArrayList<>(); - List header = Arrays.asList(NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN); - cells.add(header); + List 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 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 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; diff --git a/src/main/java/io/github/robwin/swagger2markup/builder/document/OverviewDocument.java b/src/main/java/io/github/robwin/swagger2markup/builder/document/OverviewDocument.java index 9d194bb6..8be64943 100644 --- a/src/main/java/io/github/robwin/swagger2markup/builder/document/OverviewDocument.java +++ b/src/main/java/io/github/robwin/swagger2markup/builder/document/OverviewDocument.java @@ -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(); } } diff --git a/src/main/java/io/github/robwin/swagger2markup/builder/document/PathsDocument.java b/src/main/java/io/github/robwin/swagger2markup/builder/document/PathsDocument.java index 9bdb814a..07fc2fa8 100644 --- a/src/main/java/io/github/robwin/swagger2markup/builder/document/PathsDocument.java +++ b/src/main/java/io/github/robwin/swagger2markup/builder/document/PathsDocument.java @@ -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 tagOrdering; + private final Comparator pathOrdering; + private final Comparator 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 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 pathEntry : paths.entrySet()) { - Path path = pathEntry.getValue(); - if(path != null) { - createPathSections(pathEntry.getKey(), path); - } + + Set> sortedPaths; + if (this.pathOrdering == null) + sortedPaths = new LinkedHashSet<>(); + else + sortedPaths = new TreeSet<>(new PathUtils.PathPairComparator(this.pathOrdering)); + for (Map.Entry e : paths.entrySet()) { + sortedPaths.add(Pair.of(e.getKey(), e.getValue())); } - }else{ + + for (Pair pathEntry : sortedPaths) { + createPathSections(pathEntry.getKey(), pathEntry.getValue()); + } + } else { this.markupDocBuilder.sectionTitleLevel1(RESOURCES); - Multimap> pathsGroupedByTag = groupPathsByTag(paths); + Multimap> pathsGroupedByTag = groupPathsByTag(paths, tagOrdering, pathOrdering); Map 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 operationEntry : path.getOperationMap().entrySet()){ + + Map operationsMap; + if (pathMethodOrdering == null) + operationsMap = new LinkedHashMap<>(); + else + operationsMap = new TreeMap<>(pathMethodOrdering); + operationsMap.putAll(path.getOperationMap()); + + for(Map.Entry 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 localDefinitions = new ArrayList<>(); if(CollectionUtils.isNotEmpty(parameters)){ List> cells = new ArrayList<>(); - // Table header row - List header = Arrays.asList(TYPE_COLUMN, NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN); - cells.add(header); + List 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 tags = operation.getTags(); if (CollectionUtils.isNotEmpty(tags)) { addPathSectionTitle(TAGS, docBuilder); - docBuilder.unorderedList(tags); + Set 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 localDefinitions = new ArrayList<>(); if(MapUtils.isNotEmpty(responses)){ List> cells = new ArrayList<>(); - cells.add(Arrays.asList(HTTP_CODE_COLUMN, DESCRIPTION_COLUMN, SCHEMA_COLUMN)); + List cols = Arrays.asList( + new MarkupTableColumn(HTTP_CODE_COLUMN, 1), + new MarkupTableColumn(DESCRIPTION_COLUMN, 6), + new MarkupTableColumn(SCHEMA_COLUMN, 1)); for(Map.Entry 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 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 localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), docBuilder); + addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder); + List localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), this.markupDocBuilder); for (Type localDefinition : localDefinitions) inlineDefinitions(Collections.singletonList(localDefinition), depth - 1, docBuilder); } diff --git a/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java b/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java index 3858c6f0..cc7f613b 100644 --- a/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java +++ b/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java @@ -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 tagOrdering; + private final Comparator pathOrdering; + private final Comparator pathMethodOrdering; + private final Comparator 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 tagOrdering, Comparator pathOrdering, + Comparator pathMethodOrdering, Comparator 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 getTagOrdering() { + return tagOrdering; + } + + public Comparator getPathOrdering() { + return pathOrdering; + } + + public Comparator getPathMethodOrdering() { + return pathMethodOrdering; + } + + public Comparator getDefinitionOrdering() { + return definitionOrdering; + } } diff --git a/src/main/java/io/github/robwin/swagger2markup/type/ArrayType.java b/src/main/java/io/github/robwin/swagger2markup/type/ArrayType.java index 797ca5a2..f6a333f1 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/ArrayType.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/ArrayType.java @@ -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"; } } diff --git a/src/main/java/io/github/robwin/swagger2markup/type/BasicType.java b/src/main/java/io/github/robwin/swagger2markup/type/BasicType.java index 3af7459c..22c4cf20 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/BasicType.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/BasicType.java @@ -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 diff --git a/src/main/java/io/github/robwin/swagger2markup/type/EnumType.java b/src/main/java/io/github/robwin/swagger2markup/type/EnumType.java index 9ed9ff29..95812622 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/EnumType.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/EnumType.java @@ -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, ", ") + ")"; } } diff --git a/src/main/java/io/github/robwin/swagger2markup/type/ObjectType.java b/src/main/java/io/github/robwin/swagger2markup/type/ObjectType.java index 36731c33..85d68c98 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/ObjectType.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/ObjectType.java @@ -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 getProperties() { diff --git a/src/main/java/io/github/robwin/swagger2markup/type/RefType.java b/src/main/java/io/github/robwin/swagger2markup/type/RefType.java index f6a41441..d6e9186c 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/RefType.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/RefType.java @@ -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()); } } diff --git a/src/main/java/io/github/robwin/swagger2markup/type/Type.java b/src/main/java/io/github/robwin/swagger2markup/type/Type.java index 2660cccd..00360672 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/Type.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/Type.java @@ -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); } diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java deleted file mode 100644 index ca85be70..00000000 --- a/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java +++ /dev/null @@ -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 columnWidthRatios, List> cells, MarkupDocBuilder docBuilder) { - if (docBuilder instanceof AsciiDocBuilder) { - docBuilder.textLine("[options=\"header\",cols=\"" + join(columnWidthRatios, ",") + "\"]"); - docBuilder.textLine(AsciiDoc.TABLE.toString()); - - for (List cols : cells) { - String row = AsciiDoc.TABLE_COLUMN_DELIMITER + join(Collections2.transform(cols, new Function() { - 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 rows = Lists.newArrayList(Collections2.transform(cells, new Function, String>() { - public String apply(List cols) { - return join(Collections2.transform(cols, new Function() { - public String apply(final String col) { - return col.replace(Markdown.TABLE_COLUMN_DELIMITER.toString(), "|"); - } - }), Markdown.TABLE_COLUMN_DELIMITER.toString()); - } - })); - - docBuilder.tableWithHeaderRow(rows); - } - } -} diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/PathUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/PathUtils.java new file mode 100644 index 00000000..ccf1e40d --- /dev/null +++ b/src/main/java/io/github/robwin/swagger2markup/utils/PathUtils.java @@ -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> { + + private Comparator pathComparator; + + public PathPairComparator(Comparator pathComparator) { + this.pathComparator = pathComparator; + } + + @Override + public int compare(Pair o1, Pair o2) { + return pathComparator.compare(o1.getKey(), o2.getKey()); + } + } +} diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/PropertyUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/PropertyUtils.java index 2f695f90..581e6a0c 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/PropertyUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/PropertyUtils.java @@ -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(); diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java index 47a4600a..70efbb29 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java @@ -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> groupPathsByTag(Map paths) { - Multimap> pathsGroupedByTag = MultimapBuilder.SortedSetMultimapBuilder.treeKeys().hashSetValues().build(); + public static Multimap> groupPathsByTag(Map paths, Comparator tagComparator, Comparator pathComparator) { + MultimapBuilder.MultimapBuilderWithKeys multimapBuilderWithKeys; + if (tagComparator == null) + multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(Ordering.natural()); // FIXME as-is when tagComparator not supported because of limitations in MultiMap::hashkeys() + else + multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagComparator); + + Multimap> pathsGroupedByTag; + if (pathComparator == null) + pathsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build(); + else + pathsGroupedByTag = multimapBuilderWithKeys.treeSetValues(new PathUtils.PathPairComparator(pathComparator)).build(); + for (Map.Entry 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)); } } } diff --git a/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java b/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java index 7260e915..ecd98266 100644 --- a/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java +++ b/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java @@ -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.>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.>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> fieldsByTable) throws IOException { - final List lines = Files.readAllLines(Paths.get(doc), Charset.defaultCharset()); + private static void verifyMarkdownContainsFieldsInTables(File doc, Map> fieldsByTable) throws IOException { + final List lines = Files.readAllLines(doc.toPath(), Charset.defaultCharset()); final Map> fieldsLeftByTable = Maps.newHashMap(); for(Map.Entry> entry : fieldsByTable.entrySet()) { fieldsLeftByTable.put(entry.getKey(), Sets.newHashSet(entry.getValue())); diff --git a/src/test/resources/yaml/swagger_inlineSchema.yaml b/src/test/resources/yaml/swagger_inlineSchema.yaml index 3b3ed13a..0a0fa5ac 100644 --- a/src/test/resources/yaml/swagger_inlineSchema.yaml +++ b/src/test/resources/yaml/swagger_inlineSchema.yaml @@ -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: - 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: - 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: Loop type: $ref: '#/definitions/Location' - Affinity: - 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 + diff --git a/src/test/resources/yaml/swagger_ordering.yaml b/src/test/resources/yaml/swagger_ordering.yaml new file mode 100644 index 00000000..d98de08a --- /dev/null +++ b/src/test/resources/yaml/swagger_ordering.yaml @@ -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