From bd9d3ee4c3f41605b83baf4e9a3dc61355de8446 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Wed, 3 Feb 2016 12:02:33 +0100 Subject: [PATCH 1/7] Cleanups --- .../builder/document/DefinitionsDocument.java | 14 ++++++- .../builder/document/MarkupDocument.java | 10 +++-- .../builder/document/PathsDocument.java | 38 +++++++++++-------- .../utils/MarkupDocBuilderUtils.java | 32 ---------------- 4 files changed, 41 insertions(+), 53 deletions(-) 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 8ac42a17..5bc8baf4 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 @@ -348,13 +348,23 @@ 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) { + MarkupDocBuilderUtils.anchor(anchor, docBuilder); + 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..27d77819 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 @@ -125,11 +125,13 @@ public abstract class MarkupDocument { 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( 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 6784676a..8dc86d88 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 @@ -292,12 +292,14 @@ public class PathsDocument extends MarkupDocument { 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 @@ -494,12 +496,14 @@ public class PathsDocument extends MarkupDocument { Property property = response.getSchema(); Type type = PropertyUtils.getType(property); if (this.inlineSchemaDepthLevel > 0 && type instanceof ObjectType) { - String localTypeName = RESPONSE_INLINE_PREFIX + " " + entry.getKey(); + if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) { + String localTypeName = RESPONSE_INLINE_PREFIX + " " + 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))); }else{ @@ -512,14 +516,18 @@ public class PathsDocument extends MarkupDocument { return localDefinitions; } + /** + * Inline definitions should never been referenced in TOC, so they are just text. + */ + private void addInlineDefinitionTitle(String title, String anchor) { + MarkupDocBuilderUtils.anchor(anchor, this.markupDocBuilder); + this.markupDocBuilder.boldTextLine(title); + } + private void inlineDefinitions(List definitions, int depth) { if(CollectionUtils.isNotEmpty(definitions)){ for (Type definition: definitions) { - if(pathsGroupedBy.equals(GroupBy.AS_IS)){ - MarkupDocBuilderUtils.sectionTitleLevel(4, definition.getName(), definition.getUniqueName(), this.markupDocBuilder); - }else{ - MarkupDocBuilderUtils.sectionTitleLevel(5, definition.getName(), definition.getUniqueName(), this.markupDocBuilder); - } + addInlineDefinitionTitle(definition.getName(), definition.getUniqueName()); List localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), this.markupDocBuilder); for (Type localDefinition : localDefinitions) inlineDefinitions(Collections.singletonList(localDefinition), depth - 1); diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java index ca85be70..6f950ee9 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java @@ -53,38 +53,6 @@ public class MarkupDocBuilderUtils { } } - 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, ",") + "\"]"); From 9d90766592d4bb44be2291d17df86bfbd73d913a Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Wed, 3 Feb 2016 12:03:11 +0100 Subject: [PATCH 2/7] Workaround for https://github.com/swagger-api/swagger-parser/issues/177 --- .../robwin/swagger2markup/utils/PropertyUtils.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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(); From 1899efd2095ed66930e3f7fed514d561e07f52b4 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Wed, 3 Feb 2016 12:43:39 +0100 Subject: [PATCH 3/7] Test cleanups --- .../Swagger2MarkupConverterTest.java | 25 +++-- .../resources/yaml/swagger_inlineSchema.yaml | 97 ++++++++----------- 2 files changed, 53 insertions(+), 69 deletions(-) diff --git a/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java b/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java index ed2144e5..86edcfd0 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(9).containsAll( asList("definitions.adoc", "overview.adoc", "paths.adoc", "identified.adoc", "user.adoc", "category.adoc", "pet.adoc", "tag.adoc", "order.adoc")); - assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.adoc")))) - .contains(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "user.adoc")))); + assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.adoc").toPath()))) + .contains(new String(Files.readAllBytes(new File(outputDirectory, "user.adoc").toPath()))); } @Test @@ -272,8 +271,8 @@ public class Swagger2MarkupConverterTest { assertThat(directories).hasSize(9).containsAll( asList("definitions.md", "overview.md", "paths.md", "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(outputDirectory + File.separator + "user.md")))); + assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.md").toPath()))) + .contains(new String(Files.readAllBytes(new File(outputDirectory, "user.md").toPath()))); } @Test @@ -294,14 +293,14 @@ public class Swagger2MarkupConverterTest { asList("definitions.md", "overview.md", "paths.md", "identified.md", "user.md", "category.md", "pet.md", "tag.md", "order.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", "lastName", "email", "password", "phone", "userStatus")) .build()); verifyMarkdownContainsFieldsInTables( - outputDirectory + File.separator + "user.md", + new File(outputDirectory, "user.md"), ImmutableMap.>builder() .put("User", ImmutableSet.of("id", "username", "firstName", "lastName", "email", "password", "phone", "userStatus")) @@ -324,7 +323,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("== Определения"); } @@ -332,13 +331,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 + From 9df1c73641b7ea3a39b6c040f59439eeebdaed72 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Wed, 3 Feb 2016 14:10:17 +0100 Subject: [PATCH 4/7] fixed Markdown generation for inline schemas --- .../swagger2markup/builder/document/DefinitionsDocument.java | 1 + .../robwin/swagger2markup/builder/document/PathsDocument.java | 1 + 2 files changed, 2 insertions(+) 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 5bc8baf4..5d5aed64 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 @@ -355,6 +355,7 @@ public class DefinitionsDocument extends MarkupDocument { private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) { MarkupDocBuilderUtils.anchor(anchor, docBuilder); docBuilder.boldTextLine(title); + docBuilder.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 8dc86d88..dd9cba18 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 @@ -522,6 +522,7 @@ public class PathsDocument extends MarkupDocument { private void addInlineDefinitionTitle(String title, String anchor) { MarkupDocBuilderUtils.anchor(anchor, this.markupDocBuilder); this.markupDocBuilder.boldTextLine(title); + this.markupDocBuilder.newLine(); } private void inlineDefinitions(List definitions, int depth) { From 836d9fbae79b378960050fa078f861a6ffb32612 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Thu, 4 Feb 2016 17:34:10 +0100 Subject: [PATCH 5/7] Migrate to markup-document-builder 0.1.6-SNAPSHOT --- build.gradle | 5 +- .../builder/document/DefinitionsDocument.java | 5 +- .../builder/document/MarkupDocument.java | 16 ++-- .../builder/document/OverviewDocument.java | 9 -- .../builder/document/PathsDocument.java | 29 ++++--- .../robwin/swagger2markup/type/ArrayType.java | 6 +- .../robwin/swagger2markup/type/BasicType.java | 4 +- .../robwin/swagger2markup/type/EnumType.java | 4 +- .../swagger2markup/type/ObjectType.java | 10 ++- .../robwin/swagger2markup/type/RefType.java | 7 +- .../robwin/swagger2markup/type/Type.java | 4 +- .../utils/MarkupDocBuilderUtils.java | 84 ------------------- 12 files changed, 52 insertions(+), 131 deletions(-) delete mode 100644 src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java 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/builder/document/DefinitionsDocument.java b/src/main/java/io/github/robwin/swagger2markup/builder/document/DefinitionsDocument.java index 5d5aed64..3af38af6 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 @@ -25,7 +25,6 @@ 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; @@ -353,9 +352,9 @@ 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) { - MarkupDocBuilderUtils.anchor(anchor, docBuilder); - docBuilder.boldTextLine(title); + docBuilder.anchor(anchor); docBuilder.newLine(); + docBuilder.boldTextLine(title); } 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 27d77819..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,8 +117,12 @@ 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(); @@ -138,20 +142,18 @@ public abstract class MarkupDocument { 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 dd9cba18..04a67b46 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 @@ -20,12 +20,12 @@ package io.github.robwin.swagger2markup.builder.document; import com.google.common.base.Optional; import com.google.common.collect.Multimap; +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.PropertyUtils; import io.swagger.models.*; @@ -286,9 +286,13 @@ 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) { @@ -308,12 +312,12 @@ public class PathsDocument extends MarkupDocument { parameter.getName(), parameterDescription(operation, parameter), Boolean.toString(parameter.getRequired()), - type.displaySchema(markupLanguage), + type.displaySchema(markupDocBuilder), ParameterUtils.getDefaultValue(parameter)); cells.add(content); } addPathSectionTitle(PARAMETERS); - MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 1, 6, 1, 1, 1), cells, this.markupDocBuilder); + markupDocBuilder.tableWithColumnSpecs(cols, cells); } return localDefinitions; @@ -489,7 +493,10 @@ 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){ @@ -505,13 +512,13 @@ public class PathsDocument extends MarkupDocument { 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); - MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 6, 1), cells, this.markupDocBuilder); + markupDocBuilder.tableWithColumnSpecs(cols, cells); } return localDefinitions; } @@ -520,9 +527,9 @@ public class PathsDocument extends MarkupDocument { * Inline definitions should never been referenced in TOC, so they are just text. */ private void addInlineDefinitionTitle(String title, String anchor) { - MarkupDocBuilderUtils.anchor(anchor, this.markupDocBuilder); + markupDocBuilder.anchor(anchor); + markupDocBuilder.newLine(); this.markupDocBuilder.boldTextLine(title); - this.markupDocBuilder.newLine(); } private void inlineDefinitions(List definitions, int depth) { 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 6f950ee9..00000000 --- a/src/main/java/io/github/robwin/swagger2markup/utils/MarkupDocBuilderUtils.java +++ /dev/null @@ -1,84 +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 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); - } - } -} From 2fceda6f09a2174b03b4666f35ae3a86c9b7ec92 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Fri, 5 Feb 2016 16:35:49 +0100 Subject: [PATCH 6/7] fixed #53 : support for tags, paths and methods ordering --- .../github/robwin/swagger2markup/GroupBy.java | 1 + .../Swagger2MarkupConverter.java | 81 ++++++++++++++++++- .../builder/document/PathsDocument.java | 47 ++++++++--- .../config/Swagger2MarkupConfig.java | 27 ++++++- .../swagger2markup/utils/PathUtils.java | 45 +++++++++++ .../robwin/swagger2markup/utils/TagUtils.java | 11 +-- src/test/resources/yaml/swagger_ordering.yaml | 26 ++++++ 7 files changed, 216 insertions(+), 22 deletions(-) create mode 100644 src/main/java/io/github/robwin/swagger2markup/utils/PathUtils.java create mode 100644 src/test/resources/yaml/swagger_ordering.yaml diff --git a/src/main/java/io/github/robwin/swagger2markup/GroupBy.java b/src/main/java/io/github/robwin/swagger2markup/GroupBy.java index 7b0fbe58..c870d75b 100644 --- a/src/main/java/io/github/robwin/swagger2markup/GroupBy.java +++ b/src/main/java/io/github/robwin/swagger2markup/GroupBy.java @@ -20,5 +20,6 @@ package io.github.robwin.swagger2markup; public enum GroupBy { AS_IS, + SORTED, TAGS } diff --git a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java index c4f84fa5..dc762281 100644 --- a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java +++ b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java @@ -24,6 +24,7 @@ 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 +33,9 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; /** * @author Robert Winkler @@ -44,6 +48,42 @@ public class Swagger2MarkupConverter { private static final String PATHS_DOCUMENT = "paths"; private static final String DEFINITIONS_DOCUMENT = "definitions"; + private static final Comparator DEFAULT_TAG_COMPARATOR = new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }; + + private static final Comparator DEFAULT_PATH_COMPARATOR = new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }; + + private static final Comparator DEFAULT_PATH_METHOD_COMPARATOR = new HttpMethodComparator<>(Arrays.asList(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS)); + + public static class HttpMethodComparator implements Comparator { + private List methodsOrdering; + + public HttpMethodComparator(List methodsOrdering) { + this.methodsOrdering = methodsOrdering; + } + + @Override + public int compare(HttpMethod o1, HttpMethod o2) { + int o1Index = methodsOrdering.indexOf(o1); + if (o1Index == -1) + o1Index = methodsOrdering.size(); + int o2Index = methodsOrdering.indexOf(o2); + if (o2Index == -1) + o2Index = methodsOrdering.size() + 1; + return o1Index - o2Index; + } + }; + + /** * @param swagger2MarkupConfig the configuration */ @@ -146,6 +186,9 @@ public class Swagger2MarkupConverter { private MarkupLanguage markupLanguage = MarkupLanguage.ASCIIDOC; private Language outputLanguage = Language.EN; private int inlineSchemaDepthLevel = 0; + private Comparator tagComparator = DEFAULT_TAG_COMPARATOR; + private Comparator pathComparator = DEFAULT_PATH_COMPARATOR; + private Comparator pathMethodComparator = DEFAULT_PATH_METHOD_COMPARATOR; /** * Creates a Builder using a given Swagger source. @@ -171,7 +214,7 @@ public class Swagger2MarkupConverter { public Swagger2MarkupConverter build(){ return new Swagger2MarkupConverter(new Swagger2MarkupConfig(swagger, markupLanguage, examplesFolderPath, schemasFolderPath, descriptionsFolderPath, separatedDefinitions, pathsGroupedBy, definitionsOrderedBy, - outputLanguage, inlineSchemaDepthLevel)); + outputLanguage, inlineSchemaDepthLevel, tagComparator, pathComparator, pathMethodComparator)); } /** @@ -281,6 +324,42 @@ public class Swagger2MarkupConverter { this.inlineSchemaDepthLevel = inlineSchemaDepthLevel; return this; } + + /** + * Specifies a custom comparator function to order tags. + * By default, alphabetical ordering is applied. + * + * @param tagComparator + * @return the Swagger2MarkupConverter.Builder + */ + public Builder withTagComparator(Comparator tagComparator) { + this.tagComparator = tagComparator; + return this; + } + + /** + * Specifies a custom comparator function to order paths. + * By default, alphabetical ordering is applied. + * + * @param pathComparator + * @return the Swagger2MarkupConverter.Builder + */ + public Builder withPathComparator(Comparator pathComparator) { + this.pathComparator = pathComparator; + return this; + } + + /** + * Specifies a custom comparator function to order paths methods. + * By default, the order is GET, PUT, POST, DELETE, PATCH, HEAD, OPTIONS + * + * @param pathMethodComparator + * @return the Swagger2MarkupConverter.Builder + */ + public Builder withPathMethodComparator(Comparator pathMethodComparator) { + this.pathMethodComparator = pathMethodComparator; + return this; + } } } 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 04a67b46..ca1f5a61 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 @@ -27,6 +27,7 @@ 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.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; @@ -76,6 +77,9 @@ public class PathsDocument extends MarkupDocument { private String descriptionsFolderPath; private final GroupBy pathsGroupedBy; private final int inlineSchemaDepthLevel; + private final Comparator tagComparator; + private final Comparator pathComparator; + private final Comparator pathMethodComparator; public PathsDocument(Swagger2MarkupConfig swagger2MarkupConfig){ super(swagger2MarkupConfig); @@ -121,6 +125,9 @@ public class PathsDocument extends MarkupDocument { logger.debug("Include hand-written descriptions is disabled."); } } + tagComparator = swagger2MarkupConfig.getTagComparator(); + pathComparator = swagger2MarkupConfig.getPathComparator(); + pathMethodComparator = swagger2MarkupConfig.getPathMethodComparator(); } /** @@ -140,17 +147,25 @@ 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 || pathsGroupedBy == GroupBy.SORTED){ this.markupDocBuilder.sectionTitleLevel1(PATHS); - for (Map.Entry pathEntry : paths.entrySet()) { - Path path = pathEntry.getValue(); - if(path != null) { - createPathSections(pathEntry.getKey(), path); - } + + Set> sortedPaths; + if (pathsGroupedBy == GroupBy.SORTED) { + sortedPaths = new TreeSet<>(new PathUtils.PathPairComparator(this.pathComparator)); + } else { + sortedPaths = new LinkedHashSet<>(); } - }else{ + for (Map.Entry e : paths.entrySet()) { + sortedPaths.add(Pair.of(e.getKey(), e.getValue())); + } + + for (Pair pathEntry : sortedPaths) { + createPathSections(pathEntry.getKey(), pathEntry.getValue()); + } + } else { this.markupDocBuilder.sectionTitleLevel1(RESOURCES); - Multimap> pathsGroupedByTag = groupPathsByTag(paths); + Multimap> pathsGroupedByTag = groupPathsByTag(paths, tagComparator, pathComparator); Map tagsMap = convertTagsListToMap(swagger.getTags()); for(String tagName : pathsGroupedByTag.keySet()){ this.markupDocBuilder.sectionTitleLevel2(WordUtils.capitalize(tagName)); @@ -171,7 +186,11 @@ public class PathsDocument extends MarkupDocument { } private void createPathSections(String pathUrl, Path path){ - for(Map.Entry operationEntry : path.getOperationMap().entrySet()){ + + Map operationsMap = new TreeMap<>(pathMethodComparator); + operationsMap.putAll(path.getOperationMap()); + + for(Map.Entry operationEntry : operationsMap.entrySet()){ String methodAndPath = operationEntry.getKey() + " " + pathUrl; path(methodAndPath, operationEntry.getValue()); } @@ -224,7 +243,7 @@ public class PathsDocument extends MarkupDocument { * @param title the path title */ private void addPathTitle(String title) { - if(pathsGroupedBy.equals(GroupBy.AS_IS)){ + if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED){ this.markupDocBuilder.sectionTitleLevel2(title); }else{ this.markupDocBuilder.sectionTitleLevel3(title); @@ -237,7 +256,7 @@ public class PathsDocument extends MarkupDocument { * @param title the path title */ private void addPathSectionTitle(String title) { - if(pathsGroupedBy.equals(GroupBy.AS_IS)){ + if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED){ this.markupDocBuilder.sectionTitleLevel3(title); }else{ this.markupDocBuilder.sectionTitleLevel4(title); @@ -377,11 +396,13 @@ public class PathsDocument extends MarkupDocument { } private void tagsSection(Operation operation) { - if(pathsGroupedBy.equals(GroupBy.AS_IS)) { + if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED) { List tags = operation.getTags(); if (CollectionUtils.isNotEmpty(tags)) { addPathSectionTitle(TAGS); - this.markupDocBuilder.unorderedList(tags); + Set orderedTags = new TreeSet<>(this.tagComparator); + orderedTags.addAll(tags); + this.markupDocBuilder.unorderedList(new ArrayList<>(orderedTags)); } } } 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 a212c23d..a7cd4534 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; @@ -36,6 +39,9 @@ public class Swagger2MarkupConfig { private final OrderBy definitionsOrderedBy; private final Language outputLanguage; private final int inlineSchemaDepthLevel; + private final Comparator tagComparator; + private final Comparator pathComparator; + private final Comparator pathMethodComparator; /** * @param swagger the Swagger source @@ -48,11 +54,15 @@ 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 tagComparator specifies a custom comparator function to order tags + * @param pathComparator specifies a custom comparator function to order paths + * @param pathMethodComparator specifies a custom comparator function to order paths methods */ public Swagger2MarkupConfig(Swagger swagger, MarkupLanguage markupLanguage, String examplesFolderPath, String schemasFolderPath, String descriptionsFolderPath, boolean separatedDefinitions, GroupBy pathsGroupedBy, OrderBy definitionsOrderedBy, Language outputLanguage, - int inlineSchemaDepthLevel) { + int inlineSchemaDepthLevel, Comparator tagComparator, Comparator pathComparator, + Comparator pathMethodComparator) { this.swagger = swagger; this.markupLanguage = markupLanguage; this.examplesFolderPath = examplesFolderPath; @@ -63,6 +73,9 @@ public class Swagger2MarkupConfig { this.definitionsOrderedBy = definitionsOrderedBy; this.outputLanguage = outputLanguage; this.inlineSchemaDepthLevel = inlineSchemaDepthLevel; + this.tagComparator = tagComparator; + this.pathComparator = pathComparator; + this.pathMethodComparator = pathMethodComparator; } public Swagger getSwagger() { @@ -104,4 +117,16 @@ public class Swagger2MarkupConfig { public int getInlineSchemaDepthLevel() { return inlineSchemaDepthLevel; } + + public Comparator getTagComparator() { + return tagComparator; + } + + public Comparator getPathComparator() { + return pathComparator; + } + + public Comparator getPathMethodComparator() { + return pathMethodComparator; + } } 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/TagUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java index 47a4600a..a95a4156 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/TagUtils.java @@ -30,10 +30,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 +74,8 @@ 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) { + Multimap> pathsGroupedByTag = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagComparator).treeSetValues(new PathUtils.PathPairComparator(pathComparator)).build(); for (Map.Entry pathEntry : paths.entrySet()) { String resourcePath = pathEntry.getKey(); Path path = pathEntry.getValue(); @@ -92,7 +89,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/resources/yaml/swagger_ordering.yaml b/src/test/resources/yaml/swagger_ordering.yaml new file mode 100644 index 00000000..dbd7bc3b --- /dev/null +++ b/src/test/resources/yaml/swagger_ordering.yaml @@ -0,0 +1,26 @@ +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 \ No newline at end of file From c8919e9844159fc7276ae58f53a3a4c1f995cd85 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Fri, 5 Feb 2016 19:55:14 +0100 Subject: [PATCH 7/7] refactored orderBy system by generalizing ordering to all resources (tags, paths, definitions, path methods). definitionsOrderBy and OrderBy are deprecated (set definitionsOrdering to Ordering.natural() for back-compatibility) All orderings set to Ordering.natural() by default. Support as-is ordering for all resources by setting config options to null. --- .../github/robwin/swagger2markup/GroupBy.java | 1 - .../github/robwin/swagger2markup/OrderBy.java | 2 + .../Swagger2MarkupConverter.java | 94 ++++++++----------- .../builder/document/DefinitionsDocument.java | 15 ++- .../builder/document/PathsDocument.java | 45 +++++---- .../config/Swagger2MarkupConfig.java | 42 +++++---- .../robwin/swagger2markup/utils/TagUtils.java | 14 ++- src/test/resources/yaml/swagger_ordering.yaml | 14 ++- 8 files changed, 127 insertions(+), 100 deletions(-) diff --git a/src/main/java/io/github/robwin/swagger2markup/GroupBy.java b/src/main/java/io/github/robwin/swagger2markup/GroupBy.java index c870d75b..7b0fbe58 100644 --- a/src/main/java/io/github/robwin/swagger2markup/GroupBy.java +++ b/src/main/java/io/github/robwin/swagger2markup/GroupBy.java @@ -20,6 +20,5 @@ package io.github.robwin.swagger2markup; public enum GroupBy { AS_IS, - SORTED, TAGS } 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 5c41869f..24727cc4 100644 --- a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java +++ b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java @@ -18,6 +18,7 @@ */ 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; @@ -33,9 +34,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.Arrays; import java.util.Comparator; -import java.util.List; /** * @author Robert Winkler @@ -48,41 +47,10 @@ public class Swagger2MarkupConverter { private static final String PATHS_DOCUMENT = "paths"; private static final String DEFINITIONS_DOCUMENT = "definitions"; - private static final Comparator DEFAULT_TAG_COMPARATOR = new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1.compareTo(o2); - } - }; - - private static final Comparator DEFAULT_PATH_COMPARATOR = new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1.compareTo(o2); - } - }; - - private static final Comparator DEFAULT_PATH_METHOD_COMPARATOR = new HttpMethodComparator<>(Arrays.asList(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS)); - - public static class HttpMethodComparator implements Comparator { - private List methodsOrdering; - - public HttpMethodComparator(List methodsOrdering) { - this.methodsOrdering = methodsOrdering; - } - - @Override - public int compare(HttpMethod o1, HttpMethod o2) { - int o1Index = methodsOrdering.indexOf(o1); - if (o1Index == -1) - o1Index = methodsOrdering.size(); - int o2Index = methodsOrdering.indexOf(o2); - if (o2Index == -1) - o2Index = methodsOrdering.size() + 1; - return o1Index - o2Index; - } - }; - + 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 @@ -187,9 +155,10 @@ public class Swagger2MarkupConverter { private MarkupLanguage markupLanguage = MarkupLanguage.ASCIIDOC; private Language outputLanguage = Language.EN; private int inlineSchemaDepthLevel = 0; - private Comparator tagComparator = DEFAULT_TAG_COMPARATOR; - private Comparator pathComparator = DEFAULT_PATH_COMPARATOR; - private Comparator pathMethodComparator = DEFAULT_PATH_METHOD_COMPARATOR; + 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. @@ -215,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, tagComparator, pathComparator, pathMethodComparator)); + outputLanguage, inlineSchemaDepthLevel, tagOrdering, pathOrdering, pathMethodOrdering, definitionOrdering)); } /** @@ -308,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; } @@ -337,39 +308,56 @@ public class Swagger2MarkupConverter { /** * Specifies a custom comparator function to order tags. - * By default, alphabetical ordering is applied. + * By default, natural ordering is applied. + * Set ordering to null to keep swagger original order * - * @param tagComparator + * @param tagOrdering * @return the Swagger2MarkupConverter.Builder */ - public Builder withTagComparator(Comparator tagComparator) { - this.tagComparator = tagComparator; + public Builder withTagOrdering(Comparator tagOrdering) { + this.tagOrdering = tagOrdering; return this; } /** * Specifies a custom comparator function to order paths. - * By default, alphabetical ordering is applied. + * By default, natural ordering is applied. + * Set ordering to null to keep swagger original order * - * @param pathComparator + * @param pathOrdering * @return the Swagger2MarkupConverter.Builder */ - public Builder withPathComparator(Comparator pathComparator) { - this.pathComparator = pathComparator; + public Builder withPathOrdering(Comparator pathOrdering) { + this.pathOrdering = pathOrdering; return this; } /** * Specifies a custom comparator function to order paths methods. - * By default, the order is GET, PUT, POST, DELETE, PATCH, HEAD, OPTIONS + * By default, explicit ordering is applied : GET, PUT, POST, DELETE, PATCH, HEAD, OPTIONS + * Set ordering to null to keep swagger original order * - * @param pathMethodComparator + * @param pathMethodOrdering * @return the Swagger2MarkupConverter.Builder */ - public Builder withPathMethodComparator(Comparator pathMethodComparator) { - this.pathMethodComparator = pathMethodComparator; + 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 7f5aa8ba..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,7 +21,6 @@ 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; @@ -65,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); @@ -78,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(); @@ -117,6 +115,7 @@ public class DefinitionsDocument extends MarkupDocument { } } this.outputDirectory = outputDirectory; + this.definitionOrdering = swagger2MarkupConfig.getDefinitionOrdering(); } @Override @@ -134,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)) { 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 278a67a8..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 @@ -82,9 +82,9 @@ public class PathsDocument extends MarkupDocument { private String descriptionsFolderPath; private final GroupBy pathsGroupedBy; private final int inlineSchemaDepthLevel; - private final Comparator tagComparator; - private final Comparator pathComparator; - private final Comparator pathMethodComparator; + private final Comparator tagOrdering; + private final Comparator pathOrdering; + private final Comparator pathMethodOrdering; private boolean separatedPathsEnabled; private String outputDirectory; @@ -147,9 +147,9 @@ public class PathsDocument extends MarkupDocument { } } this.outputDirectory = outputDirectory; - tagComparator = swagger2MarkupConfig.getTagComparator(); - pathComparator = swagger2MarkupConfig.getPathComparator(); - pathMethodComparator = swagger2MarkupConfig.getPathMethodComparator(); + tagOrdering = swagger2MarkupConfig.getTagOrdering(); + pathOrdering = swagger2MarkupConfig.getPathOrdering(); + pathMethodOrdering = swagger2MarkupConfig.getPathMethodOrdering(); } /** @@ -169,15 +169,14 @@ public class PathsDocument extends MarkupDocument { private void paths(){ Map paths = swagger.getPaths(); if(MapUtils.isNotEmpty(paths)) { - if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED){ + if(pathsGroupedBy == GroupBy.AS_IS){ this.markupDocBuilder.sectionTitleLevel1(PATHS); Set> sortedPaths; - if (pathsGroupedBy == GroupBy.SORTED) { - sortedPaths = new TreeSet<>(new PathUtils.PathPairComparator(this.pathComparator)); - } else { + 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())); } @@ -187,7 +186,7 @@ public class PathsDocument extends MarkupDocument { } } else { this.markupDocBuilder.sectionTitleLevel1(RESOURCES); - Multimap> pathsGroupedByTag = groupPathsByTag(paths, tagComparator, pathComparator); + Multimap> pathsGroupedByTag = groupPathsByTag(paths, tagOrdering, pathOrdering); Map tagsMap = convertTagsListToMap(swagger.getTags()); for(String tagName : pathsGroupedByTag.keySet()){ this.markupDocBuilder.sectionTitleLevel2(WordUtils.capitalize(tagName)); @@ -209,7 +208,11 @@ public class PathsDocument extends MarkupDocument { private void createPathSections(String pathUrl, Path path){ - Map operationsMap = new TreeMap<>(pathMethodComparator); + Map operationsMap; + if (pathMethodOrdering == null) + operationsMap = new LinkedHashMap<>(); + else + operationsMap = new TreeMap<>(pathMethodOrdering); operationsMap.putAll(path.getOperationMap()); for(Map.Entry operationEntry : operationsMap.entrySet()){ @@ -289,7 +292,7 @@ public class PathsDocument extends MarkupDocument { * @param title the path title */ private void addPathTitle(String title, MarkupDocBuilder docBuilder) { - if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED){ + if(pathsGroupedBy == GroupBy.AS_IS){ docBuilder.sectionTitleLevel2(title); }else{ docBuilder.sectionTitleLevel3(title); @@ -302,7 +305,7 @@ public class PathsDocument extends MarkupDocument { * @param title the path title */ private void addPathSectionTitle(String title, MarkupDocBuilder docBuilder) { - if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED){ + if(pathsGroupedBy == GroupBy.AS_IS){ docBuilder.sectionTitleLevel3(title); }else{ docBuilder.sectionTitleLevel4(title); @@ -442,13 +445,17 @@ public class PathsDocument extends MarkupDocument { } private void tagsSection(Operation operation, MarkupDocBuilder docBuilder) { - if(pathsGroupedBy == GroupBy.AS_IS || pathsGroupedBy == GroupBy.SORTED) { + if(pathsGroupedBy == GroupBy.AS_IS) { List tags = operation.getTags(); if (CollectionUtils.isNotEmpty(tags)) { addPathSectionTitle(TAGS, docBuilder); - Set orderedTags = new TreeSet<>(this.tagComparator); - orderedTags.addAll(tags); - this.markupDocBuilder.unorderedList(new ArrayList<>(orderedTags)); + Set sortedTags; + if (tagOrdering == null) + sortedTags = new LinkedHashSet<>(); + else + sortedTags = new TreeSet<>(this.tagOrdering); + sortedTags.addAll(tags); + this.markupDocBuilder.unorderedList(new ArrayList<>(sortedTags)); } } } 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 0a73db5f..cc7f613b 100644 --- a/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java +++ b/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java @@ -37,12 +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 tagComparator; - private final Comparator pathComparator; - private final Comparator pathMethodComparator; + private final Comparator tagOrdering; + private final Comparator pathOrdering; + private final Comparator pathMethodOrdering; + private final Comparator definitionOrdering; /** * @param swagger the Swagger source @@ -56,15 +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 tagComparator specifies a custom comparator function to order tags - * @param pathComparator specifies a custom comparator function to order paths - * @param pathMethodComparator specifies a custom comparator function to order paths methods + * @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, Comparator tagComparator, Comparator pathComparator, - Comparator pathMethodComparator) { + int inlineSchemaDepthLevel, Comparator tagOrdering, Comparator pathOrdering, + Comparator pathMethodOrdering, Comparator definitionOrdering) { this.swagger = swagger; this.markupLanguage = markupLanguage; this.examplesFolderPath = examplesFolderPath; @@ -76,9 +79,10 @@ public class Swagger2MarkupConfig { this.definitionsOrderedBy = definitionsOrderedBy; this.outputLanguage = outputLanguage; this.inlineSchemaDepthLevel = inlineSchemaDepthLevel; - this.tagComparator = tagComparator; - this.pathComparator = pathComparator; - this.pathMethodComparator = pathMethodComparator; + this.tagOrdering = tagOrdering; + this.pathOrdering = pathOrdering; + this.pathMethodOrdering = pathMethodOrdering; + this.definitionOrdering = definitionOrdering; } public Swagger getSwagger() { @@ -125,15 +129,19 @@ public class Swagger2MarkupConfig { return inlineSchemaDepthLevel; } - public Comparator getTagComparator() { - return tagComparator; + public Comparator getTagOrdering() { + return tagOrdering; } - public Comparator getPathComparator() { - return pathComparator; + public Comparator getPathOrdering() { + return pathOrdering; } - public Comparator getPathMethodComparator() { - return pathMethodComparator; + public Comparator getPathMethodOrdering() { + return pathMethodOrdering; + } + + public Comparator getDefinitionOrdering() { + return definitionOrdering; } } 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 a95a4156..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; @@ -75,7 +76,18 @@ public class TagUtils { * @return Paths grouped by Tag */ public static Multimap> groupPathsByTag(Map paths, Comparator tagComparator, Comparator pathComparator) { - Multimap> pathsGroupedByTag = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagComparator).treeSetValues(new PathUtils.PathPairComparator(pathComparator)).build(); + 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(); diff --git a/src/test/resources/yaml/swagger_ordering.yaml b/src/test/resources/yaml/swagger_ordering.yaml index dbd7bc3b..d98de08a 100644 --- a/src/test/resources/yaml/swagger_ordering.yaml +++ b/src/test/resources/yaml/swagger_ordering.yaml @@ -1,6 +1,7 @@ swagger: "2.0" info: title: API + paths: /C: post: @@ -23,4 +24,15 @@ paths: delete: tags: - C - - A \ No newline at end of file + - A + +definitions: + + C: + type: string + + B: + type: string + + A: + type: string