Merge pull request #58 from Kabhal/separatedBody

fixed #53 : support for tags, paths and methods ordering
This commit is contained in:
Robert Winkler
2016-02-05 20:44:08 +01:00
21 changed files with 402 additions and 283 deletions

View File

@@ -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"

View File

@@ -17,6 +17,8 @@
*
*/
package io.github.robwin.swagger2markup;
@Deprecated
public enum OrderBy {
AS_IS,
NATURAL

View File

@@ -18,12 +18,14 @@
*/
package io.github.robwin.swagger2markup;
import com.google.common.collect.Ordering;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.builder.document.DefinitionsDocument;
import io.github.robwin.swagger2markup.builder.document.OverviewDocument;
import io.github.robwin.swagger2markup.builder.document.PathsDocument;
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.utils.Consumer;
import io.swagger.models.HttpMethod;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.apache.commons.lang3.Validate;
@@ -32,6 +34,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
/**
* @author Robert Winkler
@@ -44,6 +47,11 @@ public class Swagger2MarkupConverter {
private static final String PATHS_DOCUMENT = "paths";
private static final String DEFINITIONS_DOCUMENT = "definitions";
private static final Comparator<String> DEFAULT_TAG_ORDERING = Ordering.natural();
private static final Comparator<String> DEFAULT_PATH_ORDERING = Ordering.natural();
private static final Comparator<HttpMethod> DEFAULT_PATH_METHOD_ORDERING = Ordering.explicit(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS);
private static final Comparator<String> DEFAULT_DEFINITION_ORDERING = Ordering.natural();
/**
* @param swagger2MarkupConfig the configuration
*/
@@ -147,6 +155,10 @@ public class Swagger2MarkupConverter {
private MarkupLanguage markupLanguage = MarkupLanguage.ASCIIDOC;
private Language outputLanguage = Language.EN;
private int inlineSchemaDepthLevel = 0;
private Comparator<String> tagOrdering = DEFAULT_TAG_ORDERING;
private Comparator<String> pathOrdering = DEFAULT_PATH_ORDERING;
private Comparator<HttpMethod> pathMethodOrdering = DEFAULT_PATH_METHOD_ORDERING;
private Comparator<String> definitionOrdering = DEFAULT_DEFINITION_ORDERING;
/**
* Creates a Builder using a given Swagger source.
@@ -172,7 +184,7 @@ public class Swagger2MarkupConverter {
public Swagger2MarkupConverter build(){
return new Swagger2MarkupConverter(new Swagger2MarkupConfig(swagger, markupLanguage, examplesFolderPath,
schemasFolderPath, descriptionsFolderPath, separatedDefinitions, separatedPaths, pathsGroupedBy, definitionsOrderedBy,
outputLanguage, inlineSchemaDepthLevel));
outputLanguage, inlineSchemaDepthLevel, tagOrdering, pathOrdering, pathMethodOrdering, definitionOrdering));
}
/**
@@ -265,8 +277,10 @@ public class Swagger2MarkupConverter {
* @param definitionsOrderedBy the OrderBy enum
* @return the Swagger2MarkupConverter.Builder
*/
@Deprecated
public Builder withDefinitionsOrderedBy(OrderBy definitionsOrderedBy) {
this.definitionsOrderedBy = definitionsOrderedBy;
this.definitionOrdering = Ordering.natural();
return this;
}
@@ -291,6 +305,59 @@ public class Swagger2MarkupConverter {
this.inlineSchemaDepthLevel = inlineSchemaDepthLevel;
return this;
}
/**
* Specifies a custom comparator function to order tags.
* By default, natural ordering is applied.
* Set ordering to null to keep swagger original order
*
* @param tagOrdering
* @return the Swagger2MarkupConverter.Builder
*/
public Builder withTagOrdering(Comparator<String> tagOrdering) {
this.tagOrdering = tagOrdering;
return this;
}
/**
* Specifies a custom comparator function to order paths.
* By default, natural ordering is applied.
* Set ordering to null to keep swagger original order
*
* @param pathOrdering
* @return the Swagger2MarkupConverter.Builder
*/
public Builder withPathOrdering(Comparator<String> pathOrdering) {
this.pathOrdering = pathOrdering;
return this;
}
/**
* Specifies a custom comparator function to order paths methods.
* By default, explicit ordering is applied : GET, PUT, POST, DELETE, PATCH, HEAD, OPTIONS
* Set ordering to null to keep swagger original order
*
* @param pathMethodOrdering
* @return the Swagger2MarkupConverter.Builder
*/
public Builder withPathMethodOrdering(Comparator<HttpMethod> pathMethodOrdering) {
this.pathMethodOrdering = pathMethodOrdering;
return this;
}
/**
* Specifies a custom comparator function to order definitions.
* By default, natural ordering is applied.
* Set ordering to null to keep swagger original order
*
* @param definitionOrdering
* @return the Swagger2MarkupConverter.Builder
*/
public Builder withDefinitionOrdering(Comparator<String> definitionOrdering) {
this.definitionOrdering = definitionOrdering;
return this;
}
}
}

