Merge pull request #93 from Swagger2Markup/features/#91-examples-to-ext

fixes #91 : Move SpringRestDocs examples to extension
This commit is contained in:
Robert Winkler
2016-03-01 08:57:11 +01:00
26 changed files with 354 additions and 224 deletions

View File

@@ -69,7 +69,6 @@ public class PathsDocument extends MarkupDocument {
private final String PARAMETERS;
private final String BODY_PARAMETER;
private final String RESPONSES;
private final String EXAMPLE_CURL;
private final String EXAMPLE_REQUEST;
private final String EXAMPLE_RESPONSE;
@@ -80,9 +79,6 @@ public class PathsDocument extends MarkupDocument {
private final String DEPRECATED_OPERATION;
private static final String PATHS_ANCHOR = "paths";
private static final String REQUEST_EXAMPLE_FILE_NAME = "http-request";
private static final String RESPONSE_EXAMPLE_FILE_NAME = "http-response";
private static final String CURL_EXAMPLE_FILE_NAME = "curl-request";
private static final String DESCRIPTION_FILE_NAME = "description";
@@ -97,7 +93,6 @@ public class PathsDocument extends MarkupDocument {
PARAMETERS = labels.getString("parameters");
BODY_PARAMETER = labels.getString("body_parameter");
RESPONSES = labels.getString("responses");
EXAMPLE_CURL = labels.getString("example_curl");
EXAMPLE_REQUEST = labels.getString("example_request");
EXAMPLE_RESPONSE = labels.getString("example_response");
SECURITY = labels.getString("security");
@@ -589,56 +584,7 @@ public class PathsDocument extends MarkupDocument {
}
/**
* Builds the example section of a Swagger Operation. Tries to load the examples from
* curl-request.adoc, http-request.adoc and http-response.adoc or
* curl-request.md, http-request.md and http-response.md.
* Operation folder search order :
* - normalizeOperationFileName(operation.operationId)
* - then, normalizeOperationFileName(operation.method + " " + operation.path)
* - then, normalizeOperationFileName(operation.summary)
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void examplesSection1(PathOperation operation, MarkupDocBuilder docBuilder) {
if (config.isExamplesEnabled()) {
Optional<String> curlExample = example(normalizeName(operation.getId()), CURL_EXAMPLE_FILE_NAME);
if (!curlExample.isPresent())
curlExample = example(normalizeName(operation.getTitle()), CURL_EXAMPLE_FILE_NAME);
if (curlExample.isPresent()) {
addOperationSectionTitle(EXAMPLE_CURL, docBuilder);
docBuilder.paragraph(curlExample.get());
}
Optional<String> requestExample = example(normalizeName(operation.getId()), REQUEST_EXAMPLE_FILE_NAME);
if (!requestExample.isPresent())
requestExample = example(normalizeName(operation.getTitle()), REQUEST_EXAMPLE_FILE_NAME);
if (requestExample.isPresent()) {
addOperationSectionTitle(EXAMPLE_REQUEST, docBuilder);
docBuilder.paragraph(requestExample.get());
}
Optional<String> responseExample = example(normalizeName(operation.getId()), RESPONSE_EXAMPLE_FILE_NAME);
if (!responseExample.isPresent())
responseExample = example(normalizeName(operation.getTitle()), RESPONSE_EXAMPLE_FILE_NAME);
if (responseExample.isPresent()) {
addOperationSectionTitle(EXAMPLE_RESPONSE, docBuilder);
docBuilder.paragraph(responseExample.get());
}
}
}
/**
* Builds the example section of a Swagger Operation. Tries to load the examples from
* curl-request.adoc, http-request.adoc and http-response.adoc or
* curl-request.md, http-request.md and http-response.md.
* Operation folder search order :
* - normalizeOperationFileName(operation.operationId)
* - then, normalizeOperationFileName(operation.method + " " + operation.path)
* - then, normalizeOperationFileName(operation.summary)
* Builds the example section of a Swagger Operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
@@ -646,35 +592,17 @@ public class PathsDocument extends MarkupDocument {
private void examplesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
if (globalContext.config.isExamplesEnabled()) {
Optional<String> curlExample;
Optional<String> requestExample;
Optional<String> responseExample;
Optional<Map<String, Object>> generatedRequestExampleMap;
Optional<Map<String, Object>> generatedResponseExampleMap;
curlExample = example(normalizeName(operation.getId()), CURL_EXAMPLE_FILE_NAME);
if (!curlExample.isPresent())
curlExample = example(normalizeName(operation.getTitle()), CURL_EXAMPLE_FILE_NAME);
requestExample = example(normalizeName(operation.getId()), REQUEST_EXAMPLE_FILE_NAME);
if (!requestExample.isPresent())
requestExample = example(normalizeName(operation.getTitle()), REQUEST_EXAMPLE_FILE_NAME);
responseExample = example(normalizeName(operation.getId()), RESPONSE_EXAMPLE_FILE_NAME);
if (!responseExample.isPresent())
responseExample = example(normalizeName(operation.getTitle()), RESPONSE_EXAMPLE_FILE_NAME);
generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(operation, globalContext.swagger.getDefinitions(), markupDocBuilder);
generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(operation.getOperation(), globalContext.swagger.getDefinitions(), markupDocBuilder);
if (curlExample.isPresent()) {
addOperationSectionTitle(EXAMPLE_CURL, docBuilder);
docBuilder.paragraph(curlExample.get());
}
if (requestExample.isPresent() || generatedRequestExampleMap.isPresent()) {
if (generatedRequestExampleMap.isPresent()) {
addOperationSectionTitle(EXAMPLE_REQUEST, docBuilder);
if (requestExample.isPresent()) {
docBuilder.paragraph(requestExample.get());
}
if (generatedRequestExampleMap.isPresent() && generatedRequestExampleMap.get().size() > 0) {
for (Map.Entry<String, Object> request : generatedRequestExampleMap.get().entrySet()) {
docBuilder.sectionTitleLevel4(REQUEST + " " + request.getKey() + " :");
@@ -683,11 +611,8 @@ public class PathsDocument extends MarkupDocument {
}
}
if (responseExample.isPresent() || generatedResponseExampleMap.isPresent()) {
if (generatedResponseExampleMap.isPresent()) {
addOperationSectionTitle(EXAMPLE_RESPONSE, docBuilder);
if (responseExample.isPresent()) {
docBuilder.paragraph(responseExample.get());
}
if (generatedResponseExampleMap.isPresent() && generatedResponseExampleMap.get().size() > 0) {
for (Map.Entry<String, Object> response : generatedResponseExampleMap.get().entrySet()) {
docBuilder.sectionTitleLevel4(RESPONSE + " " + response.getKey() + " :");
@@ -698,33 +623,6 @@ public class PathsDocument extends MarkupDocument {
}
}
/**
* Reads an example
*
* @param exampleFolder the name of the folder where the example file resides
* @param exampleFileName the name of the example file
* @return the content of the file
*/
private Optional<String> example(String exampleFolder, String exampleFileName) {
for (String fileNameExtension : config.getMarkupLanguage().getFileNameExtensions()) {
URI contentUri = config.getExamplesUri().resolve(exampleFolder).resolve(exampleFileName + fileNameExtension);
try (Reader reader = io.github.robwin.swagger2markup.utils.IOUtils.uriReader(contentUri)) {
if (logger.isInfoEnabled()) {
logger.info("Example content processed {}", contentUri);
}
return Optional.of(IOUtils.toString(reader).trim());
} catch (IOException e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to read example content {} > {}", contentUri, e.getMessage());
}
}
}
return Optional.absent();
}
/**
* Builds the security section of a Swagger Operation.
*
@@ -744,7 +642,7 @@ public class PathsDocument extends MarkupDocument {
for (Map<String, List<String>> securityScheme : securitySchemes) {
for (Map.Entry<String, List<String>> securityEntry : securityScheme.entrySet()) {
String securityKey = securityEntry.getKey();
String type = "UNKNOWN";
String type = "UNKNOWN"; // FIXME -> labels
if (securityDefinitions != null && securityDefinitions.containsKey(securityKey)) {
type = securityDefinitions.get(securityKey).getType();
}

View File

@@ -41,7 +41,6 @@ public class Swagger2MarkupConfig {
private MarkupLanguage markupLanguage;
private boolean examplesEnabled;
private URI examplesUri;
private boolean schemasEnabled;
private URI schemasUri;
private boolean operationDescriptionsEnabled;
@@ -106,15 +105,6 @@ public class Swagger2MarkupConfig {
baseURI = IOUtils.uriParent(swaggerLocation);
}
if (examplesEnabled && examplesUri == null) {
if (baseURI == null) {
if (logger.isWarnEnabled())
logger.warn("Disable {} > No explicit '{}' set and no default available", "examplesEnabled", "examplesUri");
examplesEnabled = false;
} else
examplesUri = baseURI;
}
if (schemasEnabled && schemasUri == null) {
if (baseURI == null) {
if (logger.isWarnEnabled())
@@ -151,10 +141,6 @@ public class Swagger2MarkupConfig {
return examplesEnabled;
}
public URI getExamplesUri() {
return examplesUri;
}
public boolean isSchemasEnabled() {
return schemasEnabled;
}
@@ -317,8 +303,6 @@ public class Swagger2MarkupConfig {
config.markupLanguage = MarkupLanguage.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "markupLanguage"));
config.examplesEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "examplesEnabled"));
if (safeProperties.containsKey(PROPERTIES_PREFIX + "examplesUri"))
config.examplesUri = URI.create(safeProperties.getProperty(PROPERTIES_PREFIX + "examplesUri"));
config.schemasEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "schemasEnabled"));
if (safeProperties.containsKey(PROPERTIES_PREFIX + "schemasUri"))
config.schemasUri = URI.create(safeProperties.getProperty(PROPERTIES_PREFIX + "schemasUri"));
@@ -385,34 +369,10 @@ public class Swagger2MarkupConfig {
/**
* Include examples into the Paths document
*
* @param examplesUri the URI to the folder where the example documents reside. Use default URI if null.
* @return this builder
*/
public Builder withExamples(URI examplesUri) {
config.examplesEnabled = true;
config.examplesUri = examplesUri;
return this;
}
/**
* Include examples into the Paths document
*
* @param examplesPath the path to the folder where the example documents reside. Use default path if null.
* @return this builder
*/
public Builder withExamples(Path examplesPath) {
return withExamples(examplesPath.toUri());
}
/**
* Include examples into the Paths document.<br/>
* This is an alias for {@link #withExamples(URI) withExamples(null)}.
*
* @return this builder
*/
public Builder withExamples() {
withExamples((URI) null);
config.examplesEnabled = true;
return this;
}

View File

@@ -31,4 +31,31 @@ public abstract class DefinitionsContentExtension extends AbstractExtension {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
break;
case DEF_BEGIN:
case DEF_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
}

View File

@@ -1,6 +1,7 @@
package io.github.robwin.swagger2markup.extension;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.PathOperation;
public abstract class OperationsContentExtension extends AbstractExtension {
@@ -32,4 +33,34 @@ public abstract class OperationsContentExtension extends AbstractExtension {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
break;
case OP_BEGIN:
case OP_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
if (globalContext.config.getOperationsGroupedBy() == GroupBy.TAGS) {
levelOffset++;
}
return levelOffset;
}
}

View File

@@ -24,4 +24,28 @@ public abstract class OverviewContentExtension extends AbstractExtension {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
}

View File

@@ -24,4 +24,28 @@ public abstract class SecurityContentExtension extends AbstractExtension {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
}

View File

@@ -0,0 +1,82 @@
package io.github.robwin.swagger2markup.extension.repository;
import com.google.common.base.Optional;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.extension.ContentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
public class ContentExtension {
private static final Logger logger = LoggerFactory.getLogger(ContentExtension.class);
protected final Swagger2MarkupConverter.Context globalContext;
protected final ContentContext contentContext;
public ContentExtension(Swagger2MarkupConverter.Context globalContext, ContentContext contentContext) {
this.globalContext = globalContext;
this.contentContext = contentContext;
}
/**
* Reads contents from a file
*
* @param contentPath content file path
* @return content reader
*/
protected Optional<Reader> readContentPath(Path contentPath) {
if (Files.isReadable(contentPath)) {
if (logger.isInfoEnabled()) {
logger.info("Content file processed: {}", contentPath);
}
try {
Reader contentReader = new FileReader(contentPath.toFile());
return Optional.of(contentReader);
} catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn(String.format("Failed to read content file: %s", contentPath), e);
}
}
} else {
if (logger.isWarnEnabled()) {
logger.warn("Content file is not readable: {}", contentPath);
}
}
return Optional.absent();
}
/**
* Reads content from an Uri
*
* @param contentUri content file URI
* @return content reader
*/
protected Optional<Reader> readContentUri(URI contentUri) {
try {
Reader reader = io.github.robwin.swagger2markup.utils.IOUtils.uriReader(contentUri);
if (logger.isInfoEnabled()) {
logger.info("Content URI processed {}", contentUri);
}
return Optional.of(reader);
} catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to read URI content {} > {}", contentUri, e.getMessage());
}
}
return Optional.absent();
}
}

