Compare commits

...

447 Commits

Author SHA1 Message Date
ShubhamRwt
504bdb8e6c fixed gh pages 2022-03-01 12:44:13 +05:30
ShubhamRwt
0b6f4fb7e6 Fixing the docmentation for 1.3.4 2022-02-25 16:37:16 +05:30
ShubhamRwt
8748254d5a fixes for releasing 1.3.4 2022-02-22 14:56:21 +05:30
ShubhamRwt
7917565654 fixes for releasing 1.3.4 2022-02-22 14:22:38 +05:30
ShubhamRwt
30b41b0d70 Releasing 1.3.4 2022-02-22 13:49:22 +05:30
ShubhamRwt
a421b6d83a Releasing 1.3.4 2022-02-22 13:40:35 +05:30
ShubhamRwt
a8665290a0 Releasing 1.3.4 2022-02-21 15:25:20 +05:30
ShubhamRwt
61af76927e Release notes for 1.3.4 2022-02-21 15:14:33 +05:30
Shubham Rawat
2ffe3d5b8e Merge pull request #432 from Swagger2Markup/revert-431-signing
Revert "Added signing"
2022-02-18 22:03:47 +05:30
Shubham Rawat
03b5c42696 Revert "Added signing" 2022-02-18 22:03:27 +05:30
Shubham Rawat
f9b812a58d Merge pull request #431 from ShubhamRwt/signing
Added signing
2022-02-18 22:00:21 +05:30
ShubhamRwt
16cd99aece changes 2022-02-18 21:51:07 +05:30
ShubhamRwt
368bed514e github action file changes 2022-02-18 17:10:50 +05:30
Shubham Rawat
1492c40fc2 Merge pull request #430 from ShubhamRwt/github
github action file
2022-02-17 16:20:52 +05:30
Shubham Rawat
dafa73832e Update gradle-build.yml 2022-02-17 16:18:03 +05:30
Shubham Rawat
702a2cb180 Update gradle-build.yml 2022-02-17 15:38:54 +05:30
ShubhamRwt
89dbbc284b github action file 2022-02-17 15:30:04 +05:30
Shubham Rawat
6023d015b6 Merge pull request #429 from ShubhamRwt/1.3.x
Changing the build.gradle file
2022-02-17 15:22:55 +05:30
ShubhamRwt
ea2e61cfd9 Changing the build.gradle 2022-02-17 15:22:06 +05:30
ShubhamRwt
bdcbd0069c Changing the build.gradle 2022-02-17 15:15:54 +05:30
austek
859312b7d2 Remove OpenApi2Markup for 1.3.x release 2020-11-11 06:00:16 +00:00
Stefan Larsson
9de5ad0157 Fix Javadoc, added missing parameters and replaced with valid html (#415) 2020-11-05 08:45:30 +01:00
Aaron Watry
61df613cd2 tests: Update swagger petstore URLs from http to https to fix failing tests (#411)
Accessing the http URLs was doing a 302 redirect to https.

Co-authored-by: Aaron Watry <aaron.watry@advarra.com>
2020-10-02 09:57:43 +02:00
Sergei Khramkov
b70d6ca9ca Fixed the description of getMax in PropertyAdapter (#412)
Co-authored-by: Sergey.Khramkov <Sergey.Khramkov@nexign-systems.com>
2020-10-02 09:57:25 +02:00
Robert Winkler
0e15676cb7 Fixed failing test. 2020-06-16 11:36:27 +02:00
Robert Winkler
5f419a0d02 Removed SwaggerPageBreakLocations for backward compability. 2020-06-16 11:27:38 +02:00
Robert Winkler
a0efe7dd26 Removed SwaggerPageBreakLocations for backward compability. 2020-06-16 11:23:57 +02:00
Robert Winkler
21afb5adcd Removed SwaggerPageBreakLocations for backward compability. 2020-06-16 11:19:37 +02:00
Robert Winkler
7d0d73cd51 Moved classes for backward compability. 2020-06-16 11:07:28 +02:00
Robert Winkler
e8a51345a8 Delimiters should use the system line separator by default 2020-06-16 09:40:31 +02:00
Robert Winkler
f471774da9 Updated release notes. 2020-06-16 09:39:23 +02:00
Robert Winkler
0facccf009 Moved Swagger2MarkupConfig back into the main package for backward compability. 2020-06-16 09:35:09 +02:00
Robert Winkler
835c8fec03 Moved Swagger2MarkupConfig back into the main package for backward compability. 2020-06-16 09:18:04 +02:00
Robert Winkler
eea093acd4 Merge remote-tracking branch 'origin/master' 2020-06-15 13:07:14 +02:00
Robert Winkler
b32bfb3e54 Moved Swagger2MarkupConfig back into the main package for backward compability. 2020-06-15 12:25:19 +02:00
Robert Winkler
65f330baae Updated to 2.0.0-SNAPSHOT 2020-06-15 11:24:26 +02:00
Klaus Schwartz
b43a677744 Issue #248: Added a curl request example (#408)
* Issue #248 Add a curl request example

added configurable 3 kinds of request examples:

- basic (default, no source highlight)
- curl (bash source highlight)
- Invoke-WebRequest (powershell source highlight)

* updated default.properties to support curl example request feature

Issue #248 Add a curl request example

added configurable 3 kinds of request examples:

- basic (default, no source highlight)
- curl (bash source highlight)
- Invoke-WebRequest (powershell source highlight)

* added few tests, fixed extra space before query "?" delimiter, added builder configuration methods

Issue #248 Add a curl request example

* fix missig headers in example, fix Content-Type header name spelling

Issue #248 Add a curl request example
2020-06-10 15:42:27 +02:00
Paolo Patierno
4b69d6a150 Added support for MIME types with structured syntax suffixes (#410) 2020-06-08 15:47:44 +02:00
Robert Winkler
4a3ee6c5ca Feature/open api v3 support (#405) 2020-03-06 08:31:21 +01:00
Ali Ustek
69baeb6339 Merge pull request #400 from kolbdaniel1/patch-1
renamed jCenter() repository to jcenter()
2020-01-29 19:00:36 +00:00
Daniel
f7fe2b0cca renamed jCenter() repository to jcenter() 2020-01-29 14:39:45 +01:00
Ali Ustek
f853550748 Migrated markup document builder (#374)
* Initial commit

* Updated documentation

* Test travis CI

* Added library to bintray

* Updated documentation

* Updated documentation

* Updated documentation

* Published Version 1.1 to Maven Central

* Updated Bintray Badge

* Updated Bintray Badge

* Fixed maven pom issue

* Fixed issue: Comma should be escapes when constructing table in csv format in asciidoc
Fixed issue: logback.xml on the classpath

* New version number

* New version number

* Added Apache2 Copyright Header

* Updated documentation

* Updated documentation

* Updates documentation

* Fix Markdown level 3 title

* Fixed SECTION_TITLE_LEVEL3 in Markdown enum

* Added twitter batch

* Updated documentation

* Added method sectionTitleLevel4

* Added Artifactory Gradle Plugin in order to deploy snapshots to oss.jfrog.org

* Added artifactoryPublish task to TravisCI to publish SNAPSHOTS to OSS Artifactory

* Fixed coveralls badge

* Introduced new commands : anchor(anchor), crossReference(anchor, text)
Refactored writeToFile for robustness
Cleanups and fixes

* Enhanced support for tables

* Introduce inline commands : inlineAnchor, inlineCrossReference for easier markup composition

* More tests

* Renamed inline* to *AsString

* Implemented anchors and crossReferences for Markdown (GFM style)

* Updated readme

* Fixed anchor normalization

* Cleanups

* Cleanups

* Fixed replacing error

* Renamed TableColumnSpec to MarkupTableColumn

* Travis Secure Environment variables must be escaped

* Fixed travis.yml

* Fixed travis.yml

* fixed anchor normalization (again). Asciidoc anchor normalization differs between title and custom anchors => introducted crossReferenceTitle

* fixed tests compilation

* Update dependency-management-plugin to work with Gradle versions newer than 2.5

* Update Gradle wrapper to 2.10

* Fixed inter-document cross-references

* renamed crossReference -> crossReferenceAnchor and crossReferenceTitle -> crossReference as it's the default behavior
introduced addFilenameExtension (e.g. needed for inter-document cross-references)
fixed anchor normalization (support for ASCII characters in AsciiDoc)
Several workarounds with inter-document cross-references
Removed documentTitleWithAttributes as it's no use as-is

* Support for inter-document cross-references in Markdown

* fixed #9 Refactor anchor and cross-reference interface and implementation

* Updated asciidoctor-gradle-plugin: and asciidoctorj-pdf Gradle plugins to newer versions.

* [Bug] The document title must not have a anchor in front of it.

* Ignore punctuation in normalizeAnchor
Added new functions to create sections with a custom anchor not directly derived from the title

* Use paragrah local hardbreaks instead of global attribute

* fixed normalization and provided tests for normalization (finally) !

* missing Mockito in Gradle
fixed tests

* anchor normalization better manages beginning and ending escape characters, and intermediate punctuation

* introduce text, italicText, boldText
remove *AsString builders, use a new MarkupDocBuilder with toString() method instead

* Create a builder instance from another builder instance, for easier composition

* introduce forceLineBreak on all *Line methods

* Introduce new sectionTitleWithAnchor* to allow users to create titles without anchor, with a custom anchor (will be normalized anyway), or with an auto-generated anchor.

* sectionTitleWithAnchor* consistency fix when anchor == null => auto-generate anchor

* Introduce global builder configuration .withAnchorPrefix
Introduce copy() method to easily duplicate builders with configuration

* Introduce Markup-dependent specifiers on tables

* Added public interface complete documentation

* Added 2 newlines at the end of generated output when output are files. This protect the final AsciiDoc when you later include these files.

* MarkupTableColumn documentation enhancements

* Added importMarkup(markupText, levelOffset)

* Check for levelOffset < 0 in importMarkup(markupText, levelOffset)

* Support for levelOffset < 0 in importMarkup

* Use Reader in importMarkup instead of a String

* MAX_TITLE_LEVEL = 4 -> 5

* Added new interface methods to support java.nio.file.Path parameters

* Added new block methods (supporting title and admonitions)
Refactored listing() and method() methods
Does not flush buffer anymore when writeToFile

* Renamed addfileExtension to addFileExtension

* logging fix

* Support level 5 titles.
Added sectionTitleLevel(int level, String title) for convenience.

* Line separators (Mac, Windows, Linux) of input data are replaced by the system line separator.

* Removed source folder mainpjava.

* Fixed AbstractMarkupDocBuilderTest on windows machines by setting newLine to a fixed value.

* Added validation that input values are not null and empty.

* Added the functionality to provide a custom line separator which should be used.

* Added Mac line separator.

* Removed io.spring.gradle:dependency-management-plugin

* Added default line separator if provided lineSeparator is null.

* Updated versions of commons-collection, commons-lang3, commons-codec and slf4j-api.

* Removed Guava library.

* New lines in Table headers are replaced by a whitespace
New lines in Table cells are replaced by the configured line separator.

* Opens MarkupDocBuilders for additional/external markup builders (includes an example for Confluence wiki markup)

* Make changes Java 1.7 compatible.

* Adds a markup builder for Atlassian's Jira/Confluence wiki markup.

* Updated README.

* Renamed ATLASSIAN to ATLASSIAN_WIKI

* Updated publishing and coverage gradle scripts.

* Updated publishing gradle script.

* Moved source code which does not belong to the external API into an internal package.

* Copy newLine in copy() method + non regression test

* simplify empty constructors
added missing copyright headers

* factored importMarkupStyle1/2 + Style2 tests
removed deprecated tableWithHeaderRow
refactored ConfluenceMarkupBuilder

* copy with optional copyBuffer

* Added assertj-diff.

* fixing ConfluenceMarkupBuilder
fixed MarkdownBuilder with null block styles

* remove FILE_EXTENSION from Markups, use MarkupLanguage::getFileNameExtensions instead

* fixed documentTitle level for ConfluenceMarkupBuilder

* fixed LINE_BREAK for ConfluenceMarkupBuilder

* fixed empty cells for ConfluenceMarkupBuilder

* fixed crossReferences for ConfluenceMarkupBuilder

* cleanups

* removed deprecated writeToFile*

* Support column headers style generically in MarkupTableColumn

* Use DiffAssertions to check generated markup result in tests

* Introduce MarkupLanguage conversion in importMarkup. Currently support Markdown -> AsciiDoc.

* remove unnecessary newlines when importMarkup text is blank

* removed hardbreaks from AsciiDoc paragraph()

* fixed tests after removing hardbreaks

* better cell formatting : content trimming and newLines management

* fixed pipe escaping management in ConfluenceMarkup cell formatter (does not escape pipe in links in cells)
fixed corner cases in Regexp replacements (quoting)

* added OpenOption parameter in writeToFile()

* Fixed MarkupDocBuilderTests on windows by fixing line separator to LineSeparator.UNIX

* Adapted group id, versioning and root package to other swagger2markup projects

* introduced paragraph(text, hardbreaks), force line breaks on each line for Markdown and ConfluenceMarkup

* ImportMarkup, writeToFile and writeToFileWithoutExtension don't throw IOExceptions anymore, but RuntimeExceptions.

* Upgrade to Java8

* Fixed JavaDoc

* Fixed JavaDoc
Removed commons-collection by using Java8 Streams

* Updated readme

* Updated readme

* reintroduce literalTextLine(text)
rename listing -> listingBlock

* Support <> in cross-reference texts in AsciiDoc

* fixed sectionTitleWithAnchor and auto-generated anchor (and fixed tests)
fixed ConfluenceBuilder : missing replaceNewLinesWithWhiteSpace on title/anchor, removed extra newLine

* supports for blank value for text and textLine only to support adding simple spaces to document

* Released v1.0.0

* Updated readme

* Updated readme

* Updated readme

* Updated readme

* Updated readme

* Changed bold to ** and italic to __ so that special chars in the text are possible

* Updated version to 1.1.0-SNAPSHOT

* Release v1.0.0

* Updated bintray badge

* Updated docs

* Add support for page breaks

* Add page breaks to unit tests

* Updated version from 1.1.0 to 1.1.1-SNAPSHOT

* Released v1.1.1

* Updated README

* Improve code blocks in markdown (#28)

* Prepare release 1.1.2

* Update AbstractMarkupDocBuilder.java (#29)

Support relative file names both of "filename" and "./filename" while `writeToFileWithoutExtension`

* Issue #21: AsciidocBuilder should enable option to set pegdown timeout (#31)

* Upgraded gradle (#33)

* upgrade to gradle 5.6.3

* update dependencies versions

* Moved markup-document-builder files and folders into swagger2markup-builder/

* Fix merge problems from markup-document-builder

* correct expected file for instagram/overview.adoc

* fix paths to examples files in documentation files
2019-10-30 08:13:52 +01:00
Ali Ustek
75fa8f788c Moved docs to documentation module (#373) 2019-10-29 12:49:09 +01:00
Ali Ustek
7a86fdaba3 Updated version numbers and turn on strict conflict resolution (#371) 2019-10-29 12:48:43 +01:00
Ali Ustek
1566b22489 Convert project to be multi-module (#372) 2019-10-29 08:15:17 +01:00
Ali Ustek
ed026f3587 Upgraded to gradle 5.6.3 (#370) 2019-10-24 10:02:22 +02:00
Robert Winkler
6e8e4ce780 Updated READE 2019-06-27 13:02:46 +02:00
mona
60b7d90ad2 get label for operation.deprecated (#363) 2019-06-03 22:54:51 +02:00
guangp
da83465f19 add hostname in uri section of every operation, it is configurable. (#356)
* add hostname in uri section of every operation, it is configurable.

* modify java docs

* test hostname conf
2019-03-21 15:41:58 +01:00
alexmartinsrj
7ae0b64d8e Update labels_pt_BR.properties (#359)
translate of some untraslated words.
2019-03-21 15:41:24 +01:00
Sridhar Jonnalagadda
f8cbf7801d Issue #21: AsciidocBuilder should enable option to set pegdown timeout (#353) 2018-11-21 13:04:22 +01:00
Maciej Swiderski
7fbd49c5ea Issue #349 - Add support for generating example for request data based on media type (#350) 2018-11-05 10:43:03 +01:00
Valy Diarrassouba
8717e26f76 Allow to define freeform with additionalProperties: {} (#346) (#347) 2018-10-22 12:48:02 +02:00
aspekt23
483d6c3d17 Issue 291 support for title property in definitions (#348)
* Implemented preference for definition title if it is present

* Fixed failing test data
2018-10-22 12:43:09 +02:00
parrrot
03fb52fb8e Bugfix/issue336 (#345)
* added if branches for "header" parameter for examples and generated proper format

* modified expected test files to include new format of request header
2018-10-18 09:21:28 +02:00
MarosPataky
e574f0e65f Added support for minItems, maxItems property in parameters section o… (#341)
* Added support for minItems, maxItems property in parameters section of specification

* Added values for min/max items for all languages (for now, no translations are provided)

* Fixed issues with NPE and failing tests

* Added translations for min_items and max_items
2018-10-15 10:14:03 +02:00
MarosPataky
e9b04c712d Added support for enums with Integer type (#342)
* Added support for enums for Integer type, changed enums test data to reflect the change

* Fixed test failures that were caused by missing "format" part of integer type description
2018-10-15 10:13:24 +02:00
Martin Waßmann
b4c7c8860c Better generated examples for strings (#329)
* Generate examples based on string format

The following static examples are generated:
* byte: Ynl0ZQ== (base64 of byte)
* date: 1970-01-01
* date-time: 1970-01-01T00:00:00Z
* email: email@example.com
* password: secret
* uuid: f81d4fae-7dec-11d0-a765-00a0c91e6bf6

* Use first enum value as example

* Also generate string examples for path and query parameter

* Test example generation for custom string format
2018-08-06 12:50:07 +02:00
Bennet Schulz
815c161b7e fix typo in documentation (#330) 2018-08-06 10:31:18 +02:00
Łukasz Kolek
ecaaaeb049 fix: polish translation corrected from UTF-8 to encoded properites (#324) 2018-07-12 15:24:56 +02:00
Barry Ostroff
647846762d Generate examples for inline responses (#314)
* Handle untyped inlines - swagger parser no longer defaults untyped to object types
* Handle object inlines - generates a name based on method and response code
* Handle object inlines with titles - generates a name from the title
2018-05-01 21:35:43 +02:00
Michał Dul
655a15c722 Polish language translation (#311)
* Polish language translation

* language builder adjusted
2018-04-29 11:42:18 +02:00
Robert Winkler
6297b859dd Use old gitHubPages plugin 2018-04-27 13:42:29 +02:00
Robert Winkler
19f05c68f8 Prepare release v1.3.3 2018-04-27 12:59:23 +02:00
Robert Winkler
5a12bd9cce Added release notes for v1.3.3 2018-04-27 12:42:36 +02:00
Barry Ostroff
e22b374bdd Resolve issue #298 - Move to latest swagger parser (#308)
* Move to swagger-parser version 1.0.33

* Move to swagger-parser version 1.0.34

* Move to swagger-parser version 1.0.35

* Replace deprecated getSchema() method
2018-04-20 19:04:33 +02:00
Barry Ostroff
fe3749d499 Include required parameters in example request (#307)
* Include required parameters in example request

* Fix unit tests

* Add unit tests for swagger required parameters
2018-04-13 09:04:33 +02:00
Robert Winkler
85ef7f252d Updated to snapshot version. 2018-03-13 16:04:51 +01:00
Robert Winkler
f16b563a82 Prepare release v1.3.2 2017-12-11 09:20:18 +01:00
g00de
8e22dd817e make examples always start newline if there is other content before the example (#294) 2017-12-08 19:02:58 +01:00
Robert Winkler
569f3c02cd Fixed build script 2017-12-04 15:38:17 +01:00
Robert Winkler
e8c2099e4c Prepare release v1.3.2 2017-12-04 14:47:58 +01:00
ctytgat
1646fefd56 Fix crash on empty tables (#293)
* https://github.com/Swagger2Markup/swagger2markup-cli/issues/17

* https://github.com/Swagger2Markup/swagger2markup-cli/issues/17
add test case
2017-12-01 12:31:12 +01:00
bassettb
aad387802e Fix list parsing in properties file (#290)
Move up the code that enables list delimiters so that it comes before any list properties are parsed.
2017-11-15 08:33:07 +01:00
Frederik Hahne
034d0a2f50 replace deprecated gh pages plugin (#285) 2017-11-14 08:05:55 +01:00
Frederik Hahne
d2c78304c6 Description for api keys are no parsed and written (#281)
* Description for api keys are no parsed and written

close #259

* fix markdown converter tests

* fix asciidoc converter tests
2017-10-09 10:53:31 +02:00
Frederik Hahne
247857a843 Issue #162: adoc content in tables (#280)
* adoc content in tables

some dependency update and cleanup

close #162

* fix analysis remarks
2017-10-05 19:40:28 +02:00
brischniz
038ff3a40e ExternalDocs section will now be rendered in result document (#263)
* Typo fixed

* ExternalDocs section will now be rendered in result document
2017-07-17 09:13:41 +02:00
Magnus Larsson
6d8776332f Property refs are resolved as links and not as text (#265)
* Property refs are resolved as links and not as text

* Update static docs in tests to match change in code

* Remove unnecessary if check
2017-07-17 09:12:45 +02:00
Robert Winkler
4ea24b0297 Fixed typo in german language file 2017-07-11 09:01:41 +02:00
Robert Winkler
12570ecb00 Issue #254: The wildcard Mediatype */* is escaped now 2017-05-15 13:01:51 +02:00
Eugeniy Lykov
7b68aecbd7 Improve russian translation (#251)
* Improve russian translation

* Improve russian translation

Complete translation and correct errors.
2017-05-15 08:45:39 +02:00
Robert Winkler
7ce62a8a3d Updated version to 1.3.2-SNAPSHOT 2017-03-20 12:33:14 +01:00
Robert Winkler
d8c3cf725d Release 1.3.1 2017-03-20 12:28:44 +01:00
Robert Winkler
aecc531d84 Added gradle.properties to set file.encoding and sun.jnu.encoding to UTF-8 2017-03-17 09:25:30 +01:00
shardings
f107779542 Fix request path and query params' example support. (#247)
Fix request path and query params' example support.
2017-03-16 09:01:45 +01:00
shardings
70bf17011c Improve the zh_CN translation. (#246)
For human:
default_column: 默认列 -> 默认值
example_column: 例子 -> 样例
schema_column: 架构 -> 类型
overview: 概观 -> 概览
2017-03-14 16:40:01 +01:00
Robert Winkler
86ae19fe2a Update version to 1.3.1-SNAPSHOT 2017-02-20 08:39:59 +01:00
Robert Winkler
e8235c4c35 Updated README 2017-02-20 08:38:20 +01:00
Robert Winkler
63b5cd3bfb Release 1.3.0 2017-02-20 08:37:02 +01:00
Robert Winkler
12e851c127 Refactored Swagger2MarkupConfigBuilder 2017-02-03 09:33:49 +01:00
kruffin
20fa72b613 Multi-Valued Dynamic Content Folders (#240)
* Adds in the capability to have array valued properties. Mostly only affects extensions that may
need this. It is disabled by default and should work the same as it currently does. Array values
can be enabled by setting a separator character in the "swagger2markup.documentFolderSeparator"
configuration attribute.

* Modifications from code review:

* Altered the "documentFolderSeparator" name to "listDelimiter"
* Added an additional property to enable/disable the list delimiter "listDelimiterEnabled"
* Defaulted the "listDelimiter" to ','
* Updated logic that assumed the configuration was derived from AbstractConfiguration to explicitly check before casting
* Added a couple "withListDelimiter" methods to the builder

* Modifies the list delimiter parsing logic (how the delimiter is determined from properties) to be more
of a Java 8 style.
2017-02-03 09:06:49 +01:00
jbrugge
36bee8070a Fix position reference for parameters table. (#241) 2017-02-02 08:57:04 +01:00
fooinha
9a85612b8a * fix NPE for response headers with relative definitions 2017-01-21 10:34:08 +01:00
Robert Winkler
2bc18f7d90 Updated RELEASENOTES 2017-01-19 14:24:41 +01:00
Robert Winkler
6f6428543d The Number Formatter must use the Locale of the Swagger2MarkupConfig output language. 2017-01-19 14:17:17 +01:00
Robert Winkler
d03087c1b8 Fixed version in changelog 2017-01-19 14:00:39 +01:00
Robert Winkler
d2d47cf8ee Updated javslang from 2.0.4 to 2.0.5
Updated paleo-core from 0.10.1 to 0.10.2
Updated swagger-parser from v1.0.23 to v1.0.25
2017-01-19 13:59:23 +01:00
Robert Winkler
7a0f4490de Updated copyright statement 2017-01-19 11:30:50 +01:00
Cas Eliëns
d2b3c9472a Close #180. 2017-01-19 10:24:04 +01:00
Cas Eliëns
3a0b9a00a3 Improve generated examples for arrays 2017-01-19 10:24:04 +01:00
Cas Eliëns
d5cf4ad9e5 Add unit test for #180 2017-01-19 10:24:04 +01:00
Cas Eliëns
2899b2f263 Use shorter sorting syntax and update javadoc 2017-01-13 14:12:41 +01:00
Cas Eliëns
7475321e97 Add ISAAC to 'Companies who use Swagger2Markup' 2017-01-13 14:12:33 +01:00
Cas Eliëns
88a24d7bdd Add space between schema type and format 2017-01-09 12:19:41 +01:00
Robert Winkler
f798a51edc Release v1.2.0 2017-01-05 14:27:53 +01:00
Robert Winkler
81edab38f3 The notBlank validation of the type should tell which parameter is not valid. 2017-01-03 15:58:43 +01:00
Robert Winkler
039607a294 Updated version to 1.2.0-SNAPSHOT 2017-01-03 15:27:32 +01:00
Cas Eliëns
2f33522e6d Issue #214 Added support for page breaks (#226)
* Added support for page breaks
* Added documentation and config file support for page breaks and regex
2017-01-03 11:21:31 +01:00
Cas Eliëns
76c54a713a use raw JSON object instead of converting to string 2017-01-02 13:47:02 +01:00
Cas Eliëns
dcebed2d42 split reused code into methods 2017-01-02 13:47:02 +01:00
Cas Eliëns
dbf9afa8da Remove unused import 2017-01-02 13:47:02 +01:00
Cas Eliëns
f7f397b5f2 Improve printing for different ways of defining examples 2017-01-02 13:47:02 +01:00
Cas Eliëns
44f852ad42 Improve example printing for $ref'd examples 2017-01-02 13:47:02 +01:00
Cas Eliëns
e1be2f2130 Great Expectations 2017-01-02 13:47:02 +01:00
Cas Eliëns
8468607703 Improve example rendering for hardcoded examples 2017-01-02 13:47:02 +01:00
Cas Eliëns
f981318142 Example responses now display correctly 2017-01-02 13:47:02 +01:00
Cas Eliëns
e1d0d7b293 Add FIXME comment 2017-01-02 13:47:02 +01:00
Cas Eliëns
d118a0cf74 Further work on Swagger2Markup/swagger2markup#223 2017-01-02 13:47:02 +01:00
Cas Eliëns
7cb1095465 Begin work on Swagger2Markup/swagger2markup#223 2017-01-02 13:47:02 +01:00
Cas Eliëns
595b885b9a Close Swagger2Markup/swagger2markup#220 2016-12-20 14:07:27 +01:00
Cas Eliëns
b1c219bc1b Remove unused code, optimize imports, fix Codacy issues
* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Work on implementing regex sorting

* Add regex ordering translations and unit test

* Improve Regex grouping

* Make regex sorting test more like a real-world example

* Remove unused imports

* Improve code style consistency

* Improve code style consistency

* Remove empty statement

* Resolve some Codacy issues

* Remove empty constructors

* Remove unused fields

* Merge nested IF statements

* Improve method scopes

* Remove unused classes

* Remove unused imports

* Remove fixed TODO comment

* Fix codacy issues

* Fix codacy issues (reverted from commit 43f27e7fc6)

* Improve code style consistency

* Resolve some Codacy issues

* Remove empty constructors

* Remove unused fields

* Merge nested IF statements

* Improve method scopes

* Remove unused classes

* Remove unused imports

* Remove fixed TODO comment

* Fix codacy issues
2016-12-19 16:04:17 +01:00
Cas Eliëns
852b2ac3b4 PR#218 Improve code style consistency
Improved code style consistency
2016-12-13 10:44:31 +01:00
Cas Eliëns
937cded2aa Issue #215: Path grouping via a RegEx pattern
* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Work on implementing regex sorting

* Add regex ordering translations and unit test

* Improve Regex grouping

* Make regex sorting test more like a real-world example

* Remove unused imports
2016-12-13 09:58:12 +01:00
Robert Winkler
022d2453d2 Issee #216: Replace slash with system file separator in unit tests. 2016-12-09 09:17:55 +01:00
Robert Winkler
e5a187cc24 Updated version to 1.1.2-SNAPSHOT 2016-11-30 09:18:22 +01:00
Robert Winkler
83bb63321a Updated markup-document-builder from 1.0.0 to 1.1.0 2016-11-30 08:20:04 +01:00
Robert Winkler
cd5b5c9240 Refactored ParameterAdapter and created MarkupDocBuilderUtils. 2016-11-18 12:36:39 +01:00
Robert Winkler
2096ec0d5d Refactored ParameterAdapter and moved ParameterAdapter and PropertyAdapter into a new package. 2016-11-16 12:54:32 +01:00
Robert Winkler
25d4311237 Added a modularized Swagger spec test 2016-11-16 12:54:03 +01:00
Robert Winkler
7e07c2fc81 Fixed method name in DefinitionsDocument 2016-11-15 14:50:45 +01:00
Robert Winkler
5a8a618e6b Refactored document resolver and added tests. 2016-11-15 14:47:11 +01:00
Robert Winkler
f072fc99b9 Refactored Documents. Documents are also components now and can be composed of components. 2016-11-15 11:12:17 +01:00
Robert Winkler
54e881fc58 Fixed wrong import in SecuritySchemeComponent 2016-11-14 16:14:16 +01:00
Robert Winkler
cd6a3ed724 Refactored Components to be more functional. 2016-11-14 16:08:24 +01:00
Robert Winkler
5a00dde912 Refactored Components to be more functional. 2016-11-14 16:02:49 +01:00
Robert Winkler
876d7b2f7b Moved code into BodyParameterComponent 2016-11-11 14:21:43 +01:00
Robert Winkler
4b74ec0e54 Moved code into PathOperationComponent 2016-11-11 13:30:04 +01:00
Robert Winkler
a719e33332 Moved code into SecuritySchemeComponent 2016-11-11 10:29:51 +01:00
Robert Winkler
86a727f097 Refactored DocumentBuilder into components. 2016-11-10 15:48:03 +01:00
Robert Winkler
2670780076 Enhancement #206 Updated to markup-document-builder v1.1.0 which renders bold text as **text** and italic text as __text__. 2016-11-10 12:42:52 +01:00
Robert Winkler
ebf9912269 Bug #205: Fix ordering of operations when grouped by tags. 2016-11-10 12:41:26 +01:00
Robert Winkler
11549ab64e Bug #205: Fix ordering of operations when grouped by tags. 2016-11-10 10:43:12 +01:00
Robert Winkler
d128146952 Added a component API to split a document into components and improve component testability 2016-11-09 16:30:02 +01:00
Robert Winkler
686abd8842 Added a component API to split a document into components and improve component testability 2016-11-09 15:02:28 +01:00
Robert Winkler
551aeed835 Removed ListUtils and changed MapUtils.toKeySet to MapUtils.toSortedMap 2016-11-08 12:28:27 +01:00
Robert Winkler
5b1a1a2bcf Migrated some collections to Javaslang 2016-11-08 10:18:07 +01:00
Robert Winkler
09d2474a9a Added javaslang and paleo-core to improve Table rendering 2016-11-04 15:32:17 +01:00
Robert Winkler
5c00e5493c Removed ExternalLocation model from inlineSchema test. 2016-11-04 15:32:17 +01:00
Robert Winkler
c343af8f5a Updated Gradle to v3.1 2016-11-04 15:32:17 +01:00
yewton
4af7eb5b89 Add support for Japanese 2016-11-02 08:45:42 +01:00
Robert Winkler
aa9a340144 Added a config parameter which allows to prepend the basePath to all paths. 2016-11-01 14:42:46 +01:00
Robert Winkler
35ae68ceee Fixed german and spanish language files 2016-11-01 08:55:04 +01:00
Robert Winkler
560fb4ece6 Added language file for Portuguese (Brazilian) 2016-11-01 08:30:28 +01:00
Cleydson Júnior
8eb494cd5b Converting special characters to ASCII escape codes 2016-11-01 07:05:19 +01:00
Cleydson Júnior
0766336a56 Adding support for Brazilian Portuguese 2016-11-01 07:05:19 +01:00
TzeKai Lee
24352f4d1c Add format tests on request param in query and body 2016-10-28 09:07:56 +02:00
TzeKei Lee
adb0fee973 Added displaying format for string type and definitions only contains string or integer type. 2016-10-28 09:07:56 +02:00
Robert Winkler
13a7113aa7 Fixes #197 Converted ZH-language file from UTF-8 to latin1 using native2asciidoc 2016-10-25 15:25:27 +02:00
Robert Winkler
e882975726 Updated README 2016-10-18 15:27:06 +02:00
Robert Winkler
12209fe923 Updated version to 1.1.0 2016-10-18 15:14:05 +02:00
Robert Winkler
8a63744198 Updated releases notes 2016-10-18 15:11:52 +02:00
James Bassett
5871f0c9b0 Added support for exclusiveMin and exclusiveMax 2016-10-14 07:12:53 +02:00
James Bassett
908f524c64 Updated min/max value to format correctly based on the data type 2016-10-12 08:47:54 +02:00
Francisco José Bermejo Herrera
9fa0ee3def Add support for Spanish language 2016-10-03 13:46:12 +02:00
Robert Winkler
35e9450f74 Updated docker documentation 2016-09-23 10:29:46 +02:00
Robert Winkler
6033ea5a98 Updated docker documentation 2016-09-23 10:21:02 +02:00
Robert Winkler
6f24c3cb39 Merge remote-tracking branch 'origin/master' 2016-09-23 08:54:37 +02:00
Robert Winkler
e975e49d3e Added docker documentation 2016-09-23 08:54:18 +02:00
Robert Winkler
c5cfe10fa6 Merge pull request #187 from KristinaGen/master
update labels_ru
2016-09-14 09:55:56 +02:00
KristinaGen
7c988460f0 update labels_ru 2016-09-13 16:20:57 +02:00
Robert Winkler
21f1892de0 Added chinese language 2016-09-12 10:02:02 +02:00
Robert Winkler
b97344849d Merge pull request #186 from mingkaili/patch-1
labels_zh.properties
2016-09-12 09:49:43 +02:00
Mingkai Lee
935d48d4cc labels_zh.properties
Add chinese labels.properties. Add chinese language.
2016-09-12 10:26:16 +08:00
Robert Winkler
73ba233f9e Merge pull request #181 from iwannayoyo/Remove_empty_columns
eliminate empty columns in tables
2016-08-31 10:20:25 +02:00
Chris Hartman
ff955d392b eliminate empty columns in tables 2016-08-25 16:43:17 -04:00
Robert Winkler
19fde31f67 Merge pull request #177 from mhswisscom/Fix_without_reformat
recursive examples patch without reformatting
2016-08-25 13:49:45 +02:00
Marc Habegger
b3f368ac37 recursive examples patch without reformatting 2016-08-25 13:33:27 +02:00
Robert Winkler
c5efb401b4 Added releaseVersion to build.gradle and documentation.gradle scripts so that the AsciiDoc documentation always refers to the release version and not to the SNAPSHOT version. 2016-08-04 12:10:08 +02:00
Robert Winkler
f386e6ed91 Updated version to 1.0.2-SNAPSHOT 2016-08-04 10:28:30 +02:00
Robert Winkler
55b323c063 Merge pull request #171 from zerok/fix/emptycontact
Allow empty contact objects
2016-08-04 10:25:14 +02:00
Robert Winkler
6f286b52d8 Prepare release v1.0.1 2016-08-04 10:03:08 +02:00
Horst Gutmann
4850673b96 Allow empty contact objects
According to the spec the contact object can be empty (it doesn't have
any required properties). Previously, the markup generation failed in
that situation due to an empty paragraph being generated. This change
fixes that.
2016-08-04 10:00:33 +02:00
Robert Winkler
353af537ba Prepare release v1.0.1 2016-08-04 09:49:35 +02:00
Robert Winkler
2367d86eb7 Merge pull request #170 from zerok/fix/instagram-fenced-code-adoc
Fixes expected output of testSwagger2AsciiDocConversionInstagram
2016-08-03 10:11:43 +02:00
Horst Gutmann
1aec46a57c Fixes expected output of testSwagger2AsciiDocConversionInstagram
The fenced code block in the original specification was previously
converted to something resembling an inline code element, while
the new output now contains an actual code block.

This closes #168.
2016-08-03 09:38:33 +02:00
Robert Winkler
f650fb7b3e Fixed wrong expected test files after merging PR #149 and PR #156 2016-08-02 19:35:27 +02:00
Robert Winkler
568d6a6441 Failed tests shouldn't be ignored 2016-07-30 20:52:54 +02:00
Robert Winkler
630e86cd31 Merge pull request #167 from afdia/master
new property "pathSecuritySectionEnabled" (default: true)
2016-07-30 20:31:14 +02:00
Andreas
0e3e229434 + new property "pathSecuritySectionEnabled" (default: true)
The property decides whether to add the security section for every path
(introduced in pull request #63)
2016-07-30 12:18:12 +02:00
Hugo de Paix de Coeur
f41d1cbcb0 missing FR translations 2016-06-21 13:47:09 +02:00
Hugo de Paix de Coeur
20b653086d Merge pull request #156 from jfiala/master
validation constraints, german translations
2016-06-17 11:16:46 +02:00
Johannes Fiala
ae4cf35de4 validation constraints, german translations (#156) 2016-06-16 19:04:58 +02:00
Johannes Fiala
86fc9a9746 add expected results #160 2016-06-15 22:41:17 +02:00
Johannes Fiala
1b4626d9ca update test cases #160 2016-06-15 22:36:40 +02:00
Johannes Fiala
7528b34ba3 Merge branch 'master' of https://github.com/jfiala/swagger2markup 2016-06-15 22:35:23 +02:00
Johannes Fiala
ebecde1768 update test cases #160 2016-06-15 22:35:00 +02:00
Johannes Fiala
2301de6466 update test examples #160 2016-06-15 22:32:34 +02:00
Johannes Fiala
f7efad2480 Merge branch 'master' of https://github.com/jfiala/swagger2markup
Conflicts:
	src/test/resources/expected/asciidoc/validators/definitions.adoc
	src/test/resources/json/swagger_validators.json
2016-06-15 22:29:12 +02:00
Johannes Fiala
c23bd01495 add more cases to minimum/maximum tests 2016-06-15 22:28:42 +02:00
Johannes Fiala
7e5986237a Merge branch 'master' of https://github.com/jfiala/swagger2markup
Conflicts:
	src/test/resources/expected/asciidoc/validators/definitions.adoc
	src/test/resources/json/swagger_validators.json
2016-06-15 22:25:24 +02:00
Johannes Fiala
1bf26c95e3 Added simple json + test cases for validators #160´ 2016-06-15 22:19:56 +02:00
Johannes Fiala
3888e67d02 Added simple json + test cases for validators #160´ 2016-06-15 22:18:10 +02:00
Johannes Fiala
54e17321b6 Fixed check for description 2016-06-13 12:01:50 +02:00
Johannes Fiala
90f56cfe61 Merge branch 'master' of https://github.com/jfiala/swagger2markup 2016-06-13 11:56:21 +02:00
Johannes Fiala
44e33ad6f3 Fixed line-break issue if no description is present - should always
check for descriptionContent instead of description
2016-06-13 11:55:59 +02:00
Johannes Fiala
65d4e0c225 Merge branch 'master' of https://github.com/jfiala/swagger2markup 2016-06-12 18:53:59 +02:00
Johannes Fiala
d37a374d02 added example for min/max at order.quantity #160 2016-06-12 18:53:12 +02:00
Johannes Fiala
5bb5e5ff29 added new definition of swagger petstore #159 in separate file 2016-06-12 18:20:23 +02:00
Johannes Fiala
de1f84d2aa reseted to original swagger_petstore.yaml, added example for
minlength/maxlength/pattern
2016-06-12 18:12:55 +02:00
Johannes Fiala
aa35c0169c Update swagger_petstore.yaml to current version #159 2016-06-12 17:49:52 +02:00
Johannes Fiala
b53727842a Suggest adding eclipse plugin to support gradle eclipse #158 2016-06-12 17:17:56 +02:00
Johannes Fiala
f88e3d2ed4 added check if minlength equals maxlength 2016-06-12 17:15:07 +02:00
Johannes Fiala
eefda62d99 Added query if minlength equals maxlength #147 2016-06-12 17:08:56 +02:00
Johannes Fiala
592446f714 Removed quotes for Minlength/Maxlength #147 2016-06-12 17:05:45 +02:00
Johannes Fiala
3275a07325 German translations - fine tuning #157 2016-06-12 16:56:03 +02:00
Johannes Fiala
1c2b9eee26 validation constraints don't appear in generated docs #147 2016-06-12 16:50:25 +02:00
Hugo de Paix de Coeur
3a5533447b Merge pull request #149 from filip-owczarzak/Columns-Width-Too-Small
1st column in table extended width in order to avoid text wrapping
2016-06-01 14:59:50 +02:00
Filip Owczarzak
2fcd2d1a79 1st column in tables width set to 2 2016-06-01 13:49:15 +02:00
Robert Winkler
07d878be35 Added release Version to docs 2016-05-29 07:11:25 +02:00
Robert Winkler
7a75d7874b Added release Version to docs 2016-05-28 21:17:42 +02:00
Robert Winkler
99c3044218 Added release Version to docs 2016-05-28 20:49:46 +02:00
Robert Winkler
fec5fb54bb Added release Version to docs 2016-05-28 20:48:34 +02:00
Robert Winkler
031051f1f9 Added release Version to docs 2016-05-28 20:47:52 +02:00
Robert Winkler
d432c398cf Added release Version to docs 2016-05-28 20:35:07 +02:00
Robert Winkler
8eb44c26d2 Added release Version to docs 2016-05-28 20:25:23 +02:00
Robert Winkler
3a76a3e920 Added release Version to docs 2016-05-28 20:24:14 +02:00
Robert Winkler
52e80e7af6 Updated readme 2016-05-28 20:21:00 +02:00
Hugo de Paix de Coeur
1eac6a63d9 set development version to 1.0.1-SNAPSHOT 2016-05-26 16:21:42 +02:00
Hugo de Paix de Coeur
6e379042a0 #152 keep track of properties order in Composed models so that OrderBy.AS_IS works as expected 2016-05-26 13:22:37 +02:00
hdr
8367195315 fixes #150 create empty object when Swagger Parser fails to convert composed items
Added Instagram API conversion to tests next to PetStore
2016-05-26 11:23:26 +02:00
Hugo de Paix de Coeur
7de954958d Merge pull request #151 from johanhammar/master
Fix invalid XML in documentation
2016-05-26 08:24:39 +02:00
Johan Hammar
a161924a7f Fix invalid XML in documentation 2016-05-25 21:24:19 +02:00
hdr
9568f3a960 #148 Removed NPE in ExamplesUtil::exampleMapForProperties 2016-05-24 14:20:37 +02:00
Filip Owczarzak
fdb24fdf33 1st column in table extended width in order to avoid text wrapping 2016-05-24 10:28:12 +02:00
Robert Winkler
3c0f935e99 Merge remote-tracking branch 'origin/master' 2016-05-12 09:54:49 +02:00
Robert Winkler
826f4ff762 Updated images 2016-05-12 09:54:39 +02:00
Robert Winkler
ed926139b8 Updated readme 2016-05-04 21:05:59 +02:00
Robert Winkler
cb23bfe1a4 Updated Bintray badge 2016-05-02 13:22:04 +02:00
Robert Winkler
ab7d355fe4 Prepare release v1.0.0 2016-05-02 13:06:54 +02:00
Robert Winkler
87ccc182f1 Prepare release v1.0.0 2016-04-29 14:12:21 +02:00
Robert Winkler
ff21d7c985 Fixes #136: Moved default value of a property into the description column. 2016-04-19 13:09:03 +02:00
Robert Winkler
b69797ef51 Fixed levelOffset calculation when using paths grouped by TAGS 2016-04-19 10:52:38 +02:00
Robert Winkler
f1614fe81a Fixed levelOffset calculation when using paths grouped by TAGS 2016-04-19 10:38:54 +02:00
Robert Winkler
d5c9116dc7 Merge remote-tracking branch 'origin/master'
Conflicts:
	src/main/java/io/github/swagger2markup/spi/PathsDocumentExtension.java
2016-04-19 10:36:57 +02:00
Robert Winkler
5aaff59f71 Fixed levelOffset calculation when using paths grouped by TAGS 2016-04-19 10:30:57 +02:00
Robert Winkler
a20ed66400 Merge pull request #131 from ozanyildiz/master
Add Turkish language support
2016-04-15 12:24:53 +02:00
Ozan Yildiz
6312c2f3e0 add Turkish language support 2016-04-15 11:35:07 +03:00
Hugo de Paix de Coeur
2e2bd7d6c5 Enable inline schemas by default. No more depth level control. 2016-04-14 17:51:47 +02:00
Hugo de Paix de Coeur
dd7de8fe08 Added new DEFINITION_{BEFORE,AFTER} positions to DefinitionsDocumentExtension 2016-04-14 16:46:53 +02:00
Hugo de Paix de Coeur
934039bcd4 Renamed SecurityDocumentExtension positions DEFINITION -> SECURITY_SCHEME for clarity
Added new SECURITY_SCHEME_{BEFORE,AFTER} positions
2016-04-14 16:38:59 +02:00
Hugo de Paix de Coeur
98efe9543d #130 : Documentation for new PathsDocumentExtension positions 2016-04-14 15:52:24 +02:00
Hugo de Paix de Coeur
b68c0031a7 fix #130 : Supports for new PathsDocumentExtension positions (descriptions, responses, parameters, security) + OPERATION_{BEFORE,AFTER}
Fixed OPERATION_BEGIN hook call location
2016-04-14 15:32:54 +02:00
Hugo de Paix de Coeur
a587899976 Extension documentation : recommend to use different contentPaths for import files extension 2016-04-14 15:32:54 +02:00
Robert Winkler
4528f2aa0e Merge remote-tracking branch 'origin/master' 2016-04-14 12:37:35 +02:00
Robert Winkler
b2e6f498be Fixed credentials 2016-04-14 12:37:23 +02:00
Hugo de Paix de Coeur
d32179009d Created separate doc for extensions
Extensions documents enhancements
reverted to coderay until AsciiDoctor 1.5.5 (supports for highlightjs-langs attribute)
2016-04-14 12:04:17 +02:00
Hugo de Paix de Coeur
c815318972 missing language 2016-04-14 12:04:17 +02:00
Robert Winkler
7cbb52094d Changed documentation source-highlighter back to coderay, because groovy listings look strange with highlight.js 2016-04-13 14:25:12 +02:00
Hugo de Paix de Coeur
7c8dfb520f Dynamic file content extension detailed documentation 2016-04-13 14:05:01 +02:00
Hugo de Paix de Coeur
6395adddb6 Dynamic file content extension detailed documentation 2016-04-13 13:43:20 +02:00
Hugo de Paix de Coeur
01a63f895c always add space at the beginning and at the end of array/map < target type > for symmetry 2016-04-12 20:07:59 +02:00
Hugo de Paix de Coeur
5d2ba5b21e refactored PropertyUtils.getDefaultValue & ParameterUtils.getDefaultValue to return Objects.
default values are now displayed with literalText + Json.pretty
swaggerMarkupDescription now returns null when there's no description.
2016-04-12 19:16:03 +02:00
Hugo de Paix de Coeur
6e4c0c1498 refactored responses header display
fixed tests after column width update
fixed defaultString in swaggerMarkupDescription
2016-04-12 18:50:25 +02:00
Hugo de Paix de Coeur
dce6b4183a update column width using values sum = 20 for better granularity on col width 2016-04-12 18:50:25 +02:00
Hugo de Paix de Coeur
1bf36592ef advanced_usage documentation (cosmetic) 2016-04-12 18:50:25 +02:00
Robert Winkler
24d9218d14 Show stacktrace of TravisCI publishGhPages task 2016-04-12 16:07:09 +02:00
Robert Winkler
9ee6c96a3a Merge remote-tracking branch 'origin/master' 2016-04-12 15:57:10 +02:00
Robert Winkler
507307308d Fixed index.adoc 2016-04-12 15:57:03 +02:00
Hugo de Paix de Coeur
14d4268cc3 advanced_usage documentation (fixed index) 2016-04-12 15:56:24 +02:00
Hugo de Paix de Coeur
aade4453e1 advanced_usage documentation (fixed tests) 2016-04-12 15:51:19 +02:00
Robert Winkler
232a635c06 Merge remote-tracking branch 'origin/master' 2016-04-12 15:46:36 +02:00
Robert Winkler
545cf13584 Publish documentation on each commit 2016-04-12 15:46:26 +02:00
Hugo de Paix de Coeur
b7ef781fda advanced_usage documentation (cosmetic) 2016-04-12 15:06:35 +02:00
Hugo de Paix de Coeur
3f18a446af advanced_usage documentation (with examples) 2016-04-12 14:55:59 +02:00
Hugo de Paix de Coeur
391bb20de2 advanced_usage documentation (with all files) 2016-04-12 14:28:18 +02:00
Hugo de Paix de Coeur
aafac7821c advanced_usage documentation 2016-04-12 14:27:25 +02:00
Hugo de Paix de Coeur
103aef6cd6 issue template fix 2016-04-08 17:44:21 +02:00
Hugo de Paix de Coeur
6282459905 fixed #124 : fix inter-document cross-references in security schemes
Added inter-document cross-references tests in AsciiDoc and Markdown format
2016-04-08 17:39:52 +02:00
Robert Winkler
293132e6a4 Created an issue template 2016-04-08 16:59:18 +02:00
Hugo de Paix de Coeur
0e4b193d70 Use JSON schema title value to name inline schema intermediary objects, or, if not provided, generate a virtual name based on definition/property/parameter/response name
fixed column widths
fixed bug with <> and cross-references
added type to BasicType to clearly distinct type and name
refactored RefType to use referenced type name/uniqueName instead of a copy of them.
2016-04-08 15:44:38 +02:00
Robert Winkler
277e452a73 Changed gitter to slack integration 2016-04-08 14:40:13 +02:00
Hugo de Paix de Coeur
80e96933b0 missing expected files for inline_schema_flat_body test 2016-04-06 22:08:41 +02:00
Hugo de Paix de Coeur
1ab4f8ff6c fixed javadoc 2016-04-06 22:02:52 +02:00
Hugo de Paix de Coeur
9a67581ad9 fixed javadoc 2016-04-06 22:02:01 +02:00
Hugo de Paix de Coeur
9ef34dd853 fixed inlineSchema depth constant 1 -> configured depth level in definitions
fixed tests
2016-04-06 22:00:10 +02:00
Hugo de Paix de Coeur
b37c173e07 fixed inlineSchemas in collections (array and map, recursive collections, and object/collection mix) in parameters, responses and definitions
fixed missing support for withInlineSchemaDepth when withFlatBody enabled
fixed inline definitions unicity with depth > 1
2016-04-06 21:47:18 +02:00
Hugo de Paix de Coeur
105ac545b3 Moved Example column to description content 2016-04-06 19:16:17 +02:00
Hugo de Paix de Coeur
ae3f9aa353 Removed Required column and render required flag in NAME_COLUMN.
Removed header style on columns in tables.
Support for read-only property flags.
2016-04-06 18:15:09 +02:00
Hugo de Paix de Coeur
3e9fca8a0d SecurityDocument : WorkAround AsciiDoctor HTML conversion bug with + on the last paragraph line when using hardbreaks
SecurityDocument : Use italic for informations keys.
2016-04-06 14:27:04 +02:00
Hugo de Paix de Coeur
1a45054b5d fixed missing DOCUMENT_AFTER extension point call
fixed SecurityDocument DEFINITION_BEGIN->DEFINITION_END extension point call
2016-04-06 14:09:23 +02:00
Robert Winkler
be56290257 Updated documentation 2016-04-06 09:32:03 +02:00
Robert Winkler
64195e095b Updated documentation 2016-04-06 09:03:59 +02:00
Robert Winkler
5a33b3473e Merge remote-tracking branch 'origin/master' 2016-04-06 08:12:35 +02:00
Robert Winkler
df23dc09e8 Updated documentation 2016-04-06 08:12:07 +02:00
Robert Winkler
2a3ac1e6d0 Updated readme 2016-04-05 19:08:36 +02:00
Hugo de Paix de Coeur
bad8cde186 missing placeholder quoting 2016-04-05 16:08:07 +02:00
Hugo de Paix de Coeur
d9adcc2016 log normalized operation id to the console for external content, etc ... 2016-04-05 16:08:07 +02:00
Hugo de Paix de Coeur
7b59a069ef escape consume/produce in overview too (#28).
WorkAround AsciiDoctor HTML conversion bug with + on the last paragraph line.
Use italic for overview informations keys.
fixed termsOfService layout.
2016-04-05 16:08:07 +02:00
Robert Winkler
310a2e47b6 Updated documentation 2016-04-05 15:50:52 +02:00
Robert Winkler
954e302467 Updated documentation 2016-04-05 15:46:34 +02:00
Robert Winkler
abb77b7c5f Updated documentation 2016-04-05 15:36:13 +02:00
Robert Winkler
aaac78f985 Merge remote-tracking branch 'origin/master' 2016-04-05 15:05:53 +02:00
Robert Winkler
e959c9ed59 Updated documentation 2016-04-05 15:05:45 +02:00
Hugo de Paix de Coeur
1965110df9 typos 2016-04-05 15:04:39 +02:00
Hugo de Paix de Coeur
1300249555 cosmetic 2016-04-05 15:02:11 +02:00
Hugo de Paix de Coeur
05a4ee230c Remove hand-written definition/operation descriptions from code, to prepare extension (#108) 2016-04-05 14:53:41 +02:00
Robert Winkler
78411de398 Merge remote-tracking branch 'origin/master' 2016-04-05 14:52:49 +02:00
Robert Winkler
e697815c0c Updated documentation 2016-04-05 14:52:43 +02:00
Hugo de Paix de Coeur
fbd22779ee revert buildOperationTitle block from SIDEBAR to LITERAL style
fixed #28 : */* (consume/produce) not escaped
fixed tests
2016-04-05 14:25:01 +02:00
Robert Winkler
b13c57ea35 Merge remote-tracking branch 'origin/master' 2016-04-05 13:40:36 +02:00
Robert Winkler
0b38f2a91c Updated documentation 2016-04-05 13:40:30 +02:00
Robert Winkler
db36397e81 Fixed getRequiredURI and getURI in Swagger2MarkupProperties 2016-04-05 13:40:21 +02:00
Hugo de Paix de Coeur
066fd597da fix bad refactoring in URIUtils 2016-04-05 13:38:06 +02:00
Hugo de Paix de Coeur
e979d2b45b adapt to latest MDB modifications 2016-04-05 13:33:39 +02:00
Robert Winkler
4fa9f0d645 Updated documentation 2016-04-05 13:17:12 +02:00
Robert Winkler
fecf6c6161 Added a check to the static factory method fromPath to check if the input file does exist. 2016-04-05 11:12:46 +02:00
Robert Winkler
7eecba583d Added a static factory method in URIUtils to create a URI from a String representation of a URI or a Path. 2016-04-05 11:06:37 +02:00
Robert Winkler
9c6111da3e Removed checks to the static factory method fromPath to check if the input file does exist and is readable.
They are not working as expected.
2016-04-05 10:46:34 +02:00
Robert Winkler
f10882d14d Fixed checks to the static factory method fromPath to check if the input file does exist and is readable. 2016-04-05 10:25:39 +02:00
Robert Winkler
0ac9e13948 Fixed checks to the static factory method fromPath to check if the input file does exist and is readable. 2016-04-05 10:20:04 +02:00
Robert Winkler
fb3ef974a3 Added checks to the static factory method fromPath to check if the input file does exist and is readable. 2016-04-05 09:19:00 +02:00
Robert Winkler
65522e4569 Fixed static factory method fromUri so that it also excepts URIs without a scheme. 2016-04-05 08:30:59 +02:00
Hugo de Paix de Coeur
ae8961d43c fixed #44 : added a non-regression test 2016-04-04 20:14:52 +02:00
Robert Winkler
c131a8cad8 Merge pull request #123 from Swagger2Markup/features/polymorphism
fixed #22 : Add discriminator field to the output
2016-04-04 20:04:20 +02:00
Hugo de Paix de Coeur
7ad8ef8d18 fixed #22 : Add discriminator field to the output 2016-04-04 19:58:29 +02:00
Hugo de Paix de Coeur
539520903f enhanced maps test using integer with format int32 2016-04-04 17:55:53 +02:00
Hugo de Paix de Coeur
566300a598 fixed missing line breaks in overview document 2016-04-04 17:55:53 +02:00
Robert Winkler
b64bbee4b4 Merge pull request #122 from Swagger2Markup/features/enums
fixes #111 : Enum definition type values not rendered
2016-04-04 17:49:32 +02:00
Robert Winkler
8c005466c6 Updated documentation 2016-04-04 16:37:53 +02:00
Robert Winkler
d222e01466 Updated javadoc of toPath method in Swagger2MarkupConverter. 2016-04-04 16:26:17 +02:00
Hugo de Paix de Coeur
d692f616ba getTypeProperties documentation 2016-04-04 16:25:00 +02:00
Hugo de Paix de Coeur
656ebde58c fixes #111 : Enum definition type values not rendered
getAllProperties logic as been factored in ModelUtils
2016-04-04 16:16:41 +02:00
Robert Winkler
4973f9674a Added Gradle Plugin documentation 2016-04-04 13:55:52 +02:00
Robert Winkler
9fe3bf9ec0 Merge branch 'master' of https://github.com/Swagger2Markup/swagger2markup 2016-04-04 13:36:49 +02:00
Robert Winkler
074794830f Merge pull request #121 from Swagger2Markup/features/maps
fixes #113 : Support for maps (additionalProperties) in parameters, defs and responses
2016-04-04 13:36:17 +02:00
Hugo de Paix de Coeur
1f4fd9f115 cosmetic 2016-04-04 13:35:21 +02:00
Hugo de Paix de Coeur
82ac10c7a5 fixes #113 : Support for maps (additionalProperties) in parameters, definitions and responses 2016-04-04 13:31:56 +02:00
Robert Winkler
505b9047ba Updated javadoc of toPath 2016-04-04 13:04:05 +02:00
Robert Winkler
735123749e Added Gradle Plugin documentation 2016-04-04 12:18:22 +02:00
Robert Winkler
df3c8f51d5 Merge remote-tracking branch 'origin/master' 2016-04-04 12:15:16 +02:00
Robert Winkler
6de159fa7d Moved Swagger2MarkupProperties into another package. 2016-04-04 12:15:08 +02:00
Hugo de Paix de Coeur
119b190585 fixed content extensions positions documentation 2016-04-04 11:31:38 +02:00
Robert Winkler
14c0be59dd Updated documentation 2016-04-04 11:18:16 +02:00
Robert Winkler
fd2ae92663 Updated documentation 2016-04-04 11:16:29 +02:00
Robert Winkler
a57b16504f Added a check that the input file must not be a hidden file. 2016-04-04 10:49:01 +02:00
Robert Winkler
ee36c1b9f3 Added a toPath methods to the Swagger2MarkupConverter which converts the Swagger specification either into a folder or a file. 2016-04-04 10:42:25 +02:00
Robert Winkler
928ec8b325 Added a static factory method "fromURI" method to the Swagger2MarkupConverter 2016-04-04 10:31:43 +02:00
Robert Winkler
3d720f2c81 Merge branch 'master' of https://github.com/Swagger2Markup/swagger2markup 2016-04-04 08:11:03 +02:00
Robert Winkler
040c60a9ba Merged swagger-parser 1.0.18 2016-04-04 08:10:59 +02:00
Robert Winkler
2e874957fb Updated documentation 2016-04-02 20:16:40 +02:00
Robert Winkler
3ed94986ed Updated documentation 2016-04-02 20:09:21 +02:00
Robert Winkler
32f7561e26 Updated documentation 2016-04-02 20:02:07 +02:00
Robert Winkler
dbaaa195b5 Updated documentation 2016-04-02 19:56:11 +02:00
Robert Winkler
7f01e9beaa Updated documentation 2016-04-02 17:44:07 +02:00
Robert Winkler
2e95cf6b25 Updated documentation 2016-04-02 17:24:11 +02:00
Robert Winkler
23314507db Merge pull request #120 from Swagger2Markup/features/sparser-1.0.18
Features/sparser 1.0.18
2016-04-02 13:18:18 +02:00
Hugo de Paix de Coeur
cfbff5402c Reintroduce DOCUMENT_AFTER position for content extensions 2016-04-01 16:22:03 +02:00
Hugo de Paix de Coeur
6c6c625273 use released io.swagger:swagger-compat-spec-parser:1.0.18 2016-04-01 15:16:57 +02:00
Robert Winkler
a66560a255 Updated documentation 2016-04-01 14:59:27 +02:00
Robert Winkler
5ff5fc8f0f Updated documentation 2016-04-01 14:55:53 +02:00
Robert Winkler
f001b5bb7c Updated documentation 2016-04-01 14:53:56 +02:00
Hugo de Paix de Coeur
403b8fcfc7 Merge branch 'master' into features/sparser-1.0.18
# Conflicts:
#	build.gradle
2016-04-01 14:11:34 +02:00
Robert Winkler
456625ae4b Simplified loading of the default properties file. 2016-04-01 13:11:09 +02:00
Robert Winkler
5dd9163610 Merge remote-tracking branch 'origin/master' 2016-04-01 10:38:35 +02:00
Robert Winkler
3953b3328a Added commons-collections4:4.1 2016-04-01 10:38:28 +02:00
Robert Winkler
124be6c37a Added Codacy badge 2016-04-01 10:19:52 +02:00
Robert Winkler
6fc474ac09 Fixed JavaDoc 2016-04-01 10:00:57 +02:00
Robert Winkler
49ccad694e Fixed JavaDoc 2016-03-31 16:30:46 +02:00
Robert Winkler
370fa5eb8d Merge remote-tracking branch 'origin/master' 2016-03-31 16:25:12 +02:00
Robert Winkler
df61f140ca Upgrade to JDK8 2016-03-31 16:25:03 +02:00
Robert Winkler
b80b16d03f Updated readme 2016-03-24 20:08:24 +01:00
Robert Winkler
97c75c306f Updated readme 2016-03-24 20:04:21 +01:00
Robert Winkler
30258c7e75 Updated documentation. 2016-03-23 16:31:33 +01:00
Robert Winkler
e66feb5a27 Updated documentation. 2016-03-23 14:46:16 +01:00
Robert Winkler
972f2c2d6d Updated documentation. 2016-03-23 14:43:05 +01:00
Hugo de Paix de Coeur
fcf46c1588 small doc changes 2016-03-22 17:24:43 +01:00
Robert Winkler
cd38ed01a4 Updated documentation. 2016-03-22 16:38:20 +01:00
Robert Winkler
5f965e6378 Updated documentation. 2016-03-22 16:33:20 +01:00
Robert Winkler
d20bce81f0 Merge remote-tracking branch 'origin/master' 2016-03-21 16:44:52 +01:00
Robert Winkler
d9e2397f48 Updated documentation. 2016-03-21 16:43:42 +01:00
Robert Winkler
6fe35c34be Updated readme 2016-03-19 15:22:01 +01:00
Hugo de Paix de Coeur
05924c5813 Merge branch 'master' into features/sparser-1.0.18
# Conflicts:
#	build.gradle
2016-03-18 15:48:43 +01:00
Robert Winkler
b931d7f3af Fixes #116 Section titles of generated HTTP request/response have the same level 2016-03-18 15:39:03 +01:00
Robert Winkler
5b970eb2c8 Merge remote-tracking branch 'origin/master' 2016-03-18 15:06:24 +01:00
Robert Winkler
52b5bf2361 Renamed operationsGroupedBy to pathsGroupedBy to be backward compatible. 2016-03-18 15:06:17 +01:00
Hugo de Paix de Coeur
8eee21baf0 renamed intoFolder -> toFolder, asString -> toString for consistency 2016-03-18 13:20:36 +01:00
Robert Winkler
e99656704f Merge pull request #114 from ahus1/translation_to_german
translation of labels to German
2016-03-18 13:05:37 +01:00
Alexander Schwartz
235e5b7ddf translation of labels to German 2016-03-18 12:50:27 +01:00
Robert Winkler
69e7992f3e Updated markup-document-builder to 1.0.0-SNAPSHOT 2016-03-18 10:39:14 +01:00
Robert Winkler
29bfddc8d2 DiffUtils assertThatAllFilesAreEqual iterates over the expectedDirectory instead of the actualDirectory now. This allows to check only 2 files instead of always all 4 S2M documents. 2016-03-18 08:22:59 +01:00
Robert Winkler
3fc8a897a1 Removed mavenLocal() in build.gradle. 2016-03-18 08:12:41 +01:00
Hugo de Paix de Coeur
451e377cac inverted actual/expected in DiffUtils.assertThatAllFilesAreEqual for consistency with tests habits 2016-03-17 17:15:44 +01:00
Hugo de Paix de Coeur
6379b3ccf1 fixed #107 : Possibility to write the output into just one file instead of a folder 2016-03-17 17:10:53 +01:00
Hugo de Paix de Coeur
456f27c85b Merge branch 'master' into features/sparser-1.0.18 2016-03-17 15:38:06 +01:00
Hugo de Paix de Coeur
c739649f20 fixed typo bug in withSwaggerMarkupLanguage which was setting the bad markupLanguage variable 2016-03-17 15:37:37 +01:00
Hugo de Paix de Coeur
3dceb21bd5 Merge branch 'master' into features/sparser-1.0.18 2016-03-16 19:16:08 +01:00
Hugo de Paix de Coeur
23331930cc introduced .withSwaggerMarkupLanguage configuration to automatically convert Swagger file description into the target S2M language 2016-03-16 19:13:57 +01:00
Hugo de Paix de Coeur
da48f49a25 Merge branch 'master' into features/sparser-1.0.18 2016-03-16 16:32:36 +01:00
Hugo de Paix de Coeur
3775f26458 fixed refactoring bug in PathsDocumentBuilder::DefinitionDocumentResolverFromOperation 2016-03-16 16:30:20 +01:00
Robert Winkler
365d3278ff Added getRequiredMarkupLanguage method to Swagger2MarkupProperties 2016-03-16 16:09:01 +01:00
Robert Winkler
7cc9742530 Merge remote-tracking branch 'origin/master' 2016-03-16 15:51:01 +01:00
Robert Winkler
0648a9cbea Added two getPath methods to Swagger2MarkupProperties. 2016-03-16 15:50:48 +01:00
Hugo de Paix de Coeur
7766276abc Merge branch 'master' into features/sparser-1.0.18
# Conflicts:
#	build.gradle
2016-03-16 15:50:41 +01:00
Hugo de Paix de Coeur
19bc2dd0e2 moved generated test results to build/test for consistency with MDB 2016-03-16 15:37:37 +01:00
Robert Winkler
6126260aae Added a URIUtils class with a new convertUriWithoutSchemeToFileScheme method. 2016-03-16 15:15:30 +01:00
Robert Winkler
cdd0bc52e2 Added a getRequiredURI and updated the getURI method in Swagger2MarkupProperties 2016-03-16 14:07:24 +01:00
Hugo de Paix de Coeur
ccf3ee8e7d use new MDB .withHeaderColumn 2016-03-16 13:51:55 +01:00
Robert Winkler
54147bbddb Merge remote-tracking branch 'origin/master' 2016-03-16 12:42:33 +01:00
Robert Winkler
914fa2da0f Refactored Swagger2MarkupConfigBuilder to use Apache Commons configuration. 2016-03-16 12:42:27 +01:00
Hugo de Paix de Coeur
d41b14bbff added anchors for operations and definitions in !separated mode too
switched paths anchors to getId() instead of getTitle()
2016-03-16 11:39:37 +01:00
Robert Winkler
354d2167fb Added enum examples to swagger_petstore.yaml. 2016-03-16 08:52:09 +01:00
Hugo de Paix de Coeur
9eb7c671cd Merge branch 'master' into features/sparser-1.0.18 2016-03-15 18:14:48 +01:00
Hugo de Paix de Coeur
aee7708cd1 Use swagger-compat-spec-parser:1.0.18-SNAPSHOT 2016-03-15 18:07:20 +01:00
Robert Winkler
e3f946ecf8 Added missing javadoc to Swagger2MarkupConfig. 2016-03-15 15:51:08 +01:00
Robert Winkler
c25b6be1f3 Moved String constants PROPERTIES_PREFIX and EXTENSION_PREFIX into Swagger2MarkupConfig interfaces 2016-03-15 15:49:27 +01:00
Hugo de Paix de Coeur
eff69079a6 added Swagger2MarkupConfig, Swagger2MarkupExtensionRegistry documentation 2016-03-15 14:44:42 +01:00
Robert Winkler
8d8d4cd5d0 Added a method getExtensionsProperties to Swagger2MarkupConfig and withExtensionProperties to Swagger2MarkupConfigBuilder so that a user is able to configure its Swagger2Markup extension. 2016-03-15 13:42:36 +01:00
Hugo de Paix de Coeur
4bce1234af fixes package paths after massive package refactoring (2/2) 2016-03-15 12:12:44 +01:00
Hugo de Paix de Coeur
d892f0b39d fixes package paths after massive package refactoring 2016-03-15 11:23:52 +01:00
Robert Winkler
831e949d91 Uncommented tests which are not necessary anymore. 2016-03-15 11:04:53 +01:00
Robert Winkler
d48b9c217b The S2MConfig and S2MRegistry are interfaces now so that other users can develop their own implementations and don't have to use our default implementations. 2016-03-15 09:59:32 +01:00
Robert Winkler
124a66aaa9 Merge branch 'master' of https://github.com/Swagger2Markup/swagger2markup 2016-03-15 08:43:31 +01:00
Robert Winkler
08eb6841fc Refactor extension SPI to use the ServiceLoader by default 2016-03-15 08:43:26 +01:00
Hugo de Paix de Coeur
e74ac9fda5 fixes copy code to support last mdb commits 2016-03-14 19:28:07 +01:00
Robert Winkler
d4bbcc3acc Allow to use http proxy settings in unit tests. 2016-03-14 15:43:40 +01:00
Robert Winkler
9655e113c0 Fixed order of examples and security scheme definitions. 2016-03-14 15:43:20 +01:00
Robert Winkler
54c7682f00 Fixed compile issue in Swagger2MarkupConverter 2016-03-14 15:14:56 +01:00
Robert Winkler
7c8efa1060 Fixed failing Swagger2MarkupExtensionRegistryTest after moving the extensions into another repo. 2016-03-14 15:12:14 +01:00
Robert Winkler
0caf2d7a43 Merge remote-tracking branch 'origin/master' 2016-03-14 15:03:31 +01:00
Robert Winkler
533590656f Fixes #110 Move Extensions into swagger2markup-extensions repo 2016-03-14 15:03:19 +01:00
Robert Winkler
fe0fa8a9ce Moved classes from 'io.github.robwin.swagger2markup' to 'io.github.swagger2markup' 2016-03-14 15:01:32 +01:00
Robert Winkler
a85b695c80 Changed artifact group from group = 'io.github.robwin' to 'io.github.swagger2markup'.
Refactored gradle scripts.
2016-03-14 15:00:17 +01:00
Hugo de Paix de Coeur
251a6b7e73 fixes merge from master (missing some convertExample) 2016-03-14 12:10:31 +01:00
Hugo de Paix de Coeur
08b0d085db Merge branch 'master' into features/sparser-1.0.18
# Conflicts:
#	build.gradle
#	src/main/java/io/github/robwin/swagger2markup/Swagger2MarkupConfig.java
2016-03-14 11:43:04 +01:00
Hugo de Paix de Coeur
0b95f35a61 Removes formatting from RU localization 2016-03-14 11:28:23 +01:00
Robert Winkler
4073b7627d Fixes #60: Add support of Response Headers
The description of response headers was not rendered correctly.
2016-03-11 08:37:32 +01:00
Robert Winkler
2c2b599528 Fixed expected result files. 2016-03-10 16:14:31 +01:00
Robert Winkler
eb86d6f1d0 Moved buildDescriptionParagraph method ino MarkupDocumentBuilder so that it can be reused by all other builders. 2016-03-10 15:39:07 +01:00
Robert Winkler
2d74e441dc Replaced colon separator by a static final string. 2016-03-10 15:38:11 +01:00
Robert Winkler
8145dea0d5 Added gh-pages gradle-git plugin. 2016-03-10 15:37:38 +01:00
Robert Winkler
a4a217a223 Fixed security scheme title anchor. 2016-03-10 15:37:03 +01:00
Hugo de Paix de Coeur
4283b2489d Merge branch 'develop' into features/sparser-1.0.18 2016-03-03 18:05:06 +01:00
Hugo de Paix de Coeur
c6e21b9ed1 fixes configuration validators and doc 2016-03-03 18:04:15 +01:00
Hugo de Paix de Coeur
c61a94495f Merge branch 'develop' into features/sparser-1.0.18
# Conflicts:
#	src/main/java/io/github/robwin/swagger2markup/utils/ExamplesUtil.java
2016-03-03 17:49:53 +01:00
Hugo de Paix de Coeur
3e5df92223 Merge branch 'develop' into features/sparser-1.0.18
# Conflicts:
#	src/main/java/io/github/robwin/swagger2markup/utils/ExamplesUtil.java
2016-03-03 14:04:43 +01:00
Hugo de Paix de Coeur
e96dd94ee9 Support Swagger Parser 1.0.18 interfaces changes 2016-03-02 11:57:28 +01:00
555 changed files with 53080 additions and 14694 deletions

82
.github/workflows/gradle-build.yml vendored Normal file
View File

@@ -0,0 +1,82 @@
# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Build
on:
push:
branches: [ 1.3.x ]
pull_request:
branches: [ 1.3.x ]
jobs:
validation:
name: "Gradle wrapper validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.5
- uses: gradle/wrapper-validation-action@v1.0.4
build:
name: "Build and publish"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.5
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Cache SonarCloud packages
uses: actions/cache@v2.1.6
if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Build
id: gradle
uses: eskatos/gradle-command-action@v1
with:
arguments: check
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: "Comment build scan url"
uses: actions/github-script@v5
if: github.event_name == 'pull_request' && failure()
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '❌ ${{ github.workflow }} failed: ${{ steps.gradle.outputs.build-scan-url }}'
})
- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action/composite@v1
if: always()
with:
files: '**/test-results/**/*.xml'
- name: Analyze with SonarCloud
continue-on-error: true
if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
uses: eskatos/gradle-command-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
arguments: sonarqube -Psonar.organization=swagger2markup
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Publish to Sonatype
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/1.3.x' }}
uses: eskatos/gradle-command-action@v1
env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USER }}
ORG_GRADLE_PROJECT_sonatypePassword : ${{ secrets.SONATYPE_PASSWORD }}
with:
arguments: publishToSonatype
dependencies-cache-enabled: true
configuration-cache-enabled: true

3
.gitignore vendored
View File

@@ -3,3 +3,6 @@
.gradle
build
/bin/
/.classpath
/.project
/.settings/

View File

@@ -1,19 +1,18 @@
language: java
jdk:
- oraclejdk7
- openjdk8
before_install:
- chmod +x gradlew
after_success:
- ./gradlew jacocoTestReport coveralls
- ./gradlew artifactoryPublish -PbintrayUsername="${BINTRAY_USER}" -PbintrayApiKey="${BINTRAY_KEY}"
- ./gradlew publishGhPages -PgithubUser="${GITHUB_USER}" -PgithubPassword="${GITHUB_PASSWORD}"
--stacktrace
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/9c620e84679284b7d621
on_success: change
on_failure: always
on_start: false
slack: swagger2markup:Zz5kz0SnvtG6aVvZUM8yMkER
env:
global:
- secure: "SPKolgUdjIa/uJ+7/B/GPFlsa8IZg7NuZdFA8zROTaqew/xu+oX7qVGImseeBpPIEPJb02ac6hr7Y3/zvv0GJxIPtIbyDzVh73ImQUhT1ttLYGJfITAWqAPFF7RNNMtuOl3S2DLZ5OMJddkcFp00pa9nyI82Gk47B8GsaGIntAI="
- secure: "nXXuHfvFACZwdiFM3Ta0x/f49N7cAgi0AMkgEnQrh/2xWlvQk2z2ySGJQLkhJ7Wy8LDY7Yt1b1GUt6DlP3PuFFMW/cT4iARewqiJRXZXxUQz8fpTDeTo1nmVmW/zzII6Qj3QHM3NRbR/xDOVSJiT30Hnq2hcCBQJWYsTICmzjRk="
- secure: SPKolgUdjIa/uJ+7/B/GPFlsa8IZg7NuZdFA8zROTaqew/xu+oX7qVGImseeBpPIEPJb02ac6hr7Y3/zvv0GJxIPtIbyDzVh73ImQUhT1ttLYGJfITAWqAPFF7RNNMtuOl3S2DLZ5OMJddkcFp00pa9nyI82Gk47B8GsaGIntAI=
- secure: nXXuHfvFACZwdiFM3Ta0x/f49N7cAgi0AMkgEnQrh/2xWlvQk2z2ySGJQLkhJ7Wy8LDY7Yt1b1GUt6DlP3PuFFMW/cT4iARewqiJRXZXxUQz8fpTDeTo1nmVmW/zzII6Qj3QHM3NRbR/xDOVSJiT30Hnq2hcCBQJWYsTICmzjRk=
- secure: Ia/wJ572M2II76roFeGEVCzIiktG4v2j/reSn60fpk1gnoEPQEObL4j1dbVCgXBLz54YWcaQ3mICvOfBPPEl9IIV3Y6DDE2sBOmB3soznfdA/YVnJx0h0f1pfXu1dwqoiv1sgc1wewQuUWq+FV7xeDhFE3cnh9CXIexe9ykip8k=
- secure: GWfhYDsHRmTfOuEOIcHY8kT4jKBTbdhNLDQ/2amY06xenFblb4pEn6pgmn4IdK3ytjNovnZPTOOK8HqdEjhbfIGoQt6PZwuyANn4Df+zdqOC0+V+7DFG2QhEhbRCyEwPlDqTPjxlOMfAmvjFuY/NvQywoF3PYUyMfJwUV8ehmYk=

5
ISSUE_TEMPLATE Normal file
View File

@@ -0,0 +1,5 @@
Thanks for raising a Swagger2Markup issue. Please provide a brief description of your problem along with the Swagger2Markup version you are using. If possible, please also consider putting together a complete Swagger specification that reproduces the issue. It's better if the Swagger specification is small and isolate the issue.
Swagger2Markup version:
Problem description:

View File

@@ -2,11 +2,22 @@
:author: Robert Winkler
:hardbreaks:
image:https://travis-ci.org/Swagger2Markup/swagger2markup.svg?branch=master["Build Status", link="https://travis-ci.org/Swagger2Markup/swagger2markup"] image:https://coveralls.io/repos/Swagger2Markup/swagger2markup/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup"] image:https://api.bintray.com/packages/robwin/maven/swagger2markup/images/download.svg[link="https://bintray.com/robwin/maven/swagger2markup/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/RobWin/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
image:https://travis-ci.org/Swagger2Markup/swagger2markup.svg?branch=master["Build Status", link="https://travis-ci.org/Swagger2Markup/swagger2markup"] image:https://coveralls.io/repos/Swagger2Markup/swagger2markup/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup"] image:https://api.codacy.com/project/badge/grade/498a6a39d7d84ff687546359f58ee18d["Codacy code quality", link="https://www.codacy.com/app/robwin/swagger2markup"] image:https://api.bintray.com/packages/swagger2markup/Maven/swagger2markup/images/download.svg[link="https://bintray.com/swagger2markup/Maven/swagger2markup/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/RobWin/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
== Overview
NOTE: Dear community,
unfortunately I can't maintain Swagger2Markup alone anymore. There are many interesting new topics:
1) Swagger v3 support
2) Fixing bugs
2) Merge Swagger2Markup repositories and create a new multi-module repository.
Any help is welcome.
Kind regards,
Robert
The primary goal of this project is to *simplify the generation of an up-to-date RESTful API documentation by combining documentation that's been hand-written with auto-generated API documentation* produced by https://github.com/swagger-api[Swagger]. The result is intended to be an *up-to-date, easy-to-read, on- and offline user guide*, comparable to https://developer.github.com/v3/[GitHub's API documentation]. The output of Swagger2Markup can be used as an alternative to https://github.com/swagger-api/swagger-ui[swagger-ui] and can be served as static content.
NOTE: The Swagger Specification has been donated to to the https://openapis.org/[Open API Initiative (OAI)] and has been renamed to the https://github.com/OAI/OpenAPI-Specification[OpenAPI Specification].
@@ -18,16 +29,16 @@ http://asciidoctor.org/docs/asciidoc-writers-guide/[AsciiDoc] is preferable to M
You can generate your HTML5, PDF and EPUB documentation via https://github.com/asciidoctor/asciidoctorj[asciidoctorj] or even better via the https://github.com/asciidoctor/asciidoctor-gradle-plugin[asciidoctor-gradle-plugin] or https://github.com/asciidoctor/asciidoctor-maven-plugin[asciidoctor-maven-plugin].
The project requires at least JDK 7.
The project requires at least JDK 8.
== Example
image::src/docs/asciidoc/images/Swagger2Markup.PNG[]
image::swagger2markup-documentation/src/docs/asciidoc/images/Swagger2Markup.PNG[]
image::src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[]
image::swagger2markup-documentation/src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[]
== Reference documentation
- http://swagger2markup.readme.io/[Reference Documentation]
- http://swagger2markup.github.io/swagger2markup/1.3.4/[Reference Documentation]
- https://github.com/Swagger2Markup/swagger2markup/blob/master/RELEASENOTES.adoc[Release notes]
- https://github.com/Swagger2Markup/spring-swagger2markup-demo[Demo using Swagger2Markup, Spring Boot, Springfox and spring-restdocs]
@@ -37,14 +48,6 @@ image::src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[]
Pull requests are welcome.
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/18[Swagger2Markup/swagger2Markup#18] by https://github.com/sg-ad[@sg-ad]: In addition to the definitions.adoc you can also generate separate files for each definition model (ex: person.adoc, address.adoc, purchase.adoc).
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/21[Swagger2Markup/swagger2Markup#21] by https://github.com/redowl[@redowl]: Support for both reference models and composed models.
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/27[Swagger2Markup/swagger2Markup#27] by https://github.com/zmitrok[@zmitrok]: Added a hook to preprocess a Swagger Model before it is converted.
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/48[Swagger2Markup/swagger2Markup#48] by https://github.com/MeteorBoom[@MeteorBoom]: Multi language support.
=== Questions
You can ask questions about Swagger2Markup in https://gitter.im/Swagger2Markup/swagger2markup[Gitter].
@@ -61,6 +64,9 @@ If youd like an enhancement to be made to Swagger2Markup, pull requests are m
* http://www.qaware.de/[QAware GmbH]
* http://www.appdirect.com/[AppDirect] -- The leading commerce platform for selling cloud services.
* http://www.wescale.com[wescale]
* http://taskassure.com[TaskAssure]
* https://www.isaac.nl[ISAAC]
* https://www.spreadshirt.de[Spreadshirt]
== License

View File

@@ -3,6 +3,21 @@
== Version 0.1.0
* Initial version with support for AsciiDoc and Markdown
=== Version 0.1.1
* Signed jar files
=== Version 0.1.2
* Removed logback from compile dependency
=== Version 0.1.3
* Removed commons.io from compile dependency
=== Version 0.1.4
* Fixed SECTION_TITLE_LEVEL3 in Markdown enum
=== Version 0.1.5
* Added SECTION_TITLE_LEVEL4
== Version 0.2.0
* This version is not downward compatible. This version supports includes of example files and JSON/XML Schema files. See documentation.
@@ -78,9 +93,80 @@
=== Version 0.9.3
* 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 #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
== Version 1.0.0
* New configuration API
* New extension SPI
* Added new languages: turkish, german, france
* New security document
* Inline schema support
* New configuration options
* Support of deprecated path operations
=== Version 1.0.1
* Enhancement: Support to render validation constraints of properties
* Enhancement: Possibility to disable rendering of the security chapter below operations
== Version 1.1.0
* PR #177: Fixed rendering of recursive examples
* PR #186: Add support for Chinese language
* PR #190: Add support for Spanish language
* PR #192: Updated min/max value to format correctly based on the data type
* PR #193: Added support for exclusiveMin and exclusiveMax
* Changed bold to ** and italic to __ so that special chars in the text are possible
=== Version 1.1.1
* Issue #194: Added a config parameter which allows to prepend the basePath to all paths.
* Updated swagger-parser from v1.0.16 to v1.0.23
* Added javslang v2.0.4 as a dependency
* Added paleo-core v0.10.1 as a dependency
* Updated markup-document-builder from 1.0.0 to 1.1.0
* PR #201: Add support for Brazilian Portuguese language
* PR #202: Add support for Japanese language
* Issue #205: Fixed the option to influence resource ordering
* Issue #198: Chinese chinese language encoding
* Issue #207: Properties that start with an underscore are displayed correctly now
* Refactored Swagger2Markup to use a Component-Based design. A document can be composed of components and components can be composed of other components.
* Added a method to add page breaks.
== Version 1.1.2
* Improve code blocks in markdown
== Version 1.2.0
* Issue #214: Add page break locations
* Issue #223: Improve example rendering
* Issue #215: Add ability to group operations by RegEx
* Added new configuration options: pageBreakLocations, headerRegex
* Added new valid value for configuration headerRegex: REGEX
* Updated markup-document-builder from 1.1.0 to 1.1.1
== Version 1.3.0
* Updated javslang from 2.0.4 to 2.0.5
* Updated paleo-core from 0.10.1 to 0.10.2
* Updated swagger-parser from v1.0.23 to v1.0.25
* Decimal numbers are formatted into locale-specific strings
=== Version 1.3.1
* PR #247: Fix request path and query params example support.
=== Version 1.3.2
* PR #290: Fixed list parsing in properties file
* PR #293: Fixed crash on empty tables
* Updated markup-document-builder from 1.1.1 to 1.1.2
=== Version 1.3.3
* Updated swagger-parser from v1.0.25 to 1.0.35
* PR #294: Examples always start with a newline if there is other content in the same cell
* PR 307: Include required parameters in example request
=== Version 1.3.4
* Moved from bintray to Sonatype
* Introduced Github actions
* Certain bug fixes
* Added support for MIME types with structured syntax suffixes (#410)

View File

@@ -1,134 +1,117 @@
buildscript {
plugins {
id "org.sonarqube" version "2.7"
id "me.champeau.gradle.jmh" version "0.4.8"
id 'org.asciidoctor.convert' version '1.6.0'
id "org.ajoberstar.github-pages" version "1.7.2"
id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
}
apply plugin: 'idea'
apply from: "${rootDir}/libraries.gradle"
ext {
releaseVersion = '1.3.4'
}
allprojects {
apply plugin: 'jacoco'
apply plugin: 'me.champeau.gradle.jmh'
version = '1.3.4'
group 'io.github.swagger2markup'
description = 'swagger2markup Build'
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.10.1'
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.0.1'
classpath 'org.asciidoctor:asciidoctorj:1.5.2'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.0"
}
}
description = 'swagger2markup Build'
version = '1.0.0-SNAPSHOT'
group = 'io.github.robwin'
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'org.asciidoctor.convert'
apply plugin: 'jacoco'
apply plugin: 'com.github.kt3k.coveralls'
apply plugin: 'com.jfrog.bintray'
apply plugin: "com.jfrog.artifactory"
apply from: 'gradle/publishing.gradle'
tasks.withType(JavaCompile) {
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
options.deprecation = true
options.encoding = 'UTF-8'
options.compilerArgs << "-Xlint:unchecked"
}
repositories {
maven {
url "https://oss.jfrog.org/artifactory/oss-snapshot-local"
}
jcenter()
mavenCentral()
//mavenLocal()
}
dependencies {
compile 'io.github.robwin:markup-document-builder:0.1.6-SNAPSHOT'
compile 'io.swagger:swagger-compat-spec-parser:1.0.17'
testCompile 'junit:junit:4.11'
testCompile 'org.asciidoctor:asciidoctorj:1.5.4'
testCompile 'ch.qos.logback:logback-classic:1.1.2'
testCompile 'org.assertj:assertj-core:2.2.0'
testCompile 'com.sksamuel.diff:diff:1.1.11'
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
//artifactoryPublish.skip = true // apply to all projects except the root
ext {
generatedDocumentation = file('build/docs/asciidoc/generated')
}
asciidoctor {
sources {
include 'index.adoc'
coreProjects = subprojects.findAll {
p -> !p.name.endsWith("-bom")
}
backends = ['html5', 'pdf']
attributes = [
doctype: 'book',
toc: 'left',
toclevels: '3',
numbered: '',
sectlinks: '',
sectanchors: '',
hardbreaks: '',
generated: generatedDocumentation
]
}
artifactory {
contextUrl = 'https://oss.jfrog.org'
resolve {
repository {
repoKey = 'libs-release'
configure(project.coreProjects) {
apply plugin: 'signing'
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply from: "${rootDir}/publishing.gradle"
apply plugin: 'jacoco'
tasks.withType(JavaCompile) {
sourceCompatibility = "11"
targetCompatibility = "11"
options.deprecation = true
options.encoding = 'UTF-8'
options.compilerArgs += ["-Xlint:unchecked", "-parameters"]
}
tasks.withType(Javadoc){
options.encoding = 'UTF-8'
}
jmh {
duplicateClassesStrategy = 'warn'
}
configurations.all {
resolutionStrategy {
failOnVersionConflict()
}
}
publish {
repository {
repoKey = 'oss-snapshot-local' //The Artifactory repository key to publish to
//when using oss.jfrog.org the credentials are from Bintray. For local build we expect them to be found in
//~/.gradle/gradle.properties, otherwise to be set in the build server
username = project.hasProperty('bintrayUsername') ? project.bintrayUsername : System.getenv('BINTRAY_USER')
password = project.hasProperty('bintrayApiKey') ? project.bintrayApiKey : System.getenv('BINTRAY_KEY')
}
defaults {
publications('mavenJava')
}
nexusPublishing {
repositories {
sonatype()
}
}
sonarqube {
properties {
property "sonar.host.url", "https://sonarcloud.io"
property "sonar.organization", "swagger2markup"
property "sonar.projectName", "swagger2markup"
property "sonar.projectKey", "Swagger2Markup_swagger2markup"
property "sonar.links.homepage", "https://github.com/Swagger2Markup/swagger2markup"
property "sonar.links.ci", "https://travis-ci.org/Swagger2Markup/swagger2markup"
property "sonar.links.scm", "https://github.com/Swagger2Markup/swagger2markup"
property "sonar.links.issue", "https://github.com/Swagger2Markup/swagger2markup/issues"
property "sonar.language", "java"
}
}
def allTestCoverageFile = "$buildDir/jacoco/allTestCoverage.exec"
task jacocoMergeTest(type: JacocoMerge) {
destinationFile = file(allTestCoverageFile)
executionData = project.fileTree(dir: '.', include: '**/build/jacoco/test.exec')
}
task jacocoMerge(dependsOn: ['jacocoMergeTest']) {
// used to run the other merge tasks
}
subprojects {
sonarqube {
properties {
property "sonar.jacoco.reportPaths", allTestCoverageFile
}
}
if (System.properties['https.proxyHost']) {
clientConfig.proxy.host = System.properties['https.proxyHost']
clientConfig.proxy.port = System.properties['https.proxyPort'].toInteger()
}
}
jacocoTestReport {
reports {
xml.enabled = true // coveralls plugin depends on xml format report
html.enabled = true
afterEvaluate {
// exclude subprojects that don't produce a jar file or by design.
if (!project.name.equals('swagger2markup-bom') && !project.name.equals('swagger2markup-documentation')) {
jar {
inputs.property('moduleName', moduleName)
manifest.attributes(
'Automatic-Module-Name': moduleName
)
}
}
}
}
tasks.coveralls {
dependsOn 'check'
}
tasks.check.dependsOn tasks.jacocoTestReport
tasks.artifactoryPublish {
dependsOn 'check'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.10'
test {
dependsOn(subprojects.test) // required by cobertura to aggregate report
}

2
gradle.properties Normal file
View File

@@ -0,0 +1,2 @@
systemProp.file.encoding=UTF-8
systemProp.sun.jnu.encoding=UTF-8

View File

@@ -1,100 +0,0 @@
import java.text.SimpleDateFormat
Date buildTimeAndDate = new Date()
ext {
buildDate = new SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate)
buildTime = new SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate)
}
def projectArtifactId = 'swagger2markup'
jar {
manifest {
attributes(
'Built-By': 'Robert Winkler',
'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")",
'Build-Date': project.buildDate,
'Build-Time': project.buildTime,
'Specification-Title': projectArtifactId,
'Specification-Version': project.version,
'Implementation-Title': projectArtifactId,
'Implementation-Version': project.version
)
}
}
if (!project.hasProperty('bintrayUsername')) ext.bintrayUsername = ''
if (!project.hasProperty('bintrayApiKey')) ext.bintrayApiKey = ''
if (!project.hasProperty('gpgPassphrase')) ext.gpgPassphrase = ''
if (!project.hasProperty('ossUser')) ext.ossUser = ''
if (!project.hasProperty('ossPassword')) ext.ossPassword = ''
bintray {
user = project.bintrayUsername
key = project.bintrayApiKey
dryRun = false //Whether to run this as dry-run, without deploying
publish = true //If version should be auto published after an upload
publications = ['mavenJava']
pkg {
repo = 'maven'
name = 'swagger2markup'
websiteUrl = 'https://github.com/Swagger2Markup/swagger2markup'
issueTrackerUrl = 'https://github.com/Swagger2Markup/swagger2markup/issues'
vcsUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
desc = 'A Swagger to Markup (AsciiDoc and Markdown) converter.'
licenses = ['Apache-2.0']
version {
vcsTag = project.version
gpg {
sign = true //Determines whether to GPG sign the files. The default is false
passphrase = project.gpgPassphrase //Optional. The passphrase for GPG signing'
}
mavenCentralSync {
sync = true //Optional (true by default). Determines whether to sync the version to Maven Central.
user = ossUser //OSS user token
password = ossPassword //OSS user password
}
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom.withXml {
def devs = ['RobWin': 'Robert Winkler']
def root = asNode()
root.dependencies.'*'.findAll() {
it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep ->
dep.name == it.artifactId.text()
}
}.each() {
it.scope*.value = 'compile'
}
root.appendNode('name', 'swagger2markup')
root.appendNode('packaging', 'jar')
root.appendNode('url', 'https://github.com/Swagger2Markup/swagger2markup')
root.appendNode('description', 'A Swagger to Markup (AsciiDoc and Markdown) converter.')
def license = root.appendNode('licenses').appendNode('license')
license.appendNode('name', 'Apache-2.0')
license.appendNode('url', 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt')
license.appendNode('distribution', 'repo')
root.appendNode('scm').appendNode('url', 'https://github.com/Swagger2Markup/swagger2markup.git')
def developers = root.appendNode('developers')
devs.each {
def d = developers.appendNode('developer')
d.appendNode('id', it.key)
d.appendNode('name', it.value)
}
}
artifact sourcesJar
artifact javadocJar
}
}
}

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Wed Feb 10 11:09:13 CET 2016
#Mon Oct 21 16:35:38 BST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-all.zip

100
gradlew vendored
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -6,42 +6,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -60,6 +24,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -85,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

14
gradlew.bat vendored
View File

@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

52
libraries.gradle Normal file
View File

@@ -0,0 +1,52 @@
// Allows centralized definition of the version of artifacts to
// use. In that respect it serves a role similar to <dependencyManagement> in Maven
ext {
implLibraries = [:]
testLibraries = [:]
dependencyOverrides = [:]
}
implLibraries = [
asciiDocJApi : "org.asciidoctor:asciidoctorj-api:2.2.0",
commonsBeanUtils : "commons-beanutils:commons-beanutils:1.9.4",
commonsCodec : "commons-codec:commons-codec:1.13",
commonsCollections4: "org.apache.commons:commons-collections4:4.4",
commonsConf2 : "org.apache.commons:commons-configuration2:2.6",
commonsLang3 : "org.apache.commons:commons-lang3:3.9",
commonsIO : "commons-io:commons-io:2.6",
commonsText : "org.apache.commons:commons-text:1.8",
guava : 'com.google.guava:guava:27.0.1-android',
jacksonDatabind : 'com.fasterxml.jackson.core:jackson-databind:2.9.10',
mark2Ascii : "nl.jworks.markdown_to_asciidoc:markdown_to_asciidoc:1.1",
paleo : "ch.netzwerg:paleo-core:0.14.0",
pegdown : "org.pegdown:pegdown:1.6.0",
slf4j : "org.slf4j:slf4j-api:1.7.28",
swaggerV2 : "io.swagger:swagger-parser:1.0.47",
swaggerV2Converter : "io.swagger.parser.v3:swagger-parser-v2-converter:2.0.15",
swaggerV3 : "io.swagger.parser.v3:swagger-parser:2.0.15",
vavr : "io.vavr:vavr:0.10.2"
]
testLibraries = [
asciiDocJ : "org.asciidoctor:asciidoctorj:2.2.0",
assertj : "org.assertj:assertj-core:3.13.2",
assertjDiff: "io.github.robwin:assertj-diff:0.1.1",
junit : "junit:junit:4.12",
logback : "ch.qos.logback:logback-classic:1.2.3",
mockito : "org.mockito:mockito-core:3.1.0"
]
dependencyOverrides = [
assertj : testLibraries.assertj,
commonsCodec : implLibraries.commonsCodec,
commonsIO : implLibraries.commonsIO,
commonsLang3 : implLibraries.commonsLang3,
findBugs : 'com.google.code.findbugs:jsr305:3.0.2',
guava : implLibraries.guava,
jaksonCore : 'com.github.fge:jackson-coreutils:1.8',
jacksonDatabind: implLibraries.jacksonDatabind,
jnrConstants : 'com.github.jnr:jnr-constants:0.9.12',
jnrEnxio : 'com.github.jnr:jnr-enxio:0.19',
jnrPosix : 'com.github.jnr:jnr-posix:3.0.49',
jodaTime : 'joda-time:joda-time:2.9.9',
slf4j : implLibraries.slf4j,
]

91
publishing.gradle Normal file
View File

@@ -0,0 +1,91 @@
import java.text.SimpleDateFormat
Date buildTimeAndDate = new Date()
ext {
buildDate = new SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate)
buildTime = new SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate)
licenseUrl = 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt'
scmUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
}
def projectArtifactId = 'swagger2markup'
def projectUrl = 'https://github.com/Swagger2Markup/swagger2markup'
def licenseUrl = 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt'
def scmUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
def issuesUrl = 'https://github.com/Swagger2Markup/swagger2markup/issues'
jar {
manifest {
attributes(
'Built-By': 'Robert Winkler',
'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")",
'Build-Date': project.buildDate,
'Build-Time': project.buildTime,
'Specification-Title': projectArtifactId,
'Specification-Version': project.version,
'Implementation-Title': projectArtifactId,
'Implementation-Version': project.version
)
}
}
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
archiveClassifier = 'sources'
}
task javadocJar(type: Jar) {
from javadoc
archiveClassifier = 'javadoc'
}
artifacts {
archives sourcesJar
archives javadocJar
}
signing {
sign publishing.publications
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom.withXml {
def devs = ['RobWin': 'Robert Winkler',
'austek': 'Ali Ustek']
def root = asNode()
root.dependencies.'*'.findAll() {
it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep ->
dep.name == it.artifactId.text()
}
}.each() {
it.scope*.value = 'compile'
}
root.appendNode('name', projectArtifactId)
root.appendNode('packaging', 'jar')
root.appendNode('url', projectUrl)
root.appendNode('description', project.description)
def license = root.appendNode('licenses').appendNode('license')
license.appendNode('name', 'Apache-2.0')
license.appendNode('url', licenseUrl)
license.appendNode('distribution', 'repo')
root.appendNode('scm').appendNode('url', scmUrl)
def developers = root.appendNode('developers')
devs.each {
def d = developers.appendNode('developer')
d.appendNode('id', it.key)
d.appendNode('name', it.value)
}
}
artifact sourcesJar
artifact javadocJar
}
}
}

View File

@@ -1 +1,9 @@
rootProject.name = 'swagger2markup'
rootProject.name = 'swagger2markup'
include 'swagger2markup-asciidoc'
include 'swagger2markup-bom'
include 'swagger2markup-builder'
include 'swagger2markup-documentation'
include 'swagger2markup'
include 'swagger2markup-core'

View File

@@ -1,36 +0,0 @@
== Getting started
The project is published in JCenter and Maven Central. If you use Gradle or Maven, you can include Swagger2Markup as follows.
=== Gradle
[source,groovy, subs="attributes"]
----
repositories {
mavenCentral()
jCenter()
}
compile "io.github.robwin:swagger2markup:{project-version}"
----
=== Maven
[source,xml, subs="attributes, verbatim"]
----
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
central
<name>bintray</name>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>
<dependency>
<groupId>io.github.robwin</groupId>
<artifactId>swagger2markup</artifactId>
<version>{project-version}</version>
</dependency>
----

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

View File

@@ -1,20 +0,0 @@
= Swagger2Markup User Guide
Robert Winkler
:toc: left
:toclevels: 3
:source-highlighter: coderay
:numbered:
:hardbreaks:
:revnumber: {project-version}
:revdate: {localdate}
:icons: font
:pagenums:
include::introduction.adoc[]
include::getting_started.adoc[]
include::usage_guide.adoc[]
include::license.adoc[]

View File

@@ -1,764 +0,0 @@
/*
* Copyright 2016 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;
import com.google.common.base.Function;
import com.google.common.collect.Ordering;
import io.github.robwin.markup.builder.LineSeparator;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.internal.model.PathOperation;
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
import io.swagger.models.HttpMethod;
import io.swagger.models.parameters.Parameter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.Properties;
public class Swagger2MarkupConfig {
private static final Logger logger = LoggerFactory.getLogger(Swagger2MarkupConfig.class);
private MarkupLanguage markupLanguage;
private boolean generatedExamplesEnabled;
private boolean operationDescriptionsEnabled;
private URI operationDescriptionsUri;
private boolean definitionDescriptionsEnabled;
private URI definitionDescriptionsUri;
private boolean separatedDefinitionsEnabled;
private boolean separatedOperationsEnabled;
private GroupBy operationsGroupedBy;
private Language outputLanguage;
private int inlineSchemaDepthLevel;
private OrderBy tagOrderBy;
private Comparator<String> tagOrdering;
private OrderBy operationOrderBy;
private Comparator<PathOperation> operationOrdering;
private OrderBy definitionOrderBy;
private Comparator<String> definitionOrdering;
private OrderBy parameterOrderBy;
private Comparator<Parameter> parameterOrdering;
private OrderBy propertyOrderBy;
private Comparator<String> propertyOrdering;
private OrderBy responseOrderBy;
private Comparator<String> responseOrdering;
private boolean interDocumentCrossReferencesEnabled;
private String interDocumentCrossReferencesPrefix;
private boolean flatBodyEnabled;
private String anchorPrefix;
private LineSeparator lineSeparator;
private String overviewDocument;
private String pathsDocument;
private String definitionsDocument;
private String securityDocument;
private String separatedOperationsFolder;
private String separatedDefinitionsFolder;
public static Builder ofDefaults() {
return new Builder();
}
public static Builder ofProperties(Properties properties) {
return new Builder(properties);
}
/**
* Global context lazy initialization
*
* @param globalContext Partially initialized global context (globalContext.extensionRegistry == null)
*/
public void setGlobalContext(Swagger2MarkupConverter.Context globalContext) {
configureDefaultContentPaths(globalContext.getSwaggerLocation());
}
/**
* Automatically set default path for external content files based on specified {@code swaggerLocation}.<br/>
* If {@code swaggerLocation} is null, default path can't be set and features are disabled.<br/>
* Paths have to be explicitly set when swaggerLocation.scheme != 'file' to limit the number of URL requests.
*
* @param swaggerLocation base path to set default paths
* @throws RuntimeException if basePath == null and any path is not configured
*/
private void configureDefaultContentPaths(URI swaggerLocation) {
URI baseURI = null;
if (swaggerLocation != null) {
if (swaggerLocation.getScheme().equals("file"))
baseURI = IOUtils.uriParent(swaggerLocation);
}
if (operationDescriptionsEnabled && operationDescriptionsUri == null) {
if (baseURI == null) {
if (logger.isWarnEnabled())
logger.warn("Disable {} > No explicit '{}' set and no default available > Disable {}", "operationDescriptionsEnabled", "operationDescriptionsUri");
operationDescriptionsEnabled = false;
} else
operationDescriptionsUri = baseURI;
}
if (definitionDescriptionsEnabled && definitionDescriptionsUri == null) {
if (baseURI == null) {
if (logger.isWarnEnabled())
logger.warn("Disable {} > No explicit '{}' set and no default available > Disable {}", "definitionDescriptionsEnabled", "definitionDescriptionsUri");
definitionDescriptionsEnabled = false;
} else
definitionDescriptionsUri = baseURI;
}
}
public MarkupLanguage getMarkupLanguage() {
return markupLanguage;
}
public boolean isGeneratedExamplesEnabled() {
return generatedExamplesEnabled;
}
public boolean isOperationDescriptionsEnabled() {
return operationDescriptionsEnabled;
}
public URI getOperationDescriptionsUri() {
return operationDescriptionsUri;
}
public boolean isDefinitionDescriptionsEnabled() {
return definitionDescriptionsEnabled;
}
public URI getDefinitionDescriptionsUri() {
return definitionDescriptionsUri;
}
public boolean isSeparatedDefinitionsEnabled() {
return separatedDefinitionsEnabled;
}
public boolean isSeparatedOperationsEnabled() {
return separatedOperationsEnabled;
}
public GroupBy getOperationsGroupedBy() {
return operationsGroupedBy;
}
public Language getOutputLanguage() {
return outputLanguage;
}
public int getInlineSchemaDepthLevel() {
return inlineSchemaDepthLevel;
}
public OrderBy getTagOrderBy() {
return tagOrderBy;
}
public Comparator<String> getTagOrdering() {
return tagOrdering;
}
public OrderBy getOperationOrderBy() {
return operationOrderBy;
}
public Comparator<PathOperation> getOperationOrdering() {
return operationOrdering;
}
public OrderBy getDefinitionOrderBy() {
return definitionOrderBy;
}
public Comparator<String> getDefinitionOrdering() {
return definitionOrdering;
}
public OrderBy getParameterOrderBy() {
return parameterOrderBy;
}
public Comparator<Parameter> getParameterOrdering() {
return parameterOrdering;
}
public OrderBy getPropertyOrderBy() {
return propertyOrderBy;
}
public Comparator<String> getPropertyOrdering() {
return propertyOrdering;
}
public OrderBy getResponseOrderBy() {
return responseOrderBy;
}
public Comparator<String> getResponseOrdering() {
return responseOrdering;
}
public boolean isInterDocumentCrossReferencesEnabled() {
return interDocumentCrossReferencesEnabled;
}
public String getInterDocumentCrossReferencesPrefix() {
return interDocumentCrossReferencesPrefix;
}
public boolean isFlatBodyEnabled() {
return flatBodyEnabled;
}
public String getAnchorPrefix() {
return anchorPrefix;
}
public String getOverviewDocument() {
return overviewDocument;
}
public String getPathsDocument() {
return pathsDocument;
}
public String getDefinitionsDocument() {
return definitionsDocument;
}
public String getSecurityDocument() {
return securityDocument;
}
public String getSeparatedOperationsFolder() {
return separatedOperationsFolder;
}
public String getSeparatedDefinitionsFolder() {
return separatedDefinitionsFolder;
}
public LineSeparator getLineSeparator() {
return lineSeparator;
}
public static class Builder {
private static final String PROPERTIES_PREFIX = "swagger2markup.";
private static final String PROPERTIES_DEFAULT = "/io/github/robwin/swagger2markup/config/default.properties";
static final Ordering<PathOperation> OPERATION_METHOD_NATURAL_ORDERING = Ordering
.explicit(HttpMethod.POST, HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS)
.onResultOf(new Function<PathOperation, HttpMethod>() {
public HttpMethod apply(PathOperation operation) {
return operation.getMethod();
}
});
static final Ordering<PathOperation> OPERATION_PATH_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(new Function<PathOperation, String>() {
public String apply(PathOperation operation) {
return operation.getPath();
}
});
static final Ordering<Parameter> PARAMETER_IN_NATURAL_ORDERING = Ordering
.explicit("header", "path", "query", "formData", "body")
.onResultOf(new Function<Parameter, String>() {
public String apply(Parameter parameter) {
return parameter.getIn();
}
});
static final Ordering<Parameter> PARAMETER_NAME_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(new Function<Parameter, String>() {
public String apply(Parameter parameter) {
return parameter.getName();
}
});
Swagger2MarkupConfig config = new Swagger2MarkupConfig();
Builder() {
this(new Properties());
}
Builder(Properties properties) {
Properties safeProperties = new Properties(defaultProperties());
safeProperties.putAll(properties);
config.markupLanguage = MarkupLanguage.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "markupLanguage"));
config.generatedExamplesEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "generatedExamplesEnabled"));
config.operationDescriptionsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "operationDescriptionsEnabled"));
if (safeProperties.containsKey(PROPERTIES_PREFIX + "operationDescriptionsUri"))
config.operationDescriptionsUri = URI.create(safeProperties.getProperty(PROPERTIES_PREFIX + "operationDescriptionsUri"));
config.definitionDescriptionsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "definitionDescriptionsEnabled"));
if (safeProperties.containsKey(PROPERTIES_PREFIX + "definitionDescriptionsUri"))
config.definitionDescriptionsUri = URI.create(safeProperties.getProperty(PROPERTIES_PREFIX + "definitionDescriptionsUri"));
config.separatedDefinitionsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "separatedDefinitionsEnabled"));
config.separatedOperationsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "separatedOperationsEnabled"));
config.operationsGroupedBy = GroupBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "operationsGroupedBy"));
config.outputLanguage = Language.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "outputLanguage"));
config.inlineSchemaDepthLevel = Integer.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "inlineSchemaDepthLevel"));
config.interDocumentCrossReferencesEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "interDocumentCrossReferencesEnabled"));
config.interDocumentCrossReferencesPrefix = safeProperties.getProperty(PROPERTIES_PREFIX + "interDocumentCrossReferencesPrefix");
config.flatBodyEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "flatBodyEnabled"));
config.anchorPrefix = safeProperties.getProperty(PROPERTIES_PREFIX + "anchorPrefix");
config.overviewDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "overviewDocument");
config.pathsDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "pathsDocument");
config.definitionsDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "definitionsDocument");
config.securityDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "securityDocument");
config.separatedOperationsFolder = safeProperties.getProperty(PROPERTIES_PREFIX + "separatedOperationsFolder");
config.separatedDefinitionsFolder = safeProperties.getProperty(PROPERTIES_PREFIX + "separatedDefinitionsFolder");
config.tagOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "tagOrderBy"));
config.operationOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "operationOrderBy"));
config.definitionOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "definitionOrderBy"));
config.parameterOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "parameterOrderBy"));
config.propertyOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "propertyOrderBy"));
config.responseOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "responseOrderBy"));
String lineSeparator = safeProperties.getProperty(PROPERTIES_PREFIX + "lineSeparator");
if(StringUtils.isNoneBlank(lineSeparator)){
config.lineSeparator = LineSeparator.valueOf(lineSeparator);
}
}
private Properties defaultProperties() {
Properties defaultProperties = new Properties();
try {
InputStream defaultPropertiesStream = Swagger2MarkupConfig.class.getResourceAsStream(PROPERTIES_DEFAULT);
if (defaultPropertiesStream == null)
throw new RuntimeException(String.format("Can't load default properties '%s'", PROPERTIES_DEFAULT));
defaultProperties.load(defaultPropertiesStream);
} catch (IOException e) {
throw new RuntimeException(String.format("Can't load default properties '%s'", PROPERTIES_DEFAULT), e);
}
return defaultProperties;
}
public Swagger2MarkupConfig build() {
buildNaturalOrdering();
return config;
}
private void buildNaturalOrdering() {
if (config.tagOrderBy == OrderBy.NATURAL)
config.tagOrdering = Ordering.natural();
if (config.operationOrderBy == OrderBy.NATURAL)
config.operationOrdering = OPERATION_PATH_NATURAL_ORDERING.compound(OPERATION_METHOD_NATURAL_ORDERING);
if (config.definitionOrderBy == OrderBy.NATURAL)
config.definitionOrdering = Ordering.natural();
if (config.parameterOrderBy == OrderBy.NATURAL)
config.parameterOrdering = PARAMETER_IN_NATURAL_ORDERING.compound(PARAMETER_NAME_NATURAL_ORDERING);
if (config.propertyOrderBy == OrderBy.NATURAL)
config.propertyOrdering = Ordering.natural();
if (config.responseOrderBy == OrderBy.NATURAL)
config.responseOrdering = Ordering.natural();
}
/**
* Specifies the markup language which should be used to generate the files
*
* @param markupLanguage the markup language which is used to generate the files
* @return this builder
*/
public Builder withMarkupLanguage(MarkupLanguage markupLanguage) {
Validate.notNull(markupLanguage, "%s must not be null", "markupLanguage");
config.markupLanguage = markupLanguage;
return this;
}
/**
* Include generated examples into the Paths document
*
* @return this builder
*/
public Builder withGeneratedExamples() {
config.generatedExamplesEnabled = true;
return this;
}
/**
* Include hand-written descriptions into the Paths document
*
* @param operationDescriptionsUri the URI to the folder where the description documents reside.
* @return this builder
*/
public Builder withOperationDescriptions(URI operationDescriptionsUri) {
Validate.notNull(operationDescriptionsUri, "%s must not be null", "operationDescriptionsUri");
config.operationDescriptionsEnabled = true;
config.operationDescriptionsUri = operationDescriptionsUri;
return this;
}
/**
* Include hand-written descriptions into the Paths document
*
* @param operationDescriptionsPath the path to the folder where the description documents reside.
* @return this builder
*/
public Builder withOperationDescriptions(Path operationDescriptionsPath) {
Validate.notNull(operationDescriptionsPath, "%s must not be null", "operationDescriptionsPath");
return withOperationDescriptions(operationDescriptionsPath.toUri());
}
/**
* Include hand-written descriptions into the Paths document.<br/>
* Use default URI.
*
* @return this builder
*/
public Builder withOperationDescriptions() {
config.operationDescriptionsEnabled = true;
return this;
}
/**
* Include hand-written descriptions into the Definitions document
*
* @param definitionDescriptionsUri the URI to the folder where the description documents reside.
* @return this builder
*/
public Builder withDefinitionDescriptions(URI definitionDescriptionsUri) {
Validate.notNull(definitionDescriptionsUri, "%s must not be null", "definitionDescriptionsUri");
config.definitionDescriptionsEnabled = true;
config.definitionDescriptionsUri = definitionDescriptionsUri;
return this;
}
/**
* Include hand-written descriptions into the Definitions document
*
* @param definitionDescriptionsPath the path to the folder where the description documents reside.
* @return this builder
*/
public Builder withDefinitionDescriptions(Path definitionDescriptionsPath) {
Validate.notNull(definitionDescriptionsPath, "%s must not be null", "definitionDescriptionsPath");
return withDefinitionDescriptions(definitionDescriptionsPath.toUri());
}
/**
* Include hand-written descriptions into the Definitions document.<br/>
* Use default URI.
*
* @return this builder
*/
public Builder withDefinitionDescriptions() {
config.definitionDescriptionsEnabled = true;
return this;
}
/**
* In addition to the definitions file, also create separate definition files for each model definition.
*
* @return this builder
*/
public Builder withSeparatedDefinitions() {
config.separatedDefinitionsEnabled = true;
return this;
}
/**
* In addition to the paths file, also create separate path files for each path.
*
* @return this builder
*/
public Builder withSeparatedOperations() {
config.separatedOperationsEnabled = true;
return this;
}
/**
* Specifies if the paths should be grouped by tags or stay as-is.
*
* @param pathsGroupedBy the GroupBy enum
* @return this builder
*/
public Builder withPathsGroupedBy(GroupBy pathsGroupedBy) {
Validate.notNull(pathsGroupedBy, "%s must not be null", "pathsGroupedBy");
config.operationsGroupedBy = pathsGroupedBy;
return this;
}
/**
* Specifies labels language of output files
*
* @param language the enum
* @return this builder
*/
public Builder withOutputLanguage(Language language) {
Validate.notNull(language, "%s must not be null", "language");
config.outputLanguage = language;
return this;
}
/**
* Specifies maximum depth level for inline object schema displaying (0 = no inline schemasEnabled)
*
* @param inlineSchemaDepthLevel number of recursion levels for inline schemasEnabled display
* @return this builder
*/
public Builder withInlineSchemaDepthLevel(int inlineSchemaDepthLevel) {
Validate.isTrue(inlineSchemaDepthLevel >= 0, "%s must be >= 0", "inlineSchemaDepthLevel");
config.inlineSchemaDepthLevel = inlineSchemaDepthLevel;
return this;
}
/**
* Specifies tag ordering.<br/>
* By default tag ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
* Use {@link #withTagOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy tag ordering
* @return this builder
*/
public Builder withTagOrdering(OrderBy orderBy) {
Validate.notNull(orderBy, "%s must not be null", "orderBy");
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
config.tagOrderBy = orderBy;
return this;
}
/**
* Specifies a custom comparator function to order tags.
*
* @param tagOrdering tag ordering
* @return this builder
*/
public Builder withTagOrdering(Comparator<String> tagOrdering) {
Validate.notNull(tagOrdering, "%s must not be null", "tagOrdering");
config.tagOrderBy = OrderBy.CUSTOM;
config.tagOrdering = tagOrdering;
return this;
}
/**
* Specifies operation ordering.<br/>
* By default operation ordering == {@link io.github.robwin.swagger2markup.OrderBy#AS_IS}.<br/>
* Use {@link #withOperationOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy operation ordering
* @return this builder
*/
public Builder withOperationOrdering(OrderBy orderBy) {
Validate.notNull(orderBy, "%s must not be null", "orderBy");
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
config.operationOrderBy = orderBy;
return this;
}
/**
* Specifies a custom comparator function to order operations.
*
* @param operationOrdering operation ordering
* @return this builder
*/
public Builder withOperationOrdering(Comparator<PathOperation> operationOrdering) {
Validate.notNull(operationOrdering, "%s must not be null", "operationOrdering");
config.operationOrderBy = OrderBy.CUSTOM;
config.operationOrdering = operationOrdering;
return this;
}
/**
* Specifies definition ordering.<br/>
* By default definition ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
* Use {@link #withDefinitionOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy definition ordering
* @return this builder
*/
public Builder withDefinitionOrdering(OrderBy orderBy) {
Validate.notNull(orderBy, "%s must not be null", "orderBy");
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
config.definitionOrderBy = orderBy;
return this;
}
/**
* Specifies a custom comparator function to order definitions.
*
* @param definitionOrdering definition ordering
* @return this builder
*/
public Builder withDefinitionOrdering(Comparator<String> definitionOrdering) {
Validate.notNull(definitionOrdering, "%s must not be null", "definitionOrdering");
config.definitionOrderBy = OrderBy.CUSTOM;
config.definitionOrdering = definitionOrdering;
return this;
}
/**
* Specifies parameter ordering.<br/>
* By default parameter ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
* Use {@link #withParameterOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy parameter ordering
* @return this builder
*/
public Builder withParameterOrdering(OrderBy orderBy) {
Validate.notNull(orderBy, "%s must not be null", "orderBy");
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
config.parameterOrderBy = orderBy;
return this;
}
/**
* Specifies a custom comparator function to order parameters.
*
* @param parameterOrdering parameter ordering
* @return this builder
*/
public Builder withParameterOrdering(Comparator<Parameter> parameterOrdering) {
Validate.notNull(parameterOrdering, "%s must not be null", "parameterOrdering");
config.parameterOrderBy = OrderBy.CUSTOM;
config.parameterOrdering = parameterOrdering;
return this;
}
/**
* Specifies property ordering.<br/>
* By default property ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
* Use {@link #withPropertyOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy property ordering
* @return this builder
*/
public Builder withPropertyOrdering(OrderBy orderBy) {
Validate.notNull(orderBy, "%s must not be null", "orderBy");
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
config.propertyOrderBy = orderBy;
return this;
}
/**
* Specifies a custom comparator function to order propertys.
*
* @param propertyOrdering property ordering
* @return this builder
*/
public Builder withPropertyOrdering(Comparator<String> propertyOrdering) {
Validate.notNull(propertyOrdering, "%s must not be null", "propertyOrdering");
config.propertyOrderBy = OrderBy.CUSTOM;
config.propertyOrdering = propertyOrdering;
return this;
}
/**
* Specifies response ordering.<br/>
* By default response ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
* Use {@link #withResponseOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy response ordering
* @return this builder
*/
public Builder withResponseOrdering(OrderBy orderBy) {
Validate.notNull(orderBy, "%s must not be null", "orderBy");
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
config.responseOrderBy = orderBy;
return this;
}
/**
* Specifies a custom comparator function to order responses.
*
* @param responseOrdering response ordering
* @return this builder
*/
public Builder withResponseOrdering(Comparator<String> responseOrdering) {
Validate.notNull(responseOrdering, "%s must not be null", "responseOrdering");
config.responseOrderBy = OrderBy.CUSTOM;
config.responseOrdering = responseOrdering;
return this;
}
/**
* Enable use of inter-document cross-references when needed
*
* @param prefix Prefix to document in all inter-document cross-references.
* @return this builder
*/
public Builder withInterDocumentCrossReferences(String prefix) {
Validate.notNull(prefix, "%s must not be null", "prefix");
config.interDocumentCrossReferencesEnabled = true;
config.interDocumentCrossReferencesPrefix = prefix;
return this;
}
/**
* Enable use of inter-document cross-references when needed.
*
* @return this builder
*/
public Builder withInterDocumentCrossReferences() {
config.interDocumentCrossReferencesEnabled = true;
return this;
}
/**
* Optionally isolate the body parameter, if any, from other parameters
*
* @return this builder
*/
public Builder withFlatBody() {
config.flatBodyEnabled = true;
return this;
}
/**
* Optionally prefix all anchors for unicity
*.
* @param anchorPrefix anchor prefix.
* @return this builder
*/
public Builder withAnchorPrefix(String anchorPrefix) {
Validate.notNull(anchorPrefix, "%s must no be null", "anchorPrefix");
config.anchorPrefix = anchorPrefix;
return this;
}
/**
* Specifies the line separator which should be used .
*
* @param lineSeparator the lineSeparator
* @return this builder
*/
public Builder withLineSeparator(LineSeparator lineSeparator) {
Validate.notNull(lineSeparator, "%s must no be null", "lineSeparator");
config.lineSeparator = lineSeparator;
return this;
}
}
}

View File

@@ -1,292 +0,0 @@
/*
* Copyright 2016 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;
import com.google.common.annotations.VisibleForTesting;
import io.github.robwin.swagger2markup.internal.document.builder.DefinitionsDocumentBuilder;
import io.github.robwin.swagger2markup.internal.document.builder.OverviewDocumentBuilder;
import io.github.robwin.swagger2markup.internal.document.builder.PathsDocumentBuilder;
import io.github.robwin.swagger2markup.internal.document.builder.SecurityDocumentBuilder;
import io.github.robwin.swagger2markup.spi.Extension;
import io.github.robwin.swagger2markup.spi.SwaggerModelExtension;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
/**
* @author Robert Winkler
*/
public class Swagger2MarkupConverter {
private Context context;
public Swagger2MarkupConverter(Context globalContext) {
this.context = globalContext;
}
/**
* Returns the global Context
*
* @return the global Context
*/
@VisibleForTesting
Context getContext(){
return context;
}
/**
* Creates a Swagger2MarkupConverter.Builder using a remote URL.
*
* @param swaggerURL the remote URL
* @return a Swagger2MarkupConverter
*/
public static Builder from(URL swaggerURL){
Validate.notNull(swaggerURL, "swaggerURL must not be null");
return new Builder(swaggerURL);
}
/**
* Creates a Swagger2MarkupConverter.Builder using a local Path.
*
* @param swaggerPath the local Path
* @return a Swagger2MarkupConverter
*/
public static Builder from(Path swaggerPath) {
Validate.notNull(swaggerPath, "swaggerPath must not be null");
return new Builder(swaggerPath);
}
/**
* Creates a Swagger2MarkupConverter.Builder from a given Swagger model.
*
* @param swagger the Swagger source.
* @return a Swagger2MarkupConverter
*/
public static Builder from(Swagger swagger) {
Validate.notNull(swagger, "swagger must not be null");
return new Builder(swagger);
}
/**
* Creates a Swagger2MarkupConverter.Builder from a given Swagger YAML or JSON String.
*
* @param swaggerString the Swagger YAML or JSON String.
* @return a Swagger2MarkupConverter
* @throws java.io.IOException if String can not be parsed
*/
public static Builder from(String swaggerString) throws IOException {
Validate.notEmpty(swaggerString, "swaggerString must not be null");
return from(new StringReader(swaggerString));
}
/**
* Creates a Swagger2MarkupConverter.Builder from a given Swagger YAML or JSON reader.
*
* @param swaggerReader the Swagger YAML or JSON reader.
* @return a Swagger2MarkupConverter
* @throws java.io.IOException if source can not be parsed
*/
public static Builder from(Reader swaggerReader) throws IOException {
Validate.notNull(swaggerReader, "swaggerReader must not be null");
Swagger swagger = new SwaggerParser().parse(IOUtils.toString(swaggerReader));
if (swagger == null)
throw new IllegalArgumentException("Swagger source is in a wrong format");
return new Builder(swagger);
}
/**
* Builds the document with the given markup language and stores
* the files in the given folder.
*
* @param outputPath the output directory path
* @throws IOException if the files cannot be written
*/
public void intoFolder(Path outputPath) throws IOException {
Validate.notNull(outputPath, "outputPath must not be null");
applySwaggerExtensions();
buildDocuments(outputPath);
}
/**
* Builds the document with the given markup language and returns it as a String
*
* @return a the document as a String
* @throws java.io.IOException if files can not be read
*/
public String asString() throws IOException {
applySwaggerExtensions();
return buildDocuments();
}
private void applySwaggerExtensions() {
for (SwaggerModelExtension swaggerModelExtension : context.extensionRegistry.getExtensions(SwaggerModelExtension.class)) {
swaggerModelExtension.apply(context.getSwagger());
}
}
/**
* Builds all documents and writes them to a directory
*
* @param outputPath the directory path where the generated file should be stored
* @throws IOException if a file cannot be written
*/
private void buildDocuments(Path outputPath) throws IOException {
new OverviewDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getOverviewDocument()), StandardCharsets.UTF_8);
new PathsDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getPathsDocument()), StandardCharsets.UTF_8);
new DefinitionsDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getDefinitionsDocument()), StandardCharsets.UTF_8);
new SecurityDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getSecurityDocument()), StandardCharsets.UTF_8);
}
/**
* Returns all documents as a String
*
* @return a the document as a String
*/
private String buildDocuments() {
StringBuilder sb = new StringBuilder();
sb.append(new OverviewDocumentBuilder(context, null).build().toString());
sb.append(new PathsDocumentBuilder(context, null).build().toString());
sb.append(new DefinitionsDocumentBuilder(context, null).build().toString());
sb.append(new SecurityDocumentBuilder(context, null).build().toString());
return sb.toString();
}
public static class Builder {
private final Swagger swagger;
private final URI swaggerLocation;
private Swagger2MarkupConfig config;
private Swagger2MarkupExtensionRegistry extensionRegistry;
/**
* Creates a Builder from a remote URL.
*
* @param swaggerUrl the remote URL
*/
Builder(URL swaggerUrl) {
try {
this.swaggerLocation = swaggerUrl.toURI();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("swaggerURL is in a wrong format", e);
}
this.swagger = readSwagger(swaggerUrl.toString());
}
/**
* Creates a Builder from a local Path.
*
* @param swaggerPath the local Path
*/
Builder(Path swaggerPath) {
this.swaggerLocation = swaggerPath.toAbsolutePath().toUri();
this.swagger = readSwagger(swaggerPath.toString());
}
/**
* Creates a Builder using a given Swagger model.
*
* @param swagger the Swagger source.
*/
Builder(Swagger swagger) {
this.swagger = swagger;
this.swaggerLocation = null;
}
/**
* Uses the SwaggerParser to read the Swagger source.
*
* @param swaggerLocation the location of the Swagger source
* @return the Swagger model
*/
private Swagger readSwagger(String swaggerLocation){
Swagger swagger = new SwaggerParser().read(swaggerLocation);
if (swagger == null) {
throw new IllegalArgumentException("Failed to read the Swagger source");
}
return swagger;
}
public Builder withConfig(Swagger2MarkupConfig config) {
Validate.notNull(config, "config must not be null");
this.config = config;
return this;
}
public Builder withExtensionRegistry(Swagger2MarkupExtensionRegistry registry) {
Validate.notNull(config, "registry must not be null");
this.extensionRegistry = registry;
return this;
}
public Swagger2MarkupConverter build() {
if (config == null)
config = Swagger2MarkupConfig.ofDefaults().build();
if (extensionRegistry == null)
extensionRegistry = Swagger2MarkupExtensionRegistry.ofDefaults().build();
Context context = new Context(config, extensionRegistry, swagger, swaggerLocation);
config.setGlobalContext(context);
for (Extension extension : extensionRegistry.getExtensions())
extension.setGlobalContext(context);
return new Swagger2MarkupConverter(context);
}
}
public static class Context {
private Swagger2MarkupConfig config;
private Swagger2MarkupExtensionRegistry extensionRegistry;
private Swagger swagger;
private URI swaggerLocation;
Context(Swagger2MarkupConfig config, Swagger2MarkupExtensionRegistry extensionRegistry, Swagger swagger, URI swaggerLocation) {
this.config = config;
this.extensionRegistry = extensionRegistry;
this.swagger = swagger;
this.swaggerLocation = swaggerLocation;
}
public Swagger2MarkupConfig getConfig() {
return config;
}
public Swagger2MarkupExtensionRegistry getExtensionRegistry() {
return extensionRegistry;
}
public Swagger getSwagger() {
return swagger;
}
public URI getSwaggerLocation() {
return swaggerLocation;
}
}
}