View File

@@ -21,11 +21,9 @@ package io.github.robwin.swagger2markup.builder.document;
import com.google.common.collect.ImmutableMap;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.markup.builder.MarkupDocBuilders;
import io.github.robwin.swagger2markup.OrderBy;
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.type.ObjectType;
import io.github.robwin.swagger2markup.type.Type;
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
import io.swagger.models.ComposedModel;
import io.swagger.models.Model;
import io.swagger.models.RefModel;
@@ -66,8 +64,8 @@ public class DefinitionsDocument extends MarkupDocument {
private String descriptionsFolderPath;
private boolean separatedDefinitionsEnabled;
private String outputDirectory;
private final OrderBy definitionsOrderedBy;
private final int inlineSchemaDepthLevel;
private final Comparator<String> definitionOrdering;
public DefinitionsDocument(Swagger2MarkupConfig swagger2MarkupConfig, String outputDirectory){
super(swagger2MarkupConfig);
@@ -79,7 +77,6 @@ public class DefinitionsDocument extends MarkupDocument {
XML_SCHEMA = labels.getString("xml_schema");
this.inlineSchemaDepthLevel = swagger2MarkupConfig.getInlineSchemaDepthLevel();
this.definitionsOrderedBy = swagger2MarkupConfig.getDefinitionsOrderedBy();
if(isNotBlank(swagger2MarkupConfig.getSchemasFolderPath())){
this.schemasEnabled = true;
this.schemasFolderPath = swagger2MarkupConfig.getSchemasFolderPath();
@@ -118,6 +115,7 @@ public class DefinitionsDocument extends MarkupDocument {
}
}
this.outputDirectory = outputDirectory;
this.definitionOrdering = swagger2MarkupConfig.getDefinitionOrdering();
}
@Override
@@ -135,11 +133,11 @@ public class DefinitionsDocument extends MarkupDocument {
if(MapUtils.isNotEmpty(definitions)){
this.markupDocBuilder.sectionTitleLevel1(DEFINITIONS);
Set<String> definitionNames;
if(definitionsOrderedBy.equals(OrderBy.AS_IS)){
definitionNames = definitions.keySet();
}else{
definitionNames = new TreeSet<>(definitions.keySet());
}
if (definitionOrdering == null)
definitionNames = new LinkedHashSet<>();
else
definitionNames = new TreeSet<>(definitionOrdering);
definitionNames.addAll(definitions.keySet());
for(String definitionName : definitionNames){
Model model = definitions.get(definitionName);
if(isNotBlank(definitionName)) {
@@ -354,13 +352,24 @@ public class DefinitionsDocument extends MarkupDocument {
}
}
/**
* Inline definitions should never been referenced in TOC, so they are just text.
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor, null);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
private void inlineDefinitions(List<Type> definitions, int depth, MarkupDocBuilder docBuilder) {
if(CollectionUtils.isNotEmpty(definitions)){
for (Type definition: definitions) {
MarkupDocBuilderUtils.sectionTitleLevel(5, definition.getName(), definition.getUniqueName(), docBuilder);
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
List<Type> localDefinitions = typeProperties(definition, depth, new DefinitionPropertyDescriptor(definition), docBuilder);
for (Type localDefinition : localDefinitions)
inlineDefinitions(Arrays.asList(localDefinition), depth - 1, docBuilder);
inlineDefinitions(Collections.singletonList(localDefinition), depth - 1, docBuilder);
}
}

View File

@@ -21,11 +21,11 @@ package io.github.robwin.swagger2markup.builder.document;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.markup.builder.MarkupDocBuilders;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.markup.builder.MarkupTableColumn;
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.type.ObjectType;
import io.github.robwin.swagger2markup.type.RefType;
import io.github.robwin.swagger2markup.type.Type;
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
import io.github.robwin.swagger2markup.utils.PropertyUtils;
import io.swagger.models.Swagger;
import io.swagger.models.properties.Property;
@@ -117,39 +117,43 @@ public abstract class MarkupDocument {
if (type instanceof ObjectType) {
ObjectType objectType = (ObjectType) type;
List<List<String>> cells = new ArrayList<>();
List<String> header = Arrays.asList(NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN);
cells.add(header);
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(NAME_COLUMN, 1),
new MarkupTableColumn(DESCRIPTION_COLUMN, 6),
new MarkupTableColumn(REQUIRED_COLUMN, 1),
new MarkupTableColumn(SCHEMA_COLUMN, 1),
new MarkupTableColumn(DEFAULT_COLUMN, 1));
if (MapUtils.isNotEmpty(objectType.getProperties())) {
for (Map.Entry<String, Property> propertyEntry : objectType.getProperties().entrySet()) {
Property property = propertyEntry.getValue();
String propertyName = propertyEntry.getKey();
Type propertyType = PropertyUtils.getType(property);
if (depth > 0 && propertyType instanceof ObjectType) {
propertyType.setName(propertyName);
propertyType.setUniqueName(uniqueTypeName(propertyName));
localDefinitions.add(propertyType);
if (MapUtils.isNotEmpty(((ObjectType) propertyType).getProperties())) {
propertyType.setName(propertyName);
propertyType.setUniqueName(uniqueTypeName(propertyName));
localDefinitions.add(propertyType);
propertyType = new RefType(propertyType);
propertyType = new RefType(propertyType);
}
}
List<String> content = Arrays.asList(
propertyName,
propertyDescriptor.getDescription(property, propertyName),
Boolean.toString(property.getRequired()),
propertyType.displaySchema(markupLanguage),
propertyType.displaySchema(docBuilder),
PropertyUtils.getDefaultValue(property));
cells.add(content);
}
MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 6, 1, 1, 1), cells, docBuilder);
docBuilder.tableWithColumnSpecs(cols, cells);
}
else {
docBuilder.textLine(NO_CONTENT);
docBuilder.newLine();
}
}
else {
docBuilder.textLine(NO_CONTENT);
docBuilder.newLine();
}
return localDefinitions;

View File

@@ -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();
}
}

View File

@@ -22,13 +22,14 @@ import com.google.common.base.Optional;
import com.google.common.collect.Multimap;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.markup.builder.MarkupDocBuilders;
import io.github.robwin.markup.builder.MarkupTableColumn;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.type.ObjectType;
import io.github.robwin.swagger2markup.type.RefType;
import io.github.robwin.swagger2markup.type.Type;
import io.github.robwin.swagger2markup.utils.MarkupDocBuilderUtils;
import io.github.robwin.swagger2markup.utils.ParameterUtils;
import io.github.robwin.swagger2markup.utils.PathUtils;
import io.github.robwin.swagger2markup.utils.PropertyUtils;
import io.swagger.models.*;
import io.swagger.models.parameters.Parameter;
@@ -81,6 +82,9 @@ public class PathsDocument extends MarkupDocument {
private String descriptionsFolderPath;
private final GroupBy pathsGroupedBy;
private final int inlineSchemaDepthLevel;
private final Comparator<String> tagOrdering;
private final Comparator<String> pathOrdering;
private final Comparator<HttpMethod> pathMethodOrdering;
private boolean separatedPathsEnabled;
private String outputDirectory;
@@ -143,6 +147,9 @@ public class PathsDocument extends MarkupDocument {
}
}
this.outputDirectory = outputDirectory;
tagOrdering = swagger2MarkupConfig.getTagOrdering();
pathOrdering = swagger2MarkupConfig.getPathOrdering();
pathMethodOrdering = swagger2MarkupConfig.getPathMethodOrdering();
}
/**
@@ -162,17 +169,24 @@ public class PathsDocument extends MarkupDocument {
private void paths(){
Map<String, Path> paths = swagger.getPaths();
if(MapUtils.isNotEmpty(paths)) {
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
if(pathsGroupedBy == GroupBy.AS_IS){
this.markupDocBuilder.sectionTitleLevel1(PATHS);
for (Map.Entry<String, Path> pathEntry : paths.entrySet()) {
Path path = pathEntry.getValue();
if(path != null) {
createPathSections(pathEntry.getKey(), path);
}
Set<Pair<String, Path>> sortedPaths;
if (this.pathOrdering == null)
sortedPaths = new LinkedHashSet<>();
else
sortedPaths = new TreeSet<>(new PathUtils.PathPairComparator(this.pathOrdering));
for (Map.Entry<String, Path> e : paths.entrySet()) {
sortedPaths.add(Pair.of(e.getKey(), e.getValue()));
}
}else{
for (Pair<String, Path> pathEntry : sortedPaths) {
createPathSections(pathEntry.getKey(), pathEntry.getValue());
}
} else {
this.markupDocBuilder.sectionTitleLevel1(RESOURCES);
Multimap<String, Pair<String, Path>> pathsGroupedByTag = groupPathsByTag(paths);
Multimap<String, Pair<String, Path>> pathsGroupedByTag = groupPathsByTag(paths, tagOrdering, pathOrdering);
Map<String, Tag> tagsMap = convertTagsListToMap(swagger.getTags());
for(String tagName : pathsGroupedByTag.keySet()){
this.markupDocBuilder.sectionTitleLevel2(WordUtils.capitalize(tagName));
@@ -193,7 +207,15 @@ public class PathsDocument extends MarkupDocument {
}
private void createPathSections(String pathUrl, Path path){
for(Map.Entry<HttpMethod, Operation> operationEntry : path.getOperationMap().entrySet()){
Map<HttpMethod, Operation> operationsMap;
if (pathMethodOrdering == null)
operationsMap = new LinkedHashMap<>();
else
operationsMap = new TreeMap<>(pathMethodOrdering);
operationsMap.putAll(path.getOperationMap());
for(Map.Entry<HttpMethod, Operation> operationEntry : operationsMap.entrySet()){
String methodAndPath = operationEntry.getKey() + " " + pathUrl;
processPath(methodAndPath, operationEntry.getValue());
}
@@ -270,7 +292,7 @@ public class PathsDocument extends MarkupDocument {
* @param title the path title
*/
private void addPathTitle(String title, MarkupDocBuilder docBuilder) {
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
if(pathsGroupedBy == GroupBy.AS_IS){
docBuilder.sectionTitleLevel2(title);
}else{
docBuilder.sectionTitleLevel3(title);
@@ -283,7 +305,7 @@ public class PathsDocument extends MarkupDocument {
* @param title the path title
*/
private void addPathSectionTitle(String title, MarkupDocBuilder docBuilder) {
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
if(pathsGroupedBy == GroupBy.AS_IS){
docBuilder.sectionTitleLevel3(title);
}else{
docBuilder.sectionTitleLevel4(title);
@@ -332,18 +354,24 @@ public class PathsDocument extends MarkupDocument {
List<Type> localDefinitions = new ArrayList<>();
if(CollectionUtils.isNotEmpty(parameters)){
List<List<String>> cells = new ArrayList<>();
// Table header row
List<String> header = Arrays.asList(TYPE_COLUMN, NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN);
cells.add(header);
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(TYPE_COLUMN, 1),
new MarkupTableColumn(NAME_COLUMN, 1),
new MarkupTableColumn(DESCRIPTION_COLUMN, 6),
new MarkupTableColumn(REQUIRED_COLUMN, 1),
new MarkupTableColumn(SCHEMA_COLUMN, 1),
new MarkupTableColumn(DEFAULT_COLUMN, 1));
for(Parameter parameter : parameters){
Type type = ParameterUtils.getType(parameter);
if (inlineSchemaDepthLevel > 0 && type instanceof ObjectType) {
String localTypeName = parameter.getName();
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
String localTypeName = parameter.getName();
type.setName(localTypeName);
type.setUniqueName(uniqueTypeName(localTypeName));
localDefinitions.add(type);
type = new RefType(type);
type.setName(localTypeName);
type.setUniqueName(uniqueTypeName(localTypeName));
localDefinitions.add(type);
type = new RefType(type);
}
}
String parameterType = WordUtils.capitalize(parameter.getIn() + PARAMETER);
// Table content row
@@ -352,12 +380,12 @@ public class PathsDocument extends MarkupDocument {
parameter.getName(),
parameterDescription(operation, parameter, docBuilder),
Boolean.toString(parameter.getRequired()),
type.displaySchema(markupLanguage),
type.displaySchema(markupDocBuilder),
ParameterUtils.getDefaultValue(parameter));
cells.add(content);
}
addPathSectionTitle(PARAMETERS, docBuilder);
MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 1, 6, 1, 1, 1), cells, docBuilder);
docBuilder.tableWithColumnSpecs(cols, cells);
}
return localDefinitions;
@@ -417,11 +445,17 @@ public class PathsDocument extends MarkupDocument {
}
private void tagsSection(Operation operation, MarkupDocBuilder docBuilder) {
if(pathsGroupedBy.equals(GroupBy.AS_IS)) {
if(pathsGroupedBy == GroupBy.AS_IS) {
List<String> tags = operation.getTags();
if (CollectionUtils.isNotEmpty(tags)) {
addPathSectionTitle(TAGS, docBuilder);
docBuilder.unorderedList(tags);
Set<String> sortedTags;
if (tagOrdering == null)
sortedTags = new LinkedHashSet<>();
else
sortedTags = new TreeSet<>(this.tagOrdering);
sortedTags.addAll(tags);
this.markupDocBuilder.unorderedList(new ArrayList<>(sortedTags));
}
}
}
@@ -533,40 +567,50 @@ public class PathsDocument extends MarkupDocument {
List<Type> localDefinitions = new ArrayList<>();
if(MapUtils.isNotEmpty(responses)){
List<List<String>> cells = new ArrayList<>();
cells.add(Arrays.asList(HTTP_CODE_COLUMN, DESCRIPTION_COLUMN, SCHEMA_COLUMN));
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(HTTP_CODE_COLUMN, 1),
new MarkupTableColumn(DESCRIPTION_COLUMN, 6),
new MarkupTableColumn(SCHEMA_COLUMN, 1));
for(Map.Entry<String, Response> entry : responses.entrySet()){
Response response = entry.getValue();
if(response.getSchema() != null){
Property property = response.getSchema();
Type type = PropertyUtils.getType(property);
if (this.inlineSchemaDepthLevel > 0 && type instanceof ObjectType) {
String localTypeName = RESPONSE + " " + entry.getKey();
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
String localTypeName = RESPONSE + " " + entry.getKey();
type.setName(localTypeName);
type.setUniqueName(uniqueTypeName(localTypeName));
localDefinitions.add(type);
type = new RefType(type);
type.setName(localTypeName);
type.setUniqueName(uniqueTypeName(localTypeName));
localDefinitions.add(type);
type = new RefType(type);
}
}
cells.add(Arrays.asList(entry.getKey(), response.getDescription(), type.displaySchema(markupLanguage)));
cells.add(Arrays.asList(entry.getKey(), response.getDescription(), type.displaySchema(markupDocBuilder)));
}else{
cells.add(Arrays.asList(entry.getKey(), response.getDescription(), NO_CONTENT));
}
}
addPathSectionTitle(RESPONSES, docBuilder);
MarkupDocBuilderUtils.tableWithHeaderRow(Arrays.asList(1, 6, 1), cells, docBuilder);
docBuilder.tableWithColumnSpecs(cols, cells);
}
return localDefinitions;
}
/**
* Inline definitions should never been referenced in TOC, so they are just text.
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor, null);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
private void inlineDefinitions(List<Type> definitions, int depth, MarkupDocBuilder docBuilder) {
if(CollectionUtils.isNotEmpty(definitions)){
for (Type definition: definitions) {
if(pathsGroupedBy.equals(GroupBy.AS_IS)){
MarkupDocBuilderUtils.sectionTitleLevel(4, definition.getName(), definition.getUniqueName(), docBuilder);
}else{
MarkupDocBuilderUtils.sectionTitleLevel(5, definition.getName(), definition.getUniqueName(), docBuilder);
}
List<Type> localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), docBuilder);
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
List<Type> localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), this.markupDocBuilder);
for (Type localDefinition : localDefinitions)
inlineDefinitions(Collections.singletonList(localDefinition), depth - 1, docBuilder);
}

View File

@@ -22,8 +22,11 @@ import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.Language;
import io.github.robwin.swagger2markup.OrderBy;
import io.swagger.models.HttpMethod;
import io.swagger.models.Swagger;
import java.util.Comparator;
public class Swagger2MarkupConfig {
private final Swagger swagger;
@@ -34,9 +37,14 @@ public class Swagger2MarkupConfig {
private final boolean separatedDefinitions;
private final boolean separatedPaths;
private final GroupBy pathsGroupedBy;
@Deprecated
private final OrderBy definitionsOrderedBy;
private final Language outputLanguage;
private final int inlineSchemaDepthLevel;
private final Comparator<String> tagOrdering;
private final Comparator<String> pathOrdering;
private final Comparator<HttpMethod> pathMethodOrdering;
private final Comparator<String> definitionOrdering;
/**
* @param swagger the Swagger source
@@ -50,11 +58,16 @@ public class Swagger2MarkupConfig {
* @param definitionsOrderedBy specifies if the definitions should be ordered by natural ordering or stay as-is
* @param outputLanguage specifies language of labels in output files
* @param inlineSchemaDepthLevel specifies the max depth for inline object schema display (0 = no inline schemas)
* @param tagOrdering specifies a custom comparator function to order tags (null = as-is ordering)
* @param pathOrdering specifies a custom comparator function to order paths (null = as-is ordering)
* @param pathMethodOrdering specifies a custom comparator function to order paths methods (null = as-is ordering)
* @param definitionOrdering specifies a custom comparator function to order definitions (null = as-is ordering)
*/
public Swagger2MarkupConfig(Swagger swagger, MarkupLanguage markupLanguage, String examplesFolderPath,
String schemasFolderPath, String descriptionsFolderPath, boolean separatedDefinitions, boolean separatedPaths,
GroupBy pathsGroupedBy, OrderBy definitionsOrderedBy, Language outputLanguage,
int inlineSchemaDepthLevel) {
int inlineSchemaDepthLevel, Comparator<String> tagOrdering, Comparator<String> pathOrdering,
Comparator<HttpMethod> pathMethodOrdering, Comparator<String> definitionOrdering) {
this.swagger = swagger;
this.markupLanguage = markupLanguage;
this.examplesFolderPath = examplesFolderPath;
@@ -66,6 +79,10 @@ public class Swagger2MarkupConfig {
this.definitionsOrderedBy = definitionsOrderedBy;
this.outputLanguage = outputLanguage;
this.inlineSchemaDepthLevel = inlineSchemaDepthLevel;
this.tagOrdering = tagOrdering;
this.pathOrdering = pathOrdering;
this.pathMethodOrdering = pathMethodOrdering;
this.definitionOrdering = definitionOrdering;
}
public Swagger getSwagger() {
@@ -111,4 +128,20 @@ public class Swagger2MarkupConfig {
public int getInlineSchemaDepthLevel() {
return inlineSchemaDepthLevel;
}
public Comparator<String> getTagOrdering() {
return tagOrdering;
}
public Comparator<String> getPathOrdering() {
return pathOrdering;
}
public Comparator<HttpMethod> getPathMethodOrdering() {
return pathMethodOrdering;
}
public Comparator<String> getDefinitionOrdering() {
return definitionOrdering;
}
}

View File

@@ -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";
}
}

View File

@@ -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

View File

@@ -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, ", ") + ")";
}
}

View File

@@ -1,7 +1,8 @@
package io.github.robwin.swagger2markup.type;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.swagger.models.properties.Property;
import org.apache.commons.collections.MapUtils;
import java.util.Map;
@@ -15,8 +16,11 @@ public class ObjectType extends Type {
}
@Override
public String displaySchema(MarkupLanguage language) {
return "object";
public String displaySchema(MarkupDocBuilder docBuilder) {
if (MapUtils.isEmpty(properties))
return "empty object";
else
return "object";
}
public Map<String, Property> getProperties() {

View File

@@ -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());
}
}

View File

@@ -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);
}