View File

@@ -12,8 +12,8 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -21,17 +21,12 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class DynamicContentExtension {
public class DynamicContentExtension extends ContentExtension {
private static final Logger logger = LoggerFactory.getLogger(DynamicContentExtension.class);
private final Swagger2MarkupConverter.Context globalContext;
private final ContentContext contentContext;
public DynamicContentExtension(Swagger2MarkupConverter.Context globalContext, ContentContext contentContext) {
this.globalContext = globalContext;
this.contentContext = contentContext;
super(globalContext, contentContext);
}
/**
@@ -63,13 +58,15 @@ public class DynamicContentExtension {
Collections.sort(extensions, Ordering.natural());
for (Path extension : extensions) {
Optional<FileReader> extensionContent = operationExtension(extension);
Optional<Reader> extensionContent = readContentPath(extension);
if (extensionContent.isPresent()) {
try {
contentContext.docBuilder.importMarkup(extensionContent.get(), levelOffset);
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to read extension file: %s", extension), e);
} finally {
extensionContent.get().close();
}
}
}
@@ -81,31 +78,4 @@ public class DynamicContentExtension {
}
}
/**
* Reads an extension
*
* @param extension extension file
* @return extension content reader
*/
protected Optional<FileReader> operationExtension(Path extension) {
if (Files.isReadable(extension)) {
if (logger.isInfoEnabled()) {
logger.info("Extension file processed: {}", extension);
}
try {
return Optional.of(new FileReader(extension.toFile()));
} catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn(String.format("Failed to read extension file: %s", extension), e);
}
}
} else {
if (logger.isWarnEnabled()) {
logger.warn("Extension file is not readable: {}", extension);
}
}
return Optional.absent();
}
}