View File

@@ -1,112 +0,0 @@
/*
* Copyright 2016 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;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
import io.github.robwin.swagger2markup.internal.extensions.DynamicOverviewDocumentExtension;
import io.github.robwin.swagger2markup.internal.extensions.DynamicSecurityDocumentExtension;
import io.github.robwin.swagger2markup.spi.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Swagger2MarkupExtensionRegistry {
protected static final List<Class<? extends Extension>> EXTENSION_POINTS = Arrays.<Class<? extends Extension>>asList(
SwaggerModelExtension.class,
OverviewDocumentExtension.class,
SecurityDocumentExtension.class,
DefinitionsDocumentExtension.class,
PathsDocumentExtension.class
);
protected final Multimap<Class<? extends Extension>, Extension> extensions;
public Swagger2MarkupExtensionRegistry(Multimap<Class<? extends Extension>, Extension> extensions) {
this.extensions = extensions;
}
public static Builder ofEmpty() {
return new Builder(false);
}
public static Builder ofDefaults() {
return new Builder(true);
}
public static class Builder {
private final Multimap<Class<? extends Extension>, Extension> extensions;
Builder(boolean useDefaults) {
extensions = MultimapBuilder.hashKeys().arrayListValues().build();
if (useDefaults) {
withExtension(new DynamicOverviewDocumentExtension());
withExtension(new DynamicSecurityDocumentExtension());
withExtension(new DynamicPathsDocumentExtension());
withExtension(new DynamicDefinitionsDocumentExtension());
}
}
public Swagger2MarkupExtensionRegistry build() {
return new Swagger2MarkupExtensionRegistry(extensions);
}
public Builder withExtension(Extension extension) {
registerExtension(extension);
return this;
}
public void registerExtension(Extension extension) {
for (Class<? extends Extension> extensionPoint : EXTENSION_POINTS) {
if (extensionPoint.isInstance(extension)) {
extensions.put(extensionPoint, extension);
return;
}
}
throw new IllegalArgumentException("Provided extension class does not extend any of the supported extension points");
}
}
@SuppressWarnings(value = "unchecked")
public <T extends Extension> List<T> getExtensions(Class<T> extensionClass) {
List<T> ret = new ArrayList<>();
for (Map.Entry<Class<? extends Extension>, Extension> entry : extensions.entries()) {
if (extensionClass.isAssignableFrom(entry.getKey())) {
if (extensionClass.isInstance(entry.getValue()))
ret.add((T) entry.getValue());
}
}
return ret;
}
/**
* Get all extensions
* @return all extensions
*/
public List<Extension> getExtensions() {
return getExtensions(Extension.class);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2016 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.internal.document;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
public class MarkupDocument {
private MarkupDocBuilder markupDocBuilder;
public MarkupDocument(MarkupDocBuilder markupDocBuilder) {
this.markupDocBuilder = markupDocBuilder;
}
/**
* Returns a string representation of the document.
*/
public String toString() {
return markupDocBuilder.toString();
}
/**
* Writes the content of the builder to a file.
*
* @param file the generated file
* @param charset the the charset to use for encoding
* @throws IOException if the file cannot be written
*/
public void writeToFile(Path file, Charset charset) throws IOException {
markupDocBuilder.writeToFile(file, charset);
}
}

View File

@@ -1,398 +0,0 @@
/*
* Copyright 2016 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.internal.document.builder;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
import io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension;
import io.github.robwin.swagger2markup.internal.type.ObjectType;
import io.github.robwin.swagger2markup.internal.type.Type;
import io.swagger.models.ComposedModel;
import io.swagger.models.Model;
import io.swagger.models.RefModel;
import io.swagger.models.properties.Property;
import io.swagger.models.refs.RefFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import static io.github.robwin.swagger2markup.internal.utils.IOUtils.normalizeName;
import static io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension.*;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static io.github.robwin.swagger2markup.internal.utils.MapUtils.toKeySet;
/**
* @author Robert Winkler
*/
public class DefinitionsDocumentBuilder extends MarkupDocumentBuilder {
private static final String DEFINITIONS_ANCHOR = "definitions";
private final String DEFINITIONS;
private static final List<String> IGNORED_DEFINITIONS = Collections.singletonList("Void");
private static final String DESCRIPTION_FILE_NAME = "description";
public DefinitionsDocumentBuilder(Swagger2MarkupConverter.Context context, Path outputPath) {
super(context, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
DEFINITIONS = labels.getString("definitions");
if (config.isDefinitionDescriptionsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Include hand-written definition descriptions is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Include hand-written definition descriptions is disabled.");
}
}
if (config.isSeparatedDefinitionsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Create separated definition files is enabled.");
}
Validate.notNull(outputPath, "Output directory is required for separated definition files!");
} else {
if (logger.isDebugEnabled()) {
logger.debug("Create separated definition files is disabled.");
}
}
}
/**
* Builds the definitions MarkupDocument.
*
* @return the definitions MarkupDocument
*/
@Override
public MarkupDocument build() {
Map<String, Model> definitions = globalContext.getSwagger().getDefinitions();
if (MapUtils.isNotEmpty(definitions)) {
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildDefinitionsTitle(DEFINITIONS);
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildDefinitionsSection(definitions);
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
}
return new MarkupDocument(markupDocBuilder);
}
private void buildDefinitionsSection(Map<String, Model> definitions) {
Set<String> definitionNames = toKeySet(definitions, config.getDefinitionOrdering());
for (String definitionName : definitionNames) {
Model model = definitions.get(definitionName);
if (isNotBlank(definitionName)) {
if (checkThatDefinitionIsNotInIgnoreList(definitionName)) {
buildDefinition(definitions, definitionName, model);
if (logger.isInfoEnabled()) {
logger.info("Definition processed: {}", definitionName);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Definition was ignored: {}", definitionName);
}
}
}
}
}
private void buildDefinitionsTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, DEFINITIONS_ANCHOR);
}
/**
* Apply extension context to all DefinitionsContentExtension
*
* @param context context
*/
private void applyDefinitionsDocumentExtension(Context context) {
for (DefinitionsDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(DefinitionsDocumentExtension.class)) {
extension.apply(context);
}
}
/**
* Create the definition filename depending on the generation mode
*
* @param definitionName definition name
* @return definition filename
*/
private String resolveDefinitionDocument(String definitionName) {
if (config.isSeparatedDefinitionsEnabled())
return new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(normalizeName(definitionName))).getPath();
else
return markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
}
/**
* Generate definition files depending on the generation mode
*
* @param definitions all available definitions to be able to verify references
* @param definitionName definition name to process
* @param model definition model to process
*/
private void buildDefinition(Map<String, Model> definitions, String definitionName, Model model) {
if (config.isSeparatedDefinitionsEnabled()) {
MarkupDocBuilder defDocBuilder = this.markupDocBuilder.copy();
buildDefinition(definitions, definitionName, model, defDocBuilder);
Path definitionFile = outputPath.resolve(resolveDefinitionDocument(definitionName));
try {
defDocBuilder.writeToFileWithoutExtension(definitionFile, StandardCharsets.UTF_8);
} catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn(String.format("Failed to write definition file: %s", definitionFile), e);
}
}
if (logger.isInfoEnabled()) {
logger.info("Separate definition file produced: {}", definitionFile);
}
definitionRef(definitionName, this.markupDocBuilder);
} else {
buildDefinition(definitions, definitionName, model, this.markupDocBuilder);
}
}
/**
* Checks that the definition is not in the list of ignored definitions.
*
* @param definitionName the name of the definition
* @return true if the definition can be processed
*/
private boolean checkThatDefinitionIsNotInIgnoreList(String definitionName) {
return !IGNORED_DEFINITIONS.contains(definitionName);
}
/**
* Builds a concrete definition
*
* @param definitionName the name of the definition
* @param model the Swagger Model of the definition
* @param docBuilder the docbuilder do use for output
*/
private void buildDefinition(Map<String, Model> definitions, String definitionName, Model model, MarkupDocBuilder docBuilder) {
buildDefinitionTitle(definitionName, null, docBuilder);
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_BEGIN, docBuilder, definitionName, model));
buildDescriptionParagraph(definitionName, model, docBuilder);
inlineDefinitions(propertiesSection(definitions, definitionName, model, docBuilder), definitionName, config.getInlineSchemaDepthLevel(), docBuilder);
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_END, docBuilder, definitionName, model));
}
/**
* Builds a cross-reference to a separated definition file.
*
* @param definitionName definition name to target
* @param docBuilder the docbuilder do use for output
*/
private void definitionRef(String definitionName, MarkupDocBuilder docBuilder) {
buildDefinitionTitle(docBuilder.copy().crossReference(new DefinitionDocumentResolverDefault().apply(definitionName), definitionName, definitionName).toString(), "ref-" + definitionName, docBuilder);
}
/**
* Builds definition title
*
* @param title definition title
* @param anchor optional anchor (null => auto-generate from title)
* @param docBuilder the docbuilder do use for output
*/
private void buildDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.sectionTitleWithAnchorLevel2(title, anchor);
}
/**
* Override Property description functor for definitions.
* This implementation handles optional handwritten descriptions.
*/
private class DefinitionPropertyDescriptor extends PropertyDescriptor {
public DefinitionPropertyDescriptor(Type type) {
super(type);
}
@Override
public String getDescription(Property property, String propertyName) {
if (config.isDefinitionDescriptionsEnabled()) {
Optional<String> description = handWrittenDefinitionDescription(new File(normalizeName(type.getName()), normalizeName(propertyName)).toString(), DESCRIPTION_FILE_NAME);
if (description.isPresent()) {
return description.get();
} else {
return defaultString(property.getDescription());
}
} else {
return defaultString(property.getDescription());
}
}
}
/**
* Builds the properties of a definition and inline schemas.
*
* @param definitions all available definitions
* @param definitionName name of the definition to display
* @param model model of the definition to display
* @param docBuilder the docbuilder do use for output
* @return a list of inlined types.
*/
private List<ObjectType> propertiesSection(Map<String, Model> definitions, String definitionName, Model model, MarkupDocBuilder docBuilder) {
Map<String, Property> properties = getAllProperties(definitions, model);
ObjectType type = new ObjectType(definitionName, properties);
return buildPropertiesTable(type, definitionName, 1, new PropertyDescriptor(type), new DefinitionDocumentResolverFromDefinition(), docBuilder);
}
private Map<String, Property> getAllProperties(Map<String, Model> definitions, Model model) {
if (model instanceof RefModel) {
RefModel refModel = (RefModel) model;
String ref;
if (refModel.getRefFormat().equals(RefFormat.INTERNAL)) {
ref = refModel.getSimpleRef();
} else {
ref = model.getReference();
}
return definitions.containsKey(ref)
? getAllProperties(definitions, definitions.get(ref))
: null;
} else if (model instanceof ComposedModel) {
ComposedModel composedModel = (ComposedModel) model;
Map<String, Property> allProperties = new HashMap<>();
if (composedModel.getAllOf() != null) {
for (Model innerModel : composedModel.getAllOf()) {
Map<String, Property> innerProperties = getAllProperties(definitions, innerModel);
if (innerProperties != null) {
allProperties.putAll(innerProperties);
}
}
}
return ImmutableMap.copyOf(allProperties);
} else {
return model.getProperties();
}
}
private void buildDescriptionParagraph(String definitionName, Model model, MarkupDocBuilder docBuilder) {
if (config.isDefinitionDescriptionsEnabled()) {
Optional<String> description = handWrittenDefinitionDescription(normalizeName(definitionName), DESCRIPTION_FILE_NAME);
if (description.isPresent()) {
docBuilder.paragraph(description.get());
} else {
modelDescription(model, docBuilder);
}
} else {
modelDescription(model, docBuilder);
}
}
private void modelDescription(Model model, MarkupDocBuilder docBuilder) {
String description = model.getDescription();
if (isNotBlank(description)) {
docBuilder.paragraph(description);
}
}
/**
* Reads a hand-written description
*
* @param descriptionFolder the name of the folder where the description file resides
* @param descriptionFileName the name of the description file
* @return the content of the file
*/
private Optional<String> handWrittenDefinitionDescription(String descriptionFolder, String descriptionFileName) {
for (String fileNameExtension : config.getMarkupLanguage().getFileNameExtensions()) {
URI contentUri = config.getDefinitionDescriptionsUri().resolve(descriptionFolder).resolve(descriptionFileName + fileNameExtension);
try (Reader reader = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriReader(contentUri)) {
if (logger.isInfoEnabled()) {
logger.info("Definition description content processed {}", contentUri);
}
return Optional.of(IOUtils.toString(reader).trim());
} catch (IOException e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to read Operation description content {} > {}", contentUri, e.getMessage());
}
}
}
return Optional.absent();
}
/**
* Builds the title of an inline schema.
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
*
* @param title inline schema title
* @param anchor inline schema anchor
* @param docBuilder the docbuilder do use for output
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor, null);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
/**
* Builds inline schema definitions
*
* @param definitions all inline definitions to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
* @param depth current inline schema depth
* @param docBuilder the docbuilder do use for output
*/
private void inlineDefinitions(List<ObjectType> definitions, String uniquePrefix, int depth, MarkupDocBuilder docBuilder) {
if (CollectionUtils.isNotEmpty(definitions)) {
for (ObjectType definition : definitions) {
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
List<ObjectType> localDefinitions = buildPropertiesTable(definition, uniquePrefix, depth, new DefinitionPropertyDescriptor(definition), new DefinitionDocumentResolverFromDefinition(), docBuilder);
for (ObjectType localDefinition : localDefinitions)
inlineDefinitions(Collections.singletonList(localDefinition), uniquePrefix, depth - 1, docBuilder);
}
}
}
/**
* Overrides definition document resolver functor for inter-document cross-references from definitions files.
* This implementation simplify the path between two definitions because all definitions are in the same path.
*/
class DefinitionDocumentResolverFromDefinition extends DefinitionDocumentResolverDefault {
public DefinitionDocumentResolverFromDefinition() {
}
public String apply(String definitionName) {
String defaultResolver = super.apply(definitionName);
if (defaultResolver != null && config.isSeparatedDefinitionsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(normalizeName(definitionName));
else
return defaultResolver;
}
}
}