View File

@@ -1,116 +0,0 @@
package io.github.robwin.swagger2markup.utils;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.markup.builder.asciidoc.AsciiDoc;
import io.github.robwin.markup.builder.asciidoc.AsciiDocBuilder;
import io.github.robwin.markup.builder.markdown.Markdown;
import io.github.robwin.markup.builder.markdown.MarkdownBuilder;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.join;
/*
* FIXME : this code should go to markup-document-builder project
*/
public class MarkupDocBuilderUtils {
public static String normalizeAsciiDocAnchor(String anchor) {
return anchor.replaceAll("[^0-9a-zA-Z]", "_");
}
public static void anchor(String text, MarkupDocBuilder docBuilder) {
if (docBuilder instanceof AsciiDocBuilder) {
docBuilder.textLine("[[" + normalizeAsciiDocAnchor(text) + "]]");
}
}
public static void crossReference(String text, String anchor, MarkupDocBuilder docBuilder) {
if (docBuilder instanceof AsciiDocBuilder)
docBuilder.textLine(crossReference(text, anchor, MarkupLanguage.ASCIIDOC));
else if (docBuilder instanceof MarkdownBuilder)
docBuilder.textLine(crossReference(text, anchor, MarkupLanguage.MARKDOWN));
}
public static String crossReference(String text, String anchor, MarkupLanguage language) {
if (language == MarkupLanguage.ASCIIDOC) {
String normalizedAnchor = normalizeAsciiDocAnchor(anchor);
if (text == null && !anchor.equals(normalizedAnchor))
text = anchor;
if (text == null)
return AsciiDoc.CROSS_REFERENCE_START + normalizedAnchor + AsciiDoc.CROSS_REFERENCE_END;
else
return AsciiDoc.CROSS_REFERENCE_START + normalizedAnchor + "," + text + AsciiDoc.CROSS_REFERENCE_END;
} else {
if (text == null)
return anchor;
else
return text;
}
}
public static void sectionTitleLevel(int level, String title, String anchor, MarkupDocBuilder docBuilder) {
if (anchor != null)
MarkupDocBuilderUtils.anchor(anchor, docBuilder);
switch (level) {
case 1:
docBuilder.sectionTitleLevel1(title);
break;
case 2:
docBuilder.sectionTitleLevel2(title);
break;
case 3:
docBuilder.sectionTitleLevel3(title);
break;
case 4:
docBuilder.sectionTitleLevel4(title);
break;
case 5:
if (anchor == null)
MarkupDocBuilderUtils.anchor(title, docBuilder);
docBuilder.boldTextLine(title);
break;
case 6:
if (anchor == null)
MarkupDocBuilderUtils.anchor(title, docBuilder);
docBuilder.textLine(title);
break;
default:
throw new RuntimeException("Illegal section level : " + level);
}
}
public static void tableWithHeaderRow(List<Integer> columnWidthRatios, List<List<String>> cells, MarkupDocBuilder docBuilder) {
if (docBuilder instanceof AsciiDocBuilder) {
docBuilder.textLine("[options=\"header\",cols=\"" + join(columnWidthRatios, ",") + "\"]");
docBuilder.textLine(AsciiDoc.TABLE.toString());
for (List<String> cols : cells) {
String row = AsciiDoc.TABLE_COLUMN_DELIMITER + join(Collections2.transform(cols, new Function<String, String>() {
public String apply(final String col) {
return col.replace(AsciiDoc.TABLE_COLUMN_DELIMITER.toString(), "{vbar}");
}
}), AsciiDoc.TABLE_COLUMN_DELIMITER.toString());
docBuilder.textLine(row);
}
docBuilder.textLine(AsciiDoc.TABLE.toString());
} else if (docBuilder instanceof MarkdownBuilder) {
List<String> rows = Lists.newArrayList(Collections2.transform(cells, new Function<List<String>, String>() {
public String apply(List<String> cols) {
return join(Collections2.transform(cols, new Function<String, String>() {
public String apply(final String col) {
return col.replace(Markdown.TABLE_COLUMN_DELIMITER.toString(), "&#124;");
}
}), Markdown.TABLE_COLUMN_DELIMITER.toString());
}
}));
docBuilder.tableWithHeaderRow(rows);
}
}
}