View File

@@ -58,23 +58,19 @@ public class DynamicDefinitionsContentExtension extends DefinitionsContentExtens
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
case DEF_BEGIN:
case DEF_END:
levelOffset = 2;
dynamicContent.extensionsSection(contentPath.resolve(Paths.get(IOUtils.normalizeName(context.definitionName))), contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath.resolve(Paths.get(IOUtils.normalizeName(context.definitionName))), contentPrefix(context.position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));

View File

@@ -1,6 +1,5 @@
package io.github.robwin.swagger2markup.extension.repository;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.extension.OperationsContentExtension;
import io.github.robwin.swagger2markup.utils.IOUtils;
@@ -59,26 +58,19 @@ public class DynamicOperationsContentExtension extends OperationsContentExtensio
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
case OP_BEGIN:
case OP_END:
levelOffset = 3;
if (globalContext.config.getOperationsGroupedBy() == GroupBy.AS_IS) {
levelOffset = 2;
}
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.operation.getId())), contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.operation.getId())), contentPrefix(context.position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));

View File

@@ -55,18 +55,15 @@ public class DynamicOverviewContentExtension extends OverviewContentExtension {
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));

View File

@@ -55,18 +55,15 @@ public class DynamicSecurityContentExtension extends SecurityContentExtension {
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
int levelOffset;
switch (context.position) {
case DOC_BEFORE:
case DOC_AFTER:
levelOffset = 0;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
case DOC_BEGIN:
case DOC_END:
levelOffset = 1;
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset);
dynamicContent.extensionsSection(contentPath, contentPrefix(context.position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));

View File

@@ -0,0 +1,113 @@
package io.github.robwin.swagger2markup.extension.repository;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import io.github.robwin.swagger2markup.PathOperation;
import io.github.robwin.swagger2markup.extension.OperationsContentExtension;
import io.github.robwin.swagger2markup.utils.IOUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Append Spring Rest docs generated snippets to Operations content.
*/
public class SpringRestDocsExtension extends OperationsContentExtension {
private static final Logger logger = LoggerFactory.getLogger(SpringRestDocsExtension.class);
protected URI snippetUri;
protected Map<String, String> snippets = new LinkedHashMap<>();
/**
* Instantiate extension
* @param snippetUri base URI where are snippets are stored
*/
public SpringRestDocsExtension(URI snippetUri) {
super();
Validate.notNull(snippetUri);
this.snippetUri = snippetUri;
}
/**
* Add SpringRestDocs default snippets to list
* @return this instance
*/
public SpringRestDocsExtension withDefaultSnippets() {
snippets.put("http-request", "HTTP request");
snippets.put("http-response", "HTTP response");
snippets.put("curl-request", "Curl request");
return this;
}
/**
* Builds the subdirectory name where are stored snippets for the given {@code operation}.<br/>
* Default implementation use {@code normalizeName(<operation id>)}, or {@code normalizeName(<operation path>_<operation method>)} if operation id is not set.<br/>
* You can override this method to configure your own folder normalization.
*
* @param operation current operation
* @return subdirectory normalized name
*/
public String operationFolderName(PathOperation operation) {
String id = operation.getOperation().getOperationId();
if (id == null)
id = operation.getId();
return IOUtils.normalizeName(id);
}
/**
* Add an explicit list of snippets to display.
* @param snippets snippets to add. key is snippet name (without extension, e.g.: 'http-request'), value is a custom section title for the snippet.
* @return this instance
*/
public SpringRestDocsExtension withExplicitSnippets(Map<String, String> snippets) {
this.snippets.putAll(snippets);
return this;
}
public void apply(Context context) {
Validate.notNull(context);
switch (context.position) {
case OP_END:
snippets(context);
break;
}
}
public void snippets(Context context) {
for (Map.Entry<String, String> snippets : this.snippets.entrySet()) {
snippetSection(context, snippets.getKey(), snippets.getValue());
}
}
public void snippetSection(Context context, String snippetName, String title) {
ContentExtension content = new ContentExtension(globalContext, context);
Optional<Reader> snippetContent = content.readContentUri(snippetUri.resolve(operationFolderName(context.operation) + "/").resolve(context.docBuilder.addFileExtension(snippetName)));
if (snippetContent.isPresent()) {
try {
context.docBuilder.sectionTitleLevel(1 + levelOffset(context), title);
context.docBuilder.importMarkup(snippetContent.get(), levelOffset(context) + 1);
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to process snippet file: %s", snippetName), e);
} finally {
try {
snippetContent.get().close();
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
}
}

View File

@@ -42,7 +42,6 @@ body_parameter=Body parameter
responses=Responses
response=Response
request=Request
example_curl=Example CURL request
example_request=Example HTTP request
example_response=Example HTTP response
type_column=Type

View File

@@ -42,7 +42,6 @@ body_parameter=Contenu
responses=R\u0233ponses
response=R\u0233ponse
request=Requête
example_curl=Exemple de requête Curl
example_request=Exemple de requête HTTP
example_response=Exemple de r\u0233ponse HTTP
type_column=Type

View File

@@ -42,7 +42,6 @@ request=Request
parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B
body_parameter=Body parameter
responses=\u041E\u0442\u0432\u0435\u0442\u044B
example_curl=\u041F\u0440\u0438\u043C\u0435\u0440 CURL \u0437\u0430\u043F\u0440\u043E\u0441\u0430
example_request=\u041F\u0440\u0438\u043C\u0435\u0440 HTTP \u0437\u0430\u043F\u0440\u043E\u0441\u0430
example_response=\u041F\u0440\u0438\u043C\u0435\u0440 HTTP \u0437\u0430\u043F\u0440\u043E\u0441\u0430
type_column=\u0422\u0438\u043F

View File

@@ -27,6 +27,7 @@ import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.extension.Swagger2MarkupExtensionRegistry;
import io.github.robwin.swagger2markup.extension.repository.DynamicDefinitionsContentExtension;
import io.github.robwin.swagger2markup.extension.repository.DynamicOperationsContentExtension;
import io.github.robwin.swagger2markup.extension.repository.SpringRestDocsExtension;
import io.swagger.models.Swagger;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -73,6 +74,33 @@ public class Swagger2MarkupConverterTest {
asList("definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"));
}
@Test
public void testSwagger2AsciiDocConversionWithSpringRestDocsExtension() throws IOException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger.json"));
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
.withExtension(new SpringRestDocsExtension(Paths.get("src/docs/asciidoc/paths").toUri()).withDefaultSnippets())
.build();
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.withExtensionRegistry(registry)
.build()
.intoFolder(outputDirectory);
//Then
String[] directories = outputDirectory.toFile().list();
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("paths.adoc"))))
.contains("==== HTTP request", "==== HTTP response", "==== Curl request", "===== curl-request");
}
@Test
public void testSwagger2AsciiDocConversionWithExamples() throws IOException {
//Given
@@ -82,7 +110,7 @@ public class Swagger2MarkupConverterTest {
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withExamples(Paths.get("src/docs/asciidoc/paths"))
.withExamples()
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
@@ -534,7 +562,6 @@ public class Swagger2MarkupConverterTest {
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withDefinitionDescriptions()
.withExamples()
.withOperationDescriptions()
.withSchemas()
.build();
@@ -546,7 +573,6 @@ public class Swagger2MarkupConverterTest {
//Then
URI baseUri = io.github.robwin.swagger2markup.utils.IOUtils.uriParent(converterBuilder.globalContext.swaggerLocation);
assertThat(converterBuilder.globalContext.config.getDefinitionDescriptionsUri()).isEqualTo(baseUri);
assertThat(converterBuilder.globalContext.config.getExamplesUri()).isEqualTo(baseUri);
assertThat(converterBuilder.globalContext.config.getOperationDescriptionsUri()).isEqualTo(baseUri);
assertThat(converterBuilder.globalContext.config.getSchemasUri()).isEqualTo(baseUri);
}
@@ -558,7 +584,6 @@ public class Swagger2MarkupConverterTest {
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withDefinitionDescriptions()
.withExamples()
.withOperationDescriptions()
.withSchemas()
.build();
@@ -569,7 +594,6 @@ public class Swagger2MarkupConverterTest {
//Then
assertThat(converterBuilder.globalContext.config.getDefinitionDescriptionsUri()).isNull();
assertThat(converterBuilder.globalContext.config.getExamplesUri()).isNull();
assertThat(converterBuilder.globalContext.config.getOperationDescriptionsUri()).isNull();
assertThat(converterBuilder.globalContext.config.getSchemasUri()).isNull();
}

View File

@@ -46,7 +46,6 @@ public class Swagger2MarkupConfigTest {
assertThat(config.isDefinitionDescriptionsEnabled()).isFalse();
assertThat(config.getDefinitionDescriptionsUri()).isNull();
assertThat(config.isExamplesEnabled()).isFalse();
assertThat(config.getExamplesUri()).isNull();
assertThat(config.getInlineSchemaDepthLevel()).isEqualTo(0);
assertThat(config.getInterDocumentCrossReferencesPrefix()).isNull();
assertThat(config.getMarkupLanguage()).isEqualTo(MarkupLanguage.ASCIIDOC);
@@ -88,7 +87,6 @@ public class Swagger2MarkupConfigTest {
assertThat(config.isDefinitionDescriptionsEnabled()).isTrue();
assertThat(config.getDefinitionDescriptionsUri()).isEqualTo(URI.create("definitionDescriptions"));
assertThat(config.isExamplesEnabled()).isTrue();
assertThat(config.getExamplesUri()).isEqualTo(URI.create("examples"));
assertThat(config.getInlineSchemaDepthLevel()).isEqualTo(2);
assertThat(config.getInterDocumentCrossReferencesPrefix()).isEqualTo("xrefPrefix");
assertThat(config.getMarkupLanguage()).isEqualTo(MarkupLanguage.MARKDOWN);

View File

@@ -1,6 +1,5 @@
swagger2markup.markupLanguage=MARKDOWN
swagger2markup.examplesEnabled=true
swagger2markup.examplesUri=examples
swagger2markup.schemasUri=schemas
swagger2markup.schemasEnabled=true
swagger2markup.operationDescriptionsEnabled=true