View File

@@ -1,188 +0,0 @@
/*
* Copyright 2016 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.internal.document.builder;
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.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
import io.github.robwin.swagger2markup.internal.type.DefinitionDocumentResolver;
import io.github.robwin.swagger2markup.internal.type.ObjectType;
import io.github.robwin.swagger2markup.internal.type.RefType;
import io.github.robwin.swagger2markup.internal.type.Type;
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
import io.github.robwin.swagger2markup.internal.utils.PropertyUtils;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import static io.github.robwin.swagger2markup.internal.utils.MapUtils.toKeySet;
import static org.apache.commons.lang3.StringUtils.defaultString;
/**
* @author Robert Winkler
*/
public abstract class MarkupDocumentBuilder {
protected final String DEFAULT_COLUMN;
protected final String EXAMPLE_COLUMN;
protected final String REQUIRED_COLUMN;
protected final String SCHEMA_COLUMN;
protected final String NAME_COLUMN;
protected final String DESCRIPTION_COLUMN;
protected final String SCOPES_COLUMN;
protected final String DESCRIPTION;
protected final String PRODUCES;
protected final String CONSUMES;
protected final String TAGS;
protected final String NO_CONTENT;
protected Logger logger = LoggerFactory.getLogger(getClass());
protected Swagger2MarkupConverter.Context globalContext;
protected Swagger2MarkupConfig config;
protected MarkupDocBuilder markupDocBuilder;
protected Path outputPath;
MarkupDocumentBuilder(Swagger2MarkupConverter.Context globalContext, Path outputPath) {
this.globalContext = globalContext;
this.config = globalContext.getConfig();
this.outputPath = outputPath;
this.markupDocBuilder = MarkupDocBuilders.documentBuilder(config.getMarkupLanguage(), config.getLineSeparator()).withAnchorPrefix(config.getAnchorPrefix());
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
DEFAULT_COLUMN = labels.getString("default_column");
EXAMPLE_COLUMN = labels.getString("example_column");
REQUIRED_COLUMN = labels.getString("required_column");
SCHEMA_COLUMN = labels.getString("schema_column");
NAME_COLUMN = labels.getString("name_column");
DESCRIPTION_COLUMN = labels.getString("description_column");
SCOPES_COLUMN = labels.getString("scopes_column");
DESCRIPTION = DESCRIPTION_COLUMN;
PRODUCES = labels.getString("produces");
CONSUMES = labels.getString("consumes");
TAGS = labels.getString("tags");
NO_CONTENT = labels.getString("no_content");
}
/**
* Builds the MarkupDocument.
*
* @return the built MarkupDocument
* @throws IOException if the files to include are not readable
*/
public abstract MarkupDocument build() throws IOException;
/**
* Build a generic property table for any ObjectType
*
* @param type to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
* @param depth current inline schema object depth
* @param propertyDescriptor property descriptor to apply to properties
* @param definitionDocumentResolver definition document resolver to apply to property type cross-reference
* @param docBuilder the docbuilder do use for output
* @return a list of inline schemas referenced by some properties, for later display
*/
protected List<ObjectType> buildPropertiesTable(ObjectType type, String uniquePrefix, int depth, PropertyDescriptor propertyDescriptor, DefinitionDocumentResolver definitionDocumentResolver, MarkupDocBuilder docBuilder) {
List<ObjectType> localDefinitions = new ArrayList<>();
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
new MarkupTableColumn(DESCRIPTION_COLUMN, 6).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^6"),
new MarkupTableColumn(REQUIRED_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(DEFAULT_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(EXAMPLE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
if (MapUtils.isNotEmpty(type.getProperties())) {
Set<String> propertyNames = toKeySet(type.getProperties(), config.getPropertyOrdering());
for (String propertyName : propertyNames) {
Property property = type.getProperties().get(propertyName);
Type propertyType = PropertyUtils.getType(property, definitionDocumentResolver);
if (depth > 0 && propertyType instanceof ObjectType) {
if (MapUtils.isNotEmpty(((ObjectType) propertyType).getProperties())) {
propertyType.setName(propertyName);
propertyType.setUniqueName(uniquePrefix + " " + propertyName);
localDefinitions.add((ObjectType) propertyType);
propertyType = new RefType(propertyType);
}
}
Object example = PropertyUtils.getExample(config.isGeneratedExamplesEnabled(), property, markupDocBuilder);
List<String> content = Arrays.asList(
propertyName,
propertyDescriptor.getDescription(property, propertyName),
Boolean.toString(property.getRequired()),
propertyType.displaySchema(docBuilder),
PropertyUtils.getDefaultValue(property),
example != null ? Json.pretty(example) : ""
);
cells.add(content);
}
docBuilder.tableWithColumnSpecs(cols, cells);
} else {
docBuilder.textLine(NO_CONTENT);
}
return localDefinitions;
}
/**
* A functor to return descriptions for a given property
*/
class PropertyDescriptor {
protected Type type;
public PropertyDescriptor(Type type) {
this.type = type;
}
public String getDescription(Property property, String propertyName) {
return defaultString(property.getDescription());
}
}
/**
* Default {@code DefinitionDocumentResolver} functor
*/
class DefinitionDocumentResolverDefault implements DefinitionDocumentResolver {
public DefinitionDocumentResolverDefault() {
}
public String apply(String definitionName) {
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
return null;
else if (config.isSeparatedDefinitionsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(IOUtils.normalizeName(definitionName))).getPath();
else
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
}
}
}

View File

@@ -1,204 +0,0 @@
/*
* Copyright 2016 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.internal.document.builder;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
import io.github.robwin.swagger2markup.spi.OverviewDocumentExtension;
import io.swagger.models.*;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import static io.github.robwin.swagger2markup.spi.OverviewDocumentExtension.*;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.StringUtils.*;
public class OverviewDocumentBuilder extends MarkupDocumentBuilder {
private static final String OVERVIEW_ANCHOR = "overview";
private final String OVERVIEW;
private final String CURRENT_VERSION;
private final String VERSION;
private final String CONTACT_INFORMATION;
private final String CONTACT_NAME;
private final String CONTACT_EMAIL;
private final String LICENSE_INFORMATION;
private final String LICENSE;
private final String LICENSE_URL;
private final String TERMS_OF_SERVICE;
private final String URI_SCHEME;
private final String HOST;
private final String BASE_PATH;
private final String SCHEMES;
public OverviewDocumentBuilder(Swagger2MarkupConverter.Context context, Path outputPath){
super(context, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
OVERVIEW = labels.getString("overview");
CURRENT_VERSION = labels.getString("current_version");
VERSION = labels.getString("version");
CONTACT_INFORMATION = labels.getString("contact_information");
CONTACT_NAME = labels.getString("contact_name");
CONTACT_EMAIL = labels.getString("contact_email");
LICENSE_INFORMATION = labels.getString("license_information");
LICENSE = labels.getString("license");
LICENSE_URL = labels.getString("license_url");
TERMS_OF_SERVICE = labels.getString("terms_of_service");
URI_SCHEME = labels.getString("uri_scheme");
HOST = labels.getString("host");
BASE_PATH = labels.getString("base_path");
SCHEMES = labels.getString("schemes");
}
/**
* Builds the overview MarkupDocument.
*
* @return the overview MarkupDocument
*/
@Override
public MarkupDocument build(){
Swagger swagger = globalContext.getSwagger();
Info info = swagger.getInfo();
buildDocumentTitle(info.getTitle());
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildOverviewTitle(OVERVIEW);
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildDescription(info.getDescription());
buildVersionInfoSection(info.getVersion());
buildContactInfoSection(info.getContact());
buildLicenseInfoSection(info.getLicense(), info.getTermsOfService());
buildUriSchemeSection(swagger);
buildTagsSection(swagger.getTags());
buildConsumesSection(swagger.getConsumes());
buildProducesSection(swagger.getProduces());
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
return new MarkupDocument(markupDocBuilder);
}
private void buildDocumentTitle(String title) {
this.markupDocBuilder.documentTitle(title);
}
private void buildOverviewTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, OVERVIEW_ANCHOR);
}
private void buildVersionInfoSection(String version) {
if(isNotBlank(version)){
this.markupDocBuilder.sectionTitleLevel2(CURRENT_VERSION);
this.markupDocBuilder.textLine(VERSION + " : " + version);
}
}
private void buildDescription(String description) {
if(isNotBlank(description)){
this.markupDocBuilder.textLine(description);
}
}
private void buildContactInfoSection(Contact contact) {
if(contact != null){
this.markupDocBuilder.sectionTitleLevel2(CONTACT_INFORMATION);
if(isNotBlank(contact.getName())){
this.markupDocBuilder.textLine(CONTACT_NAME + " : " + contact.getName());
}
if(isNotBlank(contact.getEmail())){
this.markupDocBuilder.textLine(CONTACT_EMAIL + " : " + contact.getEmail());
}
}
}
private void buildLicenseInfoSection(License license, String termOfService) {
if(license != null && (isNotBlank(license.getName()) || isNotBlank(license.getUrl()))) {
this.markupDocBuilder.sectionTitleLevel2(LICENSE_INFORMATION);
if (isNotBlank(license.getName())) {
this.markupDocBuilder.textLine(LICENSE + " : " + license.getName());
}
if (isNotBlank(license.getUrl())) {
this.markupDocBuilder.textLine(LICENSE_URL + " : " + license.getUrl());
}
}
if(isNotBlank(termOfService)){
this.markupDocBuilder.textLine(TERMS_OF_SERVICE + " : " + termOfService);
}
}
private void buildUriSchemeSection(Swagger swagger) {
if(isNotBlank(swagger.getHost()) || isNotBlank(swagger.getBasePath()) || isNotEmpty(swagger.getSchemes())) {
this.markupDocBuilder.sectionTitleLevel2(URI_SCHEME);
if (isNotBlank(swagger.getHost())) {
this.markupDocBuilder.textLine(HOST + " : " + swagger.getHost());
}
if (isNotBlank(swagger.getBasePath())) {
this.markupDocBuilder.textLine(BASE_PATH + " : " + swagger.getBasePath());
}
if (isNotEmpty(swagger.getSchemes())) {
List<String> schemes = new ArrayList<>();
for (Scheme scheme : swagger.getSchemes()) {
schemes.add(scheme.toString());
}
this.markupDocBuilder.textLine(SCHEMES + " : " + join(schemes, ", "));
}
}
}
private void buildTagsSection(List<Tag> tags) {
if(isNotEmpty(tags)){
this.markupDocBuilder.sectionTitleLevel2(TAGS);
List<String> tagsList = new ArrayList<>();
for(Tag tag : tags){
String name = tag.getName();
String description = tag.getDescription();
if(isNoneBlank(description)){
tagsList.add(name + " : " + description);
}else{
tagsList.add(name);
}
}
this.markupDocBuilder.unorderedList(tagsList);
}
}
private void buildConsumesSection(List<String> consumes) {
if (isNotEmpty(consumes)) {
this.markupDocBuilder.sectionTitleLevel2(CONSUMES);
this.markupDocBuilder.unorderedList(consumes);
}
}
private void buildProducesSection(List<String> consumes) {
if (isNotEmpty(consumes)) {
this.markupDocBuilder.sectionTitleLevel2(PRODUCES);
this.markupDocBuilder.unorderedList(consumes);
}
}
/**
* Apply extension context to all OverviewContentExtension
*
* @param context context
*/
private void applyOverviewDocumentExtension(Context context) {
for (OverviewDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(OverviewDocumentExtension.class)) {
extension.apply(context);
}
}
}