View File

@@ -0,0 +1,45 @@
/*
*
* Copyright 2015 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package io.github.robwin.swagger2markup.utils;
import io.swagger.models.Path;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Comparator;
public class PathUtils {
private static Logger LOG = LoggerFactory.getLogger(PathUtils.class);
public static class PathPairComparator implements Comparator<Pair<String, Path>> {
private Comparator<String> pathComparator;
public PathPairComparator(Comparator<String> pathComparator) {
this.pathComparator = pathComparator;
}
@Override
public int compare(Pair<String, Path> o1, Pair<String, Path> o2) {
return pathComparator.compare(o1.getKey(), o2.getKey());
}
}
}

View File

@@ -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();

View File

@@ -21,6 +21,7 @@ package io.github.robwin.swagger2markup.utils;
import com.google.common.base.Optional;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Ordering;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import io.swagger.models.Path;
@@ -30,10 +31,7 @@ import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class TagUtils {
@@ -77,8 +75,19 @@ public class TagUtils {
* @param paths the Paths
* @return Paths grouped by Tag
*/
public static Multimap<String, Pair<String, Path>> groupPathsByTag(Map<String, Path> paths) {
Multimap<String, Pair<String, Path>> pathsGroupedByTag = MultimapBuilder.SortedSetMultimapBuilder.treeKeys().hashSetValues().build();
public static Multimap<String, Pair<String, Path>> groupPathsByTag(Map<String, Path> paths, Comparator<String> tagComparator, Comparator<String> pathComparator) {
MultimapBuilder.MultimapBuilderWithKeys<String> multimapBuilderWithKeys;
if (tagComparator == null)
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(Ordering.<String>natural()); // FIXME as-is when tagComparator not supported because of limitations in MultiMap::hashkeys()
else
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagComparator);
Multimap<String, Pair<String, Path>> pathsGroupedByTag;
if (pathComparator == null)
pathsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build();
else
pathsGroupedByTag = multimapBuilderWithKeys.treeSetValues(new PathUtils.PathPairComparator(pathComparator)).build();
for (Map.Entry<String, Path> pathEntry : paths.entrySet()) {
String resourcePath = pathEntry.getKey();
Path path = pathEntry.getValue();
@@ -92,7 +101,7 @@ public class TagUtils {
if (LOG.isInfoEnabled()) {
LOG.info("Added path operation '{} {}' to tag '{}'", httpMethod, resourcePath, tag);
}
pathsGroupedByTag.put(tag, Pair.of(resourcePath, pathEntry.getValue()));
pathsGroupedByTag.put(tag, Pair.of(resourcePath, path));
}
}
}

