From 2a486a29397a83902330cdb87c1bca86300f4443 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Wed, 10 Feb 2016 12:29:02 +0100 Subject: [PATCH 1/4] fixed #61 Refactor separated documents logic to support inter-document cross-references --- .../Swagger2MarkupConverter.java | 24 ++--- .../builder/document/DefinitionsDocument.java | 47 ++++++--- .../builder/document/MarkupDocument.java | 51 +++++++++- .../builder/document/OverviewDocument.java | 4 +- .../builder/document/PathsDocument.java | 99 ++++++++++++++----- .../config/Swagger2MarkupConfig.java | 27 +++++ .../robwin/swagger2markup/type/RefType.java | 15 ++- .../swagger2markup/utils/ModelUtils.java | 13 ++- .../swagger2markup/utils/ParameterUtils.java | 11 ++- .../swagger2markup/utils/PropertyUtils.java | 7 +- 10 files changed, 219 insertions(+), 79 deletions(-) diff --git a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java index 24727cc4..f3bb0b6a 100644 --- a/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java +++ b/src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConverter.java @@ -43,14 +43,6 @@ public class Swagger2MarkupConverter { private static final Logger LOG = LoggerFactory.getLogger(Swagger2MarkupConverter.class); private final Swagger2MarkupConfig swagger2MarkupConfig; - private static final String OVERVIEW_DOCUMENT = "overview"; - private static final String PATHS_DOCUMENT = "paths"; - private static final String DEFINITIONS_DOCUMENT = "definitions"; - - private static final Comparator DEFAULT_TAG_ORDERING = Ordering.natural(); - private static final Comparator DEFAULT_PATH_ORDERING = Ordering.natural(); - private static final Comparator DEFAULT_PATH_METHOD_ORDERING = Ordering.explicit(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS); - private static final Comparator DEFAULT_DEFINITION_ORDERING = Ordering.natural(); /** * @param swagger2MarkupConfig the configuration @@ -126,9 +118,9 @@ public class Swagger2MarkupConverter { * @throws IOException if a file cannot be written */ private void buildDocuments(String directory) throws IOException { - new OverviewDocument(swagger2MarkupConfig).build().writeToFile(directory, OVERVIEW_DOCUMENT, StandardCharsets.UTF_8); - new PathsDocument(swagger2MarkupConfig, directory).build().writeToFile(directory, PATHS_DOCUMENT, StandardCharsets.UTF_8); - new DefinitionsDocument(swagger2MarkupConfig, directory).build().writeToFile(directory, DEFINITIONS_DOCUMENT, StandardCharsets.UTF_8); + new OverviewDocument(swagger2MarkupConfig, directory).build().writeToFile(directory, swagger2MarkupConfig.getOverviewDocument(), StandardCharsets.UTF_8); + new PathsDocument(swagger2MarkupConfig, directory).build().writeToFile(directory, swagger2MarkupConfig.getPathsDocument(), StandardCharsets.UTF_8); + new DefinitionsDocument(swagger2MarkupConfig, directory).build().writeToFile(directory, swagger2MarkupConfig.getDefinitionsDocument(), StandardCharsets.UTF_8); } /** @@ -137,7 +129,7 @@ public class Swagger2MarkupConverter { * @return a the document as a String */ private String buildDocuments() { - return new OverviewDocument(swagger2MarkupConfig).build().toString() + return new OverviewDocument(swagger2MarkupConfig, null).build().toString() .concat(new PathsDocument(swagger2MarkupConfig, null).build().toString() .concat(new DefinitionsDocument(swagger2MarkupConfig, null).build().toString())); } @@ -155,10 +147,10 @@ public class Swagger2MarkupConverter { private MarkupLanguage markupLanguage = MarkupLanguage.ASCIIDOC; private Language outputLanguage = Language.EN; private int inlineSchemaDepthLevel = 0; - private Comparator tagOrdering = DEFAULT_TAG_ORDERING; - private Comparator pathOrdering = DEFAULT_PATH_ORDERING; - private Comparator pathMethodOrdering = DEFAULT_PATH_METHOD_ORDERING; - private Comparator definitionOrdering = DEFAULT_DEFINITION_ORDERING; + private Comparator tagOrdering = Ordering.natural(); + private Comparator pathOrdering = Ordering.natural(); + private Comparator pathMethodOrdering = Ordering.explicit(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS); + private Comparator definitionOrdering = Ordering.natural(); /** * Creates a Builder using a given Swagger source. 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 9c9fe4ca..63837af8 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 @@ -32,8 +32,10 @@ import io.swagger.models.refs.RefFormat; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.Validate; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -57,18 +59,15 @@ public class DefinitionsDocument extends MarkupDocument { private static final String XML = "xml"; private static final String DESCRIPTION_FOLDER_NAME = "definitions"; private static final String DESCRIPTION_FILE_NAME = "description"; - private static final String SEPARATED_DEFINITIONS_FOLDER_NAME = "definitions"; private boolean schemasEnabled; private String schemasFolderPath; private boolean handWrittenDescriptionsEnabled; private String descriptionsFolderPath; - private boolean separatedDefinitionsEnabled; - private String outputDirectory; private final int inlineSchemaDepthLevel; private final Comparator definitionOrdering; public DefinitionsDocument(Swagger2MarkupConfig swagger2MarkupConfig, String outputDirectory){ - super(swagger2MarkupConfig); + super(swagger2MarkupConfig, outputDirectory); ResourceBundle labels = ResourceBundle.getBundle("lang/labels", swagger2MarkupConfig.getOutputLanguage().toLocale()); @@ -103,7 +102,6 @@ public class DefinitionsDocument extends MarkupDocument { logger.debug("Include hand-written descriptions is disabled."); } } - this.separatedDefinitionsEnabled = swagger2MarkupConfig.isSeparatedDefinitions(); if(this.separatedDefinitionsEnabled){ if (logger.isDebugEnabled()) { logger.debug("Create separated definition files is enabled."); @@ -114,7 +112,6 @@ public class DefinitionsDocument extends MarkupDocument { logger.debug("Create separated definition files is disabled."); } } - this.outputDirectory = outputDirectory; this.definitionOrdering = swagger2MarkupConfig.getDefinitionOrdering(); } @@ -158,22 +155,28 @@ public class DefinitionsDocument extends MarkupDocument { private void processDefinition(Map definitions, String definitionName, Model model) { - definition(definitions, definitionName, model, this.markupDocBuilder); - if (separatedDefinitionsEnabled) { MarkupDocBuilder defDocBuilder = MarkupDocBuilders.documentBuilder(markupLanguage); definition(definitions, definitionName, model, defDocBuilder); - String definitionFileName = definitionName.toLowerCase(); + File definitionFile = new File(outputDirectory, resolveDefinitionDocument(definitionName)); try { - defDocBuilder.writeToFile(Paths.get(outputDirectory, SEPARATED_DEFINITIONS_FOLDER_NAME).toString(), definitionFileName, StandardCharsets.UTF_8); + String definitionDirectory = FilenameUtils.getFullPath(definitionFile.getPath()); + String definitionFileName = FilenameUtils.getName(definitionFile.getPath()); + + defDocBuilder.writeToFileWithoutExtension(definitionDirectory, definitionFileName, StandardCharsets.UTF_8); } catch (IOException e) { if (logger.isWarnEnabled()) { - logger.warn(String.format("Failed to write definition file: %s", definitionFileName), e); + logger.warn(String.format("Failed to write definition file: %s", definitionFile), e); } } if (logger.isInfoEnabled()) { - logger.info("Separate definition file produced: {}", definitionFileName); + logger.info("Separate definition file produced: {}", definitionFile); } + + definitionRef(definitionName, this.markupDocBuilder); + + } else { + definition(definitions, definitionName, model, this.markupDocBuilder); } } @@ -195,12 +198,20 @@ public class DefinitionsDocument extends MarkupDocument { * @param docBuilder the docbuilder do use for output */ private void definition(Map definitions, String definitionName, Model model, MarkupDocBuilder docBuilder){ - docBuilder.sectionTitleLevel2(definitionName); + addDefinitionTitle(definitionName, docBuilder); descriptionSection(definitionName, model, docBuilder); propertiesSection(definitions, definitionName, model, docBuilder); definitionSchema(definitionName, docBuilder); } + private void addDefinitionTitle(String title, MarkupDocBuilder docBuilder) { + docBuilder.sectionTitleLevel2(title); + } + + private void definitionRef(String definitionName, MarkupDocBuilder docBuilder){ + addDefinitionTitle(docBuilder.crossReferenceAsString(resolveDefinitionDocument(definitionName), definitionName, definitionName), docBuilder); + } + private class DefinitionPropertyDescriptor extends PropertyDescriptor { public DefinitionPropertyDescriptor(Type type) { @@ -230,7 +241,10 @@ public class DefinitionsDocument extends MarkupDocument { Map properties = getAllProperties(definitions, model); Type type = new ObjectType(definitionName, properties); - List localDefinitions = typeProperties(type, inlineSchemaDepthLevel, new PropertyDescriptor(type), docBuilder); + String definitionsRelativePath = null; + if (this.separatedDefinitionsEnabled) + definitionsRelativePath = ".."; + List localDefinitions = typeProperties(type, inlineSchemaDepthLevel, new PropertyDescriptor(type), definitionsRelativePath, docBuilder); inlineDefinitions(localDefinitions, inlineSchemaDepthLevel - 1, docBuilder); } @@ -367,7 +381,10 @@ public class DefinitionsDocument extends MarkupDocument { if(CollectionUtils.isNotEmpty(definitions)){ for (Type definition: definitions) { addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder); - List localDefinitions = typeProperties(definition, depth, new DefinitionPropertyDescriptor(definition), docBuilder); + String definitionsRelativePath = null; + if (this.separatedDefinitionsEnabled) + definitionsRelativePath = ".."; + List localDefinitions = typeProperties(definition, depth, new DefinitionPropertyDescriptor(definition), definitionsRelativePath, docBuilder); for (Type localDefinition : localDefinitions) 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 78105fa6..7755af19 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 @@ -18,6 +18,7 @@ */ package io.github.robwin.swagger2markup.builder.document; +import com.google.common.base.Function; import io.github.robwin.markup.builder.MarkupDocBuilder; import io.github.robwin.markup.builder.MarkupDocBuilders; import io.github.robwin.markup.builder.MarkupLanguage; @@ -33,6 +34,8 @@ import org.apache.commons.collections.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; +import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.*; @@ -59,13 +62,22 @@ public abstract class MarkupDocument { protected Swagger swagger; protected MarkupLanguage markupLanguage; protected MarkupDocBuilder markupDocBuilder; + protected boolean separatedDefinitionsEnabled; + protected String separatedDefinitionsFolder; + protected String definitionsDocument; + protected String outputDirectory; + protected static AtomicInteger typeIdCount = new AtomicInteger(0); - MarkupDocument(Swagger2MarkupConfig swagger2MarkupConfig) { + MarkupDocument(Swagger2MarkupConfig swagger2MarkupConfig, String outputDirectory) { this.swagger = swagger2MarkupConfig.getSwagger(); this.markupLanguage = swagger2MarkupConfig.getMarkupLanguage(); this.markupDocBuilder = MarkupDocBuilders.documentBuilder(markupLanguage); + this.separatedDefinitionsEnabled = swagger2MarkupConfig.isSeparatedDefinitions(); + this.separatedDefinitionsFolder = swagger2MarkupConfig.getSeparatedDefinitionsFolder(); + this.definitionsDocument = swagger2MarkupConfig.getDefinitionsDocument(); + this.outputDirectory = outputDirectory; ResourceBundle labels = ResourceBundle.getBundle("lang/labels", swagger2MarkupConfig.getOutputLanguage().toLocale()); @@ -81,6 +93,39 @@ public abstract class MarkupDocument { NO_CONTENT = labels.getString("no_content"); } + protected String normalizeDefinitionFileName(String definitionName) { + return definitionName.toLowerCase(); + } + + protected String resolveDefinitionDocument(String definitionName, String relativePath) { + if (this.outputDirectory == null) + return null; + else if (this.separatedDefinitionsEnabled) + return new File(new File(relativePath, this.separatedDefinitionsFolder), this.markupDocBuilder.addfileExtension(normalizeDefinitionFileName(definitionName))).getPath(); + else + return new File(relativePath, this.markupDocBuilder.addfileExtension(this.definitionsDocument)).getPath(); + } + + protected String resolveDefinitionDocument(String definitionName) { + return resolveDefinitionDocument(definitionName, null); + } + + class DefinitionDocumentResolver implements Function { + private String relativePath; + + public DefinitionDocumentResolver(String relativePath) { + this.relativePath = relativePath; + } + + public DefinitionDocumentResolver() {} + + @Nullable + @Override + public String apply(@Nullable String definitionName) { + return resolveDefinitionDocument(definitionName, relativePath); + } + } + /** * Builds the MarkupDocument. * @@ -112,7 +157,7 @@ public abstract class MarkupDocument { return name + "-" + typeIdCount.getAndIncrement(); } - public List typeProperties(Type type, int depth, PropertyDescriptor propertyDescriptor, MarkupDocBuilder docBuilder) { + public List typeProperties(Type type, int depth, PropertyDescriptor propertyDescriptor, String definitionsRelativePath, MarkupDocBuilder docBuilder) { List localDefinitions = new ArrayList<>(); if (type instanceof ObjectType) { ObjectType objectType = (ObjectType) type; @@ -127,7 +172,7 @@ public abstract class MarkupDocument { for (Map.Entry propertyEntry : objectType.getProperties().entrySet()) { Property property = propertyEntry.getValue(); String propertyName = propertyEntry.getKey(); - Type propertyType = PropertyUtils.getType(property); + Type propertyType = PropertyUtils.getType(property, new DefinitionDocumentResolver(definitionsRelativePath)); if (depth > 0 && propertyType instanceof ObjectType) { if (MapUtils.isNotEmpty(((ObjectType) propertyType).getProperties())) { propertyType.setName(propertyName); 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 8be64943..165104cc 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 @@ -45,8 +45,8 @@ public class OverviewDocument extends MarkupDocument { private final String BASE_PATH; private final String SCHEMES; - public OverviewDocument(Swagger2MarkupConfig swagger2MarkupConfig){ - super(swagger2MarkupConfig); + public OverviewDocument(Swagger2MarkupConfig swagger2MarkupConfig, String outputDirectory){ + super(swagger2MarkupConfig, outputDirectory); ResourceBundle labels = ResourceBundle.getBundle("lang/labels", swagger2MarkupConfig.getOutputLanguage().toLocale()); 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 07fc2fa8..34625932 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 @@ -37,10 +37,12 @@ import io.swagger.models.properties.Property; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.tuple.Pair; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -49,8 +51,7 @@ import java.util.*; import java.util.regex.Pattern; import static io.github.robwin.swagger2markup.utils.TagUtils.*; -import static org.apache.commons.lang3.StringUtils.defaultString; -import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.apache.commons.lang3.StringUtils.*; /** * @author Robert Winkler @@ -72,7 +73,6 @@ public class PathsDocument extends MarkupDocument { private static final String CURL_EXAMPLE_FILE_NAME = "curl-request"; private static final String DESCRIPTION_FOLDER_NAME = "paths"; private static final String DESCRIPTION_FILE_NAME = "description"; - private static final String SEPARATED_PATHS_FOLDER_NAME = "paths"; private final String PARAMETER; private static final Pattern FILENAME_FORBIDDEN_PATTERN = Pattern.compile("[^0-9A-Za-z-_]+"); @@ -86,10 +86,12 @@ public class PathsDocument extends MarkupDocument { private final Comparator pathOrdering; private final Comparator pathMethodOrdering; private boolean separatedPathsEnabled; - private String outputDirectory; + private String separatedPathsFolder; + private String pathsDocument; + public PathsDocument(Swagger2MarkupConfig swagger2MarkupConfig, String outputDirectory){ - super(swagger2MarkupConfig); + super(swagger2MarkupConfig, outputDirectory); ResourceBundle labels = ResourceBundle.getBundle("lang/labels", swagger2MarkupConfig.getOutputLanguage().toLocale()); @@ -105,6 +107,7 @@ public class PathsDocument extends MarkupDocument { HTTP_CODE_COLUMN = labels.getString("http_code_column"); PARAMETER = labels.getString("parameter"); + this.pathsDocument = swagger2MarkupConfig.getPathsDocument(); this.inlineSchemaDepthLevel = swagger2MarkupConfig.getInlineSchemaDepthLevel(); this.pathsGroupedBy = swagger2MarkupConfig.getPathsGroupedBy(); if(isNotBlank(swagger2MarkupConfig.getExamplesFolderPath())){ @@ -136,6 +139,7 @@ public class PathsDocument extends MarkupDocument { } this.separatedPathsEnabled = swagger2MarkupConfig.isSeparatedPaths(); + this.separatedPathsFolder = swagger2MarkupConfig.getSeparatedPathsFolder(); if(this.separatedPathsEnabled){ if (logger.isDebugEnabled()) { logger.debug("Create separated path files is enabled."); @@ -146,7 +150,6 @@ public class PathsDocument extends MarkupDocument { logger.debug("Create separated path files is disabled."); } } - this.outputDirectory = outputDirectory; tagOrdering = swagger2MarkupConfig.getTagOrdering(); pathOrdering = swagger2MarkupConfig.getPathOrdering(); pathMethodOrdering = swagger2MarkupConfig.getPathMethodOrdering(); @@ -221,30 +224,61 @@ public class PathsDocument extends MarkupDocument { } } - private void processPath(String methodAndPath, Operation operation) { + private String normalizePathFileName(String methodAndPath, Operation operation) { + String pathFileName = operation.getOperationId(); - path(methodAndPath, operation, this.markupDocBuilder); + if (pathFileName == null) + pathFileName = methodAndPath; + pathFileName = FILENAME_FORBIDDEN_PATTERN.matcher(pathFileName).replaceAll("_").toLowerCase(); + return pathFileName; + } + + private String resolvePathDocument(String methodAndPath, Operation operation) { + if (this.outputDirectory == null) + return null; + else if (this.separatedPathsEnabled) + return "./" + this.separatedPathsFolder + "/" + this.markupDocBuilder.addfileExtension(normalizePathFileName(methodAndPath, operation)); + else + return "./" + this.markupDocBuilder.addfileExtension(this.pathsDocument); + } + + private void processPath(String methodAndPath, Operation operation) { if (separatedPathsEnabled) { MarkupDocBuilder pathDocBuilder = MarkupDocBuilders.documentBuilder(markupLanguage); path(methodAndPath, operation, pathDocBuilder); - String pathFileName = operation.getOperationId(); - if (pathFileName == null) - pathFileName = methodAndPath; - pathFileName = FILENAME_FORBIDDEN_PATTERN.matcher(pathFileName).replaceAll("_").toLowerCase(); + File pathFile = new File(outputDirectory, resolvePathDocument(methodAndPath, operation)); + try { - pathDocBuilder.writeToFile(Paths.get(outputDirectory, SEPARATED_PATHS_FOLDER_NAME).toString(), pathFileName, StandardCharsets.UTF_8); + String pathDirectory = FilenameUtils.getFullPath(pathFile.getPath()); + String pathFileName = FilenameUtils.getName(pathFile.getPath()); + + pathDocBuilder.writeToFileWithoutExtension(pathDirectory, pathFileName, StandardCharsets.UTF_8); } catch (IOException e) { if (logger.isWarnEnabled()) { - logger.warn(String.format("Failed to write path file: %s", pathFileName), e); + logger.warn(String.format("Failed to write path file: %s", pathFile), e); } } if (logger.isInfoEnabled()) { - logger.info("Separate path file produced: {}", pathFileName); + logger.info("Separate path file produced: {}", pathFile); } + + pathRef(methodAndPath, operation, this.markupDocBuilder); + + } else { + path(methodAndPath, operation, this.markupDocBuilder); } } + + private String operationName(String methodAndPath, Operation operation) { + String operationName = operation.getSummary(); + if(isBlank(operationName)) { + operationName = methodAndPath; + } + return operationName; + } + /** * Builds an operation. * @@ -264,6 +298,18 @@ public class PathsDocument extends MarkupDocument { } } + /** + * Builds a cross-reference to separated path file + * @param methodAndPath the Method of the operation and the URL of the path + * @param operation the Swagger Operation + */ + private void pathRef(String methodAndPath, Operation operation, MarkupDocBuilder docBuilder) { + String document = resolvePathDocument(methodAndPath, operation); + String operationName = operationName(methodAndPath, operation); + + addPathTitle(docBuilder.crossReferenceAsString(document, operationName, operationName), docBuilder); + } + /** * Adds the path title to the document. If the operation has a summary, the title is the summary. * Otherwise the title is the method of the operation and the URL of the path. @@ -272,15 +318,13 @@ public class PathsDocument extends MarkupDocument { * @param operation the Swagger Operation */ private void pathTitle(String methodAndPath, Operation operation, MarkupDocBuilder docBuilder) { - String summary = operation.getSummary(); - String title; - if(isNotBlank(summary)) { - title = summary; - addPathTitle(title, docBuilder); + String operationName = operationName(methodAndPath, operation); + + addPathTitle(operationName, docBuilder); + if(operationName.equals(operation.getSummary())) { docBuilder.listing(methodAndPath); - }else{ - addPathTitle(methodAndPath, docBuilder); } + if (logger.isInfoEnabled()) { logger.info("Path processed: {}", methodAndPath); } @@ -362,7 +406,7 @@ public class PathsDocument extends MarkupDocument { new MarkupTableColumn(SCHEMA_COLUMN, 1), new MarkupTableColumn(DEFAULT_COLUMN, 1)); for(Parameter parameter : parameters){ - Type type = ParameterUtils.getType(parameter); + Type type = ParameterUtils.getType(parameter, new DefinitionDocumentResolver()); if (inlineSchemaDepthLevel > 0 && type instanceof ObjectType) { if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) { String localTypeName = parameter.getName(); @@ -455,7 +499,7 @@ public class PathsDocument extends MarkupDocument { else sortedTags = new TreeSet<>(this.tagOrdering); sortedTags.addAll(tags); - this.markupDocBuilder.unorderedList(new ArrayList<>(sortedTags)); + docBuilder.unorderedList(new ArrayList<>(sortedTags)); } } } @@ -575,7 +619,7 @@ public class PathsDocument extends MarkupDocument { Response response = entry.getValue(); if(response.getSchema() != null){ Property property = response.getSchema(); - Type type = PropertyUtils.getType(property); + Type type = PropertyUtils.getType(property, new DefinitionDocumentResolver()); if (this.inlineSchemaDepthLevel > 0 && type instanceof ObjectType) { if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) { String localTypeName = RESPONSE + " " + entry.getKey(); @@ -610,7 +654,10 @@ public class PathsDocument extends MarkupDocument { if(CollectionUtils.isNotEmpty(definitions)){ for (Type definition: definitions) { addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder); - List localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), this.markupDocBuilder); + String definitionsRelativePath = null; + if (this.separatedPathsEnabled) + definitionsRelativePath = ".."; + List localDefinitions = typeProperties(definition, depth, new PropertyDescriptor(definition), definitionsRelativePath, docBuilder); for (Type localDefinition : localDefinitions) inlineDefinitions(Collections.singletonList(localDefinition), depth - 1, docBuilder); } diff --git a/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java b/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java index cc7f613b..4af02945 100644 --- a/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java +++ b/src/main/java/io/github/robwin/swagger2markup/config/Swagger2MarkupConfig.java @@ -46,6 +46,13 @@ public class Swagger2MarkupConfig { private final Comparator pathMethodOrdering; private final Comparator definitionOrdering; + private static final String OVERVIEW_DOCUMENT = "overview"; + private static final String PATHS_DOCUMENT = "paths"; + private static final String DEFINITIONS_DOCUMENT = "definitions"; + + private static final String SEPARATED_DEFINITIONS_FOLDER = "definitions"; + private static final String SEPARATED_PATHS_FOLDER = "paths"; + /** * @param swagger the Swagger source * @param markupLanguage the markup language which is used to generate the files @@ -144,4 +151,24 @@ public class Swagger2MarkupConfig { public Comparator getDefinitionOrdering() { return definitionOrdering; } + + public String getOverviewDocument() { + return OVERVIEW_DOCUMENT; + } + + public String getPathsDocument() { + return PATHS_DOCUMENT; + } + + public String getDefinitionsDocument() { + return DEFINITIONS_DOCUMENT; + } + + public String getSeparatedDefinitionsFolder() { + return SEPARATED_DEFINITIONS_FOLDER; + } + + public String getSeparatedPathsFolder() { + return SEPARATED_PATHS_FOLDER; + } } 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 d6e9186c..2aba2155 100644 --- a/src/main/java/io/github/robwin/swagger2markup/type/RefType.java +++ b/src/main/java/io/github/robwin/swagger2markup/type/RefType.java @@ -4,8 +4,11 @@ import io.github.robwin.markup.builder.MarkupDocBuilder; public class RefType extends Type { - public RefType(String name) { + private String document; + + public RefType(String document, String name) { super(name); + this.document = document; } public RefType(Type type) { @@ -14,6 +17,14 @@ public class RefType extends Type { @Override public String displaySchema(MarkupDocBuilder docBuilder) { - return docBuilder.crossReferenceAsString(getUniqueName(), getName()); + return docBuilder.crossReferenceAsString(getDocument(), getUniqueName(), getName()); + } + + public String getDocument() { + return document; + } + + public void setDocument(String document) { + this.document = document; } } diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/ModelUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/ModelUtils.java index 9e2d5fac..e4d3880e 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/ModelUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/ModelUtils.java @@ -18,10 +18,8 @@ */ package io.github.robwin.swagger2markup.utils; -import io.github.robwin.swagger2markup.type.ArrayType; -import io.github.robwin.swagger2markup.type.ObjectType; -import io.github.robwin.swagger2markup.type.RefType; -import io.github.robwin.swagger2markup.type.Type; +import com.google.common.base.Function; +import io.github.robwin.swagger2markup.type.*; import io.swagger.models.ArrayModel; import io.swagger.models.Model; import io.swagger.models.ModelImpl; @@ -36,15 +34,16 @@ public final class ModelUtils { * @param model the model * @return the type of the model, or otherwise null */ - public static Type getType(Model model) { + public static Type getType(Model model, Function definitionDocumentResolver) { Validate.notNull(model, "model must not be null!"); if (model instanceof ModelImpl) { return new ObjectType(null, model.getProperties()); } else if (model instanceof RefModel) { - return new RefType(((RefModel) model).getSimpleRef()); + String simpleRef = ((RefModel) model).getSimpleRef(); + return new RefType(definitionDocumentResolver.apply(simpleRef), simpleRef); } else if (model instanceof ArrayModel) { ArrayModel arrayModel = ((ArrayModel) model); - return new ArrayType(null, PropertyUtils.getType(arrayModel.getItems())); + return new ArrayType(null, PropertyUtils.getType(arrayModel.getItems(), definitionDocumentResolver)); } return null; } diff --git a/src/main/java/io/github/robwin/swagger2markup/utils/ParameterUtils.java b/src/main/java/io/github/robwin/swagger2markup/utils/ParameterUtils.java index 112c0a77..82a3fffd 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/ParameterUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/ParameterUtils.java @@ -18,6 +18,7 @@ */ package io.github.robwin.swagger2markup.utils; +import com.google.common.base.Function; import io.github.robwin.swagger2markup.type.*; import io.swagger.models.Model; import io.swagger.models.parameters.AbstractSerializableParameter; @@ -40,14 +41,14 @@ public final class ParameterUtils { * @param parameter the parameter * @return the type of the parameter, or otherwise null */ - public static Type getType(Parameter parameter){ + public static Type getType(Parameter parameter, Function definitionDocumentResolver){ Validate.notNull(parameter, "parameter must not be null!"); Type type = null; if(parameter instanceof BodyParameter){ BodyParameter bodyParameter = (BodyParameter)parameter; Model model = bodyParameter.getSchema(); if(model != null){ - type = ModelUtils.getType(model); + type = ModelUtils.getType(model, definitionDocumentResolver); }else{ type = new BasicType("string"); } @@ -63,12 +64,12 @@ public final class ParameterUtils { } if(type.getName().equals("array")){ String collectionFormat = serializableParameter.getCollectionFormat(); - type = new ArrayType(null, PropertyUtils.getType(serializableParameter.getItems()), collectionFormat); + type = new ArrayType(null, PropertyUtils.getType(serializableParameter.getItems(), definitionDocumentResolver), collectionFormat); } } else if(parameter instanceof RefParameter){ - RefParameter refParameter = (RefParameter)parameter; - type = new RefType(refParameter.getSimpleRef()); + String simpleRef = ((RefParameter)parameter).getSimpleRef(); + type = new RefType(definitionDocumentResolver.apply(simpleRef), simpleRef); } return type; } 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 581e6a0c..e6c0cb88 100644 --- a/src/main/java/io/github/robwin/swagger2markup/utils/PropertyUtils.java +++ b/src/main/java/io/github/robwin/swagger2markup/utils/PropertyUtils.java @@ -18,6 +18,7 @@ */ package io.github.robwin.swagger2markup.utils; +import com.google.common.base.Function; import io.github.robwin.swagger2markup.type.*; import io.swagger.models.properties.*; import io.swagger.models.refs.RefFormat; @@ -37,7 +38,7 @@ public final class PropertyUtils { * @param property the property * @return the type of the property */ - public static Type getType(Property property){ + public static Type getType(Property property, Function definitionDocumentResolver){ Validate.notNull(property, "property must not be null!"); Type type; if(property instanceof RefProperty){ @@ -45,11 +46,11 @@ public final class PropertyUtils { 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()); + type = new RefType(definitionDocumentResolver.apply(refProperty.getSimpleRef()), refProperty.getSimpleRef()); }else if(property instanceof ArrayProperty){ ArrayProperty arrayProperty = (ArrayProperty)property; Property items = arrayProperty.getItems(); - type = new ArrayType(null, getType(items)); + type = new ArrayType(null, getType(items, definitionDocumentResolver)); }else if(property instanceof StringProperty){ StringProperty stringProperty = (StringProperty)property; List enums = stringProperty.getEnum(); From eddbd9610eb82cda473ed31743438f428a5978f5 Mon Sep 17 00:00:00 2001 From: Robert Winkler Date: Wed, 10 Feb 2016 13:32:14 +0100 Subject: [PATCH 2/4] Updated RELEASENOTES --- RELEASENOTES.adoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/RELEASENOTES.adoc b/RELEASENOTES.adoc index 3e96f98d..aa9497ca 100644 --- a/RELEASENOTES.adoc +++ b/RELEASENOTES.adoc @@ -77,4 +77,10 @@ * Multi language support. Added russian. === Version 0.9.3 -* Updated swagger-parser from v1.0.13 to v1.0.16 \ No newline at end of file +* Updated swagger-parser from v1.0.13 to v1.0.16 +* Enhancement #61 Refactor separated documents logic to support inter-document cross-references +* Enhancement #53 : support for tags, paths and methods ordering +* Enhancement #51 : Support for separated operations files +* Enhancement #52: Markdown generation for inline schemas + + From 7cb9b97bfba35a7dc8c3c759e5faad1d5ed72a4c Mon Sep 17 00:00:00 2001 From: Robert Winkler Date: Wed, 10 Feb 2016 13:39:35 +0100 Subject: [PATCH 3/4] Updated swagger-compat-spec-parser from 1.0.16 to 1.0.17 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 839f7697..c2883928 100644 --- a/build.gradle +++ b/build.gradle @@ -59,7 +59,7 @@ dependencies { dependencyManagement { dependencies { dependency "io.github.robwin:markup-document-builder:0.1.6-SNAPSHOT" - dependency "io.swagger:swagger-compat-spec-parser:1.0.16" + dependency "io.swagger:swagger-compat-spec-parser:1.0.17" dependency "commons-collections:commons-collections:3.2.1" dependency "commons-io:commons-io:2.4" dependency "junit:junit:4.11" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 70bf843d..4cc1564c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Feb 07 12:01:31 CET 2016 +#Wed Feb 10 13:33:16 CET 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip From c291991236c5332d527bebd7c118ea4004d555a1 Mon Sep 17 00:00:00 2001 From: Hugo de Paix de Coeur Date: Wed, 10 Feb 2016 13:40:18 +0100 Subject: [PATCH 4/4] Fixed tests (no way to compare output to definitions. as the generation logic changed) : definitions. is now just a link list to separated files --- .../Swagger2MarkupConverterTest.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java b/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java index ecd98266..b4873fd3 100644 --- a/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java +++ b/src/test/java/io/github/robwin/swagger2markup/Swagger2MarkupConverterTest.java @@ -249,9 +249,6 @@ public class Swagger2MarkupConverterTest { String[] directories = outputDirectory.list(); assertThat(directories).hasSize(4).containsAll( asList("definitions", "definitions.adoc", "overview.adoc", "paths.adoc")); - File definitionsDirectory = new File(outputDirectory, "definitions"); - assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.adoc").toPath()))) - .contains(new String(Files.readAllBytes(new File(definitionsDirectory, "user.adoc").toPath()))); } @Test @@ -275,9 +272,6 @@ public class Swagger2MarkupConverterTest { String[] definitions = definitionsDirectory.list(); assertThat(definitions).hasSize(6).containsAll( asList("identified.md", "user.md", "category.md", "pet.md", "tag.md", "order.md")); - - assertThat(new String(Files.readAllBytes(new File(outputDirectory, "definitions.md").toPath()))) - .contains(new String(Files.readAllBytes(new File(definitionsDirectory, "user.md").toPath()))); } @Test @@ -296,13 +290,7 @@ public class Swagger2MarkupConverterTest { String[] directories = outputDirectory.list(); assertThat(directories).hasSize(4).containsAll( asList("definitions", "definitions.md", "overview.md", "paths.md")); - verifyMarkdownContainsFieldsInTables( - 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()); + File definitionsDirectory = new File(outputDirectory, "definitions"); verifyMarkdownContainsFieldsInTables( new File(definitionsDirectory, "user.md"),