View File

@@ -1,812 +0,0 @@
/*
* Copyright 2016 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.internal.document.builder;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.Multimap;
import io.github.robwin.markup.builder.*;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
import io.github.robwin.swagger2markup.internal.model.PathOperation;
import io.github.robwin.swagger2markup.internal.type.ObjectType;
import io.github.robwin.swagger2markup.internal.type.RefType;
import io.github.robwin.swagger2markup.internal.type.Type;
import io.github.robwin.swagger2markup.internal.utils.*;
import io.github.robwin.swagger2markup.spi.PathsDocumentExtension;
import io.swagger.models.*;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static io.github.robwin.swagger2markup.internal.utils.IOUtils.normalizeName;
import static io.github.robwin.swagger2markup.internal.utils.ListUtils.*;
import static io.github.robwin.swagger2markup.internal.utils.MapUtils.toKeySet;
import static io.github.robwin.swagger2markup.internal.utils.TagUtils.convertTagsListToMap;
import static io.github.robwin.swagger2markup.internal.utils.TagUtils.getTagDescription;
import static io.github.robwin.swagger2markup.spi.PathsDocumentExtension.*;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public class PathsDocumentBuilder extends MarkupDocumentBuilder {
private final String RESPONSE;
private final String REQUEST;
private final String PATHS;
private final String RESOURCES;
private final String PARAMETERS;
private final String BODY_PARAMETER;
private final String RESPONSES;
private final String HEADERS_COLUMN;
private final String EXAMPLE_REQUEST;
private final String EXAMPLE_RESPONSE;
private final String SECURITY;
private final String TYPE_COLUMN;
private final String HTTP_CODE_COLUMN;
private final String DEPRECATED_OPERATION;
private final String UNKNOWN;
private static final String PATHS_ANCHOR = "paths";
private static final String DESCRIPTION_FILE_NAME = "description";
public PathsDocumentBuilder(Swagger2MarkupConverter.Context globalContext, java.nio.file.Path outputPath) {
super(globalContext, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
RESPONSE = labels.getString("response");
REQUEST = labels.getString("request");
PATHS = labels.getString("paths");
RESOURCES = labels.getString("resources");
PARAMETERS = labels.getString("parameters");
BODY_PARAMETER = labels.getString("body_parameter");
RESPONSES = labels.getString("responses");
HEADERS_COLUMN = labels.getString("headers_column");
EXAMPLE_REQUEST = labels.getString("example_request");
EXAMPLE_RESPONSE = labels.getString("example_response");
SECURITY = labels.getString("security");
TYPE_COLUMN = labels.getString("type_column");
HTTP_CODE_COLUMN = labels.getString("http_code_column");
DEPRECATED_OPERATION = labels.getString("operation.deprecated");
UNKNOWN = labels.getString("unknown");
if (config.isGeneratedExamplesEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Include examples is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Include examples is disabled.");
}
}
if (config.isOperationDescriptionsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Include hand-written operation descriptions is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Include hand-written operation descriptions is disabled.");
}
}
if (config.isSeparatedOperationsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Create separated operation files is enabled.");
}
Validate.notNull(outputPath, "Output directory is required for separated operation files!");
} else {
if (logger.isDebugEnabled()) {
logger.debug("Create separated operation files is disabled.");
}
}
}
/**
* Builds the paths MarkupDocument.
*
* @return the paths MarkupDocument
*/
@Override
public MarkupDocument build() {
Map<String, Path> paths = globalContext.getSwagger().getPaths();
if (MapUtils.isNotEmpty(paths)) {
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildPathsTitle();
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildsPathsSection(paths);
applyPathsDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
}
return new MarkupDocument(markupDocBuilder);
}
private void buildsPathsSection(Map<String, Path> paths) {
Set<PathOperation> pathOperations = toPathOperationsSet(paths);
if (CollectionUtils.isNotEmpty(pathOperations)) {
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
for (PathOperation operation : pathOperations) {
buildOperation(operation);
}
} else {
Multimap<String, PathOperation> operationsGroupedByTag = TagUtils.groupOperationsByTag(pathOperations, config.getTagOrdering(), config.getOperationOrdering());
Map<String, Tag> tagsMap = convertTagsListToMap(globalContext.getSwagger().getTags());
for (String tagName : operationsGroupedByTag.keySet()) {
this.markupDocBuilder.sectionTitleLevel2(WordUtils.capitalize(tagName));
Optional<String> tagDescription = getTagDescription(tagsMap, tagName);
if (tagDescription.isPresent()) {
this.markupDocBuilder.paragraph(tagDescription.get());
}
for (PathOperation operation : operationsGroupedByTag.get(tagName)) {
buildOperation(operation);
}
}
}
}
}
/**
* Builds the path title depending on the operationsGroupedBy configuration setting.
*/
private void buildPathsTitle() {
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
buildPathsTitle(PATHS);
} else {
buildPathsTitle(RESOURCES);
}
}
/**
* Converts the Swagger paths into a list PathOperations.
*
* @param paths the Swagger paths
* @return the path operations
*/
private Set<PathOperation> toPathOperationsSet(Map<String, Path> paths) {
Set<PathOperation> pathOperations;
if (config.getOperationOrdering() != null) {
pathOperations = new TreeSet<>(config.getOperationOrdering());
}else{
pathOperations = new LinkedHashSet<>();
}
for (Map.Entry<String, Path> path : paths.entrySet()) {
Map<HttpMethod, Operation> operations = path.getValue().getOperationMap(); // TODO AS_IS does not work because of https://github.com/swagger-api/swagger-core/issues/1696
if (MapUtils.isNotEmpty(operations)) {
for (Map.Entry<HttpMethod, Operation> operation : operations.entrySet()) {
pathOperations.add(new PathOperation(operation.getKey(), path.getKey(), operation.getValue()));
}
}
}
return pathOperations;
}
private void buildPathsTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, PATHS_ANCHOR);
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(Context context) {
for (PathsDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(PathsDocumentExtension.class)) {
extension.apply(context);
}
}
/**
* Create the operation filename depending on the generation mode
*
* @param operation operation
* @return operation filename
*/
private String resolveOperationDocument(PathOperation operation) {
if (config.isSeparatedOperationsEnabled())
return new File(config.getSeparatedOperationsFolder(), this.markupDocBuilder.addFileExtension(normalizeName(operation.getId()))).getPath();
else
return this.markupDocBuilder.addFileExtension(config.getPathsDocument());
}
/**
* Builds a path operation depending on generation mode.
*
* @param operation operation
*/
private void buildOperation(PathOperation operation) {
if (config.isSeparatedOperationsEnabled()) {
MarkupDocBuilder pathDocBuilder = this.markupDocBuilder.copy();
buildOperation(operation, pathDocBuilder);
java.nio.file.Path operationFile = outputPath.resolve(resolveOperationDocument(operation));
try {
pathDocBuilder.writeToFileWithoutExtension(operationFile, StandardCharsets.UTF_8);
} catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn(String.format("Failed to write operation file: %s", operationFile), e);
}
}
if (logger.isInfoEnabled()) {
logger.info("Separate operation file produced: {}", operationFile);
}
buildOperationRef(operation, this.markupDocBuilder);
} else {
buildOperation(operation, this.markupDocBuilder);
}
if (logger.isInfoEnabled()) {
logger.info("Operation processed: {}", operation);
}
}
/**
* Returns the operation name depending on available informations.
* The summary is used to name the operation, or else the operation summary is used.
*
* @param operation operation
* @return operation name
*/
private String operationName(PathOperation operation) {
return operation.getTitle();
}
/**
* Builds a path operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildOperation(PathOperation operation, MarkupDocBuilder docBuilder) {
if (operation != null) {
applyPathsDocumentExtension(new Context(Position.OPERATION_BEGIN, docBuilder, operation));
buildDeprecatedSection(operation, docBuilder);
buildOperationTitle(operation, docBuilder);
buildDescriptionSection(operation, docBuilder);
inlineDefinitions(buildParametersSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), config.getInlineSchemaDepthLevel(), docBuilder);
inlineDefinitions(buildBodyParameterSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), config.getInlineSchemaDepthLevel(), docBuilder);
inlineDefinitions(buildResponsesSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), config.getInlineSchemaDepthLevel(), docBuilder);
buildConsumesSection(operation, docBuilder);
buildProducesSection(operation, docBuilder);
buildTagsSection(operation, docBuilder);
buildSecuritySchemeSection(operation, docBuilder);
buildExamplesSection(operation, docBuilder);
applyPathsDocumentExtension(new Context(Position.OPERATION_END, docBuilder, operation));
}
}
/**
* Builds a cross-reference to a separated operation file
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildOperationRef(PathOperation operation, MarkupDocBuilder docBuilder) {
String document;
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
document = null;
else if (config.isSeparatedOperationsEnabled())
document = defaultString(config.getInterDocumentCrossReferencesPrefix()) + resolveOperationDocument(operation);
else
document = defaultString(config.getInterDocumentCrossReferencesPrefix()) + resolveOperationDocument(operation);
String operationName = operationName(operation);
buildOperationTitle(docBuilder.copy().crossReference(document, operationName, operationName).toString(), "ref-" + operationName, docBuilder);
}
/**
* Builds a warning if method is deprecated.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildDeprecatedSection(PathOperation operation, MarkupDocBuilder docBuilder) {
Boolean deprecated = operation.getOperation().isDeprecated();
if (deprecated != null && deprecated) {
docBuilder.block(DEPRECATED_OPERATION, MarkupBlockStyle.EXAMPLE, null, MarkupAdmonition.CAUTION);
}
}
/**
* Adds the operation 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 operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildOperationTitle(PathOperation operation, MarkupDocBuilder docBuilder) {
String operationName = operationName(operation);
buildOperationTitle(operationName, null, docBuilder);
if (operationName.equals(operation.getOperation().getSummary())) {
docBuilder.listing(operation.getMethod() + " " + operation.getPath());
}
}
/**
* Adds a operation title to the document.
*
* @param title the operation title
* @param anchor optional anchor (null => auto-generate from title)
* @param docBuilder the MarkupDocBuilder to use
*/
private void buildOperationTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
docBuilder.sectionTitleWithAnchorLevel2(title, anchor);
} else {
docBuilder.sectionTitleWithAnchorLevel3(title, anchor);
}
}
/**
* Adds a operation section title to the document.
*
* @param title the section title
* @param docBuilder the MarkupDocBuilder to use
*/
private void buildSectionTitle(String title, MarkupDocBuilder docBuilder) {
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
docBuilder.sectionTitleLevel3(title);
} else {
docBuilder.sectionTitleLevel4(title);
}
}
/**
* Adds a response section title to the document.
*
* @param title the response title
* @param docBuilder the MarkupDocBuilder to use
*/
private void buildResponseTitle(String title, MarkupDocBuilder docBuilder) {
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
docBuilder.sectionTitleLevel4(title);
} else {
docBuilder.sectionTitleLevel5(title);
}
}
/**
* Adds a operation description to the document.
* If hand-written descriptions exist, it tries to load the description from a file.
* If the file cannot be read, the description of the operation is returned.
* 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 buildDescriptionSection(PathOperation operation, MarkupDocBuilder docBuilder) {
if (config.isOperationDescriptionsEnabled()) {
Optional<String> description = handWrittenOperationDescription(normalizeName(operation.getId()), DESCRIPTION_FILE_NAME);
if (!description.isPresent())
description = handWrittenOperationDescription(normalizeName(operation.getTitle()), DESCRIPTION_FILE_NAME);
if (description.isPresent()) {
operationDescription(description.get(), docBuilder);
} else {
operationDescription(operation.getOperation().getDescription(), docBuilder);
}
} else {
operationDescription(operation.getOperation().getDescription(), docBuilder);
}
}
private void operationDescription(String description, MarkupDocBuilder docBuilder) {
if (isNotBlank(description)) {
buildSectionTitle(DESCRIPTION, docBuilder);
docBuilder.paragraph(description);
}
}
/**
* Filter parameters to display in parameters section
*
* @param parameter parameter to filter
* @return true if parameter can be displayed
*/
private boolean filterParameter(Parameter parameter) {
return (!config.isFlatBodyEnabled() || !StringUtils.equals(parameter.getIn(), "body"));
}
private List<ObjectType> buildParametersSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<Parameter> parameters = operation.getOperation().getParameters();
if (config.getParameterOrdering() != null)
Collections.sort(parameters, config.getParameterOrdering());
List<ObjectType> localDefinitions = new ArrayList<>();
boolean displayParameters = false;
if (CollectionUtils.isNotEmpty(parameters)) {
for (Parameter p : parameters) {
if (filterParameter(p)) {
displayParameters = true;
break;
}
}
}
if (displayParameters) {
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(TYPE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
new MarkupTableColumn(DESCRIPTION_COLUMN, 6).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^6"),
new MarkupTableColumn(REQUIRED_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(DEFAULT_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
for (Parameter parameter : parameters) {
if (filterParameter(parameter)) {
Type type = ParameterUtils.getType(parameter, new DefinitionDocumentResolverFromOperation());
if (config.getInlineSchemaDepthLevel() > 0 && type instanceof ObjectType) {
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
String localTypeName = parameter.getName();
type.setName(localTypeName);
type.setUniqueName(operation.getId() + " " + localTypeName);
localDefinitions.add((ObjectType) type);
type = new RefType(type);
}
}
String parameterType = WordUtils.capitalize(parameter.getIn());
List<String> content = Arrays.asList(
parameterType,
parameter.getName(),
parameterDescription(operation, parameter),
Boolean.toString(parameter.getRequired()),
type.displaySchema(markupDocBuilder),
ParameterUtils.getDefaultValue(parameter));
cells.add(content);
}
}
buildSectionTitle(PARAMETERS, docBuilder);
docBuilder.tableWithColumnSpecs(cols, cells);
}
return localDefinitions;
}
/**
* Builds the body parameter section, if {@code Swagger2MarkupConfig.isIsolatedBody()} is true
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
* @return a list of inlined types.
*/
private List<ObjectType> buildBodyParameterSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<ObjectType> localDefinitions = new ArrayList<>();
if (config.isFlatBodyEnabled()) {
List<Parameter> parameters = operation.getOperation().getParameters();
if (CollectionUtils.isNotEmpty(parameters)) {
for (Parameter parameter : parameters) {
if (StringUtils.equals(parameter.getIn(), "body")) {
Type type = ParameterUtils.getType(parameter, new DefinitionDocumentResolverFromOperation());
buildSectionTitle(BODY_PARAMETER, docBuilder);
if (isNotBlank(parameter.getDescription())) {
docBuilder.paragraph(parameter.getDescription());
}
MarkupDocBuilder typeInfos = MarkupDocBuilders.documentBuilder(config.getMarkupLanguage(), config.getLineSeparator());
typeInfos.italicText(REQUIRED_COLUMN).textLine(": " + parameter.getRequired());
typeInfos.italicText(NAME_COLUMN).textLine(": " + parameter.getName());
if (!(type instanceof ObjectType)) {
typeInfos.italicText(TYPE_COLUMN).textLine(": " + type.displaySchema(docBuilder));
docBuilder.paragraph(typeInfos.toString());
} else {
docBuilder.paragraph(typeInfos.toString());
localDefinitions.addAll(buildPropertiesTable((ObjectType) type, operation.getId(), config.getInlineSchemaDepthLevel(), new PropertyDescriptor(type), new DefinitionDocumentResolverFromOperation(), docBuilder));
}
}
}
}
}
return localDefinitions;
}
/**
* Retrieves the description of a parameter, or otherwise an empty String.
* If hand-written descriptions exist, it tries to load the description from a file.
* If the file cannot be read, the description of the parameter is returned.
* Operation folder search order :
* - normalizeOperationFileName(operation.operationId)
* - then, normalizeOperationFileName(operation.method + " " + operation.path)
* - then, normalizeOperationFileName(operation.summary)
*
* @param operation the Swagger Operation
* @param parameter the Swagger Parameter
* @return the description of a parameter.
*/
private String parameterDescription(final PathOperation operation, Parameter parameter) {
if (config.isOperationDescriptionsEnabled()) {
final String parameterName = parameter.getName();
if (isNotBlank(parameterName)) {
Optional<String> description = handWrittenOperationDescription(new File(normalizeName(operation.getId()), parameterName).getPath(), DESCRIPTION_FILE_NAME);
if (!description.isPresent())
description = handWrittenOperationDescription(new File(normalizeName(operation.getTitle()), parameterName).getPath(), DESCRIPTION_FILE_NAME);
if (description.isPresent()) {
return description.get();
} else {
return defaultString(parameter.getDescription());
}
} else {
return defaultString(parameter.getDescription());
}
} else {
return defaultString(parameter.getDescription());
}
}
private void buildConsumesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<String> consumes = operation.getOperation().getConsumes();
if (CollectionUtils.isNotEmpty(consumes)) {
buildSectionTitle(CONSUMES, docBuilder);
docBuilder.unorderedList(consumes);
}
}
private void buildProducesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<String> produces = operation.getOperation().getProduces();
if (CollectionUtils.isNotEmpty(produces)) {
buildSectionTitle(PRODUCES, docBuilder);
docBuilder.unorderedList(produces);
}
}
private void buildTagsSection(PathOperation operation, MarkupDocBuilder docBuilder) {
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
List<String> tags = operation.getOperation().getTags();
if (CollectionUtils.isNotEmpty(tags)) {
buildSectionTitle(TAGS, docBuilder);
Set<String> tagsSet = toSet(tags, config.getTagOrdering());
docBuilder.unorderedList(new ArrayList<>(tagsSet));
}
}
}
/**
* Builds the example section of a Swagger Operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildExamplesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
Map<String, Object> generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(config.isGeneratedExamplesEnabled(), operation, globalContext.getSwagger().getDefinitions(), markupDocBuilder);
Map<String, Object> generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(config.isGeneratedExamplesEnabled(), operation.getOperation(), globalContext.getSwagger().getDefinitions(), markupDocBuilder);
exampleMap(generatedRequestExampleMap, EXAMPLE_REQUEST, REQUEST, docBuilder);
exampleMap(generatedResponseExampleMap, EXAMPLE_RESPONSE, RESPONSE, docBuilder);
}
private void exampleMap(Map<String, Object> exampleMap, String operationSectionTitle, String sectionTile, MarkupDocBuilder docBuilder) {
if (exampleMap.size() > 0) {
buildSectionTitle(operationSectionTitle, docBuilder);
for (Map.Entry<String, Object> entry : exampleMap.entrySet()) {
buildSectionTitle(sectionTile + " " + entry.getKey(), docBuilder);
docBuilder.listing(Json.pretty(entry.getValue()));
}
}
}
/**
* Builds the security section of a Swagger Operation.
*
* @param operation the Swagger Operation
* @param docBuilder the MarkupDocBuilder document builder
*/
private void buildSecuritySchemeSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<Map<String, List<String>>> securitySchemes = operation.getOperation().getSecurity();
if (CollectionUtils.isNotEmpty(securitySchemes)) {
buildSectionTitle(SECURITY, docBuilder);
Map<String, SecuritySchemeDefinition> securityDefinitions = globalContext.getSwagger().getSecurityDefinitions();
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(TYPE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
new MarkupTableColumn(SCOPES_COLUMN, 6).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^6"));
for (Map<String, List<String>> securityScheme : securitySchemes) {
for (Map.Entry<String, List<String>> securityEntry : securityScheme.entrySet()) {
String securityKey = securityEntry.getKey();
String type = UNKNOWN;
if (securityDefinitions != null && securityDefinitions.containsKey(securityKey)) {
type = securityDefinitions.get(securityKey).getType();
}
List<String> content = Arrays.asList(type, docBuilder.copy().crossReference(securityKey, securityKey).toString(),
Joiner.on(",").join(securityEntry.getValue()));
cells.add(content);
}
}
docBuilder.tableWithColumnSpecs(cols, cells);
}
}
/**
* Reads a hand-written description
*
* @param descriptionFolder the name of the folder where the description file resides
* @param descriptionFileName the name of the description file
* @return the content of the file
*/
private Optional<String> handWrittenOperationDescription(String descriptionFolder, String descriptionFileName) {
for (String fileNameExtension : config.getMarkupLanguage().getFileNameExtensions()) {
URI contentUri = config.getOperationDescriptionsUri().resolve(descriptionFolder).resolve(descriptionFileName + fileNameExtension);
try (Reader reader = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriReader(contentUri)) {
if (logger.isInfoEnabled()) {
logger.info("Operation description content processed {}", contentUri);
}
return Optional.of(IOUtils.toString(reader).trim());
} catch (IOException e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to read Operation description content {} > {}", contentUri, e.getMessage());
}
}
}
return Optional.absent();
}
private List<ObjectType> buildResponsesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
Map<String, Response> responses = operation.getOperation().getResponses();
List<ObjectType> localDefinitions = new ArrayList<>();
if (MapUtils.isNotEmpty(responses)) {
buildSectionTitle(RESPONSES, docBuilder);
List<MarkupTableColumn> responseCols = Arrays.asList(
new MarkupTableColumn(HTTP_CODE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
new MarkupTableColumn(DESCRIPTION_COLUMN, 3).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
List<MarkupTableColumn> responseHeaderCols = Arrays.asList(
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
new MarkupTableColumn(DESCRIPTION_COLUMN, 3).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(DEFAULT_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
Set<String> responseNames = toKeySet(responses, config.getResponseOrdering());
for (String responseName : responseNames) {
List<List<String>> cells = new ArrayList<>();
List<List<String>> responseHeaderCells = new ArrayList<>();
Response response = responses.get(responseName);
if (response.getSchema() != null) {
Property property = response.getSchema();
Type type = PropertyUtils.getType(property, new DefinitionDocumentResolverFromOperation());
if (config.getInlineSchemaDepthLevel() > 0 && type instanceof ObjectType) {
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
String localTypeName = RESPONSE + " " + responseName;
type.setName(localTypeName);
type.setUniqueName(operation.getId() + " " + localTypeName);
localDefinitions.add((ObjectType) type);
type = new RefType(type);
}
}
cells.add(Arrays.asList(responseName, response.getDescription(), type.displaySchema(markupDocBuilder)));
} else {
cells.add(Arrays.asList(responseName, response.getDescription(), NO_CONTENT));
}
buildResponseTitle(HTTP_CODE_COLUMN + " " + responseName, docBuilder);
docBuilder.tableWithColumnSpecs(responseCols, cells);
Map<String, Property> headers = response.getHeaders();
if(MapUtils.isNotEmpty(headers)) {
docBuilder.boldTextLine(HEADERS_COLUMN);
for(Map.Entry<String, Property> entry : headers.entrySet()){
Property property = entry.getValue();
Type propertyType = PropertyUtils.getType(property, null);
responseHeaderCells.add(Arrays.asList(entry.getKey(),
response.getDescription(),
propertyType.displaySchema(markupDocBuilder),
PropertyUtils.getDefaultValue(property)));
}
docBuilder.tableWithColumnSpecs(responseHeaderCols, responseHeaderCells);
}
}
}
return localDefinitions;
}
/**
* Builds the title of an inline schema.
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
*
* @param title inline schema title
* @param anchor inline schema anchor
* @param docBuilder the docbuilder do use for output
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
/**
* Builds inline schema definitions
*
* @param definitions all inline definitions to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
* @param depth current inline schema depth
* @param docBuilder the docbuilder do use for output
*/
private void inlineDefinitions(List<ObjectType> definitions, String uniquePrefix, int depth, MarkupDocBuilder docBuilder) {
if (CollectionUtils.isNotEmpty(definitions)) {
for (ObjectType definition : definitions) {
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
List<ObjectType> localDefinitions = buildPropertiesTable(definition, uniquePrefix, depth, new PropertyDescriptor(definition), new DefinitionDocumentResolverFromOperation(), docBuilder);
for (ObjectType localDefinition : localDefinitions)
inlineDefinitions(Collections.singletonList(localDefinition), uniquePrefix, depth - 1, docBuilder);
}
}
}
/**
* Overrides definition document resolver functor for inter-document cross-references from operations files.
* This implementation adapt the relative paths to definitions files
*/
class DefinitionDocumentResolverFromOperation extends DefinitionDocumentResolverDefault {
public DefinitionDocumentResolverFromOperation() {
}
public String apply(String definitionName) {
String defaultResolver = super.apply(definitionName);
if (defaultResolver != null && config.isSeparatedOperationsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File("..", defaultResolver).getPath();
else
return defaultResolver;
}
}
}

View File

@@ -1,145 +0,0 @@
/*
* Copyright 2016 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.internal.document.builder;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.markup.builder.MarkupTableColumn;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
import io.github.robwin.swagger2markup.spi.SecurityDocumentExtension;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.nio.file.Path;
import java.util.*;
import static io.github.robwin.swagger2markup.spi.SecurityDocumentExtension.Context;
import static io.github.robwin.swagger2markup.spi.SecurityDocumentExtension.Position;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public class SecurityDocumentBuilder extends MarkupDocumentBuilder {
private static final String SECURITY_ANCHOR = "security";
private final String SECURITY;
private final String TYPE;
private final String NAME;
private final String IN;
private final String FLOW;
private final String AUTHORIZATION_URL;
private final String TOKEN_URL;
public SecurityDocumentBuilder(Swagger2MarkupConverter.Context context, Path outputPath) {
super(context, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
SECURITY = labels.getString("security");
TYPE = labels.getString("security_type");
NAME = labels.getString("security_name");
IN = labels.getString("security_in");
FLOW = labels.getString("security_flow");
AUTHORIZATION_URL = labels.getString("security_authorizationUrl");
TOKEN_URL = labels.getString("security_tokenUrl");
}
/**
* Builds the security MarkupDocument.
*
* @return the security MarkupDocument
*/
@Override
public MarkupDocument build(){
Map<String, SecuritySchemeDefinition> definitions = globalContext.getSwagger().getSecurityDefinitions();
if (MapUtils.isNotEmpty(definitions)) {
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildSecurityTitle(SECURITY);
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildSecuritySchemeDefinitionsSection(definitions);
applySecurityDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
}
return new MarkupDocument(markupDocBuilder);
}
private void buildSecurityTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, SECURITY_ANCHOR);
}
private void buildSecuritySchemeDefinitionsSection(Map<String, SecuritySchemeDefinition> definitions) {
for (Map.Entry<String, SecuritySchemeDefinition> entry : definitions.entrySet()) {
String definitionName = entry.getKey();
SecuritySchemeDefinition definition = entry.getValue();
buildSecuritySchemeDefinitionTitle(definitionName);
applySecurityDocumentExtension(new Context(Position.DEFINITION_BEGIN, markupDocBuilder, definitionName, definition));
buildDescriptionParagraph(definition.getDescription());
buildSecurityScheme(definition);
applySecurityDocumentExtension(new Context(Position.DEFINITION_BEGIN, markupDocBuilder, definitionName, definition));
}
}
private void buildDescriptionParagraph(String description) {
if(StringUtils.isNotBlank(description)) {
markupDocBuilder.paragraph(description);
}
}
private MarkupDocBuilder buildSecuritySchemeDefinitionTitle(String definitionName) {
return markupDocBuilder.sectionTitleLevel2(definitionName);
}
private void buildSecurityScheme(SecuritySchemeDefinition securityScheme) {
String type = securityScheme.getType();
markupDocBuilder.textLine(TYPE + " : " + type);
if (securityScheme instanceof ApiKeyAuthDefinition) {
markupDocBuilder.textLine(NAME + " : " + ((ApiKeyAuthDefinition) securityScheme).getName());
markupDocBuilder.textLine(IN + " : " + ((ApiKeyAuthDefinition) securityScheme).getIn());
} else if (securityScheme instanceof OAuth2Definition) {
OAuth2Definition oauth2Scheme = (OAuth2Definition) securityScheme;
String flow = oauth2Scheme.getFlow();
markupDocBuilder.textLine(FLOW + " : " + flow);
if (isNotBlank(oauth2Scheme.getAuthorizationUrl())) {
markupDocBuilder.textLine(AUTHORIZATION_URL + " : " + oauth2Scheme.getAuthorizationUrl());
}
if (isNotBlank(oauth2Scheme.getTokenUrl())) {
markupDocBuilder.textLine(TOKEN_URL + " : " + oauth2Scheme.getTokenUrl());
}
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(new MarkupTableColumn(NAME_COLUMN, 1),
new MarkupTableColumn(DESCRIPTION_COLUMN, 6));
for (Map.Entry<String, String> scope : oauth2Scheme.getScopes().entrySet()) {
List<String> content = Arrays.asList(scope.getKey(), scope.getValue());
cells.add(content);
}
markupDocBuilder.tableWithColumnSpecs(cols, cells);
}
}
/**
* Apply extension context to all SecurityContentExtension
*
* @param context context
*/
private void applySecurityDocumentExtension(Context context) {
for (SecurityDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(SecurityDocumentExtension.class)) {
extension.apply(context);
}
}
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import com.google.common.base.Optional;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.spi.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;
class ContentExtension {
private static final Logger logger = LoggerFactory.getLogger(ContentExtension.class);
protected final Swagger2MarkupConverter.Context globalContext;
protected final ContentContext contentContext;
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("Failed to read content file {} > {}", contentPath, e.getMessage());
}
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Failed to read content file {}", 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.internal.utils.IOUtils.uriReader(contentUri);
if (logger.isInfoEnabled()) {
logger.info("Content URI {} processed", contentUri);
}
return Optional.of(reader);
} catch (IOException e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to read content URI {} > {}", contentUri, e.getMessage());
}
}
return Optional.absent();
}
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.spi.ContentContext;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
class DynamicContentExtension extends ContentExtension {
private static final Logger logger = LoggerFactory.getLogger(DynamicContentExtension.class);
DynamicContentExtension(Swagger2MarkupConverter.Context globalContext, ContentContext contentContext) {
super(globalContext, contentContext);
}
/**
* Builds extension sections
*
* @param contentPath the path where the content files reside
* @param prefix extension file prefix
* @param levelOffset import markup level offset
*/
public void extensionsSection(Path contentPath, final String prefix, int levelOffset) {
final Collection<String> filenameExtensions = Collections2.transform(globalContext.getConfig().getMarkupLanguage().getFileNameExtensions(), new Function<String, String>() {
public String apply(String input) {
return StringUtils.stripStart(input, ".");
}
});
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
String fileName = entry.getFileName().toString();
return fileName.startsWith(prefix) && FilenameUtils.isExtension(fileName, filenameExtensions);
}
};
try (DirectoryStream<Path> extensionFiles = Files.newDirectoryStream(contentPath, filter)) {
if (extensionFiles != null) {
List<Path> extensions = Lists.newArrayList(extensionFiles);
Collections.sort(extensions, Ordering.natural());
for (Path extension : extensions) {
Optional<Reader> extensionContent = readContentPath(extension);
if (extensionContent.isPresent()) {
try {
contentContext.getMarkupDocBuilder().importMarkup(extensionContent.get(), levelOffset);
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to read extension file %s", extension), e);
} finally {
extensionContent.get().close();
}
}
}
}
} catch (IOException e) {
if (logger.isDebugEnabled())
logger.debug("Failed to read extension files from directory {}", contentPath);
}
}
}