View File

@@ -31,7 +31,6 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -178,7 +177,7 @@ public class Swagger2MarkupConverterTest {
String[] directories = outputDirectory.list();
assertThat(directories).hasSize(3).containsAll(asList("definitions.adoc", "overview.adoc", "paths.adoc"));
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "overview.adoc"))))
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "overview.adoc").toPath())))
.doesNotContain("=== URI scheme");
}
@@ -197,7 +196,7 @@ public class Swagger2MarkupConverterTest {
String[] directories = outputDirectory.list();
assertThat(directories).hasSize(3).containsAll(asList("definitions.adoc", "overview.adoc", "paths.adoc"));
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "overview.adoc"))))
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "overview.adoc").toPath())))
.contains("=== URI scheme");
}
@@ -251,8 +250,8 @@ public class Swagger2MarkupConverterTest {
assertThat(directories).hasSize(4).containsAll(
asList("definitions", "definitions.adoc", "overview.adoc", "paths.adoc"));
File definitionsDirectory = new File(outputDirectory, "definitions");
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.adoc"))))
.contains(new String(Files.readAllBytes(Paths.get(definitionsDirectory + File.separator + "user.adoc"))));
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.adoc").toPath())))
.contains(new String(Files.readAllBytes(new File(definitionsDirectory, "user.adoc").toPath())));
}
@Test
@@ -277,8 +276,8 @@ public class Swagger2MarkupConverterTest {
assertThat(definitions).hasSize(6).containsAll(
asList("identified.md", "user.md", "category.md", "pet.md", "tag.md", "order.md"));
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.md"))))
.contains(new String(Files.readAllBytes(Paths.get(definitionsDirectory + File.separator + "user.md"))));
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.md").toPath())))
.contains(new String(Files.readAllBytes(new File(definitionsDirectory, "user.md").toPath())));
}
@Test
@@ -298,7 +297,7 @@ public class Swagger2MarkupConverterTest {
assertThat(directories).hasSize(4).containsAll(
asList("definitions", "definitions.md", "overview.md", "paths.md"));
verifyMarkdownContainsFieldsInTables(
outputDirectory + File.separator + "definitions.md",
new File(outputDirectory, "definitions.md"),
ImmutableMap.<String, Set<String>>builder()
.put("Identified", ImmutableSet.of("id"))
.put("User", ImmutableSet.of("id", "username", "firstName",
@@ -306,7 +305,7 @@ public class Swagger2MarkupConverterTest {
.build());
File definitionsDirectory = new File(outputDirectory, "definitions");
verifyMarkdownContainsFieldsInTables(
definitionsDirectory + File.separator + "user.md",
new File(definitionsDirectory, "user.md"),
ImmutableMap.<String, Set<String>>builder()
.put("User", ImmutableSet.of("id", "username", "firstName",
"lastName", "email", "password", "phone", "userStatus"))
@@ -329,7 +328,7 @@ public class Swagger2MarkupConverterTest {
.intoFolder(outputDirectory.getAbsolutePath());
//Then
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.adoc"))))
assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.adoc").toPath())))
.contains("== Определения");
}
@@ -337,13 +336,13 @@ public class Swagger2MarkupConverterTest {
* Given a markdown document to search, this checks to see if the specified tables
* have all of the expected fields listed.
*
* @param doc path of markdown document to inspect
* @param doc markdown document file to inspect
* @param fieldsByTable map of table name (header) to field names expected
* to be found in that table.
* @throws IOException if the markdown document could not be read
*/
private static void verifyMarkdownContainsFieldsInTables(String doc, Map<String, Set<String>> fieldsByTable) throws IOException {
final List<String> lines = Files.readAllLines(Paths.get(doc), Charset.defaultCharset());
private static void verifyMarkdownContainsFieldsInTables(File doc, Map<String, Set<String>> fieldsByTable) throws IOException {
final List<String> lines = Files.readAllLines(doc.toPath(), Charset.defaultCharset());
final Map<String, Set<String>> fieldsLeftByTable = Maps.newHashMap();
for(Map.Entry<String, Set<String>> entry : fieldsByTable.entrySet()) {
fieldsLeftByTable.put(entry.getKey(), Sets.newHashSet(entry.getValue()));

View File

@@ -1,9 +1,9 @@
swagger: "2.0"
info:
title: FCU API
description: Outscale FCU service
title: API
description: Service API
version: "2.18"
host: fcu.eu-west-2.outscale.com
host: service.host.com
schemes:
- https
consumes:
@@ -18,28 +18,6 @@ paths:
tags:
- All
parameters:
- $ref: "#/parameters/Version"
- name: array
in: query
type: array
items:
type: string
- name: ref array
in: query
type: array
items:
$ref: '#/definitions/Simple'
- name: csv
in: query
type: array
collectionFormat: pipes
items:
type: boolean
- name: FirstParameter
description: <description>
in: body
schema:
$ref: '#/definitions/Simple'
- name: LaunchCommandRequest
description: Launch something
in: body
@@ -51,10 +29,17 @@ paths:
- MinCount
- MaxCount
properties:
DryRun:
Command:
description: Dummy description
type: boolean
SecurityGroup.N:
type: object
properties:
path:
description: Command path
type: string
args:
description: Command arguments
type: string
Options:
description: Dummy description
type: array
items:
@@ -63,12 +48,9 @@ paths:
Location:
description: Dummy description
$ref: '#/definitions/Location'
KernelId:
description: Dummy description
type: string
responses:
200:
description: Reservation
description: Result
schema:
type: object
properties:
@@ -84,34 +66,29 @@ paths:
$ref: '#/definitions/Error'
parameters:
Version:
name: Version
description: <description>
in: query
type: boolean
definitions:
ExternalLocation:
$ref: ./swagger_inlineSchema.yaml#/definitions/Location
Simple:
description: simple def
type: string
Error:
type: integer
type: object
properties:
error-code:
description: Error code
type: integer
message:
description: Error message
type: string
Location:
type: object
properties:
Loop:
description: <description>
description: Loop
type:
$ref: '#/definitions/Location'
Affinity:
description: <description>
Place:
description: Place
type: string
InlineDepthSchema:
@@ -120,16 +97,24 @@ definitions:
Loop:
type: object
properties:
P1:
description: description P1
p1:
description: Description p1
type: string
p2:
description: description P2
description: Description p2
type: object
properties:
pv1:
description: pv1
p2-1:
description: Description p2-1
type: string
pv2:
description: pv2
type: boolean
p2-2:
description: Description p2-2
type: object
properties:
p2-2-1:
description: Description p2-2-1
type: string
p2-2-2:
description: Description p2-2-2
type: boolean

View File

@@ -0,0 +1,38 @@
swagger: "2.0"
info:
title: API
paths:
/C:
post:
tags:
- C
- B
get:
tags:
- C
- A
/B:
get:
tags:
- B
/A:
get:
tags:
- B
- C
delete:
tags:
- C
- A
definitions:
C:
type: string
B:
type: string
A:
type: string