View File

@@ -1,100 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
import io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Dynamically search for markup files in {@code contentPath} to append in Definitions, with the format :<br/>
* - {@code document-before-*.<markup.ext>} : import before Definitions document with levelOffset = 0<br/>
* - {@code document-begin-*.<markup.ext>} : import just after Definitions document main title with levelOffset = 1<br/>
* - {@code document-end-*.<markup.ext>} : import at the end of Definitions document with levelOffset = 1<br/>
* - {@code definition-begin-*.<markup.ext>} : import just after each definition title with levelOffset = 2<br/>
* - {@code definition-end-*.<markup.ext>} : import at the end of each definition with levelOffset = 2<br/>
* <p/>
* Markup files are appended in the natural order of their names, for each category.
*/
public final class DynamicDefinitionsDocumentExtension extends DefinitionsDocumentExtension {
private static final Logger logger = LoggerFactory.getLogger(DynamicDefinitionsDocumentExtension.class);
protected Path contentPath;
public DynamicDefinitionsDocumentExtension(Path contentPath) {
super();
Validate.notNull(contentPath);
this.contentPath = contentPath;
}
public DynamicDefinitionsDocumentExtension() {
super();
}
@Override
public void init(Swagger2MarkupConverter.Context globalContext) {
if (contentPath == null) {
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
if (logger.isWarnEnabled())
logger.warn("Disable DynamicDefinitionsContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
} else {
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
}
}
}
@Override
public void apply(Context context) {
Validate.notNull(context);
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
DynamicDefinitionsDocumentExtension.Position position = context.getPosition();
switch (position) {
case DOCUMENT_BEFORE:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_BEGIN:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_END:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DEFINITION_BEGIN:
dynamicContent.extensionsSection(contentPath.resolve(Paths.get(IOUtils.normalizeName(context.getDefinitionName().get()))), contentPrefix(position), levelOffset(context));
break;
case DEFINITION_END:
dynamicContent.extensionsSection(contentPath.resolve(Paths.get(IOUtils.normalizeName(context.getDefinitionName().get()))), contentPrefix(position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", position));
}
}
}
public String contentPrefix(Position position) {
return position.name().toLowerCase().replace('_', '-');
}
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.spi.OverviewDocumentExtension;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Dynamically search for markup files in {@code contentPath} to append to Overview, with the format :<br/>
* - {@code document-before-*.<markup.ext>} : import before Overview document with levelOffset = 0<br/>
* - {@code document-begin-*.<markup.ext>} : import just after Overview document main title with levelOffset = 1<br/>
* - {@code document-end-*.<markup.ext>} : import at the end of Overview document with levelOffset = 1<br/>
* <p/>
* Markup files are appended in the natural order of their names, for each category.
*/
public final class DynamicOverviewDocumentExtension extends OverviewDocumentExtension {
private static final Logger logger = LoggerFactory.getLogger(DynamicOverviewDocumentExtension.class);
protected Path contentPath;
public DynamicOverviewDocumentExtension() {
super();
}
public DynamicOverviewDocumentExtension(Path contentPath) {
super();
Validate.notNull(contentPath);
this.contentPath = contentPath;
}
@Override
public void init(Swagger2MarkupConverter.Context globalContext) {
if (contentPath == null) {
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
if (logger.isWarnEnabled())
logger.warn("Disable > DynamicOverviewContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
} else {
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
}
}
}
@Override
public void apply(Context context) {
Validate.notNull(context);
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
OverviewDocumentExtension.Position position = context.getPosition();
switch (position) {
case DOCUMENT_BEFORE:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_BEGIN:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_END:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", position));
}
}
}
private String contentPrefix(Position position) {
return position.name().toLowerCase().replace('_', '-');
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
import io.github.robwin.swagger2markup.spi.PathsDocumentExtension;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Dynamically search for markup files in {@code contentPath} to append to Operations, with the format :<br/>
* - {@code document-before-*.<markup.ext>} : import before Paths document with levelOffset = 0<br/>
* - {@code document-begin-*.<markup.ext>} : import just after Paths document main title with levelOffset = 1<br/>
* - {@code document-end-*.<markup.ext>} : import at the end of Paths document with levelOffset = 1<br/>
* - {@code operation-begin-*.<markup.ext>} : import just after each operation title with levelOffset = 2(GroupBy.AS_IS) | 3(GroupBy.TAGS)<br/>
* - {@code operation-end-*.<markup.ext>} : import at the end of each operation with levelOffset = 2(GroupBy.AS_IS) | 3(GroupBy.TAGS)<br/>
* <p/>
* Markup files are appended in the natural order of their names, for each category.
*/
public final class DynamicPathsDocumentExtension extends PathsDocumentExtension {
private static final Logger logger = LoggerFactory.getLogger(DynamicPathsDocumentExtension.class);
protected Path contentPath;
public DynamicPathsDocumentExtension() {
super();
}
public DynamicPathsDocumentExtension(Path contentPath) {
super();
Validate.notNull(contentPath);
this.contentPath = contentPath;
}
@Override
public void init(Swagger2MarkupConverter.Context globalContext) {
if (contentPath == null) {
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
if (logger.isWarnEnabled())
logger.warn("Disable DynamicOperationsContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
} else {
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
}
}
}
@Override
public void apply(Context context) {
Validate.notNull(context);
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
PathsDocumentExtension.Position position = context.getPosition();
switch (position) {
case DOCUMENT_BEFORE:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_BEGIN:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_END:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case OPERATION_BEGIN:
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getOperation().get().getId())), contentPrefix(position), levelOffset(context));
break;
case OPERATION_END:
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getOperation().get().getId())), contentPrefix(position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", position));
}
}
}
private String contentPrefix(Position position) {
return position.name().toLowerCase().replace('_', '-');
}
}

View File

@@ -1,100 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
import io.github.robwin.swagger2markup.spi.SecurityDocumentExtension;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Dynamically search for markup files in {@code contentPath} to append to Overview, with the format :<br/>
* - {@code document-before-*.<markup.ext>} : import before Overview document with levelOffset = 0<br/>
* - {@code document-begin-*.<markup.ext>} : import just after Overview document main title with levelOffset = 1<br/>
* - {@code document-end-*.<markup.ext>} : import at the end of Overview document with levelOffset = 1<br/>
* - {@code definition-begin-*.<markup.ext>} : import just after each definition title with levelOffset = 2<br/>
* - {@code definition-end-*.<markup.ext>} : import at the end of each definition with levelOffset = 2<br/>
* <p/>
* Markup files are appended in the natural order of their names, for each category.
*/
public final class DynamicSecurityDocumentExtension extends SecurityDocumentExtension {
private static final Logger logger = LoggerFactory.getLogger(DynamicSecurityDocumentExtension.class);
protected Path contentPath;
public DynamicSecurityDocumentExtension() {
super();
}
public DynamicSecurityDocumentExtension(Path contentPath) {
super();
Validate.notNull(contentPath);
this.contentPath = contentPath;
}
@Override
public void init(Swagger2MarkupConverter.Context globalContext) {
if (contentPath == null) {
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
if (logger.isWarnEnabled())
logger.warn("Disable > DynamicSecurityContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
} else {
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
}
}
}
@Override
public void apply(Context context) {
Validate.notNull(context);
if (contentPath != null) {
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
SecurityDocumentExtension.Position position = context.getPosition();
switch (position) {
case DOCUMENT_BEFORE:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_BEGIN:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DOCUMENT_END:
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
break;
case DEFINITION_BEGIN:
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getDefinitionName().get())), contentPrefix(position), levelOffset(context));
break;
case DEFINITION_END:
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getDefinitionName().get())), contentPrefix(position), levelOffset(context));
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", position));
}
}
}
private String contentPrefix(Position position) {
return position.name().toLowerCase().replace('_', '-');
}
}

View File

@@ -1,168 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import com.google.common.base.Optional;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension;
import io.github.robwin.swagger2markup.internal.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.ArrayList;
import java.util.List;
/**
* Add external schemas to content.<br/>
* Supported formats are :
* <ul>
* <li>XML Schema (.xsd)</li>
* <li>JSON Schema (.json)</li>
* </ul>
*/
public final class SchemaExtension extends DefinitionsDocumentExtension {
private static final Logger logger = LoggerFactory.getLogger(SchemaExtension.class);
private static final List<SchemaMetadata> DEFAULT_SCHEMAS = new ArrayList<SchemaMetadata>() {{
add(new SchemaMetadata("JSON Schema", "json", "json"));
add(new SchemaMetadata("XML Schema", "xsd", "xml"));
}};
protected List<SchemaMetadata> schemas = new ArrayList<>();
protected URI schemaBaseUri;
public SchemaExtension(URI schemaBaseUri) {
super();
Validate.notNull(schemaBaseUri);
this.schemaBaseUri = schemaBaseUri;
}
public SchemaExtension() {
super();
}
public SchemaExtension withDefaultSchemas() {
schemas.addAll(DEFAULT_SCHEMAS);
return this;
}
public SchemaExtension withSchemas(List<SchemaMetadata> schemas) {
schemas.addAll(schemas);
return this;
}
@Override
public void init(Swagger2MarkupConverter.Context globalContext) {
if (schemaBaseUri == null) {
if (globalContext.getSwaggerLocation() == null) {
if (logger.isWarnEnabled())
logger.warn("Disable SchemaExtension > Can't set default schemaBaseUri from swaggerLocation. You have to explicitly configure the schemaBaseUri.");
} else {
schemaBaseUri = IOUtils.uriParent(globalContext.getSwaggerLocation());
}
}
}
@Override
public void apply(Context context) {
Validate.notNull(context);
if (schemaBaseUri != null) {
switch (context.getPosition()) {
case DOCUMENT_BEFORE:
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case DEFINITION_BEGIN:
break;
case DEFINITION_END:
for (SchemaMetadata schema : DEFAULT_SCHEMAS) {
schemaSection(context, schema, levelOffset(context));
}
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.getPosition()));
}
}
}
/**
* Builds snippet URI for the given {@code definitionName} and {@code schema}.<br/>
* Default implementation use {@code <schemaBaseUri>/normalizeName(<definitionName>)/schema.<schema.extension>}.<br/>
* You can override this method to configure your own folder normalization.
*
* @param context current context
* @param definitionName current definition name
* @return subdirectory normalized name
*/
public URI definitionSchemaUri(Context context, String definitionName, SchemaMetadata schema) {
return schemaBaseUri.resolve(IOUtils.normalizeName(definitionName) + "/").resolve("schema" + (schema.extension != null ? "." + schema.extension : ""));
}
private void schemaSection(Context context, SchemaMetadata schema, int levelOffset) {
ContentExtension contentExtension = new ContentExtension(globalContext, context);
URI schemaUri = definitionSchemaUri(context, context.getDefinitionName().get(), schema);
try {
Optional<Reader> extensionContent = contentExtension.readContentUri(schemaUri);
if (extensionContent.isPresent()) {
try {
context.getMarkupDocBuilder().sectionTitleLevel(1 + levelOffset, schema.title);
context.getMarkupDocBuilder().listing(org.apache.commons.io.IOUtils.toString(extensionContent.get()).trim(), schema.language);
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to read schema URI : %s", schemaUri), e);
} finally {
extensionContent.get().close();
}
}
} catch (IOException e) {
if (logger.isDebugEnabled())
logger.debug("Failed to read schema URI {}", schemaUri);
}
}
public static class SchemaMetadata {
/**
* Schema title
*/
public String title;
/**
* Schema file extension, without dot (e.g.: xsd).<br/>
* Set to null if there's no extension
*/
public String extension;
/**
* Schema content language (e.g.: xml)
*/
public String language;
public SchemaMetadata(String title, String extension, String language) {
this.title = title;
this.extension = extension;
this.language = language;
}
}
}

View File

@@ -1,150 +0,0 @@
/*
* Copyright 2016 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.internal.extensions;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import io.github.robwin.swagger2markup.internal.model.PathOperation;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import io.github.robwin.swagger2markup.spi.PathsDocumentExtension;
import io.github.robwin.swagger2markup.internal.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 final class SpringRestDocsExtension extends PathsDocumentExtension {
private static final Logger logger = LoggerFactory.getLogger(SpringRestDocsExtension.class);
private static final Map<String, String> DEFAULT_SNIPPETS = new LinkedHashMap<String, String>() {{
put("http-request", "HTTP request");
put("http-response", "HTTP response");
put("curl-request", "Curl request");
}};
protected URI snippetBaseUri;
protected Map<String, String> snippets = new LinkedHashMap<>();
/**
* Instantiate extension
* @param snippetBaseUri base URI where are snippets are stored
*/
public SpringRestDocsExtension(URI snippetBaseUri) {
super();
Validate.notNull(snippetBaseUri);
this.snippetBaseUri = snippetBaseUri;
}
public SpringRestDocsExtension() {
super();
}
@Override
public void init(Swagger2MarkupConverter.Context globalContext) {
if (snippetBaseUri == null) {
if (globalContext.getSwaggerLocation() == null) {
if (logger.isWarnEnabled())
logger.warn("Disable SpringRestDocsExtension > Can't set default snippetBaseUri from swaggerLocation. You have to explicitly configure the snippetBaseUri.");
} else {
snippetBaseUri = IOUtils.uriParent(globalContext.getSwaggerLocation());
}
}
}
/**
* Add SpringRestDocs default snippets to list
* @return this instance
*/
public SpringRestDocsExtension withDefaultSnippets() {
snippets.putAll(DEFAULT_SNIPPETS);
return this;
}
/**
* 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;
}
/**
* Builds snippet URI for the given {@code operation} and {@code snippetName}.<br/>
* Default implementation use {@code <snippetBaseUri>/<normalizeName(<operation id>)>/<snippetName>.<markup ext>}.<br/>
* You can override this method to configure your own folder normalization.
*
* @param context current context
* @param operation current operation
* @return subdirectory normalized name
*/
public URI operationSnippetUri(Context context, PathOperation operation, String snippetName) {
return snippetBaseUri.resolve(IOUtils.normalizeName(operation.getId()) + "/").resolve(context.getMarkupDocBuilder().addFileExtension(snippetName));
}
@Override
public void apply(Context context) {
Validate.notNull(context);
switch (context.getPosition()) {
case OPERATION_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);
URI snippetUri = operationSnippetUri(context, context.getOperation().get(), snippetName);
Optional<Reader> snippetContent = content.readContentUri(snippetUri);
if (snippetContent.isPresent()) {
try {
context.getMarkupDocBuilder().sectionTitleLevel(1 + levelOffset(context), title);
context.getMarkupDocBuilder().importMarkup(snippetContent.get(), levelOffset(context) + 1);
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to process snippet URI : %s", snippetUri), e);
} finally {
try {
snippetContent.get().close();
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright 2016 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.internal.model;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import static org.apache.commons.lang3.StringUtils.isBlank;
public class PathOperation {
protected HttpMethod method;
protected String path;
protected Operation operation;
public PathOperation(HttpMethod method, String path, Operation operation) {
this.method = method;
this.path = path;
this.operation = operation;
}
public HttpMethod getMethod() {
return method;
}
public String getPath() {
return path;
}
/**
* Returns the display title for an operation
* @return the operation title
*/
public String getTitle() {
String operationName = operation.getSummary();
if (isBlank(operationName)) {
operationName = getMethod().toString() + " " + getPath();
}
return operationName;
}
/**
* Returns an unique id for the operation.<br/>
* Use {@code <operation id>}, then {@code <operation path> lowercase(<operation method>)} if operation id is not set.
*
* @return operation unique id
*/
public String getId() {
String id = operation.getOperationId();
if (id == null)
id = getPath() + " " + getMethod().toString().toLowerCase();
return id;
}
public Operation getOperation() {
return operation;
}
@Override
public String toString() {
return getId();
}
}

View File

@@ -1,284 +0,0 @@
/*
* Copyright 2016 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.internal.utils;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.internal.model.PathOperation;
import io.swagger.models.*;
import io.swagger.models.parameters.*;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ExamplesUtil {
private static Logger logger = LoggerFactory.getLogger(ExamplesUtil.class);
/**
* Generates a Map of response examples
*
* @param operation the Swagger Operation
* @return map containing response examples.
*/
public static Map<String, Object> generateResponseExampleMap(boolean generateMissingExamples, Operation operation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Map<String, Object> examples = new HashMap<>();
Map<String, Response> responses = operation.getResponses();
for (Map.Entry<String, Response> responseEntry : responses.entrySet()) {
Response response = responseEntry.getValue();
Object example = response.getExamples();
if (example == null) {
Property schema = response.getSchema();
if (schema != null) {
example = schema.getExample();
if (example == null && schema instanceof RefProperty) {
String simpleRef = ((RefProperty) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
}
if (example == null && generateMissingExamples) {
example = PropertyUtils.generateExample(schema, markupDocBuilder);
}
}
}
if (example != null)
examples.put(responseEntry.getKey(), example);
}
return examples;
}
/**
* Generates examples for request
*
* @param pathOperation the Swagger Operation
* @return an Optional with the example content
*/
public static Map<String, Object> generateRequestExampleMap(boolean generateMissingExamples, PathOperation pathOperation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Operation operation = pathOperation.getOperation();
List<Parameter> parameters = operation.getParameters();
Map<String, Object> examples = new HashMap<>();
// Path example should always be included (if generateMissingExamples):
if (generateMissingExamples)
examples.put("path", pathOperation.getPath());
for (Parameter parameter : parameters) {
Object example = null;
if (parameter instanceof BodyParameter) {
example = ((BodyParameter) parameter).getExamples();
if (example == null) {
Model schema = ((BodyParameter) parameter).getSchema();
if (schema instanceof RefModel) {
String simpleRef = ((RefModel) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
} else if (generateMissingExamples) {
if (schema instanceof ComposedModel) {
example = exampleMapForProperties(getPropertiesForComposedModel(
(ComposedModel) schema, definitions), definitions, markupDocBuilder);
} else if (schema instanceof ArrayModel) {
example = generateExampleForArrayModel((ArrayModel) schema, definitions, markupDocBuilder);
} else {
example = schema.getExample();
if (example == null) {
example = exampleMapForProperties(schema.getProperties(), definitions, markupDocBuilder);
}
}
}
}
} else if (parameter instanceof AbstractSerializableParameter) {
if (generateMissingExamples) {
Object abstractSerializableParameterExample;
abstractSerializableParameterExample = ((AbstractSerializableParameter) parameter).getExample();
if (abstractSerializableParameterExample == null) {
Property item = ((AbstractSerializableParameter) parameter).getItems();
if (item != null) {
abstractSerializableParameterExample = PropertyUtils.convertExample(item.getExample(), item.getType());
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = PropertyUtils.generateExample(item, markupDocBuilder);
}
}
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = ParameterUtils.generateExample((AbstractSerializableParameter)parameter, markupDocBuilder);
}
}
if (parameter instanceof PathParameter) {
String pathExample = (String) examples.get("path");
pathExample = pathExample.replace('{' + parameter.getName() + '}', String.valueOf(abstractSerializableParameterExample));
example = pathExample;
} else {
example = abstractSerializableParameterExample;
}
if (parameter instanceof QueryParameter) {
//noinspection unchecked
@SuppressWarnings("unchecked")
Map<String, Object> queryExampleMap = (Map<String, Object>) examples.get("query");
if (queryExampleMap == null) {
queryExampleMap = new HashMap<>();
}
queryExampleMap.put(parameter.getName(), abstractSerializableParameterExample);
example = queryExampleMap;
}
}
} else if (parameter instanceof RefParameter) {
String simpleRef = ((RefParameter) parameter).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
}
if (example != null)
examples.put(parameter.getIn(), example);
}
return examples;
}
/**
* Generates an example object from a simple reference
*
* @param simpleRef the simple reference string
* @return returns an Object or Map of examples
*/
public static Object generateExampleForRefModel(boolean generateMissingExamples, String simpleRef, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Model model = definitions.get(simpleRef);
Object example = null;
if (model != null) {
example = model.getExample();
if (example == null && generateMissingExamples) {
if (model instanceof ComposedModel) {
example = exampleMapForProperties(getPropertiesForComposedModel((ComposedModel) model, definitions), definitions, markupDocBuilder);
} else {
example = exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder);
}
}
}
return example;
}
private static Map<String, Property> getPropertiesForComposedModel(ComposedModel model, Map<String, Model> definitions) {
Map<String, Property> combinedProperties;
if (model.getParent() instanceof RefModel) {
Map<String, Property> parentProperties = definitions.get(((RefModel) model.getParent()).getSimpleRef()).getProperties();
if (parentProperties == null) {
return null;
} else {
combinedProperties = new LinkedHashMap<>(parentProperties);
}
} else {
combinedProperties = new LinkedHashMap<>(model.getParent().getProperties());
}
Map<String, Property> childProperties;
if (model.getChild() instanceof RefModel) {
childProperties = definitions.get(((RefModel) model.getChild()).getSimpleRef()).getProperties();
} else {
childProperties = model.getChild().getProperties();
}
if (childProperties != null) {
combinedProperties.putAll(childProperties);
}
return combinedProperties;
}
/**
* Generates a map of examples from a map of properties. If defined examples are found, those are used. Otherwise,
* examples are generated from the type.
*
* @param properties map of properties
* @return a Map of examples
*/
public static Map<String, Object> exampleMapForProperties(Map<String, Property> properties, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Map<String, Object> exampleMap = new HashMap<>();
for (Map.Entry<String, Property> property : properties.entrySet()) {
Object exampleObject = PropertyUtils.convertExample(property.getValue().getExample(), property.getValue().getType());
if (exampleObject == null) {
if (property.getValue() instanceof RefProperty) {
exampleObject = generateExampleForRefModel(true, ((RefProperty) property.getValue()).getSimpleRef(), definitions, markupDocBuilder);
} else if (property.getValue() instanceof ArrayProperty) {
exampleObject = generateExampleForArrayProperty((ArrayProperty) property.getValue(), definitions, markupDocBuilder);
} else if (property.getValue() instanceof MapProperty) {
exampleObject = generateExampleForMapProperty((MapProperty) property.getValue(), markupDocBuilder);
}
if (exampleObject == null) {
Property valueProperty = property.getValue();
exampleObject = PropertyUtils.generateExample(valueProperty, markupDocBuilder);
}
}
exampleMap.put(property.getKey(), exampleObject);
}
return exampleMap;
}
public static Object generateExampleForMapProperty(MapProperty property, MarkupDocBuilder markupDocBuilder) {
if (property.getExample() != null) {
return property.getExample();
}
Map<String, Object> exampleMap = new HashMap<>();
Property valueProperty = property.getAdditionalProperties();
if (valueProperty.getExample() != null) {
return valueProperty.getExample();
}
exampleMap.put("string", PropertyUtils.generateExample(valueProperty, markupDocBuilder));
return exampleMap;
}
public static Object generateExampleForArrayModel(ArrayModel model, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
if (model.getExample() != null) {
return model.getExample();
} else if (model.getProperties() != null) {
return new Object[]{exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder)};
} else {
Property itemProperty = model.getItems();
if (itemProperty.getExample() != null) {
return new Object[]{PropertyUtils.convertExample(itemProperty.getExample(), itemProperty.getType())};
} else if (itemProperty instanceof ArrayProperty) {
return new Object[]{generateExampleForArrayProperty((ArrayProperty) itemProperty, definitions, markupDocBuilder)};
} else if (itemProperty instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) itemProperty).getSimpleRef(), definitions, markupDocBuilder)};
} else {
return new Object[]{PropertyUtils.generateExample(itemProperty, markupDocBuilder)};
}
}
}
/**
* Generates examples from an ArrayProperty
*
* @param value ArrayProperty
* @return array of Object
*/
public static Object[] generateExampleForArrayProperty(ArrayProperty value, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Property property = value.getItems();
if (property.getExample() != null) {
return new Object[]{PropertyUtils.convertExample(property.getExample(), property.getType())};
} else if (property instanceof ArrayProperty) {
return new Object[]{generateExampleForArrayProperty((ArrayProperty) property, definitions, markupDocBuilder)};
} else if (property instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, markupDocBuilder)};
} else {
return new Object[]{PropertyUtils.generateExample(property, markupDocBuilder)};
}
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2016 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.internal.utils;
import java.util.*;
public class ListUtils {
/**
* Returns the List as an Set either ordered or as-is, if the comparator is null.
*
* @param list the List
* @param comparator the comparator to use.
* @return the Set
*/
public static Set<String> toSet(List<String> list, Comparator<String> comparator){
Set<String> set;
if (comparator == null)
set = new LinkedHashSet<>();
else
set = new TreeSet<>(comparator);
set.addAll(list);
return set;
}
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2016 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.internal.utils;
import com.google.common.base.Function;
import io.github.robwin.swagger2markup.internal.type.ArrayType;
import io.github.robwin.swagger2markup.internal.type.ObjectType;
import io.github.robwin.swagger2markup.internal.type.RefType;
import io.github.robwin.swagger2markup.internal.type.Type;
import io.swagger.models.ArrayModel;
import io.swagger.models.Model;
import io.swagger.models.ModelImpl;
import io.swagger.models.RefModel;
import org.apache.commons.lang3.Validate;
public final class ModelUtils {
/**
* Retrieves the type of a model, or otherwise null
*
* @param model the model
* @return the type of the model, or otherwise null
*/
public static Type getType(Model model, Function<String, String> definitionDocumentResolver) {
Validate.notNull(model, "model must not be null!");
if (model instanceof ModelImpl) {
return new ObjectType(null, model.getProperties());
} else if (model instanceof RefModel) {
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(), definitionDocumentResolver));
}
return null;
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright 2016 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.internal.utils;
import com.google.common.base.Function;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.internal.type.*;
import io.swagger.models.Model;
import io.swagger.models.parameters.AbstractSerializableParameter;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.RefParameter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.defaultString;
public final class ParameterUtils {
/**
* Retrieves the type of a parameter, or otherwise null
*
* @param parameter the parameter
* @return the type of the parameter, or otherwise null
*/
public static Type getType(Parameter parameter, Function<String, String> 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, definitionDocumentResolver);
}else{
type = new BasicType("string");
}
}
else if(parameter instanceof AbstractSerializableParameter){
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
@SuppressWarnings("unchecked")
List<String> enums = serializableParameter.getEnum();
if(CollectionUtils.isNotEmpty(enums)){
type = new EnumType(null, enums);
}else{
type = new BasicType(serializableParameter.getType(), serializableParameter.getFormat());
}
if(type.getName().equals("array")){
String collectionFormat = serializableParameter.getCollectionFormat();
type = new ArrayType(null, PropertyUtils.getType(serializableParameter.getItems(), definitionDocumentResolver), collectionFormat);
}
}
else if(parameter instanceof RefParameter){
String simpleRef = ((RefParameter)parameter).getSimpleRef();
type = new RefType(definitionDocumentResolver.apply(simpleRef), simpleRef);
}
return type;
}
/**
* Retrieves the default value of a parameter, or otherwise an empty String
*
* @param parameter the parameter
* @return the default value of the parameter, or otherwise an empty String
*/
public static String getDefaultValue(Parameter parameter){
Validate.notNull(parameter, "parameter must not be null!");
String defaultValue = "";
if(parameter instanceof AbstractSerializableParameter){
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
defaultValue = serializableParameter.getDefaultValue();
}
return defaultString(defaultValue);
}
/**
* Generate a default example value for parameter.
*
* @param parameter parameter
* @param markupDocBuilder doc builder
* @return a generated example for the parameter
*/
public static Object generateExample(AbstractSerializableParameter parameter, MarkupDocBuilder markupDocBuilder) {
switch (parameter.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
default:
return parameter.getType();
}
}
}

View File

@@ -1,195 +0,0 @@
/*
* Copyright 2016 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.internal.utils;
import com.google.common.base.Function;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.internal.type.*;
import io.swagger.models.properties.*;
import io.swagger.models.refs.RefFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public final class PropertyUtils {
/**
* Retrieves the type and format of a property.
*
* @param property the property
* @return the type of the property
*/
public static Type getType(Property property, Function<String, String> definitionDocumentResolver) {
Validate.notNull(property, "property must not be null");
Type type;
if (property instanceof RefProperty) {
RefProperty refProperty = (RefProperty) property;
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(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, definitionDocumentResolver));
} else if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
List<String> enums = stringProperty.getEnum();
if (CollectionUtils.isNotEmpty(enums)) {
type = new EnumType(null, enums);
} else {
type = new BasicType(property.getType());
}
} else if (property instanceof ObjectProperty) {
type = new ObjectType(null, ((ObjectProperty) property).getProperties());
} else {
if (isNotBlank(property.getFormat())) {
type = new BasicType(property.getType(), property.getFormat());
} else {
type = new BasicType(property.getType());
}
}
return type;
}
/**
* Retrieves the default value of a property, or otherwise returns an empty String.
*
* @param property the property
* @return the default value of the property, or otherwise an empty String
*/
public static String getDefaultValue(Property property) {
Validate.notNull(property, "property must not be null");
String defaultValue = "";
if (property instanceof BooleanProperty) {
BooleanProperty booleanProperty = (BooleanProperty) property;
defaultValue = Objects.toString(booleanProperty.getDefault(), "");
} else if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
defaultValue = Objects.toString(stringProperty.getDefault(), "");
} else if (property instanceof DoubleProperty) {
DoubleProperty doubleProperty = (DoubleProperty) property;
defaultValue = Objects.toString(doubleProperty.getDefault(), "");
} else if (property instanceof FloatProperty) {
FloatProperty floatProperty = (FloatProperty) property;
defaultValue = Objects.toString(floatProperty.getDefault(), "");
} else if (property instanceof IntegerProperty) {
IntegerProperty integerProperty = (IntegerProperty) property;
defaultValue = Objects.toString(integerProperty.getDefault(), "");
} else if (property instanceof LongProperty) {
LongProperty longProperty = (LongProperty) property;
defaultValue = Objects.toString(longProperty.getDefault(), "");
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
defaultValue = Objects.toString(uuidProperty.getDefault(), "");
}
return defaultValue;
}
/**
* Return example display string for the given {@code property}.
*
* @param property property
* @param markupDocBuilder doc builder
* @return property example display string
*/
public static Object getExample(boolean generateMissingExamples, Property property, MarkupDocBuilder markupDocBuilder) {
Validate.notNull(property, "property must not be null");
Object examplesValue = null;
if (property.getExample() != null) {
examplesValue = convertExample(property.getExample(), property.getType());
} else if (property instanceof MapProperty) {
Property additionalProperty = ((MapProperty) property).getAdditionalProperties();
if (additionalProperty.getExample() != null) {
examplesValue = additionalProperty.getExample();
} else if (generateMissingExamples) {
Map<String, Object> exampleMap = new HashMap<>();
exampleMap.put("string", generateExample(additionalProperty, markupDocBuilder));
examplesValue = exampleMap;
}
} else if (property instanceof ArrayProperty) {
if (generateMissingExamples) {
Property itemProperty = ((ArrayProperty) property).getItems();
List<Object> exampleArray = new ArrayList<>();
exampleArray.add(generateExample(itemProperty, markupDocBuilder));
examplesValue = exampleArray;
}
} else if (generateMissingExamples) {
examplesValue = generateExample(property, markupDocBuilder);
}
return examplesValue;
}
/**
* Generate a default example value for property.
*
* @param property property
* @param markupDocBuilder doc builder
* @return a generated example for the property
*/
public static Object generateExample(Property property, MarkupDocBuilder markupDocBuilder) {
switch (property.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
case "ref":
if (property instanceof RefProperty) {
return markupDocBuilder.copy().crossReference(((RefProperty) property).getSimpleRef()).toString();
}
default:
return property.getType();
}
}
/**
* Convert a string {@code value} to specified {@code type}.
*
* @param value value to convert
* @param type target conversion type
* @return converted value as object
*/
public static Object convertExample(String value, String type) {
if (value == null) {
return null;
}
try {
switch (type) {
case "integer":
return Integer.valueOf(value);
case "number":
return Float.valueOf(value);
case "boolean":
return Boolean.valueOf(value);
case "string":
return value;
default:
return value;
}
} catch (NumberFormatException e) {
throw new RuntimeException(String.format("Value '%s' cannot be converted to '%s'", value, type), e);
}
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright 2016 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.internal.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.github.robwin.swagger2markup.internal.model.PathOperation;
import io.swagger.models.Tag;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class TagUtils {
private static Logger LOG = LoggerFactory.getLogger(TagUtils.class);
/**
* Converts the global Tag list into a Map where the tag name is the key and the Tag the value.
*
* @param tags the List of tags
* @return the Map of tags
*/
public static Map<String, Tag> convertTagsListToMap(List<Tag> tags) {
if (tags == null) {
tags = new ArrayList<>();
}
Map<String, Tag> tagsMap = new HashMap<>();
for (Tag tag : tags) tagsMap.put(tag.getName(), tag);
return tagsMap;
}
/**
* Retrieves the optional description of a tag.
*
* @param tagsMap the Map of tags
* @param tagName the name of the tag
* @return the optional description of the tag
*/
public static Optional<String> getTagDescription(Map<String, Tag> tagsMap, String tagName) {
Tag tag = tagsMap.get(tagName);
if(tag != null){
return Optional.fromNullable(tag.getDescription());
}
return Optional.absent();
}
/**
* Groups the operations by tag. The key of the Multimap is the tag name.
* The value of the Multimap is a PathOperation
*
* @param allOperations all operations
* @param tagOrdering comparator for tags
* @param operationOrdering comparator for operations, for a given tag
* @return Operations grouped by Tag
*/
public static Multimap<String, PathOperation> groupOperationsByTag(Set<PathOperation> allOperations, Comparator<String> tagOrdering, Comparator<PathOperation> operationOrdering) {
MultimapBuilder.MultimapBuilderWithKeys<String> multimapBuilderWithKeys;
if (tagOrdering == null)
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(Ordering.<String>natural()); // FIXME as-is sorting not supported because of limitations in MultiMap::hashkeys(). Replaced with Ordering.natural()
else
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagOrdering);
Multimap<String, PathOperation> operationsGroupedByTag;
if (operationOrdering == null)
operationsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build();
else
operationsGroupedByTag = multimapBuilderWithKeys.treeSetValues(operationOrdering).build();
for (PathOperation operation : allOperations) {
List<String> tags = operation.getOperation().getTags();
Validate.notEmpty(tags, "Can't GroupBy.TAGS > Operation '%s' has not tags", operation);
for (String tag : tags) {
if (LOG.isInfoEnabled()) {
LOG.info("Added path operation '{}' to tag '{}'", operation, tag);
}
operationsGroupedByTag.put(tag, operation);
}
}
return operationsGroupedByTag;
}
}

View File

@@ -1,108 +0,0 @@
/*
* Copyright 2016 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.spi;
import com.google.common.base.Optional;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.internal.model.PathOperation;
import org.apache.commons.lang3.Validate;
/**
* A SecurityContentExtension can be used to extend the paths document.
*/
public abstract class PathsDocumentExtension extends AbstractExtension {
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
DOCUMENT_END,
OPERATION_BEGIN,
OPERATION_END
}
public static class Context extends ContentContext {
private Position position;
/**
* null if position == DOC_*
*/
private PathOperation operation;
/**
* @param position the current position
* @param docBuilder the MarkupDocBuilder
*/
public Context(Position position, MarkupDocBuilder docBuilder) {
super(docBuilder);
Validate.isTrue(position != Position.OPERATION_BEGIN && position != Position.OPERATION_END, "You must provide an operation for this position");
this.position = position;
}
/**
* @param position the current position
* @param docBuilder the MarkupDocBuilder
* @param operation the current path operation
*/
public Context(Position position, MarkupDocBuilder docBuilder, PathOperation operation) {
super(docBuilder);
Validate.notNull(operation);
this.position = position;
this.operation = operation;
}
public Position getPosition() {
return position;
}
public Optional<PathOperation> getOperation() {
return Optional.fromNullable(operation);
}
}
public PathsDocumentExtension() {
}
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 DOCUMENT_BEFORE:
case DOCUMENT_BEGIN:
case DOCUMENT_END:
levelOffset = 1;
break;
case OPERATION_BEGIN:
case OPERATION_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
if (globalContext.getConfig().getOperationsGroupedBy() == GroupBy.TAGS) {
levelOffset++;
}
return levelOffset;
}
}

View File

@@ -1,54 +0,0 @@
definitions=\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044F
json_schema=JSON \u0441\u0445\u0435\u043C\u0430
xml_schema=XML \u0441\u0445\u0435\u043C\u0430
default_column=\u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E
required_column=\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E
example_column=\u041F\u0440\u0438\u043C\u0435\u0440
schema_column=\u0421\u0445\u0435\u043C\u0430
name_column=\u0418\u043C\u044F
description_column=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435
headers_column=Headers
scopes_column=\u041E\u0431\u043B\u0430\u0441\u0442\u0438 \u043F\u0440\u0438\u043C\u0435\u043D\u0435\u043D\u0438\u044F
produces=\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442
consumes=\u041F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442
tags=\u0422\u044D\u0433\u0438
overview=\u041E\u0431\u0437\u043E\u0440
current_version=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0432\u0435\u0440\u0441\u0438\u0438
version=\u0412\u0435\u0440\u0441\u0438\u044F\:\u0020
contact_information=\u041A\u043E\u043D\u0442\u0430\u043A\u0442\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F
contact_name=\u041A\u043E\u043D\u0442\u0430\u043A\u0442\:\u0020
contact_email=Email \u043A\u043E\u043D\u0442\u0430\u043A\u0442\u0430\:\u0020
license_information=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u043B\u0438\u0446\u0435\u043D\u0446\u0438\u0438
license=\u041B\u0438\u0446\u0435\u043D\u0437\u0438\u044F\:\u0020
license_url=URL \u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0438\:\u0020
terms_of_service=\u0423\u0441\u043B\u043E\u0432\u0438\u044F \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\:\u0020
uri_scheme=\u0421\u0445\u0435\u043C\u0430 URI
host=\u0423\u0437\u0435\u043B\:\u0020
base_path=\u041E\u0441\u043D\u043E\u0432\u043D\u043E\u0439 \u043F\u0443\u0442\u044C\:\u0020
schemes=\u0421\u0445\u0435\u043C\u044B\:\u0020
security_type=\u0422\u0438\u043F\:\u0020
security_name=\u0418\u043C\u044F\:\u0020
security_in=\u0421\u043E\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044F \u0432\:\u0020
security_flow=\u041F\u043E\u0442\u043E\u043A\:\u0020
security_authorizationUrl=URL \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u0438\:\u0020
security_tokenUrl=URL \u0442\u043E\u043A\u0435\u043D\u0430\:\u0020
paths=\u041F\u0443\u0442\u0438
resources=\u041E\u0442\u0432\u0435\u0442\u044B
security=\u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u044C
response=\u041E\u0442\u0432\u0435\u0442
request=\u0417\u0430\u043F\u0440\u043E\u0441
parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B
body_parameter=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 \u0442\u0435\u043B\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u0430
responses=\u041E\u0442\u0432\u0435\u0442\u044B
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
http_code_column=HTTP \u043A\u043E\u0434
parameter=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440
unknown=Unknown
no_content=\u0411\u0435\u0437 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E
operation.deprecated=\u042D\u0442\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u0430.

View File

@@ -1,459 +0,0 @@
/*
* Copyright 2016 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;
import io.github.robwin.swagger2markup.assertions.DiffUtils;
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
import io.github.robwin.swagger2markup.internal.extensions.SchemaExtension;
import io.github.robwin.swagger2markup.internal.extensions.SpringRestDocsExtension;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import static org.assertj.core.api.BDDAssertions.assertThat;
public class AsciidocConverterTest {
private static final Logger LOG = LoggerFactory.getLogger(AsciidocConverterTest.class);
private static final String[] EXPECTED_FILES = new String[]{"definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"};
private List<String> expectedFiles;
@Before
public void setUp(){
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
}
@Test
public void testSwagger2AsciiDocConversionAsString() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
//When
String asciiDocAsString = Swagger2MarkupConverter.from(file).build()
.asString();
//Then
assertThat(asciiDocAsString).isNotEmpty();
}
@Test
public void testSwagger2AsciiDocConversion() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/default").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversion.html");
}
@Test
public void testSwagger2AsciiDocConversionFromString() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/yaml/swagger_petstore.yaml"));
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupConverter.from(swaggerJsonString).withConfig(config).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/default").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversion.html");
}
@Test
public void testSwagger2AsciiDocConversionWithSpringRestDocsExtension() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/yaml/swagger_petstore.yaml"));
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
.withExtension(new SpringRestDocsExtension(Paths.get("src/test/resources/docs/asciidoc/paths").toUri()).withDefaultSnippets())
.build();
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.withExtensionRegistry(registry)
.build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/spring_rest_docs").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversionWithSpringRestDocsExtension.html");
}
@Test
public void testSwagger2AsciiDocConversionWithExamples() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/examples").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversionWithExamples.html");
}
@Test
public void testSwagger2AsciiDocConversionWithGeneratedExamples() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withGeneratedExamples()
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/generated_examples").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversionWithGeneratedExamples.html");
}
@Test
public void testSwagger2AsciiDocWithInlineSchema() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_inlineSchema.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withInlineSchemaDepthLevel(1)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/inline_schema").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocWithInlineSchema.html");
}
@Test
public void testSwagger2AsciiDocGroupedByTags() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withPathsGroupedBy(GroupBy.TAGS)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/group_by_tags").toURI());
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocGroupedByTags.html");
}
@Test
public void testSwagger2AsciiDocGroupedByTagsWithMissingTag() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_missing_tag.json").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
try {
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withPathsGroupedBy(GroupBy.TAGS)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
// If NullPointerException was not thrown, test would fail the specified message
failBecauseExceptionWasNotThrown(NullPointerException.class);
} catch (Exception e) {
assertThat(e).hasMessage("Can't GroupBy.TAGS > Operation 'updatePet' has not tags");
}
}
@Test
public void testSwagger2AsciiDocConversionWithDefinitionDescriptions() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withDefinitionDescriptions(Paths.get("src/test/resources/docs/asciidoc/definitions"))
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
}
@Test
public void testSwagger2AsciiDocConversionDoesNotContainUriScheme() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_should_not_contain_uri_scheme.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConverter.from(file).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc"))))
.doesNotContain("=== URI scheme");
}
@Test
public void testSwagger2AsciiDocConversionContainsUriScheme() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_should_contain_uri_scheme.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConverter.from(file).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc"))))
.contains("=== URI scheme");
}
@Test
public void testSwagger2AsciiDocConversionWithSeparatedDefinitions() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withSeparatedDefinitions()
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
expectedFiles.add("definitions");
assertThat(files).hasSize(5).containsAll(expectedFiles);
Path definitionsDirectory = outputDirectory.resolve("definitions");
String[] definitions = definitionsDirectory.toFile().list();
assertThat(definitions).hasSize(5).containsAll(
asList("Category.adoc", "Order.adoc", "Pet.adoc", "Tag.adoc", "User.adoc"));
}
@Test
public void testSwagger2AsciiDocConversionWithSeparatedOperations() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withSeparatedOperations()
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.intoFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
expectedFiles.add("operations");
assertThat(files).hasSize(5).containsAll(expectedFiles);
Path pathsDirectory = outputDirectory.resolve("operations");
String[] paths = pathsDirectory.toFile().list();
assertThat(paths).hasSize(18);
}
@Test
public void testSwagger2AsciiDocConversionWithRussianOutputLanguage() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withOutputLanguage(Language.RU)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
//Then
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")), Charset.forName("UTF-8")))
.contains("== Определения");
}
@Test
public void testSwagger2AsciiDocConversionWithFrenchOutputLanguage() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withOutputLanguage(Language.FR)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.intoFolder(outputDirectory);
//Then
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc")), Charset.forName("UTF-8")))
.contains("== Sch\u00E9ma d'URI");
}
@Test
public void testSwagger2AsciiDocExtensions() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
.withExtension(new DynamicDefinitionsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")))
.withExtension(new DynamicPathsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")))
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.withExtensionRegistry(registry)
.build()
.intoFolder(outputDirectory);
//Then
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("paths.adoc")))).contains(
"Pet update request extension");
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")))).contains(
"Pet extension");
}
@Test
public void testSwagger2AsciiDocSchemaExtension() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.build();
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
.withExtension(new SchemaExtension(Paths.get("src/test/resources/docs/asciidoc/extensions").toUri()))
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.withExtensionRegistry(registry)
.build()
.intoFolder(outputDirectory);
//Then
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")))).contains(
"=== Pet");
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")))).contains(
"==== XML Schema");
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright 2016 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;
import io.swagger.models.Swagger;
import org.junit.Test;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import static org.assertj.core.api.Assertions.assertThat;
public class GeneralConverterTest {
@Test
public void testConfigDefaultPaths() throws URISyntaxException {
//Given
Path file = Paths.get(GeneralConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withDefinitionDescriptions()
.withOperationDescriptions()
.build();
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(file)
.withConfig(config)
.build();
//Then
URI baseUri = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriParent(converter.getContext().getSwaggerLocation());
assertThat(converter.getContext().getConfig().getDefinitionDescriptionsUri()).isEqualTo(baseUri);
assertThat(converter.getContext().getConfig().getOperationDescriptionsUri()).isEqualTo(baseUri);
}
@Test
public void testConfigDefaultPathsWithUri() throws MalformedURLException {
//Given
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withDefinitionDescriptions()
.withOperationDescriptions()
.build();
Swagger2MarkupConverter converterBuilder = Swagger2MarkupConverter.from(URI.create("http://petstore.swagger.io/v2/swagger.json").toURL())
.withConfig(config)
.build();
//Then
assertThat(converterBuilder.getContext().getConfig().getDefinitionDescriptionsUri()).isNull();
assertThat(converterBuilder.getContext().getConfig().getOperationDescriptionsUri()).isNull();
}
@Test
public void testDefaultPathsWithoutFile() {
//Given
//When
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
.withDefinitionDescriptions()
.build();
//Then
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(new Swagger())
.withConfig(config)
.build();
assertThat(converter.getContext().getConfig().isDefinitionDescriptionsEnabled()).isFalse();
}
}

View File

@@ -1,88 +0,0 @@
/*
*
* Copyright 2016 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.assertions;
import com.sksamuel.diffpatch.DiffMatchPatch;
import org.apache.commons.io.IOUtils;
import org.assertj.core.api.AbstractAssert;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedList;
import static org.assertj.core.api.Assertions.assertThat;
public class DiffAssert extends AbstractAssert<DiffAssert, Path>{
public DiffAssert(Path actual) {
super(actual, DiffAssert.class);
}
/**
* Verifies that the content of the actual File is equal to the given one.
*
* @param expected the given value to compare the actual value to.
* @param reportPath the path to the report which should be generated if the files differ.
* @return {@code this} assertion object.
* @throws AssertionError if the actual value is not equal to the given one or if the actual value is {@code null}..
*/
public DiffAssert isEqualTo(Path expected, Path reportPath) {
LinkedList<DiffMatchPatch.Diff> diffs = diff(actual, expected);
boolean allDiffsAreEqual = assertThatAllDiffsAreEqual(diffs);
if(!allDiffsAreEqual){
writeHtmlReport(reportPath, diffs);
}
assertThat(allDiffsAreEqual).as("The content of the following files differ. Actual: %s, Expected %s. Check the HTML report for more details: %s", actual.toAbsolutePath(), expected.toAbsolutePath(), reportPath.toAbsolutePath()).isTrue();
return myself;
}
public boolean assertThatAllDiffsAreEqual(LinkedList<DiffMatchPatch.Diff> diffs){
for(DiffMatchPatch.Diff diff : diffs){
if(diff.operation == DiffMatchPatch.Operation.DELETE || diff.operation == DiffMatchPatch.Operation.INSERT){
return false;
}
}
return true;
}
private static LinkedList<DiffMatchPatch.Diff> diff(Path actual, Path expected){
DiffMatchPatch differ = new DiffMatchPatch();
try {
return differ.diff_main(IOUtils.toString(expected.toUri()), IOUtils.toString(actual.toUri()), false);
} catch (IOException e) {
throw new RuntimeException("Failed to diff files.", e);
}
}
private static void writeHtmlReport(Path reportPath, LinkedList<DiffMatchPatch.Diff> diffs){
DiffMatchPatch differ = new DiffMatchPatch();
try {
Files.createDirectories(reportPath.getParent());
try (BufferedWriter writer = Files.newBufferedWriter(reportPath, Charset.forName("UTF-8"))) {
writer.write(differ.diff_prettyHtml(diffs));
}
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to write report %s", reportPath.toAbsolutePath()), e);
}
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2016 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.spi;
import io.github.robwin.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
import io.swagger.models.Swagger;
import org.junit.Test;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class Swagger2MarkupExtensionRegistryTest {
@Test
public void testRegistering() {
Swagger2MarkupExtensionRegistry.Builder registryBuilder = Swagger2MarkupExtensionRegistry.ofDefaults();
registryBuilder.withExtension(new MySwaggerModelExtension());
registryBuilder.withExtension(new DynamicDefinitionsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")));
registryBuilder.withExtension(new DynamicPathsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")));
try {
registryBuilder.withExtension(new AbstractExtension() {
});
fail("No IllegalArgumentException thrown");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage()).isEqualTo("Provided extension class does not extend any of the supported extension points");
}
}
@Test
public void testListing() {
Extension ext1 = new MySwaggerModelExtension();
Extension ext2 = new MySwaggerModelExtension();
Extension ext3 = new SwaggerModelExtension() {
public void apply(Swagger swagger) {
}
};
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofDefaults()
.withExtension(ext2)
.withExtension(ext3)
.withExtension(ext1)
.build();
List<Extension> extensions = registry.getExtensions(Extension.class);
assertThat(extensions.size()).isEqualTo(7);
assertThat(extensions).contains(ext1, ext2, ext3);
assertThat(registry.getExtensions(SwaggerModelExtension.class)).isEqualTo(Arrays.asList(ext2, ext3, ext1));
}
}

View File

@@ -1,5 +0,0 @@
This is a hand-written description.
AsciiDoc is better suited for descriptions than:
* JavaDoc
* Annotations

View File

@@ -1 +0,0 @@
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*

View File

@@ -1 +0,0 @@
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*

View File

@@ -1,3 +0,0 @@
== Pet extension
This is an extension for this definition

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="" ?>
<xsd>This is an XML Schema</xsd>

View File

@@ -1,11 +0,0 @@
== Pet update request extension
----
Request
----
== Pet update response extension
----
Response
----

View File

@@ -1,2 +0,0 @@
This is a hand-written description.
AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*

View File

@@ -1,5 +0,0 @@
This is a hand-written description.
AsciiDoc is better suited for descriptions than:
* JavaDoc
* Annotations

View File

@@ -1,5 +0,0 @@
This is a hand-written description.
AsciiDoc is better suited for descriptions than:
* JavaDoc
* Annotations

View File

@@ -1 +0,0 @@
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*

View File

@@ -1 +0,0 @@
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*

View File

@@ -1,3 +0,0 @@
## Pet extension
This is an extension for this definition

View File

@@ -1,11 +0,0 @@
## Pet update request extension
```
Request
```
## Pet update response extension
```
Response
```

View File

@@ -1 +0,0 @@
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*

View File

@@ -1,5 +0,0 @@
This is a hand-written description.
It is better suited for adding descriptions than:
* JavaDoc
* Annotations

View File

@@ -1,69 +0,0 @@
[[_definitions]]
== Definitions
=== Category
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== Order
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|complete||false|boolean||
|id||false|integer(int64)||
|petId||false|integer(int64)||
|quantity||false|integer(int32)||
|shipDate||false|string(date-time)||
|status|Order Status|false|string||
|===
=== Pet
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|category||false|<<_category,Category>>||
|id||false|integer(int64)||
|name||true|string||"doggie"
|photoUrls||true|string array||
|status|pet status in the store|false|string||
|tags||false|<<_tag,Tag>> array||
|===
=== Tag
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== User
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|email||false|string||
|firstName||false|string||
|id||false|integer(int64)||
|lastName||false|string||
|password||false|string||
|phone||false|string||
|userStatus|User Status|false|integer(int32)||
|username||false|string||
|===

View File

@@ -1,36 +0,0 @@
= Swagger Petstore
[[_overview]]
== Overview
This is a sample server Petstore server.
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
Version : 1.0.0
=== Contact information
Contact : apiteam@swagger.io
=== License information
License : Apache 2.0
License URL : http://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : http://helloreverb.com/terms/
=== URI scheme
Host : petstore.swagger.io
BasePath : /v2
Schemes : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -1,993 +0,0 @@
[[_paths]]
== Paths
=== Add a new pet to the store
----
POST /pets
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
==== Responses
===== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Invalid input|No Content
|===
==== Consumes
* application/json
* application/xml
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Update an existing pet
----
PUT /pets
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Pet not found|No Content
|===
===== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Validation exception|No Content
|===
==== Consumes
* application/json
* application/xml
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Finds Pets by status
----
GET /pets/findByStatus
----
==== Description
[%hardbreaks]
Multiple status values can be provided with comma seperated strings
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|status|Status values that need to be considered for filter|false|multi string array|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>> array
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid status value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Finds Pets by tags
----
GET /pets/findByTags
----
==== Description
[%hardbreaks]
Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|tags|Tags to filter by|false|multi string array|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>> array
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid tag value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Updates a pet in the store with form data
----
POST /pets/{petId}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be updated|true|string|
|FormData|name|Updated name of the pet|true|string|
|FormData|status|Updated status of the pet|true|string|
|===
==== Responses
===== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Invalid input|No Content
|===
==== Consumes
* application/x-www-form-urlencoded
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Find pet by ID
----
GET /pets/{petId}
----
==== Description
[%hardbreaks]
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be fetched|true|integer(int64)|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Pet not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|apiKey|<<_api_key,api_key>>|
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Deletes a pet
----
DELETE /pets/{petId}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Header|api_key||true|string|
|Path|petId|Pet id to delete|true|integer(int64)|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid pet value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Place an order for a pet
----
POST /stores/order
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|order placed for purchasing the pet|false|<<_order,Order>>|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_order,Order>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid Order|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Find purchase order by ID
----
GET /stores/order/{orderId}
----
==== Description
[%hardbreaks]
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of pet that needs to be fetched|true|string|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_order,Order>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Order not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Delete purchase order by ID
----
DELETE /stores/order/{orderId}
----
==== Description
[%hardbreaks]
For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of the order that needs to be deleted|true|string|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Order not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Create user
----
POST /users
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Created user object|false|<<_user,User>>|
|===
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Creates list of users with given input array
----
POST /users/createWithArray
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Creates list of users with given input array
----
POST /users/createWithList
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Logs user into the system
----
GET /users/login
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|password|The password for login in clear text|false|string|
|Query|username|The user name for login|false|string|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|string
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username/password supplied|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Logs out current logged in user session
----
GET /users/logout
----
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Get user by user name
----
GET /users/{username}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be fetched. Use user1 for testing.|true|string|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_user,User>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Updated user
----
PUT /users/{username}
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|name that need to be deleted|true|string|
|Body|body|Updated user object|false|<<_user,User>>|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid user supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Delete user
----
DELETE /users/{username}
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be deleted|true|string|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user

View File

@@ -1,23 +0,0 @@
[[_security]]
== Security
=== api_key
Type : apiKey
Name : api_key
In : HEADER
=== petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.io/api/oauth/dialog
[options="header", cols="1,6"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===

View File

@@ -1,84 +0,0 @@
[[_definitions]]
== Definitions
=== Category
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||123
|name||false|string||"Canines"
|===
=== Identified
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|===
=== Order
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|complete||false|boolean||
|id||false|integer(int64)||77
|petId||false|integer(int64)||
|quantity||false|integer(int32)||
|shipDate||false|string(date-time)||
|status|Order Status|false|string||"DONE"
|===
=== Pet
[%hardbreaks]
Test description
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|category||false|<<_category,Category>>||
|id||false|integer(int64)||
|name||true|string||"doggie"
|nicknames||false|object||
|photoUrls||true|string array||
|status|pet status in the store|false|string||
|tags||false|<<_tag,Tag>> array||
|weight|the weight of the pet|false|number||
|===
=== Tag
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== User
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|email||false|string||
|firstName||false|string||
|id||false|integer(int64)||
|lastName||false|string||
|password||false|string||
|phone||false|string||
|pictures||false|string(byte) array||
|userStatus|User Status|false|integer(int32)||
|username||false|string||
|===

View File

@@ -1,36 +0,0 @@
= Swagger Petstore API
[[_overview]]
== Overview
This is a sample server Petstore server.
[Learn about Swagger](http://swagger.wordnik.com) or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
Version : 1.0.0
=== Contact information
Contact : apiteam@wordnik.com
=== License information
License : Apache 2.0
License URL : http://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : http://helloreverb.com/terms/
=== URI scheme
Host : petstore.swagger.wordnik.com
BasePath : /v2
Schemes : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -1,984 +0,0 @@
[[_paths]]
== Paths
=== Add a new pet to the store
----
POST /pets
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
==== Responses
===== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Invalid input|No Content
|===
==== Consumes
* application/json
* application/xml
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Example HTTP response
==== Response 405
----
{
"application/json" : {
"name" : "Puma",
"type" : 22,
"color" : "Black",
"gender" : "Female",
"breed" : "Mixed"
}
}
----
=== Update an existing pet
----
PUT /pets
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Pet not found|No Content
|===
===== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Validation exception|No Content
|===
==== Consumes
* application/json
* application/xml
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Finds Pets by status
----
GET /pets/findByStatus
----
==== Description
[%hardbreaks]
Multiple status values can be provided with comma seperated strings
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|status|Status values that need to be considered for filter|false|multi string array|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>> array
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid status value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Finds Pets by tags
----
GET /pets/findByTags
----
==== Description
[%hardbreaks]
Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|tags|Tags to filter by|false|multi string array|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>> array
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid tag value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Updates a pet in the store with form data
----
POST /pets/{petId}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be updated|true|string|
|FormData|name|Updated name of the pet|true|string|
|FormData|status|Updated status of the pet|true|string|
|===
==== Responses
===== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Invalid input|No Content
|===
==== Consumes
* application/x-www-form-urlencoded
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Find pet by ID
----
GET /pets/{petId}
----
==== Description
[%hardbreaks]
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of the pet|true|integer(int64)|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>>
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Pet not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|apiKey|<<_api_key,api_key>>|
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Deletes a pet
----
DELETE /pets/{petId}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Header|api_key||true|string|
|Path|petId|Pet id to delete|true|integer(int64)|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid pet value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Place an order for a pet
----
POST /stores/order
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|order placed for purchasing the pet|false|<<_order,Order>>|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_order,Order>>
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid Order|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
==== Example HTTP request
==== Request body
----
{
"id" : 99,
"petId" : 122,
"quantity" : 2,
"shipDate" : "2016-02-22T23:02:05Z",
"status" : "PENDING",
"complete" : true
}
----
==== Example HTTP response
==== Response 200
----
{
"id" : 99,
"petId" : 122,
"quantity" : 2,
"shipDate" : "2016-02-22T23:02:05Z",
"status" : "PENDING",
"complete" : true
}
----
=== Find purchase order by ID
----
GET /stores/order/{orderId}
----
==== Description
[%hardbreaks]
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of pet that needs to be fetched|true|string|
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_order,Order>>
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Order not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
==== Example HTTP response
==== Response 200
----
{
"id" : 99,
"petId" : 122,
"quantity" : 2,
"shipDate" : "2016-02-22T23:02:05Z",
"status" : "PENDING",
"complete" : true
}
----
=== Delete purchase order by ID
----
DELETE /stores/order/{orderId}
----
==== Description
[%hardbreaks]
For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of the order that needs to be deleted|true|string|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Order not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Create user
----
POST /users
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Created user object|false|<<_user,User>>|
|===
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Creates list of users with given input array
----
POST /users/createWithArray
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Creates list of users with given input array
----
POST /users/createWithList
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Logs user into the system
----
GET /users/login
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|password|The password for login in clear text|false|string|testPassword
|Query|username|The user name for login|false|string|testUser
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|string
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username/password supplied|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Logs out current logged in user session
----
GET /users/logout
----
==== Responses
===== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Get user by user name
----
GET /users/{username}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be fetched. Use user1 for testing.|true|string|testUser
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_user,User>>
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Updated user
----
PUT /users/{username}
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|name that need to be deleted|true|string|
|Body|body|Updated user object|false|<<_user,User>>|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid user supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Delete user
----
DELETE /users/{username}
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be deleted|true|string|
|===
==== Responses
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username supplied|No Content
|===
===== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user

View File

@@ -1,23 +0,0 @@
[[_security]]
== Security
=== api_key
Type : apiKey
Name : api_key
In : HEADER
=== petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.wordnik.com/api/oauth/dialog
[options="header", cols="1,6"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===

View File

@@ -1,86 +0,0 @@
[[_definitions]]
== Definitions
=== Category
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||123
|name||false|string||"Canines"
|===
=== Identified
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||0
|===
=== Order
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|complete||false|boolean||true
|id||false|integer(int64)||77
|petId||false|integer(int64)||0
|quantity||false|integer(int32)||0
|shipDate||false|string(date-time)||"string"
|status|Order Status|false|string||"DONE"
|===
=== Pet
[%hardbreaks]
Test description
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|category||false|<<_category,Category>>||"<<_category>>"
|id||false|integer(int64)||0
|name||true|string||"doggie"
|nicknames||false|object||{
"string" : "string"
}
|photoUrls||true|string array||[ "string" ]
|status|pet status in the store|false|string||"string"
|tags||false|<<_tag,Tag>> array||[ "<<_tag>>" ]
|weight|the weight of the pet|false|number||0.0
|===
=== Tag
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||0
|name||false|string||"string"
|===
=== User
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|email||false|string||"string"
|firstName||false|string||"string"
|id||false|integer(int64)||0
|lastName||false|string||"string"
|password||false|string||"string"
|phone||false|string||"string"
|pictures||false|string(byte) array||[ "string" ]
|userStatus|User Status|false|integer(int32)||0
|username||false|string||"string"
|===

View File

@@ -1,36 +0,0 @@
= Swagger Petstore API
[[_overview]]
== Overview
This is a sample server Petstore server.
[Learn about Swagger](http://swagger.wordnik.com) or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
Version : 1.0.0
=== Contact information
Contact : apiteam@wordnik.com
=== License information
License : Apache 2.0
License URL : http://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : http://helloreverb.com/terms/
=== URI scheme
Host : petstore.swagger.wordnik.com
BasePath : /v2
Schemes : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -1,23 +0,0 @@
[[_security]]
== Security
=== api_key
Type : apiKey
Name : api_key
In : HEADER
=== petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.wordnik.com/api/oauth/dialog
[options="header", cols="1,6"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===

View File

@@ -1,69 +0,0 @@
[[_definitions]]
== Definitions
=== Category
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== Order
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|complete||false|boolean||
|id||false|integer(int64)||
|petId||false|integer(int64)||
|quantity||false|integer(int32)||
|shipDate||false|string(date-time)||
|status|Order Status|false|string||
|===
=== Pet
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|category||false|<<_category,Category>>||
|id||false|integer(int64)||
|name||true|string||"doggie"
|photoUrls||true|string array||
|status|pet status in the store|false|string||
|tags||false|<<_tag,Tag>> array||
|===
=== Tag
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== User
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|email||false|string||
|firstName||false|string||
|id||false|integer(int64)||
|lastName||false|string||
|password||false|string||
|phone||false|string||
|userStatus|User Status|false|integer(int32)||
|username||false|string||
|===

View File

@@ -1,36 +0,0 @@
= Swagger Petstore
[[_overview]]
== Overview
This is a sample server Petstore server.
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
Version : 1.0.0
=== Contact information
Contact : apiteam@swagger.io
=== License information
License : Apache 2.0
License URL : http://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : http://helloreverb.com/terms/
=== URI scheme
Host : petstore.swagger.io
BasePath : /v2
Schemes : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -1,918 +0,0 @@
[[_paths]]
== Resources
=== Pet
[%hardbreaks]
Pet resource
==== Add a new pet to the store
----
POST /pets
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
===== Responses
====== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Invalid input|No Content
|===
===== Consumes
* application/json
* application/xml
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Update an existing pet
----
PUT /pets
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
===== Responses
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Pet not found|No Content
|===
====== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Validation exception|No Content
|===
===== Consumes
* application/json
* application/xml
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Finds Pets by status
----
GET /pets/findByStatus
----
===== Description
[%hardbreaks]
Multiple status values can be provided with comma seperated strings
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|status|Status values that need to be considered for filter|false|multi string array|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>> array
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid status value|No Content
|===
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Finds Pets by tags
----
GET /pets/findByTags
----
===== Description
[%hardbreaks]
Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|tags|Tags to filter by|false|multi string array|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>> array
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid tag value|No Content
|===
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Updates a pet in the store with form data
----
POST /pets/{petId}
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be updated|true|string|
|FormData|name|Updated name of the pet|true|string|
|FormData|status|Updated status of the pet|true|string|
|===
===== Responses
====== HTTP Code 405
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|405|Invalid input|No Content
|===
===== Consumes
* application/x-www-form-urlencoded
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Find pet by ID
----
GET /pets/{petId}
----
===== Description
[%hardbreaks]
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be fetched|true|integer(int64)|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_pet,Pet>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Pet not found|No Content
|===
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|apiKey|<<_api_key,api_key>>|
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
==== Deletes a pet
----
DELETE /pets/{petId}
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Header|api_key||true|string|
|Path|petId|Pet id to delete|true|integer(int64)|
|===
===== Responses
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid pet value|No Content
|===
===== Produces
* application/json
* application/xml
===== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Store
[%hardbreaks]
Store resource
==== Place an order for a pet
----
POST /stores/order
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|order placed for purchasing the pet|false|<<_order,Order>>|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_order,Order>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid Order|No Content
|===
===== Produces
* application/json
* application/xml
==== Find purchase order by ID
----
GET /stores/order/{orderId}
----
===== Description
[%hardbreaks]
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of pet that needs to be fetched|true|string|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_order,Order>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Order not found|No Content
|===
===== Produces
* application/json
* application/xml
==== Delete purchase order by ID
----
DELETE /stores/order/{orderId}
----
===== Description
[%hardbreaks]
For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of the order that needs to be deleted|true|string|
|===
===== Responses
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid ID supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|Order not found|No Content
|===
===== Produces
* application/json
* application/xml
=== User
[%hardbreaks]
User resource
==== Create user
----
POST /users
----
===== Description
[%hardbreaks]
This can only be done by the logged in user.
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Created user object|false|<<_user,User>>|
|===
===== Responses
====== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
===== Produces
* application/json
* application/xml
==== Creates list of users with given input array
----
POST /users/createWithArray
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
===== Responses
====== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
===== Produces
* application/json
* application/xml
==== Creates list of users with given input array
----
POST /users/createWithList
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
===== Responses
====== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
===== Produces
* application/json
* application/xml
==== Logs user into the system
----
GET /users/login
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|password|The password for login in clear text|false|string|
|Query|username|The user name for login|false|string|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|string
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username/password supplied|No Content
|===
===== Produces
* application/json
* application/xml
==== Logs out current logged in user session
----
GET /users/logout
----
===== Responses
====== HTTP Code default
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|default|successful operation|No Content
|===
===== Produces
* application/json
* application/xml
==== Get user by user name
----
GET /users/{username}
----
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be fetched. Use user1 for testing.|true|string|
|===
===== Responses
====== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|successful operation|<<_user,User>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|successful operation|integer|
|X-Rate-Limit-Remaining|successful operation|integer|
|X-Rate-Limit-Reset|successful operation|integer|
|===
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
===== Produces
* application/json
* application/xml
==== Updated user
----
PUT /users/{username}
----
===== Description
[%hardbreaks]
This can only be done by the logged in user.
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|name that need to be deleted|true|string|
|Body|body|Updated user object|false|<<_user,User>>|
|===
===== Responses
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid user supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
===== Produces
* application/json
* application/xml
==== Delete user
----
DELETE /users/{username}
----
===== Description
[%hardbreaks]
This can only be done by the logged in user.
===== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be deleted|true|string|
|===
===== Responses
====== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Invalid username supplied|No Content
|===
====== HTTP Code 404
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|404|User not found|No Content
|===
===== Produces
* application/json
* application/xml

View File

@@ -1,23 +0,0 @@
[[_security]]
== Security
=== api_key
Type : apiKey
Name : api_key
In : HEADER
=== petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.io/api/oauth/dialog
[options="header", cols="1,6"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===

View File

@@ -1,62 +0,0 @@
[[_definitions]]
== Definitions
=== Error
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|error-code|Error code|false|integer||
|message|Error message|false|string||
|===
=== ExternalLocation
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|Place|Place|false|string||
|===
=== InlineDepthSchema
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|Loop||false|<<_inlinedepthschema_loop,Loop>>||
|===
[[_inlinedepthschema_loop]]
*Loop*
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|p1|Description p1|false|string||
|p2|Description p2|false|<<_inlinedepthschema_p2,p2>>||
|===
[[_inlinedepthschema_p2]]
*p2*
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|p2-1|Description p2-1|false|string||
|p2-2|Description p2-2|false|object||
|===
=== Location
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|Place|Place|false|string||
|===

View File

@@ -1,25 +0,0 @@
= API
[[_overview]]
== Overview
Service API
=== Version information
Version : 2.18
=== URI scheme
Host : service.host.com
Schemes : HTTPS
=== Consumes
* application/json
=== Produces
* application/json

View File

@@ -1,93 +0,0 @@
[[_paths]]
== Paths
=== LaunchCommand
----
POST /LaunchCommand
----
==== Description
[%hardbreaks]
Dummy description
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|Option|An optional option|false|string|
|Query|Version|The API version|false|string|
|Body|LaunchCommandRequest|Launch something new|false|<<_launchcommand_post_launchcommandrequest,LaunchCommandRequest>>|
|===
[[_launchcommand_post_launchcommandrequest]]
*LaunchCommandRequest*
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|Command|Dummy description|true|<<_launchcommand_post_command,Command>>||
|Location|Dummy description|false|<<_location,Location>>||
|Options|Dummy description|false|string||
|===
[[_launchcommand_post_command]]
*Command*
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|args|Command arguments|false|string||
|path|Command path|false|string||
|===
==== Responses
===== HTTP Code 200
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|200|Result|<<_launchcommand_post_response_200,Response 200>>
|===
*Headers*
[options="header", cols=".^1h,.^3,.^1,.^1"]
|===
|Name|Description|Schema|Default
|X-Rate-Limit-Limit|Result|integer|
|X-Rate-Limit-Remaining|Result|integer|
|X-Rate-Limit-Reset|Result|integer|
|===
===== HTTP Code 400
[options="header", cols=".^1h,.^3,.^1"]
|===
|HTTP Code|Description|Schema
|400|Error|<<_error,Error>>
|===
[[_launchcommand_post_response_200]]
*Response 200*
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|Location|<description>|false|<<_location,Location>>||
|ReservationId|<description>|false|string||
|===
==== Tags
* All

View File

@@ -1,69 +0,0 @@
[[_definitions]]
== Definitions
=== Category
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== Order
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|complete||false|boolean||
|id||false|integer(int64)||
|petId||false|integer(int64)||
|quantity||false|integer(int32)||
|shipDate||false|string(date-time)||
|status|Order Status|false|string||
|===
=== Pet
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|category||false|<<_category,Category>>||
|id||false|integer(int64)||
|name||true|string||"doggie"
|photoUrls||true|string array||
|status|pet status in the store|false|string||
|tags||false|<<_tag,Tag>> array||
|===
=== Tag
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||
|name||false|string||
|===
=== User
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|email||false|string||
|firstName||false|string||
|id||false|integer(int64)||
|lastName||false|string||
|password||false|string||
|phone||false|string||
|userStatus|User Status|false|integer(int32)||
|username||false|string||
|===

View File

@@ -1,36 +0,0 @@
= Swagger Petstore
[[_overview]]
== Overview
This is a sample server Petstore server.
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
Version : 1.0.0
=== Contact information
Contact : apiteam@swagger.io
=== License information
License : Apache 2.0
License URL : http://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : http://helloreverb.com/terms/
=== URI scheme
Host : petstore.swagger.io
BasePath : /v2
Schemes : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -1,23 +0,0 @@
[[_security]]
== Security
=== api_key
Type : apiKey
Name : api_key
In : HEADER
=== petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.io/api/oauth/dialog
[options="header", cols="1,6"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===

View File

@@ -1,59 +0,0 @@
<a name="definitions"></a>
## Definitions
### Category
|Name|Description|Required|Schema|Default|Example|
|---|---|---|---|---|---|
|id||false|integer(int64)|||
|name||false|string|||
### Order
|Name|Description|Required|Schema|Default|Example|
|---|---|---|---|---|---|
|complete||false|boolean|||
|id||false|integer(int64)|||
|petId||false|integer(int64)|||
|quantity||false|integer(int32)|||
|shipDate||false|string(date-time)|||
|status|Order Status|false|string|||
### Pet
|Name|Description|Required|Schema|Default|Example|
|---|---|---|---|---|---|
|category||false|[Category](#category)|||
|id||false|integer(int64)|||
|name||true|string||"doggie"|
|photoUrls||true|string array|||
|status|pet status in the store|false|string|||
|tags||false|[Tag](#tag) array|||
### Tag
|Name|Description|Required|Schema|Default|Example|
|---|---|---|---|---|---|
|id||false|integer(int64)|||
|name||false|string|||
### User
|Name|Description|Required|Schema|Default|Example|
|---|---|---|---|---|---|
|email||false|string|||
|firstName||false|string|||
|id||false|integer(int64)|||
|lastName||false|string|||
|password||false|string|||
|phone||false|string|||
|userStatus|User Status|false|integer(int32)|||
|username||false|string|||

View File

@@ -1,857 +0,0 @@
<a name="paths"></a>
## Paths
### Add a new pet to the store
```
POST /pets
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Body|body|Pet object that needs to be added to the store|false|[Pet](#pet)||
#### Responses
##### HTTP Code 405
|HTTP Code|Description|Schema|
|---|---|---|
|405|Invalid input|No Content|
#### Consumes
* application/json
* application/xml
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Update an existing pet
```
PUT /pets
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Body|body|Pet object that needs to be added to the store|false|[Pet](#pet)||
#### Responses
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid ID supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|Pet not found|No Content|
##### HTTP Code 405
|HTTP Code|Description|Schema|
|---|---|---|
|405|Validation exception|No Content|
#### Consumes
* application/json
* application/xml
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Finds Pets by status
```
GET /pets/findByStatus
```
#### Description
Multiple status values can be provided with comma seperated strings
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Query|status|Status values that need to be considered for filter|false|multi string array||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|[Pet](#pet) array|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid status value|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Finds Pets by tags
```
GET /pets/findByTags
```
#### Description
Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Query|tags|Tags to filter by|false|multi string array||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|[Pet](#pet) array|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid tag value|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Updates a pet in the store with form data
```
POST /pets/{petId}
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|petId|ID of pet that needs to be updated|true|string||
|FormData|name|Updated name of the pet|true|string||
|FormData|status|Updated status of the pet|true|string||
#### Responses
##### HTTP Code 405
|HTTP Code|Description|Schema|
|---|---|---|
|405|Invalid input|No Content|
#### Consumes
* application/x-www-form-urlencoded
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Find pet by ID
```
GET /pets/{petId}
```
#### Description
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|petId|ID of pet that needs to be fetched|true|integer(int64)||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|[Pet](#pet)|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid ID supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|Pet not found|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|apiKey|[api_key](#api_key)||
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Deletes a pet
```
DELETE /pets/{petId}
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Header|api_key||true|string||
|Path|petId|Pet id to delete|true|integer(int64)||
#### Responses
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid pet value|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* pet
#### Security
|Type|Name|Scopes|
|---|---|---|
|oauth2|[petstore_auth](#petstore_auth)|write_pets,read_pets|
### Place an order for a pet
```
POST /stores/order
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Body|body|order placed for purchasing the pet|false|[Order](#order)||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|[Order](#order)|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid Order|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* store
### Find purchase order by ID
```
GET /stores/order/{orderId}
```
#### Description
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|orderId|ID of pet that needs to be fetched|true|string||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|[Order](#order)|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid ID supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|Order not found|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* store
### Delete purchase order by ID
```
DELETE /stores/order/{orderId}
```
#### Description
For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|orderId|ID of the order that needs to be deleted|true|string||
#### Responses
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid ID supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|Order not found|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* store
### Create user
```
POST /users
```
#### Description
This can only be done by the logged in user.
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Body|body|Created user object|false|[User](#user)||
#### Responses
##### HTTP Code default
|HTTP Code|Description|Schema|
|---|---|---|
|default|successful operation|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Creates list of users with given input array
```
POST /users/createWithArray
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Body|body|List of user object|false|[User](#user) array||
#### Responses
##### HTTP Code default
|HTTP Code|Description|Schema|
|---|---|---|
|default|successful operation|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Creates list of users with given input array
```
POST /users/createWithList
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Body|body|List of user object|false|[User](#user) array||
#### Responses
##### HTTP Code default
|HTTP Code|Description|Schema|
|---|---|---|
|default|successful operation|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Logs user into the system
```
GET /users/login
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Query|password|The password for login in clear text|false|string||
|Query|username|The user name for login|false|string||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|string|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid username/password supplied|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Logs out current logged in user session
```
GET /users/logout
```
#### Responses
##### HTTP Code default
|HTTP Code|Description|Schema|
|---|---|---|
|default|successful operation|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Get user by user name
```
GET /users/{username}
```
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|username|The name that needs to be fetched. Use user1 for testing.|true|string||
#### Responses
##### HTTP Code 200
|HTTP Code|Description|Schema|
|---|---|---|
|200|successful operation|[User](#user)|
**Headers**
|Name|Description|Schema|Default|
|---|---|---|---|
|X-Rate-Limit-Limit|successful operation|integer||
|X-Rate-Limit-Remaining|successful operation|integer||
|X-Rate-Limit-Reset|successful operation|integer||
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid username supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|User not found|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Updated user
```
PUT /users/{username}
```
#### Description
This can only be done by the logged in user.
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|username|name that need to be deleted|true|string||
|Body|body|Updated user object|false|[User](#user)||
#### Responses
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid user supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|User not found|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user
### Delete user
```
DELETE /users/{username}
```
#### Description
This can only be done by the logged in user.
#### Parameters
|Type|Name|Description|Required|Schema|Default|
|---|---|---|---|---|---|
|Path|username|The name that needs to be deleted|true|string||
#### Responses
##### HTTP Code 400
|HTTP Code|Description|Schema|
|---|---|---|
|400|Invalid username supplied|No Content|
##### HTTP Code 404
|HTTP Code|Description|Schema|
|---|---|---|
|404|User not found|No Content|
#### Produces
* application/json
* application/xml
#### Tags
* user

View File

@@ -1,21 +0,0 @@
<a name="security"></a>
## Security
### api_key
Type : apiKey
Name : api_key
In : HEADER
### petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.io/api/oauth/dialog
|Name|Description|
|---|---|
|write_pets|modify pets in your account|
|read_pets|read your pets|

View File

@@ -1,54 +0,0 @@
{
"apiVersion" : "0.0.1-SNAPSHOT",
"swaggerVersion" : "1.2",
"basePath" : "",
"resourcePath" : "/resource/x/v2",
"apis" : [ {
"path" : "/resource/x/v2",
"operations" : [ {
"method" : "POST",
"nickname" : "createX",
"type" : "string",
"parameters" : [ {
"type": "string",
"description" : "The x in JSON format",
"paramType" : "body",
"name" : "body",
"required" : true
} ],
"summary" : "Creates a x x.",
"notes" : "If id already exists, the x is updated.",
"responseMessages" : [ {
"code" : 200,
"message" : "ok"
}, {
"code" : 500,
"message" : "error"
} ],
"consumes" : [ "application/json" ]
} ]
}, {
"path" : "/resource/x/v2/{id}",
"operations" : [ {
"method" : "GET",
"nickname" : "getX",
"type" : "string",
"parameters" : [ {
"type" : "integer",
"description" : "A valid x x UUID",
"paramType" : "path",
"name" : "id",
"required" : true
} ],
"summary" : "Gets the x x with the specified id.",
"responseMessages" : [ {
"code" : 200,
"message" : "ok"
}, {
"code" : 404,
"message" : "not found"
} ],
"produces" : [ "application/json" ]
} ]
} ]
}

View File

@@ -1,883 +0,0 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server Petstore server.\n\n[Learn about Swagger](http://swagger.wordnik.com) or join the IRC channel `#swagger` on irc.freenode.net.\n\nFor this sample, you can use the api key `special-key` to test the authorization filters\n",
"version": "1.0.0",
"title": "Swagger Petstore API",
"termsOfService": "http://helloreverb.com/terms/",
"contact": {
"name": "apiteam@wordnik.com"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"host": "petstore.swagger.wordnik.com",
"basePath": "/v2",
"schemes": [
"http"
],
"tags": [
{
"name": "pet",
"description": "Pet resource"
},
{
"name": "store",
"description": "Store resource"
},
{
"name": "user",
"description": "User resource"
}
],
"paths": {
"/pets": {
"post": {
"tags": [
"pet"
],
"summary": "Add a new pet to the store",
"description": "",
"operationId": "addPet",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": false,
"schema": {
"$ref": "#/definitions/Pet"
}
}
],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
},
"put": {
"summary": "Update an existing pet",
"description": "",
"operationId": "updatePet",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": false,
"schema": {
"$ref": "#/definitions/Pet"
}
}
],
"responses": {
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Pet not found"
},
"405": {
"description": "Validation exception"
}
},
"security": [
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
}
},
"/pets/findByStatus": {
"get": {
"tags": [
"pet"
],
"summary": "Finds Pets by status",
"description": "Multiple status values can be provided with comma seperated strings",
"operationId": "findPetsByStatus",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "query",
"name": "status",
"description": "Status values that need to be considered for filter",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi"
}
],
"responses": {
"200": {
"$ref": "#/responses/FoundPets"
},
"400": {
"description": "Invalid status value"
}
},
"security": [
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
}
},
"/pets/findByTags": {
"get": {
"tags": [
"pet"
],
"summary": "Finds Pets by tags",
"description": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
"operationId": "findPetsByTags",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "query",
"name": "tags",
"description": "Tags to filter by",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi"
}
],
"responses": {
"200": {
"$ref": "#/responses/FoundPets"
},
"400": {
"description": "Invalid tag value"
}
},
"security": [
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
}
},
"/pets/{petId}": {
"get": {
"tags": [
"pet"
],
"summary": "Find pet by ID",
"description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions",
"operationId": "getPetById",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"$ref": "#/parameters/petId"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Pet"
}
},
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Pet not found"
}
},
"security": [
{
"api_key": []
},
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
},
"post": {
"tags": [
"pet"
],
"summary": "Updates a pet in the store with form data",
"description": "",
"operationId": "updatePetWithForm",
"consumes": [
"application/x-www-form-urlencoded"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "petId",
"description": "ID of pet that needs to be updated",
"required": true,
"type": "string"
},
{
"in": "formData",
"name": "name",
"description": "Updated name of the pet",
"required": true,
"type": "string"
},
{
"in": "formData",
"name": "status",
"description": "Updated status of the pet",
"required": true,
"type": "string"
}
],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
},
"delete": {
"tags": [
"pet"
],
"summary": "Deletes a pet",
"description": "",
"operationId": "deletePet",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "header",
"name": "api_key",
"description": "",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "petId",
"description": "Pet id to delete",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"400": {
"description": "Invalid pet value"
}
},
"security": [
{
"petstore_auth": [
"write_pets",
"read_pets"
]
}
]
}
},
"/stores/order": {
"post": {
"tags": [
"store"
],
"summary": "Place an order for a pet",
"description": "",
"operationId": "placeOrder",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "order placed for purchasing the pet",
"required": false,
"schema": {
"$ref": "#/definitions/Order"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Order"
}
},
"400": {
"description": "Invalid Order"
}
}
}
},
"/stores/order/{orderId}": {
"get": {
"tags": [
"store"
],
"summary": "Find purchase order by ID",
"description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
"operationId": "getOrderById",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "orderId",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Order"
}
},
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Order not found"
}
}
},
"delete": {
"tags": [
"store"
],
"summary": "Delete purchase order by ID",
"description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
"operationId": "deleteOrder",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "orderId",
"description": "ID of the order that needs to be deleted",
"required": true,
"type": "string"
}
],
"responses": {
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Order not found"
}
}
}
},
"/users": {
"post": {
"tags": [
"user"
],
"summary": "Create user",
"description": "This can only be done by the logged in user.",
"operationId": "createUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Created user object",
"required": false,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/users/createWithArray": {
"post": {
"tags": [
"user"
],
"summary": "Creates list of users with given input array",
"description": "",
"operationId": "createUsersWithArrayInput",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "List of user object",
"required": false,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/users/createWithList": {
"post": {
"tags": [
"user"
],
"summary": "Creates list of users with given input array",
"description": "",
"operationId": "createUsersWithListInput",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "List of user object",
"required": false,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/users/login": {
"get": {
"tags": [
"user"
],
"summary": "Logs user into the system",
"description": "",
"operationId": "loginUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "query",
"name": "username",
"description": "The user name for login",
"required": false,
"type": "string",
"default": "testUser"
},
{
"in": "query",
"name": "password",
"description": "The password for login in clear text",
"required": false,
"type": "string",
"default": "testPassword"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid username/password supplied"
}
}
}
},
"/users/logout": {
"get": {
"tags": [
"user"
],
"summary": "Logs out current logged in user session",
"description": "",
"operationId": "logoutUser",
"produces": [
"application/json",
"application/xml"
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/users/{username}": {
"get": {
"tags": [
"user"
],
"summary": "Get user by user name",
"description": "",
"operationId": "getUserByName",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "username",
"description": "The name that needs to be fetched. Use user1 for testing.",
"required": true,
"type": "string",
"default": "testUser"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/User"
}
},
"400": {
"description": "Invalid username supplied"
},
"404": {
"description": "User not found"
}
}
},
"put": {
"tags": [
"user"
],
"summary": "Updated user",
"description": "This can only be done by the logged in user.",
"operationId": "updateUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "username",
"description": "name that need to be deleted",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "Updated user object",
"required": false,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"400": {
"description": "Invalid user supplied"
},
"404": {
"description": "User not found"
}
}
},
"delete": {
"tags": [
"user"
],
"summary": "Delete user",
"description": "This can only be done by the logged in user.",
"operationId": "deleteUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "username",
"description": "The name that needs to be deleted",
"required": true,
"type": "string"
}
],
"responses": {
"400": {
"description": "Invalid username supplied"
},
"404": {
"description": "User not found"
}
}
}
}
},
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"name": "api_key",
"in": "header"
},
"petstore_auth": {
"type": "oauth2",
"authorizationUrl": "http://petstore.swagger.wordnik.com/api/oauth/dialog",
"flow": "implicit",
"scopes": {
"write_pets": "modify pets in your account",
"read_pets": "read your pets"
}
}
},
"responses":{
"FoundPets": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
}
},
"parameters":{
"petId": {
"in": "path",
"name": "petId",
"description": "ID of the pet",
"required": true,
"type": "integer",
"format": "int64"
}
},
"definitions": {
"Identified": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
}
}
},
"User": {
"allOf": [
{
"$ref": "#/definitions/Identified"
},
{
"properties": {
"username": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "integer",
"format": "int32",
"description": "User Status"
},
"pictures": {
"type": "array",
"items": {
"type": "string",
"format": "byte"
}
}
}
}
]
},
"Category": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"Pet": {
"description" : "Test description",
"required": [
"name",
"photoUrls"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"category": {
"$ref": "#/definitions/Category"
},
"name": {
"type": "string",
"example": "doggie"
},
"photoUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"tags": {
"type": "array",
"items": {
"$ref": "#/definitions/Tag"
}
},
"status": {
"type": "string",
"description": "pet status in the store"
}
}
},
"Tag": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"Order": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"petId": {
"type": "integer",
"format": "int64"
},
"quantity": {
"type": "integer",
"format": "int32"
},
"shipDate": {
"type": "string",
"format": "date-time"
},
"status": {
"type": "string",
"description": "Order Status"
},
"complete": {
"type": "boolean"
}
}
}
}
}

View File

@@ -1,138 +0,0 @@
swagger: "2.0"
info:
title: API
description: Service API
version: "2.18"
host: service.host.com
schemes:
- https
consumes:
- application/json
produces:
- application/json
paths:
/LaunchCommand:
post:
summary: LaunchCommand
description: Dummy description
tags:
- All
parameters:
- name: Version
description: The API version
type: string
in: query
- name: Option
description: An optional option
type: string
in: query
- name: LaunchCommandRequest
description: Launch something new
in: body
schema:
description: Inline schema
type: object
required:
- Command
- MinCount
- MaxCount
properties:
Command:
description: Dummy description
type: object
properties:
path:
description: Command path
type: string
args:
description: Command arguments
type: string
Options:
description: Dummy description
type: array
items:
type: string
type: string
Location:
description: Dummy description
$ref: '#/definitions/Location'
responses:
200:
description: Result
schema:
type: object
properties:
ReservationId:
description: <description>
type: string
Location:
description: <description>
$ref: '#/definitions/Location'
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
type: integer
400:
description: Error
schema:
$ref: '#/definitions/Error'
definitions:
ExternalLocation:
$ref: ./swagger_inlineSchema.yaml#/definitions/Location
Error:
type: object
properties:
error-code:
description: Error code
type: integer
message:
description: Error message
type: string
Location:
type: object
properties:
Loop:
description: Loop
type:
$ref: '#/definitions/Location'
Place:
description: Place
type: string
InlineDepthSchema:
type: object
properties:
Loop:
type: object
properties:
p1:
description: Description p1
type: string
p2:
description: Description p2
type: object
properties:
p2-1:
description: Description p2-1
type: string
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,25 @@
ext.moduleName="io.github.swagger2markup.asciidoc"
dependencies {
configurations.all {
// resolutionStrategy.force dependencyOverrides.commonsCodec
// resolutionStrategy.force dependencyOverrides.commonsIO
// resolutionStrategy.force dependencyOverrides.commonsLang3
resolutionStrategy.force dependencyOverrides.jnrConstants
resolutionStrategy.force dependencyOverrides.jnrEnxio
resolutionStrategy.force dependencyOverrides.jnrPosix
// resolutionStrategy.force dependencyOverrides.jodaTime
resolutionStrategy.force dependencyOverrides.slf4j
// resolutionStrategy.force dependencyOverrides.jacksonDatabind
// resolutionStrategy.force dependencyOverrides.guava
// resolutionStrategy.force dependencyOverrides.findBugs
// resolutionStrategy.force dependencyOverrides.jaksonCore
}
implementation implLibraries.asciiDocJApi
implementation implLibraries.commonsText
implementation implLibraries.slf4j
testImplementation implLibraries.commonsIO
testImplementation testLibraries.asciiDocJ
testImplementation testLibraries.junit
testImplementation testLibraries.logback
}

View File

@@ -0,0 +1,887 @@
package io.github.swagger2markup.adoc;
import io.github.swagger2markup.adoc.converter.internal.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.asciidoctor.ast.List;
import org.asciidoctor.ast.*;
import org.asciidoctor.converter.ConverterFor;
import org.asciidoctor.converter.StringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
@ConverterFor(AsciidocConverter.NAME)
public class AsciidocConverter extends StringConverter {
private Logger logger = LoggerFactory.getLogger(getClass());
public static final String NAME = "adoc";
private final Pattern emptyLineOrStartWith = Pattern.compile("(?m)^\\s*(?:\\r?\\n)|(?m)^\\s+");
private final Pattern coListItemIdPattern = Pattern.compile(".*-(\\d+)");
private final Pattern tableColumnsStylePattern = Pattern.compile("((\\d+)\\*)?([<^>])?(\\.[<^>])?(\\d+)?([adehlmsv])?");
private static final java.util.List<String> attributeToExclude = Arrays.asList(
"localtime",
"filetype",
"asciidoctor-version",
"doctime",
"localyear",
"docdate",
"localdate",
"localdatetime",
"docdatetime",
"backend",
"basebackend",
"doctitle",
"docyear"
);
private static final String[] supportedUrlSchemes = new String[]{
"http",
"https",
"ftp",
"irc",
"mailto"
};
public AsciidocConverter(String backend, Map<String, Object> opts) {
super(backend, opts);
}
/**
* Converts an {@link ContentNode} using the specified transform along
* with additional options. If a transform is not specified, implementations
* typically derive one from the {@link ContentNode#getNodeName()} property.
*
* <p>Implementations are free to decide how to carry out the conversion. In
* the case of the built-in converters, the tranform value is used to
* dispatch to a handler method. The TemplateConverter uses the value of
* the transform to select a template to render.
*
* @param node The concrete instance of FlowNode to convert
* @param transform An optional String transform that hints at which transformation
* should be applied to this node. If a transform is not specified,
* the transform is typically derived from the value of the
* node's node_name property. (optional, default: null)
* @param opts An optional map of options that provide additional hints about
* how to convert the node. (optional, default: empty map)
* @return the converted result
*/
@Override
public String convert(ContentNode node, String transform, Map<Object, Object> opts) {
if (null == transform) {
transform = node.getNodeName();
}
switch (transform) {
case "inline_quoted":
return convertInlineQuoted((PhraseNode) node);
case "paragraph":
return convertParagraph((StructuralNode) node);
case "inline_anchor":
return convertInlineAnchor((PhraseNode) node);
case "section":
return convertSection((Section) node);
case "listing":
return convertListing((Block) node);
case "literal":
return convertLiteral((StructuralNode) node);
case "ulist":
return convertUList((List) node);
case "olist":
return convertOList((List) node);
case "dlist":
return convertDescriptionList((DescriptionList) node);
case "admonition":
return convertAdmonition((Block) node);
case "colist":
return convertCoList((List) node);
case "embedded":
case "document":
return convertEmbedded((Document) node);
case "example":
return convertExample((Block) node);
case "floating_title":
return convertFloatingTitle((StructuralNode) node);
case "image":
return convertImage((StructuralNode) node);
case "inline_break":
return convertInlineBreak(node);
case "inline_button":
return convertInlineButton(node);
case "inline_callout":
return convertInlineCallout(node);
case "inline_footnote":
return convertInlineFootnote(node);
case "inline_image":
return convertInlineImage((PhraseNode) node);
case "inline_indexterm":
return convertInlineIndexTerm(node);
case "inline_kbd":
return convertInlineKbd(node);
case "inline_menu":
return convertInlineMenu(node);
case "open":
return convertOpen((StructuralNode) node);
case "page_break":
return convertPageBreak(node);
case "preamble":
return convertPreamble((StructuralNode) node);
case "quote":
return convertQuote((StructuralNode) node);
case "sidebar":
return convertSidebar((StructuralNode) node);
case "stem":
return convertStem(node);
case "table":
return convertTable((Table) node);
case "thematic_break":
return convertThematicBreak(node);
case "verse":
return convertVerse((StructuralNode) node);
case "video":
return convertVideo(node);
case "toc":
return convertToc(node);
case "pass":
return convertPass(node);
case "audio":
return convertAudio(node);
// didn't exist on html converter
case "list":
return convertList((List) node);
case "list_item":
return convertListItem((ListItem) node);
default:
logger.debug("Don't know how to convert transform: [" + transform + "] Node: " + node);
return null;
}
}
String convertEmbedded(Document node) {
logger.debug("convertEmbedded");
StringBuilder sb = new StringBuilder();
appendId(node, sb);
if (StringUtils.isNotBlank(node.getDoctitle())) {
sb.append(repeat(node.getLevel() + 1,DOCUMENT_TITLE)).append(' ').append(StringEscapeUtils.unescapeHtml4(node.getDoctitle())).append(LINE_SEPARATOR);
}
Map<String, Object> attributes = node.getAttributes();
appendAuthors(sb, attributes);
appendRevisionDetails(sb, attributes);
appendDocumentAttributes(sb, attributes);
appendTrailingNewLine(sb);
appendChildBlocks(node, sb);
return sb.toString();
}
private void appendAuthors(StringBuilder sb, Map<String, Object> attributes) {
Long authorCount = (Long) attributes.getOrDefault("authorcount", 0L);
if (authorCount == 1) {
String author = getAuthorDetail(attributes, "author", "email");
if (StringUtils.isNotBlank(author)) {
sb.append(author).append(LINE_SEPARATOR);
}
} else if (authorCount > 1) {
String authors = LongStream.rangeClosed(1, authorCount)
.mapToObj(i -> getAuthorDetail(attributes, "author_" + i, "email_" + i))
.collect(Collectors.joining("; "));
if (StringUtils.isNotBlank(authors)) {
sb.append(authors).append(LINE_SEPARATOR);
}
}
}
private void appendDocumentAttributes(StringBuilder sb, Map<String, Object> attributes) {
attributes.forEach((k, v) -> {
if (!attributeToExclude.contains(k) && v != null && !v.toString().isEmpty())
sb.append(COLON).append(k).append(COLON).append(" ").append(v).append(LINE_SEPARATOR);
});
}
private void appendRevisionDetails(StringBuilder sb, Map<String, Object> attributes) {
String revDetails = Stream.of(attributes.get("revnumber"), attributes.get("revdate")).filter(Objects::nonNull)
.filter(o -> !o.toString().isEmpty()).map(Object::toString)
.collect(Collectors.joining(", "));
if (!revDetails.isEmpty()) {
sb.append("v").append(revDetails).append(LINE_SEPARATOR);
}
}
private String getAuthorDetail(Map<String, Object> attributes, String authorKey, String emailKey) {
String author = attributes.getOrDefault(authorKey, "").toString();
String email = attributes.getOrDefault(emailKey, "").toString();
if (StringUtils.isNotBlank(email)) {
email = " <" + email + ">";
}
return (author + email).trim();
}
private String convertInlineAnchor(PhraseNode node) {
logger.debug("convertInlineAnchor");
String type = node.getType();
switch (type) {
case "xref": {
String attrs;
String text;
String path = Optional.ofNullable(node.getAttributes().get("path")).orElse("").toString();
if (StringUtils.isNotBlank(path)) {
ArrayList<String> list = new ArrayList<>();
if (StringUtils.isNotBlank(node.getRole())) {
list.add(" class=\"#{node.role}\"");
}
append_link_constraint_attrs(node, list);
attrs = String.join(" ", list);
text = StringUtils.isNotBlank(node.getText()) ? node.getText() : path;
} else {
attrs = StringUtils.isNotBlank(node.getRole()) ? " class=\"" + node.getRole() + "\"" : "";
text = node.getText();
if (StringUtils.isNotBlank(text)) {
text = node.getAttributes().get("refid").toString();
}
}
return node.getTarget() + ATTRIBUTES_BEGIN + text + (StringUtils.isNotBlank(attrs) ? "," + attrs : "") + ATTRIBUTES_END;
}
case "ref":
return node.getId();
case "link": {
ArrayList<String> attrs = new ArrayList<>();
String target = node.getTarget();
String includePrefix = !StringUtils.startsWithAny(target, supportedUrlSchemes) ? "include::" : "";
String text = node.getText();
if (!target.equals(text)) {
attrs.add(text);
}
if (StringUtils.isNotBlank(node.getId())) {
attrs.add("id=\"" + node.getId() + "\"");
}
String role = node.getRole();
if (StringUtils.isNotBlank(role) && !role.equals("bare")) {
attrs.add("role=\"" + role + "\"");
}
String title = node.getAttribute("title", "").toString();
if (StringUtils.isNotBlank(title)) {
attrs.add("title=\"" + title + "\"");
}
return includePrefix + target + ATTRIBUTES_BEGIN + String.join(",", attrs) + ATTRIBUTES_END;
}
case "bibref":
return node.getId() + ATTRIBUTES_BEGIN + (StringUtils.isNotBlank(node.getReftext()) ? node.getReftext() : node.getId()) + ATTRIBUTES_END;
default:
logger.warn("unknown anchor type: " + node.getType());
return null;
}
}
private String convertAdmonition(Block node) {
logger.debug("convertAdmonition");
StringBuilder sb = new StringBuilder();
java.util.List<StructuralNode> blocks = node.getBlocks();
if (blocks.isEmpty()) {
sb.append(node.getStyle()).append(": ").append(node.getSource());
} else {
appendTitle(node, sb);
sb.append(ATTRIBUTES_BEGIN).append(node.getStyle()).append(ATTRIBUTES_END)
.append(LINE_SEPARATOR).append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
appendChildBlocks(node, sb);
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
}
return sb.toString();
}
private String convertInlineQuoted(PhraseNode node) {
logger.debug("convertInlineQuoted");
StringBuilder sb = new StringBuilder();
String marker = "";
switch (node.getType()) {
case "monospaced":
marker = "`";
break;
case "emphasis":
marker = "_";
break;
case "strong":
marker = "*";
break;
case "superscript":
marker = "^";
break;
case "subscript":
marker = "~";
break;
case "double":
case "single":
case "mark":
case "asciimath":
case "latexmath":
marker = "";
break;
}
sb.append(marker).append(node.getText()).append(marker);
return sb.toString();
}
private String convertFloatingTitle(StructuralNode node) {
logger.debug("convertFloatingTitle");
return ATTRIBUTES_BEGIN + "discrete" + ATTRIBUTES_END + LINE_SEPARATOR +
repeat(node.getLevel() + 1, TITLE) + ' ' + node.getTitle() + LINE_SEPARATOR;
}
private String convertExample(Block node) {
logger.debug("convertExample");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
appendChildBlocks(node, sb);
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
return sb.toString();
}
private String convertInlineButton(ContentNode node) {
logger.debug("convertInlineButton: name" + node.getNodeName());
return "convertInlineButton";
}
private String convertInlineCallout(ContentNode node) {
logger.debug("convertInlineCallout: name" + node.getNodeName());
return "convertInlineCallout";
}
private String convertInlineBreak(ContentNode node) {
logger.debug("convertInlineBreak: name" + node.getNodeName());
return "convertInlineBreak";
}
private String convertInlineFootnote(ContentNode node) {
logger.debug("convertInlineFootnote: name" + node.getNodeName());
return "convertInlineFootnote";
}
private String convertInlineImage(PhraseNode node) {
logger.debug("convertInlineImage");
if (node.getType().equals("icon")) {
return (new IconNode(node)).toAsciiDocContent();
} else {
return (new BlockImageNode(node)).toAsciiDocContent();
}
}
private String convertInlineIndexTerm(ContentNode node) {
logger.debug("convertInlineIndexTerm: name" + node.getNodeName());
return "convertInlineIndexTerm";
}
private String convertInlineKbd(ContentNode node) {
logger.debug("convertInlineKbd: name" + node.getNodeName());
return "convertInlineKbd";
}
private String convertInlineMenu(ContentNode node) {
logger.debug("convertInlineMenu: name" + node.getNodeName());
return "convertInlineMenu";
}
private String convertOpen(StructuralNode node) {
logger.debug("convertOpen");
StringBuilder sb = new StringBuilder();
switch (node.getStyle()) {
case "abstract":
sb.append(ATTRIBUTES_BEGIN).append("abstract").append(ATTRIBUTES_END).append(LINE_SEPARATOR);
break;
case "open":
sb.append(DELIMITER_OPEN_BLOCK).append(LINE_SEPARATOR);
}
sb.append(Optional.ofNullable(((Block) node).getSource()).orElse(""));
appendChildBlocks(node, sb);
if ("open".equals(node.getStyle())) {
sb.append(DELIMITER_OPEN_BLOCK).append(LINE_SEPARATOR);
}
return sb.toString();
}
private String convertPageBreak(ContentNode node) {
logger.debug("convertPageBreak: name" + node.getNodeName());
return DELIMITER_PAGE_BREAK + LINE_SEPARATOR;
}
private String convertQuote(StructuralNode node) {
logger.debug("convertQuote");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
sb.append(ATTRIBUTES_BEGIN);
java.util.List<String> attrs = new ArrayList<>();
if (StringUtils.isNotBlank(node.getStyle())) {
attrs.add("quote");
}
appendAttributeTo(node, attrs, "attribution");
appendAttributeTo(node, attrs, "citetitle");
sb.append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
java.util.List<StructuralNode> blocks = node.getBlocks();
if (!blocks.isEmpty()) {
sb.append("____").append(LINE_SEPARATOR);
appendChildBlocks(node, sb);
sb.append("____").append(LINE_SEPARATOR);
} else {
sb.append(((Block) node).getSource());
}
return sb.toString();
}
private String convertSidebar(StructuralNode node) {
logger.debug("convertSidebar");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
appendChildBlocks(node, sb);
return sb.toString();
}
private String convertStem(ContentNode node) {
logger.debug("convertStem: name" + node.getNodeName());
return "convertStem";
}
private String convertThematicBreak(ContentNode node) {
logger.debug("convertThematicBreak: name" + node.getNodeName());
return DELIMITER_THEMATIC_BREAK + LINE_SEPARATOR;
}
private String convertVerse(StructuralNode node) {
logger.debug("convertVerse");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
sb.append(ATTRIBUTES_BEGIN);
java.util.List<String> attrs = new ArrayList<>();
if (StringUtils.isNotBlank(node.getStyle())) {
attrs.add("verse");
}
appendAttributeTo(node, attrs, "attribution");
appendAttributeTo(node, attrs, "citetitle");
sb.append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
String source = ((Block) node).getSource();
boolean matches = emptyLineOrStartWith.matcher(source).find();
if (matches) {
sb.append(DELIMITER_VERSE).append(LINE_SEPARATOR);
}
sb.append(source);
if (matches) {
sb.append(LINE_SEPARATOR).append(DELIMITER_VERSE);
}
appendTrailingNewLine(sb);
return sb.toString();
}
private String convertVideo(ContentNode node) {
logger.debug("convertVideo: name" + node.getNodeName());
return "convertVideo";
}
private String convertToc(ContentNode node) {
logger.debug("convertToc: name" + node.getNodeName());
return "convertToc";
}
private String convertPass(ContentNode node) {
logger.debug("convertPass: name" + node.getNodeName());
return "convertPass";
}
private String convertAudio(ContentNode node) {
logger.debug("convertAudio: name" + node.getNodeName());
return "convertAudio";
}
private String convertCell(Cell node) {
logger.debug("convertCell");
StringBuilder sb = new StringBuilder();
String source = node.getSource();
if (StringUtils.isNotBlank(source)) {
sb.append(source);
}
Document innerDocument = node.getInnerDocument();
if (null != innerDocument) {
appendChildBlocks(innerDocument, sb, false);
}
return sb.toString().replaceAll(LINE_SEPARATOR + LINE_SEPARATOR + "+", LINE_SEPARATOR + LINE_SEPARATOR);
}
private String convertRow(Row node, java.util.List<TableCellStyle> columnStyles, String delimiterTableCell) {
logger.debug("convertRow");
StringBuilder sb = new StringBuilder();
node.getCells().forEach(cell -> {
boolean addNewLine = false;
int colspan = cell.getColspan();
if (colspan != 0) {
addNewLine = true;
sb.append(colspan).append('+');
}
int rowspan = cell.getRowspan();
if (rowspan != 0) {
addNewLine = true;
sb.append('.').append(rowspan).append('+');
}
int index = cell.getColumn().getColumnNumber() - 1;
TableCellStyle tableCellStyle = (columnStyles.size() > index) ? columnStyles.get(index) : null;
boolean hAlignmentAdded = false;
TableCellHorizontalAlignment hAlignment = TableCellHorizontalAlignment.fromName(cell.getHorizontalAlignment().name());
if ((null != hAlignment) && (null == tableCellStyle || hAlignment != tableCellStyle.horizontalAlignment)) {
hAlignmentAdded = true;
addNewLine = true;
sb.append(hAlignment.getDelimiter());
}
TableCellVerticalAlignment vAlignment = TableCellVerticalAlignment.fromName(cell.getVerticalAlignment().name());
if ((null != vAlignment) && (null == tableCellStyle || hAlignmentAdded || vAlignment != tableCellStyle.verticalAlignment)) {
addNewLine = true;
sb.append(vAlignment.getDelimiter());
}
Style style = Style.fromName(cell.getAttribute("style", "").toString());
if (null != style && (null == tableCellStyle || style != tableCellStyle.style)) {
addNewLine = true;
sb.append(style.getShortHand());
}
sb.append(delimiterTableCell).append(convertCell(cell));
if (addNewLine) {
sb.append(LINE_SEPARATOR);
} else {
sb.append(' ');
}
});
return sb.toString();
}
private String convertTable(Table node) {
logger.debug("convertTable");
java.util.List<TableCellStyle> columnStyles = new ArrayList<>();
for (String col : node.getAttribute("cols", "").toString().split(",")) {
Matcher matcher = tableColumnsStylePattern.matcher(col);
if (matcher.find()) {
int multiplier = 1;
String multiplierGroup = matcher.group(2);
if (null != multiplierGroup) {
try {
multiplier = Integer.parseInt(multiplierGroup);
} catch (NumberFormatException ignored) {
}
}
int width = 0;
try {
width = Integer.parseInt(matcher.group(5));
} catch (NumberFormatException ignored) {
}
TableCellStyle tableCellStyle = new TableCellStyle(
TableCellHorizontalAlignment.fromString(matcher.group(3)),
TableCellVerticalAlignment.fromString(matcher.group(4)),
Style.fromString(matcher.group(6)),
width
);
for (int i = 0; i < multiplier; i++) {
columnStyles.add(tableCellStyle);
}
}
}
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
sb.append(new TableNode(node).toAsciiDocContent());
boolean innerTable = isInnerTable(node);
String tableDelimiter = innerTable ? DELIMITER_INNER_TABLE : DELIMITER_TABLE;
String cellDelimiter = innerTable ? DELIMITER_INNER_TABLE_CELL : DELIMITER_TABLE_CELL;
sb.append(tableDelimiter).append(LINE_SEPARATOR);
appendRows(node.getHeader(), sb, columnStyles, cellDelimiter);
appendRows(node.getBody(), sb, columnStyles, cellDelimiter);
appendRows(node.getFooter(), sb, columnStyles, cellDelimiter);
sb.append(tableDelimiter).append(LINE_SEPARATOR);
return sb.toString();
}
private boolean isInnerTable(ContentNode node) {
if(null != node) {
ContentNode parent = node.getParent();
if (null != parent) {
return parent instanceof Table || isInnerTable(parent);
}
}
return false;
}
private void appendRows(java.util.List<Row> rows, StringBuilder sb, java.util.List<TableCellStyle> columnStyles, String delimiterTableCell) {
rows.forEach(row -> sb.append(convertRow(row, columnStyles, delimiterTableCell)).append(LINE_SEPARATOR));
}
private String convertDescriptionList(DescriptionList node) {
logger.debug("convertDescriptionList");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
String style = Optional.ofNullable(node.getStyle()).orElse("");
switch (style) {
case STYLE_HORIZONTAL:
sb.append(ATTRIBUTES_BEGIN).append(STYLE_HORIZONTAL).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
node.getItems().forEach(item -> sb.append(convertDescriptionListEntry(item, node.getLevel(), false)));
break;
case STYLE_Q_AND_A:
sb.append(ATTRIBUTES_BEGIN).append(STYLE_Q_AND_A).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
default:
node.getItems().forEach(item -> sb.append(convertDescriptionListEntry(item, node.getLevel(), true)));
break;
}
appendTrailingNewLine(sb);
return sb.toString();
}
private String convertDescriptionListEntry(DescriptionListEntry node, int level, Boolean descriptionOnNewLine) {
logger.debug("convertDescriptionListEntry");
StringBuilder sb = new StringBuilder();
String delimiter = repeat(level + 1, MARKER_D_LIST_ITEM);
String entryTerms = node.getTerms().stream()
.map(term -> Optional.ofNullable(term.getSource()).orElse(""))
.collect(Collectors.joining(delimiter + LINE_SEPARATOR, "", delimiter));
sb.append(entryTerms);
ListItem description = node.getDescription();
if (null != description) {
if (descriptionOnNewLine) {
sb.append(LINE_SEPARATOR);
}
String desc = Optional.ofNullable(description.getSource()).orElse("");
if (StringUtils.isNotBlank(desc)) {
sb.append(desc).append(LINE_SEPARATOR);
}
appendChildBlocks(description, sb);
}
return sb.toString();
}
private String convertListing(Block node) {
logger.debug("convertListing");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
if (STYLE_SOURCE.equals(node.getStyle())) {
sb.append(new SourceNode(node).toAsciiDocContent());
} else {
sb.append(new BlockListingNode(node).toAsciiDocContent());
}
return sb.toString();
}
private String convertUList(List node) {
logger.debug("convertUList");
StringBuilder sb = new StringBuilder();
appendStyle(node, sb);
appendTitle(node, sb);
appendChildBlocks(node, sb);
appendTrailingNewLine(sb);
return sb.toString();
}
private String convertOList(List node) {
logger.debug("convertOList");
StringBuilder sb = new StringBuilder();
java.util.List<String> attrs = new ArrayList<>();
String start = node.getAttribute("start", "").toString();
if (StringUtils.isNotBlank(start)) {
attrs.add("start=" + start);
}
if (node.isOption("reversed")) {
attrs.add("%reversed");
}
if (!attrs.isEmpty()) {
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
}
appendTitle(node, sb);
appendChildBlocks(node, sb);
appendTrailingNewLine(sb);
return sb.toString();
}
private String convertCoList(List node) {
logger.debug("convertCoList");
StringBuilder result = new StringBuilder();
appendChildBlocks(node, result);
return result.toString();
}
private String convertListItem(ListItem node) {
logger.debug("convertListItem");
StringBuilder sb = new StringBuilder();
String marker = Optional.ofNullable(node.getMarker()).orElse(repeat(node.getLevel(), MARKER_LIST_ITEM));
String coids = node.getAttribute("coids", "").toString();
Matcher matcher = coListItemIdPattern.matcher(coids);
if (matcher.find()) {
marker = marker.replaceAll("\\d+", matcher.group(1));
}
sb.append(marker).append(" ");
if (node.hasAttribute("checkbox")) {
sb.append('[');
if (node.hasAttribute("checked")) {
sb.append('x');
} else {
sb.append(' ');
}
sb.append(']').append(' ');
}
sb.append(Optional.ofNullable(node.getSource()).orElse(""));
appendTrailingNewLine(sb);
appendChildBlocks(node, sb);
return sb.toString();
}
private String convertList(List node) {
logger.debug("convertList");
return node.getContent().toString();
}
private String convertPreamble(StructuralNode node) {
logger.debug("convertPreamble");
return node.getContent().toString();
}
private String convertImage(StructuralNode node) {
logger.debug("convertImage");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
appendRoles(node, sb);
sb.append(new BlockImageNode(node).toAsciiDocContent());
return sb.toString();
}
private String convertLiteral(StructuralNode node) {
logger.debug("convertLiteral");
return ATTRIBUTES_BEGIN + node.getContext() + ATTRIBUTES_END + LINE_SEPARATOR +
StringEscapeUtils.unescapeHtml4(node.getContent().toString()) + LINE_SEPARATOR;
}
private String convertParagraph(StructuralNode node) {
logger.debug("convertParagraph");
StringBuilder sb = new StringBuilder();
appendTitle(node, sb);
sb.append(new ParagraphAttributes(node).toAsciiDocContent());
appendSource((Block) node, sb);
appendTrailingNewLine(sb);
return sb.toString();
}
private String convertSection(Section node) {
logger.debug("convertSection");
StringBuilder sb = new StringBuilder();
appendId(node, sb);
sb.append(new DelimitedBlockNode(node).toAsciiDocContent()).append(StringUtils.repeat(TITLE, node.getLevel() + 1))
.append(" ").append(StringEscapeUtils.unescapeHtml4(node.getTitle())).append(LINE_SEPARATOR);
appendChildBlocks(node, sb);
appendTrailingNewLine(sb);
return sb.toString();
}
private void append_link_constraint_attrs(ContentNode node, java.util.List<String> attrs) {
String rel = node.getAttribute("nofollow-option").toString();
String window = node.getAttributes().get("window").toString();
if (StringUtils.isNotBlank(window)) {
attrs.add("target = \"#{window}\"");
if (window.equals("_blank") || (node.getAttributes().containsKey("option-noopener"))) {
if (StringUtils.isNotBlank(rel)) {
attrs.add("rel = \"" + rel + "noopener\"");
} else {
attrs.add(" rel=\"noopener\"");
}
}
} else if (StringUtils.isNotBlank(rel)) {
attrs.add("rel = " + rel + "\"");
}
}
private String repeat(int count, String with) {
return new String(new char[count]).replace("\0", with);
}
private void appendChildBlocks(StructuralNode parentNode, StringBuilder sb) {
appendChildBlocks(parentNode, sb, true);
}
private void appendChildBlocks(StructuralNode parentNode, StringBuilder sb, boolean addTrailingLineSeparator) {
final boolean isParentAListItem = parentNode instanceof ListItem || parentNode instanceof DescriptionListEntry;
parentNode.getBlocks().forEach(childNode -> {
String childNodeValue = childNode.convert();
if (StringUtils.isNotBlank(childNodeValue)) {
if (isParentAListItem && (sb.toString().contains("+" + LINE_SEPARATOR) || !(childNode instanceof List || childNode instanceof DescriptionList))) {
sb.append('+').append(LINE_SEPARATOR);
}
sb.append(childNodeValue);
if (addTrailingLineSeparator && !StringUtils.endsWith(childNodeValue, LINE_SEPARATOR)) {
sb.append(LINE_SEPARATOR);
}
}
});
}
private void appendTrailingNewLine(StringBuilder sb) {
if (!sb.toString().endsWith(LINE_SEPARATOR + LINE_SEPARATOR)) {
sb.append(LINE_SEPARATOR);
}
}
private void appendId(StructuralNode node, StringBuilder sb) {
String id = node.getId();
if (StringUtils.isNotBlank(id)) {
sb.append("[[").append(id).append("]]").append(LINE_SEPARATOR);
}
}
private void appendSource(Block node, StringBuilder sb) {
String source = node.getSource();
if (StringUtils.isNotBlank(source)) {
sb.append(source).append(LINE_SEPARATOR);
}
}
private void appendTitle(StructuralNode node, StringBuilder sb) {
String title = node.getTitle();
if (StringUtils.isNotBlank(title)) {
sb.append(".").append(StringEscapeUtils.unescapeHtml4(title)).append(LINE_SEPARATOR);
}
}
private void appendStyle(StructuralNode node, StringBuilder sb) {
String style = node.getStyle();
if (StringUtils.isNotBlank(style)) {
sb.append(ATTRIBUTES_BEGIN).append(style).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
}
}
private void appendRoles(StructuralNode node, StringBuilder sb) {
java.util.List<String> roles = node.getRoles();
if (!roles.isEmpty()) {
sb.append(ATTRIBUTES_BEGIN).append(".").append(String.join(".", roles))
.append(ATTRIBUTES_END).append(LINE_SEPARATOR);
}
}
private void appendAttributeTo(StructuralNode node, java.util.List<String> attrs, String name) {
String attribution = node.getAttribute(name, "").toString();
if (StringUtils.isNotBlank(attribution)) {
attrs.add(attribution);
}
}
}

View File

@@ -0,0 +1,70 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Block;
import org.asciidoctor.ast.StructuralNode;
import java.util.*;
public class BlockImpl extends StructuralNodeImpl implements Block {
private List<String> lines;
public BlockImpl(StructuralNode parent, String context) {
this(parent, context, "");
}
public BlockImpl(StructuralNode parent, String context, Object content) {
this(parent, context, new HashMap<>(), content);
}
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes) {
this(parent, context, attributes, "");
}
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, Object content) {
this(parent, context, attributes, new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
}
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs) {
this(parent, context, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs);
}
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs) {
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
this.lines = new ArrayList<>();
}
@Override
@Deprecated
public List<String> lines() {
return getLines();
}
@Override
public List<String> getLines() {
return lines;
}
@Override
public void setLines(List<String> lines) {
this.lines = lines;
}
@Override
@Deprecated
public String source() {
return getSource();
}
@Override
public String getSource() {
return String.join("\n", lines);
}
@Override
public void setSource(String source) {
setLines(Arrays.asList(source.split("\n")));
}
}

View File

@@ -0,0 +1,112 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Cell;
import org.asciidoctor.ast.Column;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.Table;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CellImpl extends ContentNodeImpl implements Cell {
private final int colspan;
private final int rowspan;
private String text;
private String style;
private Document innerDocument;
public CellImpl(Column parent, String text) {
this(parent, "table_cell", new HashMap<>(), new ArrayList<>(), 0, 0);
this.text = text;
}
public CellImpl(Column parent, Document innerDocument) {
this(parent, "table_cell", new HashMap<>(), new ArrayList<>(), 0, 0);
this.innerDocument = innerDocument;
}
public CellImpl(Column parent, String context, Map<String, Object> attributes, List<String> roles, int colspan, int rowspan) {
super(parent, context, attributes, roles);
this.colspan = colspan;
this.rowspan = rowspan;
}
@Override
public Column getColumn() {
return (Column) getParent();
}
@Override
public int getColspan() {
return colspan;
}
@Override
public int getRowspan() {
return rowspan;
}
@Override
public String getText() {
return text;
}
@Override
public String getSource() {
return text;
}
@Override
public void setSource(String source) {
this.text = source;
}
@Override
public Object getContent() {
return text;
}
@Override
public String getStyle() {
return style;
}
@Override
public void setStyle(String style) {
this.style = style;
}
@Override
public Table.HorizontalAlignment getHorizontalAlignment() {
return Table.HorizontalAlignment.valueOf(((String) getAttribute("halign", "left")).toUpperCase());
}
@Override
public void setHorizontalAlignment(Table.HorizontalAlignment halign) {
setAttribute("halign", halign.name().toLowerCase(), true);
}
@Override
public Table.VerticalAlignment getVerticalAlignment() {
return Table.VerticalAlignment.valueOf(((String) getAttribute("valign", "top")).toUpperCase());
}
@Override
public void setVerticalAlignment(Table.VerticalAlignment valign) {
setAttribute("valign", valign.name().toLowerCase(), true);
}
@Override
public Document getInnerDocument() {
return innerDocument;
}
@Override
public void setInnerDocument(Document document) {
this.innerDocument = document;
}
}

View File

@@ -0,0 +1,81 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Column;
import org.asciidoctor.ast.Table;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ColumnImpl extends ContentNodeImpl implements Column {
private String style;
private Number columnNumber = -1;
private Number width = 0;
public ColumnImpl(Table parent) {
this(parent, "table_column", new HashMap<>(), new ArrayList<>());
}
public ColumnImpl(Table parent, String context, Map<String, Object> attributes, List<String> roles) {
super(parent, context, attributes, roles);
}
@Override
public String getStyle() {
return style;
}
@Override
public void setStyle(String style) {
this.style = style;
}
@Override
public Table getTable() {
return (Table) getParent();
}
@Override
public int getColumnNumber() {
return columnNumber.intValue();
}
public void setColumnNumber(Integer columnNumber) {
setAttribute("colnumber", columnNumber, true);
this.columnNumber = columnNumber;
}
@Override
public int getWidth() {
return width.intValue();
}
@Override
public void setWidth(int width) {
setAttribute("width", width, true);
this.width = width;
}
@Override
public Table.HorizontalAlignment getHorizontalAlignment() {
return Table.HorizontalAlignment.valueOf(((String) getAttribute("halign", "left")).toUpperCase());
}
@Override
public void setHorizontalAlignment(Table.HorizontalAlignment halign) {
setAttribute("halign", halign.name().toLowerCase(), true);
}
@Override
public Table.VerticalAlignment getVerticalAlignment() {
return Table.VerticalAlignment.valueOf(((String) getAttribute("valign", "top")).toUpperCase());
}
@Override
public void setVerticalAlignment(Table.VerticalAlignment valign) {
setAttribute("valign", valign.name().toLowerCase(), true);
}
}

Some files were not shown because too many files have changed in this diff Show More