Compare commits

...

105 Commits

Author SHA1 Message Date
qingmo
ac22f63404 fix(gradlebuildconfig): add pom.xml & change swaggerV2 from runtime to compile for maven project (#438)
add new pom.xml generate task in jar task && change swaggerV2 from implementation to api
2022-04-26 08:34:27 +02:00
rui
aeaab37c8a ci: remove travis (#434)
* ci: remove travis

* docs: remove travis
2022-02-28 13:25:25 +01:00
ShubhamRwt
8dd6426f90 Resolving issues with build.gradle 2022-02-17 15:09:07 +05:30
ShubhamRwt
198bcfe22f Resolving issues with build.gradle 2022-02-17 15:06:50 +05:30
ShubhamRwt
3614b469d6 Resolving issues with build.gradle 2022-02-17 14:31:03 +05:30
ShubhamRwt
7d28f3344c Resolving issues with github actions 2022-02-17 12:13:26 +05:30
Shubham Rawat
32a42b1da5 Merge pull request #428 from ShubhamRwt/code
Added the sonar organization in build.gradle
2022-02-16 16:54:14 +05:30
ShubhamRwt
a9e18732c8 changes 2022-02-16 16:51:06 +05:30
ShubhamRwt
5b56e1af8a changes 2022-02-16 16:44:50 +05:30
Shubham Rawat
352977eef5 Merge pull request #425 from Swagger2Markup/githubActions
Moving from the travis.yml to github actions
2022-02-16 15:14:28 +05:30
Shubham Rawat
743624ee77 Merge pull request #424 from ShubhamRwt/releaseProcess
Moving from Bintray to Sonatype and other additional changes
2022-02-16 15:14:12 +05:30
ShubhamRwt
5f910fd564 changes 2022-02-14 14:47:25 +05:30
Shubham Rawat
fb03267275 Create gradle-build.yml 2022-02-14 14:22:05 +05:30
ShubhamRwt
c665d1f5cd changes 2022-02-14 14:16:19 +05:30
ShubhamRwt
da23c929c0 Move from bintray to SonaType 2022-02-14 14:10:11 +05:30
ShubhamRwt
7141fc094b changes 2022-02-14 13:01:32 +05:30
ShubhamRwt
f6152f6c9b changes 2022-02-14 12:52:22 +05:30
ShubhamRwt
9f89c40280 changes 2022-02-14 12:38:53 +05:30
ShubhamRwt
f60999dd9f changes 2022-02-11 16:38:55 +05:30
ShubhamRwt
a45caa4d19 changes 2022-02-11 16:34:41 +05:30
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
531 changed files with 30908 additions and 3320 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: [ master ]
pull_request:
branches: [ master ]
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/master' }}
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

2
.gitignore vendored
View File

@@ -6,3 +6,5 @@ build
/.classpath
/.project
/.settings/
*.ipr
*.iws

View File

@@ -1,18 +0,0 @@
language: java
jdk:
- oraclejdk8
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:
slack: swagger2markup:Zz5kz0SnvtG6aVvZUM8yMkER
env:
global:
- 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=

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.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"]
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].
@@ -22,12 +33,12 @@ 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.github.io/swagger2markup/1.1.1/[Reference Documentation]
- http://swagger2markup.github.io/swagger2markup/1.3.3/[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]
@@ -54,6 +65,8 @@ If youd like an enhancement to be made to Swagger2Markup, pull requests are m
* 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.
@@ -102,6 +117,7 @@
* 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.
@@ -115,11 +131,39 @@
* 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
== 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-SNAPSHOT
* 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 2.0.0
* Added openapi2markup to support OpenAPI v3
* Issue #409: Fixed JSON response example

View File

@@ -1,70 +1,121 @@
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.3'
}
allprojects {
apply plugin: 'jacoco'
apply plugin: 'me.champeau.gradle.jmh'
version = '2.0.0-SNAPSHOT'
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 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.0"
classpath "org.ajoberstar:gradle-git:1.3.2"
}
//artifactoryPublish.skip = true // apply to all projects except the root
ext {
coreProjects = subprojects.findAll {
p -> !p.name.contains("documentation") && !p.name.endsWith("-bom")
}
}
description = 'swagger2markup Build'
version = '1.2.0-SNAPSHOT'
ext.releaseVersion = '1.1.1'
group = 'io.github.swagger2markup'
apply plugin: 'java'
apply plugin: 'eclipse'
apply from: 'gradle/publishing.gradle'
apply from: 'gradle/coverage.gradle'
apply from: 'gradle/documentation.gradle'
configure(project.coreProjects) {
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply from: "${rootDir}/publishing.gradle"
apply plugin: 'jacoco'
tasks.withType(JavaCompile) {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
options.deprecation = true
options.encoding = 'UTF-8'
options.compilerArgs << "-Xlint:unchecked"
}
repositories {
maven {
url "https://oss.jfrog.org/artifactory/oss-snapshot-local"
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()
}
}
jcenter()
mavenCentral()
//mavenLocal()
}
dependencies {
compile 'io.github.swagger2markup:markup-document-builder:1.1.1-SNAPSHOT'
compile 'io.swagger:swagger-compat-spec-parser:1.0.23'
compile 'org.apache.commons:commons-configuration2:2.1'
compile 'commons-beanutils:commons-beanutils:1.9.2'
compile 'org.apache.commons:commons-collections4:4.1'
compile 'io.javaslang:javaslang:2.0.4'
compile 'ch.netzwerg:paleo-core:0.10.1'
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:3.5.2'
testCompile 'io.github.robwin:assertj-diff:0.1.1'
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
}
}
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 {
into("META-INF/maven/$project.group/$project.name") {
from {generatePomFileForMavenJavaPublication}
rename ".*", "pom.xml"
}
inputs.property('moduleName', moduleName)
manifest.attributes(
'Automatic-Module-Name': moduleName
)
}
}
}
}
tasks.check.dependsOn tasks.jacocoTestReport
test {
if (System.properties['http.proxyHost']) {
systemProperty 'http.proxyHost', System.properties['http.proxyHost']
systemProperty 'http.proxyPort', System.properties['http.proxyPort']
systemProperty 'http.nonProxyHosts', System.properties['http.nonProxyHosts']
}
systemProperty 'file.encoding', 'UTF-8'
}
task wrapper(type: Wrapper) {
gradleVersion = '3.1'
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,13 +0,0 @@
apply plugin: 'jacoco'
apply plugin: 'com.github.kt3k.coveralls'
jacocoTestReport {
reports {
xml.enabled = true // coveralls plugin depends on xml format report
html.enabled = true
}
}
tasks.coveralls {
dependsOn 'check'
}

View File

@@ -1,151 +0,0 @@
import java.text.SimpleDateFormat
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
apply plugin: "com.jfrog.artifactory"
Date buildTimeAndDate = new Date()
ext {
buildDate = new SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate)
buildTime = new SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate)
projectUrl = 'https://github.com/Swagger2Markup/swagger2markup'
licenseUrl = 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt'
scmUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
issuesUrl = 'https://github.com/Swagger2Markup/swagger2markup/issues'
}
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
}
jar {
manifest {
attributes(
'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")",
'Built-With': "gradle-${project.getGradle().getGradleVersion()}, groovy-${GroovySystem.getVersion()}",
'Build-Time': "${new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")}",
'Specification-Title': "${project.name}",
'Specification-Version': project.version.toString(),
'Implementation-Title': "${project.name}",
'Implementation-Version': project.version.toString()
)
}
}
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 = ''
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', project.name)
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
}
}
}
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'
userOrg = 'swagger2markup'
websiteUrl = projectUrl
issueTrackerUrl = issuesUrl
vcsUrl = scmUrl
desc = rootProject.description
licenses = ['Apache-2.0']
version {
vcsTag = rootProject.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
}
}
}
}
artifactory {
contextUrl = 'https://oss.jfrog.org'
resolve {
repository {
repoKey = 'libs-release'
}
}
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')
}
}
if (System.properties['https.proxyHost']) {
clientConfig.proxy.host = System.properties['https.proxyHost']
clientConfig.proxy.port = System.properties['https.proxyPort'].toInteger()
}
}
tasks.artifactoryPublish {
dependsOn 'check'
}

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Thu Nov 03 09:37: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-3.1-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" "$@"

12
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
@@ -49,7 +49,6 @@ goto fail
@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,
]

View File

@@ -0,0 +1,34 @@
ext.moduleName="io.github.swagger2markup.openapi2markup"
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
resolutionStrategy.force dependencyOverrides.assertj
}
// implementation implLibraries.swaggerV2Converter
compile project(':swagger2markup-asciidoc')
compile project(':swagger2markup-core')
implementation implLibraries.asciiDocJApi
implementation implLibraries.commonsText
implementation implLibraries.commonsBeanUtils
implementation implLibraries.slf4j
implementation implLibraries.swaggerV3
implementation implLibraries.commonsCollections4
implementation implLibraries.commonsConf2
implementation implLibraries.vavr
testImplementation testLibraries.assertj
testImplementation testLibraries.assertjDiff
testImplementation testLibraries.junit
testImplementation testLibraries.logback
}

View File

@@ -0,0 +1,378 @@
/*
* Copyright 2017 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.swagger2markup;
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
import io.github.swagger2markup.config.OpenAPILabels;
import io.github.swagger2markup.config.builder.OpenAPI2MarkupConfigBuilder;
import io.github.swagger2markup.extension.OpenAPI2MarkupExtensionRegistry;
import io.github.swagger2markup.extension.builder.OpenAPI2MarkupExtensionRegistryBuilder;
import io.github.swagger2markup.internal.document.ComponentsDocument;
import io.github.swagger2markup.internal.document.OverviewDocument;
import io.github.swagger2markup.internal.document.PathsDocument;
import io.github.swagger2markup.internal.document.SecurityDocument;
import io.github.swagger2markup.utils.URIUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class OpenAPI2MarkupConverter extends AbstractSchema2MarkupConverter<OpenAPI> {
private final OverviewDocument overviewDocument;
private final PathsDocument pathsDocument;
private final ComponentsDocument componentsDocument;
private final SecurityDocument securityDocument;
private final OpenAPIContext openAPIContext;
public OpenAPI2MarkupConverter(OpenAPIContext context) {
super(context);
this.openAPIContext = context;
this.overviewDocument = new OverviewDocument(context);
this.pathsDocument = new PathsDocument(context);
this.componentsDocument = new ComponentsDocument(context);
this.securityDocument = new SecurityDocument(context);
}
/**
* Creates a OpenAPI2MarkupConverter.Builder from a URI.
*
* @param swaggerUri the URI
* @return a OpenAPI2MarkupConverter
*/
public static Builder from(URI swaggerUri) {
Validate.notNull(swaggerUri, "swaggerUri must not be null");
String scheme = swaggerUri.getScheme();
if (scheme != null && swaggerUri.getScheme().startsWith("http")) {
try {
return from(swaggerUri.toURL());
} catch (MalformedURLException e) {
throw new RuntimeException("Failed to convert URI to URL", e);
}
} else if (scheme != null && swaggerUri.getScheme().startsWith("file")) {
return from(Paths.get(swaggerUri));
} else {
return from(URIUtils.convertUriWithoutSchemeToFileScheme(swaggerUri));
}
}
/**
* Creates a OpenAPI2MarkupConverter.Builder using a remote URL.
*
* @param swaggerURL the remote URL
* @return a OpenAPI2MarkupConverter
*/
public static Builder from(URL swaggerURL) {
Validate.notNull(swaggerURL, "swaggerURL must not be null");
return new Builder(swaggerURL);
}
/**
* Creates a OpenAPI2MarkupConverter.Builder using a local Path.
*
* @param swaggerPath the local Path
* @return a OpenAPI2MarkupConverter
*/
public static Builder from(Path swaggerPath) {
Validate.notNull(swaggerPath, "swaggerPath must not be null");
if (Files.notExists(swaggerPath)) {
throw new IllegalArgumentException(String.format("swaggerPath does not exist: %s", swaggerPath));
}
try {
if (Files.isHidden(swaggerPath)) {
throw new IllegalArgumentException("swaggerPath must not be a hidden file");
}
} catch (IOException e) {
throw new RuntimeException("Failed to check if swaggerPath is a hidden file", e);
}
return new Builder(swaggerPath);
}
/**
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger model.
*
* @param openAPI the Swagger source.
* @return a OpenAPI2MarkupConverter
*/
public static Builder from(OpenAPI openAPI) {
Validate.notNull(openAPI, "schema must not be null");
return new Builder(openAPI);
}
/**
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger YAML or JSON String.
*
* @param swaggerString the Swagger YAML or JSON String.
* @return a OpenAPI2MarkupConverter
*/
public static Builder from(String swaggerString) {
Validate.notEmpty(swaggerString, "swaggerString must not be null");
return from(new StringReader(swaggerString));
}
/**
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger YAML or JSON reader.
*
* @param schemaReader the schema YAML or JSON reader.
* @return a OpenAPI2MarkupConverter
*/
public static Builder from(Reader schemaReader) {
Validate.notNull(schemaReader, "swaggerReader must not be null");
OpenAPI openAPI;
try {
//TODO
openAPI = new OpenAPIV3Parser().read(IOUtils.toString(schemaReader));
} catch (IOException e) {
throw new RuntimeException("Swagger source can not be parsed", e);
}
if (openAPI == null)
throw new IllegalArgumentException("Swagger source is in a wrong format");
return new Builder(openAPI);
}
@Override
public void toFolder(Path outputDirectory) {
Validate.notNull(outputDirectory, "outputDirectory must not be null");
openAPIContext.setOutputPath(outputDirectory);
writeToFile(applyOverviewDocument(), outputDirectory.resolve(openAPIContext.config.getOverviewDocument()));
writeToFile(applyPathsDocument(), outputDirectory.resolve(openAPIContext.config.getPathsDocument()));
writeToFile(applyComponentsDocument(), outputDirectory.resolve(openAPIContext.config.getDefinitionsDocument()));
writeToFile(applySecurityDocument(), outputDirectory.resolve(openAPIContext.config.getSecurityDocument()));
}
@Override
public void toFile(Path outputFile) {
Validate.notNull(outputFile, "outputFile must not be null");
writeToFile(applyOverviewDocument(), outputFile);
writeToFile(applyPathsDocument(), outputFile);
writeToFile(applyComponentsDocument(), outputFile);
writeToFile(applySecurityDocument(), outputFile);
}
@Override
public void toFileWithoutExtension(Path outputFile) {
Validate.notNull(outputFile, "outputFile must not be null");
writeToFileWithoutExtension(applyOverviewDocument(), outputFile);
writeToFileWithoutExtension(applyPathsDocument(), outputFile);
writeToFileWithoutExtension(applyComponentsDocument(), outputFile);
writeToFileWithoutExtension(applySecurityDocument(), outputFile);
}
@Override
public String toString() {
return applyOverviewDocument().convert() +
applyPathsDocument().convert() +
applyComponentsDocument().convert() +
applySecurityDocument().convert();
}
private Document applyOverviewDocument() {
return overviewDocument.apply(
openAPIContext.createDocument(),
OverviewDocument.parameters(openAPIContext.getSchema()));
}
private Document applyPathsDocument() {
return pathsDocument.apply(
openAPIContext.createDocument(),
PathsDocument.parameters(openAPIContext.getSchema()));
}
private Document applyComponentsDocument() {
return componentsDocument.apply(
openAPIContext.createDocument(),
ComponentsDocument.parameters(openAPIContext.getSchema().getComponents()));
}
private Document applySecurityDocument() {
return securityDocument.apply(
openAPIContext.createDocument(),
SecurityDocument.parameters(openAPIContext.getSchema()));
}
private void writeToFile(Document document, Path path) {
MarkupLanguage markupLanguage = openAPIContext.config.getMarkupLanguage();
if (isMarkupLanguageSupported(markupLanguage)) {
String fileExtension = markupLanguage.getFileNameExtensions().get(0);
writeToFileWithoutExtension(document, path.resolveSibling(path.getFileName().toString() + fileExtension));
} else {
throw new RuntimeException("Given Markup language '"+markupLanguage+"' is not supported by "+getClass().getName());
}
}
private boolean isMarkupLanguageSupported(MarkupLanguage markupLanguage) {
return markupLanguage == MarkupLanguage.ASCIIDOC;
}
private void writeToFileWithoutExtension(Document document, Path file) {
if (file.getParent() != null) {
try {
Files.createDirectories(file.getParent());
} catch (IOException e) {
throw new RuntimeException("Failed create directory", e);
}
}
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
writer.write(document.convert());
} catch (IOException e) {
throw new RuntimeException("Failed to write file", e);
}
if (logger.isInfoEnabled()) {
logger.info("Markup document written to: {}", file);
}
}
public static class OpenAPIContext extends Context<OpenAPI> {
private OpenSchema2MarkupConfig config;
private OpenAPI2MarkupExtensionRegistry extensionRegistry;
public OpenAPIContext(OpenSchema2MarkupConfig config,
OpenAPI2MarkupExtensionRegistry extensionRegistry,
OpenAPI schema, URI swaggerLocation, Labels labels) {
super(config, extensionRegistry, schema, swaggerLocation, labels);
this.config = config;
this.extensionRegistry = extensionRegistry;
}
@Override
public OpenSchema2MarkupConfig getConfig() {
return config;
}
@Override
public OpenAPI2MarkupExtensionRegistry getExtensionRegistry() {
return extensionRegistry;
}
public Document createDocument() {
return new DocumentImpl();
}
}
public static class Builder {
private final OpenAPI openAPI;
private final URI schemaLocation;
private OpenSchema2MarkupConfig config;
private OpenAPI2MarkupExtensionRegistry extensionRegistry;
/**
* Creates a Builder from a remote URL.
*
* @param schemaUrl the remote URL
*/
Builder(URL schemaUrl) {
try {
this.schemaLocation = schemaUrl.toURI();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("swaggerURL is in a wrong format", e);
}
this.openAPI = readSchema(schemaUrl.toString());
}
/**
* Creates a Builder from a local Path.
*
* @param swaggerPath the local Path
*/
Builder(Path swaggerPath) {
this.schemaLocation = swaggerPath.toAbsolutePath().toUri();
this.openAPI = readSchema(swaggerPath.toString());
}
/**
* Creates a Builder using a given Swagger model.
*
* @param openAPI the Swagger source.
*/
Builder(OpenAPI openAPI) {
this.openAPI = openAPI;
this.schemaLocation = null;
}
/**
* Uses the SwaggerParser to read the Swagger source.
*
* @param schemaLocation the location of the Swagger source
* @return the Swagger model
*/
private OpenAPI readSchema(String schemaLocation) {
OpenAPI openAPI = new OpenAPIV3Parser().read(schemaLocation);
if (openAPI == null) {
throw new IllegalArgumentException("Failed to read the schema");
}
return openAPI;
}
public Builder withConfig(OpenSchema2MarkupConfig config) {
Validate.notNull(config, "config must not be null");
this.config = config;
return this;
}
public Builder withExtensionRegistry(OpenAPI2MarkupExtensionRegistry registry) {
Validate.notNull(registry, "registry must not be null");
this.extensionRegistry = registry;
return this;
}
public OpenAPI2MarkupConverter build() {
if (config == null)
config = new OpenAPI2MarkupConfigBuilder().build();
if (extensionRegistry == null)
extensionRegistry = new OpenAPI2MarkupExtensionRegistryBuilder().build();
OpenAPILabels openApiLabels = new OpenAPILabels(config);
OpenAPIContext context = new OpenAPIContext(config, extensionRegistry, openAPI, schemaLocation, openApiLabels);
initExtensions(context);
applySwaggerExtensions(context);
return new OpenAPI2MarkupConverter(context);
}
private void initExtensions(OpenAPIContext context) {
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getDefinitionsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getSecurityDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
}
private void applySwaggerExtensions(OpenAPIContext context) {
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.apply(context.getSchema()));
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 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.swagger2markup;
import org.apache.commons.configuration2.Configuration;
import java.util.Map;
import java.util.Properties;
public class OpenAPI2MarkupProperties extends Schema2MarkupProperties {
public OpenAPI2MarkupProperties(Properties properties) {
super(properties);
}
public OpenAPI2MarkupProperties(Map<String, String> map) {
super(map);
}
public OpenAPI2MarkupProperties(Configuration configuration) {
super(configuration);
}
}

View File

@@ -0,0 +1,7 @@
package io.github.swagger2markup;
import io.github.swagger2markup.config.builder.Schema2MarkupConfigBuilder;
public class OpenSchema2MarkupConfig extends Schema2MarkupConfigBuilder.DefaultSchema2MarkupConfig {
}

View File

@@ -0,0 +1,72 @@
package io.github.swagger2markup.config;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.OpenSchema2MarkupConfig;
import java.util.ResourceBundle;
public class OpenAPILabels extends Labels {
public static final String LABEL_CONTENT = "label_content";
public static final String LABEL_DEFAULT = "label_default";
public static final String LABEL_DEPRECATED = "label_deprecated";
public static final String LABEL_EXAMPLE = "label_example";
public static final String LABEL_EXAMPLES = "label_examples";
public static final String LABEL_EXCLUSIVE_MAXIMUM = "label_exclusive_maximum";
public static final String LABEL_EXCLUSIVE_MINIMUM = "label_exclusive_minimum";
public static final String LABEL_EXTERNAL_VALUE = "label_external_value";
public static final String LABEL_FORMAT = "label_format";
public static final String LABEL_MAXIMUM = "label_maximum";
public static final String LABEL_MAX_ITEMS = "label_max_items";
public static final String LABEL_MAX_LENGTH = "label_max_length";
public static final String LABEL_MAX_PROPERTIES = "label_max_properties";
public static final String LABEL_MINIMUM = "label_minimum";
public static final String LABEL_MIN_ITEMS = "label_min_items";
public static final String LABEL_MIN_LENGTH = "label_min_length";
public static final String LABEL_MIN_PROPERTIES = "label_min_properties";
public static final String LABEL_MULTIPLE_OF = "label_multiple_of";
public static final String LABEL_NO_LINKS = "label_no_links";
public static final String LABEL_NULLABLE = "label_nullable";
public static final String LABEL_OPERATION = "label_operation";
public static final String LABEL_OPTIONAL = "label_optional";
public static final String LABEL_PARAMETERS = "label_parameters";
public static final String LABEL_READ_ONLY = "label_read_only";
public static final String LABEL_REQUIRED = "label_required";
public static final String LABEL_SERVER = "label_server";
public static final String LABEL_TERMS_OF_SERVICE = "label_terms_of_service";
public static final String LABEL_TITLE = "label_title";
public static final String LABEL_TYPE = "label_type";
public static final String LABEL_UNIQUE_ITEMS = "label_unique_items";
public static final String LABEL_WRITE_ONLY = "label_write_only";
public static final String SECTION_TITLE_COMPONENTS = "section_title_components";
public static final String SECTION_TITLE_PARAMETERS = "section_title_parameters";
public static final String SECTION_TITLE_PATHS = "section_title_paths";
public static final String SECTION_TITLE_SCHEMAS = "section_title_schemas";
public static final String SECTION_TITLE_SECURITY = "section_title_security";
public static final String SECTION_TITLE_SERVERS = "section_title_servers";
public static final String SECTION_TITLE_OVERVIEW = "section_title_overview";
public static final String SECTION_TITLE_TAGS = "section_title_tags";
public static final String SECTION_TITLE_RESPONSES = "section_title_responses";
public static final String SECTION_TITLE_HEADERS = "section_title_headers";
public static final String SECTION_TITLE_LINKS = "section_title_links";
public static final String TABLE_HEADER_DEFAULT = "table_header_default";
public static final String TABLE_HEADER_DESCRIPTION = "table_header_description";
public static final String TABLE_HEADER_HTTP_CODE = "table_header_http_code";
public static final String TABLE_HEADER_LINKS = "table_header_links";
public static final String TABLE_HEADER_NAME = "table_header_name";
public static final String TABLE_HEADER_POSSIBLE_VALUES = "table_header_possible_values";
public static final String TABLE_HEADER_SCHEMA = "table_header_schema";
public static final String TABLE_HEADER_SCOPES = "table_header_scopes";
public static final String TABLE_HEADER_TYPE = "table_header_type";
public static final String TABLE_HEADER_VARIABLE = "table_header_variable";
public static final String TABLE_TITLE_HEADERS = "table_title_headers";
public static final String TABLE_TITLE_PARAMETERS = "table_title_parameters";
public static final String TABLE_TITLE_PROPERTIES = "table_title_properties";
public static final String TABLE_TITLE_RESPONSES = "table_title_responses";
public static final String TABLE_TITLE_SECURITY = "table_title_security";
public static final String TABLE_TITLE_SERVER_VARIABLES = "table_title_server_variables";
public OpenAPILabels(OpenSchema2MarkupConfig config) {
super(ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getLanguage().toLocale()));
}
}

View File

@@ -0,0 +1,38 @@
package io.github.swagger2markup.config.builder;
import io.github.swagger2markup.OpenAPI2MarkupProperties;
import io.github.swagger2markup.OpenSchema2MarkupConfig;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ConfigurationConverter;
import org.apache.commons.configuration2.MapConfiguration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import java.util.Map;
import java.util.Properties;
public class OpenAPI2MarkupConfigBuilder extends Schema2MarkupConfigBuilder<OpenAPI2MarkupConfigBuilder, OpenSchema2MarkupConfig> {
public OpenAPI2MarkupConfigBuilder() {
this(new PropertiesConfiguration());
}
public OpenAPI2MarkupConfigBuilder(Properties properties) {
this(ConfigurationConverter.getConfiguration(properties));
}
public OpenAPI2MarkupConfigBuilder(Map<String, String> map) {
this(new MapConfiguration(map));
}
private OpenAPI2MarkupConfigBuilder(Configuration configuration) {
super(OpenAPI2MarkupConfigBuilder.class,
new OpenSchema2MarkupConfig(),
new OpenAPI2MarkupProperties(getCompositeConfiguration(configuration)), configuration);
}
@Override
public OpenSchema2MarkupConfig build() {
buildNaturalOrdering();
return config;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import io.github.swagger2markup.OpenAPI2MarkupConverter.OpenAPIContext;
/**
* An abstract OpenAPI extension which must be extended by an other OpenAPI extensions
*/
abstract class AbstractExtension implements Extension {
protected OpenAPIContext globalContext;
/**
* Global context lazy initialization
*
* @param globalContext Global context
*/
public void setGlobalContext(OpenAPIContext globalContext) {
this.globalContext = globalContext;
}
}

View File

@@ -0,0 +1,15 @@
package io.github.swagger2markup.extension;
import org.asciidoctor.ast.Document;
public class ContentContext {
private Document document;
public ContentContext(Document document) {
this.document = document;
}
public Document getDocument() {
return document;
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import io.swagger.models.Model;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import java.util.Optional;
/**
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
*/
public abstract class DefinitionsDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
DOCUMENT_END,
DOCUMENT_AFTER,
DEFINITION_BEFORE,
DEFINITION_BEGIN,
DEFINITION_END,
DEFINITION_AFTER
}
public static class Context extends ContentContext {
private Position position;
/**
* null if position == DOCUMENT_*
*/
private String definitionName;
/**
* null if position == DOCUMENT_*
*/
private Model model;
/**
* @param position the current position
* @param document document object
*/
public Context(Position position, Document document) {
super(document);
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
this.position = position;
}
/**
* @param position the current position
* @param document document object
* @param definitionName the name of the current definition
* @param model the current Model of the definition
*/
public Context(Position position, Document document, String definitionName, Model model) {
super(document);
Validate.inclusiveBetween(Position.DEFINITION_BEFORE, Position.DEFINITION_AFTER, position);
Validate.notNull(definitionName);
Validate.notNull(model);
this.position = position;
this.definitionName = definitionName;
this.model = model;
}
public Position getPosition() {
return position;
}
public Optional<String> getDefinitionName() {
return Optional.ofNullable(definitionName);
}
public Optional<Model> getModel() {
return Optional.ofNullable(model);
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import static io.github.swagger2markup.OpenAPI2MarkupConverter.OpenAPIContext;
/**
* Extension interface which must be implemented by an OpenAPI extension
*/
interface Extension {
/**
* Global context lazy initialization
*
* @param globalContext Global context
*/
void setGlobalContext(OpenAPIContext globalContext);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import io.github.swagger2markup.OpenSchema2MarkupConfig;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.Labels;
import io.swagger.v3.oas.models.OpenAPI;
import io.vavr.Function2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class MarkupComponent<D, T, R> implements Function2<D, T, R> {
protected Logger logger = LoggerFactory.getLogger(getClass());
protected OpenAPI2MarkupConverter.Context<OpenAPI> context;
protected Labels labels;
protected OpenSchema2MarkupConfig config;
protected OpenAPI2MarkupExtensionRegistry extensionRegistry;
public MarkupComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
this.context = context;
this.config = context.getConfig();
this.extensionRegistry = context.getExtensionRegistry();
this.labels = context.getLabels();
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import java.util.List;
/**
* Extension points registry interface.
*/
public interface OpenAPI2MarkupExtensionRegistry extends Schema2MarkupExtensionRegistry {
/**
* OpenAPIModelExtension extension point can be used to preprocess the Swagger model.
*
* @return registered extensions extending OpenAPIModelExtension extension point
*/
List<OpenAPIModelExtension> getSwaggerModelExtensions();
/**
* OverviewDocumentExtension extension point can be used to extend the overview document content.
*
* @return registered extensions extending OverviewDocumentExtension extension point
*/
List<OverviewDocumentExtension> getOverviewDocumentExtensions();
/**
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
*
* @return registered extensions extending DefinitionsDocumentExtension extension point
*/
List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions();
/**
* SecurityContentExtension extension point can be used to extend the security document content.
*
* @return registered extensions extending SecurityContentExtension extension point
*/
List<SecurityDocumentExtension> getSecurityDocumentExtensions();
/**
* PathsDocumentExtension extension point can be used to extend the paths document content.
*
* @return registered extensions extending PathsDocumentExtension extension point
*/
List<PathsDocumentExtension> getPathsDocumentExtensions();
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import io.swagger.v3.oas.models.OpenAPI;
/**
* OpenAPIModelExtension extension point can be used to preprocess the Swagger model.
*/
public abstract class OpenAPIModelExtension extends AbstractExtension {
public abstract void apply(OpenAPI openAPI);
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import org.asciidoctor.ast.Document;
/**
* OverviewDocumentExtension extension point can be used to extend the overview document content.
*/
public abstract class OverviewDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_AFTER,
DOCUMENT_BEGIN,
DOCUMENT_END
}
public static class Context extends ContentContext {
private Position position;
/**
* @param position the current position
* @param document document object
*/
public Context(Position position, Document document) {
super(document);
this.position = position;
}
public Position getPosition() {
return position;
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import io.github.swagger2markup.model.PathOperation;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import java.util.Optional;
/**
* PathsDocumentExtension extension point can be used to extend the paths document content.
*/
public abstract class PathsDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
DOCUMENT_END,
DOCUMENT_AFTER,
OPERATION_BEFORE,
OPERATION_BEGIN,
OPERATION_END,
OPERATION_AFTER,
OPERATION_DESCRIPTION_BEFORE,
OPERATION_DESCRIPTION_BEGIN,
OPERATION_DESCRIPTION_END,
OPERATION_DESCRIPTION_AFTER,
OPERATION_PARAMETERS_BEFORE,
OPERATION_PARAMETERS_BEGIN,
OPERATION_PARAMETERS_END,
OPERATION_PARAMETERS_AFTER,
OPERATION_RESPONSES_BEFORE,
OPERATION_RESPONSES_BEGIN,
OPERATION_RESPONSES_END,
OPERATION_RESPONSES_AFTER,
OPERATION_SECURITY_BEFORE,
OPERATION_SECURITY_BEGIN,
OPERATION_SECURITY_END,
OPERATION_SECURITY_AFTER
}
public static class Context extends ContentContext {
private Position position;
/**
* null if position == DOCUMENT_*
*/
private PathOperation operation;
/**
* Context for positions DOCUMENT_*
*
* @param position the current position
* @param document document object
*/
public Context(Position position, Document document) {
super(document);
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
this.position = position;
}
/**
* Context for all other positions
*
* @param position the current position
* @param document document object
* @param operation the current path operation
*/
public Context(Position position, Document document, PathOperation operation) {
super(document);
Validate.inclusiveBetween(Position.OPERATION_BEFORE, Position.OPERATION_SECURITY_AFTER, position);
Validate.notNull(operation);
this.position = position;
this.operation = operation;
}
public Position getPosition() {
return position;
}
public Optional<PathOperation> getOperation() {
return Optional.ofNullable(operation);
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2017 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.swagger2markup.extension;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import java.util.Optional;
/**
* SecurityContentExtension extension point can be used to extend the security document content.
*/
public abstract class SecurityDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
DOCUMENT_END,
DOCUMENT_AFTER,
SECURITY_SCHEME_BEFORE,
SECURITY_SCHEME_BEGIN,
SECURITY_SCHEME_END,
SECURITY_SCHEME_AFTER
}
public static class Context extends ContentContext {
private Position position;
/**
* null if position == DOCUMENT_*
*/
private String securitySchemeName;
/**
* null if position == DOCUMENT_*
*/
private SecuritySchemeDefinition securityScheme;
/**
* @param position the current position
* @param document the MarkupDocBuilder
*/
public Context(Position position, Document document) {
super(document);
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
this.position = position;
}
/**
* @param position the current position
* @param document the MarkupDocBuilder
* @param securitySchemeName the name of the current securityScheme
* @param securityScheme the current security scheme securityScheme
*/
public Context(Position position, Document document, String securitySchemeName, SecuritySchemeDefinition securityScheme) {
super(document);
Validate.inclusiveBetween(Position.SECURITY_SCHEME_BEFORE, Position.SECURITY_SCHEME_AFTER, position);
Validate.notNull(securitySchemeName);
Validate.notNull(securityScheme);
this.position = position;
this.securitySchemeName = securitySchemeName;
this.securityScheme = securityScheme;
}
public Position getPosition() {
return position;
}
public Optional<String> getSecuritySchemeName() {
return Optional.ofNullable(securitySchemeName);
}
public Optional<SecuritySchemeDefinition> getSecurityScheme() {
return Optional.ofNullable(securityScheme);
}
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright 2017 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.swagger2markup.extension.builder;
import io.github.swagger2markup.extension.*;
import java.util.List;
import static java.util.ServiceLoader.load;
import static org.apache.commons.collections4.IteratorUtils.toList;
public class OpenAPI2MarkupExtensionRegistryBuilder {
private final Context context;
public OpenAPI2MarkupExtensionRegistryBuilder() {
List<OpenAPIModelExtension> openAPIModelExtensions = toList(load(OpenAPIModelExtension.class).iterator());
List<OverviewDocumentExtension> overviewDocumentExtensions = toList(load(OverviewDocumentExtension.class).iterator());
List<DefinitionsDocumentExtension> definitionsDocumentExtensions = toList(load(DefinitionsDocumentExtension.class).iterator());
List<PathsDocumentExtension> pathsDocumentExtensions = toList(load(PathsDocumentExtension.class).iterator());
List<SecurityDocumentExtension> securityDocumentExtensions = toList(load(SecurityDocumentExtension.class).iterator());
context = new Context(
openAPIModelExtensions,
overviewDocumentExtensions,
definitionsDocumentExtensions,
pathsDocumentExtensions,
securityDocumentExtensions);
}
public OpenAPI2MarkupExtensionRegistry build() {
return new DefaultOpenAPI2MarkupExtensionRegistry(context);
}
public OpenAPI2MarkupExtensionRegistryBuilder withSwaggerModelExtension(OpenAPIModelExtension extension) {
context.openAPIModelExtensions.add(extension);
return this;
}
public OpenAPI2MarkupExtensionRegistryBuilder withOverviewDocumentExtension(OverviewDocumentExtension extension) {
context.overviewDocumentExtensions.add(extension);
return this;
}
public OpenAPI2MarkupExtensionRegistryBuilder withDefinitionsDocumentExtension(DefinitionsDocumentExtension extension) {
context.definitionsDocumentExtensions.add(extension);
return this;
}
public OpenAPI2MarkupExtensionRegistryBuilder withPathsDocumentExtension(PathsDocumentExtension extension) {
context.pathsDocumentExtensions.add(extension);
return this;
}
public OpenAPI2MarkupExtensionRegistryBuilder withSecurityDocumentExtension(SecurityDocumentExtension extension) {
context.securityDocumentExtensions.add(extension);
return this;
}
static class DefaultOpenAPI2MarkupExtensionRegistry implements OpenAPI2MarkupExtensionRegistry {
private Context context;
DefaultOpenAPI2MarkupExtensionRegistry(Context context) {
this.context = context;
}
@Override
public List<OpenAPIModelExtension> getSwaggerModelExtensions() {
return context.openAPIModelExtensions;
}
@Override
public List<OverviewDocumentExtension> getOverviewDocumentExtensions() {
return context.overviewDocumentExtensions;
}
@Override
public List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions() {
return context.definitionsDocumentExtensions;
}
@Override
public List<SecurityDocumentExtension> getSecurityDocumentExtensions() {
return context.securityDocumentExtensions;
}
@Override
public List<PathsDocumentExtension> getPathsDocumentExtensions() {
return context.pathsDocumentExtensions;
}
}
private static class Context {
final List<OpenAPIModelExtension> openAPIModelExtensions;
final List<OverviewDocumentExtension> overviewDocumentExtensions;
final List<DefinitionsDocumentExtension> definitionsDocumentExtensions;
final List<PathsDocumentExtension> pathsDocumentExtensions;
final List<SecurityDocumentExtension> securityDocumentExtensions;
Context(List<OpenAPIModelExtension> openAPIModelExtensions,
List<OverviewDocumentExtension> overviewDocumentExtensions,
List<DefinitionsDocumentExtension> definitionsDocumentExtensions,
List<PathsDocumentExtension> pathsDocumentExtensions,
List<SecurityDocumentExtension> securityDocumentExtensions) {
this.openAPIModelExtensions = openAPIModelExtensions;
this.overviewDocumentExtensions = overviewDocumentExtensions;
this.definitionsDocumentExtensions = definitionsDocumentExtensions;
this.pathsDocumentExtensions = pathsDocumentExtensions;
this.securityDocumentExtensions = securityDocumentExtensions;
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.media.Encoding;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.StructuralNode;
import java.util.Collections;
import java.util.Map;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLES;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.italicUnconstrained;
public class EncodingComponent extends MarkupComponent<StructuralNode, EncodingComponent.Parameters, StructuralNode> {
private final HeadersComponent headersComponent;
public EncodingComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.headersComponent = new HeadersComponent(context);
}
public static EncodingComponent.Parameters parameters(Map<String, Encoding> encodings) {
return new EncodingComponent.Parameters(encodings);
}
public StructuralNode apply(StructuralNode node, Map<String, Encoding> encodings) {
return apply(node, parameters(encodings));
}
@Override
public StructuralNode apply(StructuralNode node, EncodingComponent.Parameters parameters) {
Map<String, Encoding> encodings = parameters.encodings;
if (encodings == null || encodings.isEmpty()) return node;
DescriptionListImpl encodingList = new DescriptionListImpl(node);
encodingList.setTitle(labels.getLabel(LABEL_EXAMPLES));
encodings.forEach((name, encoding) -> {
DescriptionListEntryImpl encodingEntry = new DescriptionListEntryImpl(encodingList, Collections.singletonList(new ListItemImpl(encodingList, name)));
ListItemImpl tagDesc = new ListItemImpl(encodingEntry, "");
ParagraphBlockImpl encodingBlock = new ParagraphBlockImpl(tagDesc);
StringBuilder sb = new StringBuilder();
String contentType = encoding.getContentType();
if(StringUtils.isNotBlank(contentType)){
sb.append("Content-Type:").append(contentType).append(LINE_SEPARATOR);
}
if(encoding.getAllowReserved()){
sb.append(italicUnconstrained("Allow Reserved").toLowerCase()).append(LINE_SEPARATOR);
}
if(encoding.getExplode()){
sb.append(italicUnconstrained("Explode").toLowerCase()).append(LINE_SEPARATOR);
}
Encoding.StyleEnum style = encoding.getStyle();
if(style != null){
sb.append("style").append(style).append(LINE_SEPARATOR);
}
encodingBlock.setSource(sb.toString());
tagDesc.append(encodingBlock);
headersComponent.apply(tagDesc, encoding.getHeaders());
encodingEntry.setDescription(tagDesc);
encodingList.addEntry(encodingEntry);
});
node.append(encodingList);
return node;
}
public static class Parameters {
private final Map<String, Encoding> encodings;
public Parameters(Map<String, Encoding> encodings) {
this.encodings = encodings;
}
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.examples.Example;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.StructuralNode;
import java.util.Collections;
import java.util.Map;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLES;
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXTERNAL_VALUE;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.appendDescription;
public class ExamplesComponent extends MarkupComponent<StructuralNode, ExamplesComponent.Parameters, StructuralNode> {
private final MediaTypeExampleComponent mediaTypeExampleComponent;
public ExamplesComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.mediaTypeExampleComponent = new MediaTypeExampleComponent(context);
}
public static ExamplesComponent.Parameters parameters(Map<String, Example> examples) {
return new ExamplesComponent.Parameters(examples);
}
public StructuralNode apply(StructuralNode node, Map<String, Example> examples) {
return apply(node, parameters(examples));
}
@Override
public StructuralNode apply(StructuralNode node, ExamplesComponent.Parameters parameters) {
Map<String, Example> examples = parameters.examples;
if (examples == null || examples.isEmpty()) return node;
DescriptionListImpl examplesList = new DescriptionListImpl(node);
examplesList.setTitle(labels.getLabel(LABEL_EXAMPLES));
examples.forEach((name, example) -> {
DescriptionListEntryImpl exampleEntry = new DescriptionListEntryImpl(examplesList, Collections.singletonList(new ListItemImpl(examplesList, name)));
ListItemImpl tagDesc = new ListItemImpl(exampleEntry, "");
ParagraphBlockImpl exampleBlock = new ParagraphBlockImpl(tagDesc);
appendDescription(exampleBlock, example.getSummary());
appendDescription(exampleBlock, example.getDescription());
mediaTypeExampleComponent.apply(tagDesc, example.getValue());
ParagraphBlockImpl paragraphBlock = new ParagraphBlockImpl(tagDesc);
String source = "";
generateRefLink(source, example.getExternalValue(), labels.getLabel(LABEL_EXTERNAL_VALUE));
generateRefLink(source, example.get$ref(), "");
if(StringUtils.isNotBlank(source)){
paragraphBlock.setSource(source);
tagDesc.append(paragraphBlock);
}
exampleEntry.setDescription(tagDesc);
examplesList.addEntry(exampleEntry);
});
node.append(examplesList);
return node;
}
private String generateRefLink(String source, String ref, String alt) {
if (StringUtils.isNotBlank(ref)) {
if (StringUtils.isBlank(alt)) {
alt = ref.substring(ref.lastIndexOf('/') + 1);
}
String anchor = ref.replaceFirst("#", "").replaceAll("/", "_");
source += "<<" + anchor + "," + alt + ">>" + LINE_SEPARATOR;
}
return source;
}
public static class Parameters {
private final Map<String, Example> examples;
public Parameters(Map<String, Example> examples) {
this.examples = examples;
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.extension.MarkupComponent;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.swagger.v3.oas.models.ExternalDocumentation;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.Block;
import org.asciidoctor.ast.StructuralNode;
public class ExternalDocumentationComponent extends MarkupComponent<StructuralNode, ExternalDocumentationComponent.Parameters, StructuralNode> {
public ExternalDocumentationComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
}
public static Parameters parameters(ExternalDocumentation externalDocs) {
return new Parameters(externalDocs);
}
public StructuralNode apply(StructuralNode node, ExternalDocumentation externalDocs) {
return apply(node, parameters(externalDocs));
}
@Override
public StructuralNode apply(StructuralNode node, Parameters params) {
ExternalDocumentation externalDocs = params.externalDocs;
if (externalDocs == null) return node;
String url = externalDocs.getUrl();
if (StringUtils.isNotBlank(url)) {
Block paragraph = new ParagraphBlockImpl(node);
String desc = externalDocs.getDescription();
paragraph.setSource(url + (StringUtils.isNotBlank(desc) ? "[" + desc + "]" : ""));
node.append(paragraph);
}
return node;
}
public static class Parameters {
private final ExternalDocumentation externalDocs;
public Parameters(ExternalDocumentation externalDocs) {
this.externalDocs = externalDocs;
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.headers.Header;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.generateInnerDoc;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.getSchemaTypeAsString;
public class HeadersComponent extends MarkupComponent<StructuralNode, HeadersComponent.Parameters, StructuralNode> {
private final SchemaComponent schemaComponent;
public HeadersComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.schemaComponent = new SchemaComponent(context);
}
public static HeadersComponent.Parameters parameters(Map<String, Header> headers) {
return new HeadersComponent.Parameters(headers);
}
public StructuralNode apply(StructuralNode node, Map<String, Header> headers) {
return apply(node, parameters(headers));
}
@Override
public StructuralNode apply(StructuralNode node, HeadersComponent.Parameters parameters) {
Map<String, Header> headers = parameters.headers;
if (null == headers || headers.isEmpty()) return node;
TableImpl responseHeadersTable = new TableImpl(node, new HashMap<>(), new ArrayList<>());
responseHeadersTable.setOption("header");
responseHeadersTable.setAttribute("caption", "", true);
responseHeadersTable.setAttribute("cols", ".^2a,.^14a,.^4a", true);
responseHeadersTable.setTitle(labels.getLabel(TABLE_TITLE_HEADERS));
responseHeadersTable.setHeaderRow(labels.getLabel(TABLE_HEADER_NAME), labels.getLabel(TABLE_HEADER_DESCRIPTION), labels.getLabel(TABLE_HEADER_SCHEMA));
headers.forEach((name, header) ->
responseHeadersTable.addRow(
generateInnerDoc(responseHeadersTable, name),
generateInnerDoc(responseHeadersTable, Optional.ofNullable(header.getDescription()).orElse("")),
generateInnerDoc(responseHeadersTable, getSchemaTypeAsString(header.getSchema()))
));
node.append(responseHeadersTable);
return node;
}
public static class Parameters {
private final Map<String, Header> headers;
public Parameters(Map<String, Header> headers) {
this.headers = headers;
}
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.links.Link;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import java.util.Map;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.italicUnconstrained;
public class LinkComponent extends MarkupComponent<StructuralNode, LinkComponent.Parameters, StructuralNode> {
public LinkComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
}
public static LinkComponent.Parameters parameters(Map<String, Link> links) {
return new LinkComponent.Parameters(links);
}
public Document apply(StructuralNode parent, Map<String, Link> links) {
return apply(parent, parameters(links));
}
@Override
public Document apply(StructuralNode parent, LinkComponent.Parameters parameters) {
DocumentImpl linksDocument = new DocumentImpl(parent);
ParagraphBlockImpl linkParagraph = new ParagraphBlockImpl(linksDocument);
Map<String, Link> links = parameters.links;
if (null == links || links.isEmpty()) {
linkParagraph.setSource(labels.getLabel(LABEL_NO_LINKS));
} else {
StringBuilder sb = new StringBuilder();
links.forEach((name, link) -> {
sb.append(name).append(" +").append(LINE_SEPARATOR);
sb.append(italicUnconstrained(labels.getLabel(LABEL_OPERATION))).append(' ')
.append(italicUnconstrained(link.getOperationId())).append(" +").append(LINE_SEPARATOR);
Map<String, String> linkParameters = link.getParameters();
if (null != linkParameters && !linkParameters.isEmpty()) {
sb.append(italicUnconstrained(labels.getLabel(LABEL_PARAMETERS))).append(" {").append(" +").append(LINE_SEPARATOR);
linkParameters.forEach((param, value) ->
sb.append('"').append(param).append("\": \"").append(value).append('"').append(" +").append(LINE_SEPARATOR)
);
sb.append('}').append(" +").append(LINE_SEPARATOR);
}
});
linkParagraph.setSource(sb.toString());
}
linksDocument.append(linkParagraph);
return linksDocument;
}
public static class Parameters {
private final Map<String, Link> links;
public Parameters(Map<String, Link> links) {
this.links = links;
}
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.media.Content;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import java.util.Collections;
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_CONTENT;
public class MediaContentComponent extends MarkupComponent<StructuralNode, MediaContentComponent.Parameters, StructuralNode> {
private final MediaTypeExampleComponent mediaTypeExampleComponent;
private final ExamplesComponent examplesComponent;
private final SchemaComponent schemaComponent;
private final EncodingComponent encodingComponent;
public MediaContentComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.mediaTypeExampleComponent = new MediaTypeExampleComponent(context);
this.examplesComponent = new ExamplesComponent(context);
this.schemaComponent = new SchemaComponent(context);
this.encodingComponent = new EncodingComponent(context);
}
public static MediaContentComponent.Parameters parameters(Content content) {
return new MediaContentComponent.Parameters(content);
}
public StructuralNode apply(StructuralNode node, Content content) {
return apply(node, parameters(content));
}
@Override
public StructuralNode apply(StructuralNode node, MediaContentComponent.Parameters parameters) {
Content content = parameters.content;
if (content == null || content.isEmpty()) return node;
DescriptionListImpl mediaContentList = new DescriptionListImpl(node);
mediaContentList.setTitle(labels.getLabel(LABEL_CONTENT));
content.forEach((type, mediaType) -> {
DescriptionListEntryImpl tagEntry = new DescriptionListEntryImpl(mediaContentList, Collections.singletonList(new ListItemImpl(mediaContentList, type)));
ListItemImpl tagDesc = new ListItemImpl(tagEntry, "");
Document tagDescDocument = schemaComponent.apply(mediaContentList, mediaType.getSchema());
mediaTypeExampleComponent.apply(tagDescDocument, mediaType.getExample());
examplesComponent.apply(tagDescDocument, mediaType.getExamples());
encodingComponent.apply(tagDescDocument, mediaType.getEncoding());
tagDesc.append(tagDescDocument);
tagEntry.setDescription(tagDesc);
mediaContentList.addEntry(tagEntry);
});
node.append(mediaContentList);
return node;
}
public static class Parameters {
private final Content content;
public Parameters(Content content) {
this.content = content;
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.StructuralNode;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.DELIMITER_BLOCK;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLE;
public class MediaTypeExampleComponent extends MarkupComponent<StructuralNode, MediaTypeExampleComponent.Parameters, StructuralNode> {
public MediaTypeExampleComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
}
public static MediaTypeExampleComponent.Parameters parameters(Object example) {
return new MediaTypeExampleComponent.Parameters(example);
}
public StructuralNode apply(StructuralNode node, Object example) {
return apply(node, parameters(example));
}
@Override
public StructuralNode apply(StructuralNode node, MediaTypeExampleComponent.Parameters parameters) {
Object example = parameters.example;
if (example == null || StringUtils.isBlank(example.toString())) return node;
ParagraphBlockImpl sourceBlock = new ParagraphBlockImpl(node);
sourceBlock.setTitle(labels.getLabel(LABEL_EXAMPLE));
sourceBlock.setAttribute("style", "source", true);
sourceBlock.setSource(DELIMITER_BLOCK + LINE_SEPARATOR + example + LINE_SEPARATOR + DELIMITER_BLOCK);
node.append(sourceBlock);
return node;
}
public static class Parameters {
private final Object example;
public Parameters(Object example) {
this.example = example;
}
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.parameters.Parameter;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.ast.Table;
import java.util.*;
import java.util.stream.Collectors;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
public class ParametersComponent extends MarkupComponent<StructuralNode, ParametersComponent.Parameters, StructuralNode> {
private final SchemaComponent schemaComponent;
public ParametersComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.schemaComponent = new SchemaComponent(context);
}
public static ParametersComponent.Parameters parameters(Map<String, Parameter> parameters) {
return new ParametersComponent.Parameters(parameters);
}
public static ParametersComponent.Parameters parameters(List<Parameter> parameters) {
if(null == parameters) {
return new ParametersComponent.Parameters(new HashMap<>());
}
return new ParametersComponent.Parameters(parameters.stream().collect(Collectors.toMap(Parameter::getName, parameter -> parameter)));
}
public StructuralNode apply(StructuralNode parent, List<Parameter> params) {
return apply(parent, parameters(params));
}
public StructuralNode apply(StructuralNode parent, Map<String, Parameter> params) {
return apply(parent, parameters(params));
}
@Override
public StructuralNode apply(StructuralNode parent, ParametersComponent.Parameters componentParameters) {
Map<String, Parameter> parameters = componentParameters.parameters;
if (null == parameters || parameters.isEmpty()) return parent;
TableImpl pathParametersTable = new TableImpl(parent, new HashMap<>(), new ArrayList<>());
pathParametersTable.setOption("header");
pathParametersTable.setAttribute("caption", "", true);
pathParametersTable.setAttribute("cols", ".^2a,.^3a,.^10a,.^5a", true);
pathParametersTable.setTitle(labels.getLabel(TABLE_TITLE_PARAMETERS));
pathParametersTable.setHeaderRow(
labels.getLabel(TABLE_HEADER_TYPE),
labels.getLabel(TABLE_HEADER_NAME),
labels.getLabel(TABLE_HEADER_DESCRIPTION),
labels.getLabel(TABLE_HEADER_SCHEMA));
parameters.forEach((alt, parameter) ->
pathParametersTable.addRow(
generateInnerDoc(pathParametersTable, boldUnconstrained(parameter.getIn()), alt),
getParameterNameDocument(pathParametersTable, parameter),
generateInnerDoc(pathParametersTable, Optional.ofNullable(parameter.getDescription()).orElse("")),
generateInnerDoc(pathParametersTable, getSchemaTypeAsString(parameter.getSchema()))
));
parent.append(pathParametersTable);
return parent;
}
private Document getParameterNameDocument(Table table, Parameter parameter) {
String documentContent = boldUnconstrained(parameter.getName()) + " +" + LINE_SEPARATOR + requiredIndicator(parameter.getRequired(),
labels.getLabel(LABEL_REQUIRED), labels.getLabel(LABEL_OPTIONAL));
return generateInnerDoc(table, documentContent);
}
public static class Parameters {
private final Map<String, Parameter> parameters;
public Parameters(Map<String, Parameter> parameters) {
this.parameters = parameters;
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.media.Schema;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
public class PropertiesTableComponent extends MarkupComponent<StructuralNode, PropertiesTableComponent.Parameters, StructuralNode> {
private final SchemaComponent schemaComponent;
PropertiesTableComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.schemaComponent = new SchemaComponent(context);
}
public static Parameters parameters(@SuppressWarnings("rawtypes") Map<String, Schema> properties, List<String> schemaRequired) {
return new Parameters(properties, schemaRequired);
}
public StructuralNode apply(StructuralNode parent, @SuppressWarnings("rawtypes") Map<String, Schema> properties, List<String> schemaRequired) {
return apply(parent, parameters(properties, schemaRequired));
}
public StructuralNode apply(StructuralNode parent, Parameters params) {
@SuppressWarnings("rawtypes") Map<String, Schema> properties = params.properties;
List<String> schemaRequired = params.schemaRequired;
if (null == properties || properties.isEmpty()) return parent;
List<String> finalSchemaRequired = (null == schemaRequired) ? new ArrayList<>() : schemaRequired;
TableImpl propertiesTable = new TableImpl(parent, new HashMap<>(), new ArrayList<>());
propertiesTable.setOption("header");
propertiesTable.setAttribute("caption", "", true);
propertiesTable.setAttribute("cols", ".^4a,.^16a,.^4a", true);
propertiesTable.setTitle(labels.getLabel(TABLE_TITLE_PROPERTIES));
propertiesTable.setHeaderRow(
labels.getLabel(TABLE_HEADER_NAME),
labels.getLabel(TABLE_HEADER_DESCRIPTION),
labels.getLabel(TABLE_HEADER_SCHEMA));
properties.forEach((name, schema) -> propertiesTable.addRow(
generateInnerDoc(propertiesTable, name + LINE_SEPARATOR + requiredIndicator(finalSchemaRequired.contains(name),
labels.getLabel(LABEL_REQUIRED), labels.getLabel(LABEL_OPTIONAL))),
schemaComponent.apply(propertiesTable, schema),
generateInnerDoc(propertiesTable, getSchemaTypeAsString(schema))
));
parent.append(propertiesTable);
return parent;
}
@SuppressWarnings("rawtypes")
public static class Parameters {
private final Map<String, Schema> properties;
private final List<String> schemaRequired;
public Parameters(Map<String, Schema> properties, List<String> schemaRequired) {
this.properties = properties;
this.schemaRequired = schemaRequired;
}
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.ast.Table;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.generateInnerDoc;
public class ResponseComponent extends MarkupComponent<StructuralNode, ResponseComponent.Parameters, StructuralNode> {
private final HeadersComponent headersComponent;
private final LinkComponent linkComponent;
private final MediaContentComponent mediaContentComponent;
public ResponseComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.headersComponent = new HeadersComponent(context);
this.linkComponent = new LinkComponent(context);
this.mediaContentComponent = new MediaContentComponent(context);
}
public static Parameters parameters(Map<String, ApiResponse> apiResponses) {
return new Parameters(apiResponses);
}
public StructuralNode apply(StructuralNode serverSection, Map<String, ApiResponse> apiResponses) {
return apply(serverSection, parameters(apiResponses));
}
@Override
public StructuralNode apply(StructuralNode serverSection, Parameters params) {
Map<String, ApiResponse> apiResponses = params.apiResponses;
if (null == apiResponses || apiResponses.isEmpty()) return serverSection;
TableImpl pathResponsesTable = new TableImpl(serverSection, new HashMap<>(), new ArrayList<>());
pathResponsesTable.setOption("header");
pathResponsesTable.setAttribute("caption", "", true);
pathResponsesTable.setAttribute("cols", ".^2a,.^14a,.^4a", true);
pathResponsesTable.setTitle(labels.getLabel(TABLE_TITLE_RESPONSES));
pathResponsesTable.setHeaderRow(
labels.getLabel(TABLE_HEADER_HTTP_CODE),
labels.getLabel(TABLE_HEADER_DESCRIPTION),
labels.getLabel(TABLE_HEADER_LINKS));
apiResponses.forEach((httpCode, apiResponse) ->
pathResponsesTable.addRow(
generateInnerDoc(pathResponsesTable, httpCode),
getResponseDescriptionColumnDocument(pathResponsesTable, apiResponse),
linkComponent.apply(pathResponsesTable, apiResponse.getLinks())
));
serverSection.append(pathResponsesTable);
return serverSection;
}
private Document getResponseDescriptionColumnDocument(Table table, ApiResponse apiResponse) {
Document document = generateInnerDoc(table, Optional.ofNullable(apiResponse.getDescription()).orElse(""));
headersComponent.apply(document, apiResponse.getHeaders());
mediaContentComponent.apply(document, apiResponse.getContent());
return document;
}
public static class Parameters {
private final Map<String, ApiResponse> apiResponses;
public Parameters(Map<String, ApiResponse> apiResponses) {
this.apiResponses = apiResponses;
}
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.github.swagger2markup.internal.helper.OpenApiHelpers;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.boldUnconstrained;
public class SchemaComponent extends MarkupComponent<StructuralNode, SchemaComponent.Parameters, StructuralNode> {
private final OpenAPI2MarkupConverter.OpenAPIContext context;
public SchemaComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.context = context;
}
public static SchemaComponent.Parameters parameters(@SuppressWarnings("rawtypes") Schema schema) {
return new SchemaComponent.Parameters(schema);
}
public Document apply(StructuralNode parent, @SuppressWarnings("rawtypes") Schema schema) {
return apply(parent, parameters(schema));
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Document apply(StructuralNode parent, SchemaComponent.Parameters parameters) {
Document schemaDocument = new DocumentImpl(parent);
Schema schema = parameters.schema;
if (null == schema) return schemaDocument;
OpenApiHelpers.appendDescription(schemaDocument, schema.getDescription());
Map<String, Boolean> schemasBooleanProperties = new HashMap<String, Boolean>() {{
put(labels.getLabel(LABEL_DEPRECATED), schema.getDeprecated());
put(labels.getLabel(LABEL_NULLABLE), schema.getNullable());
put(labels.getLabel(LABEL_READ_ONLY), schema.getReadOnly());
put(labels.getLabel(LABEL_WRITE_ONLY), schema.getWriteOnly());
put(labels.getLabel(LABEL_UNIQUE_ITEMS), schema.getUniqueItems());
put(labels.getLabel(LABEL_EXCLUSIVE_MAXIMUM), schema.getExclusiveMaximum());
put(labels.getLabel(LABEL_EXCLUSIVE_MINIMUM), schema.getExclusiveMinimum());
}};
Map<String, Object> schemasValueProperties = new HashMap<String, Object>() {{
put(labels.getLabel(LABEL_TITLE), schema.getTitle());
put(labels.getLabel(LABEL_DEFAULT), schema.getDefault());
put(labels.getLabel(LABEL_MAXIMUM), schema.getMaximum());
put(labels.getLabel(LABEL_MINIMUM), schema.getMinimum());
put(labels.getLabel(LABEL_MAX_LENGTH), schema.getMaxLength());
put(labels.getLabel(LABEL_MIN_LENGTH), schema.getMinLength());
put(labels.getLabel(LABEL_MAX_ITEMS), schema.getMaxItems());
put(labels.getLabel(LABEL_MIN_ITEMS), schema.getMinItems());
put(labels.getLabel(LABEL_MAX_PROPERTIES), schema.getMaxProperties());
put(labels.getLabel(LABEL_MIN_PROPERTIES), schema.getMinProperties());
put(labels.getLabel(LABEL_MULTIPLE_OF), schema.getMultipleOf());
}};
Stream<String> schemaBooleanStream = schemasBooleanProperties.entrySet().stream()
.filter(e -> null != e.getValue() && e.getValue())
.map(e -> OpenApiHelpers.italicUnconstrained(e.getKey().toLowerCase()));
Stream<String> schemaValueStream = schemasValueProperties.entrySet().stream()
.filter(e -> null != e.getValue() && StringUtils.isNotBlank(e.getValue().toString()))
.map(e -> boldUnconstrained(e.getKey()) + ": " + e.getValue());
ParagraphBlockImpl paragraphBlock = new ParagraphBlockImpl(schemaDocument);
String source = Stream.concat(schemaBooleanStream, schemaValueStream).collect(Collectors.joining(" +" + LINE_SEPARATOR));
paragraphBlock.setSource(source);
schemaDocument.append(paragraphBlock);
Map<String, Schema> properties = schema.getProperties();
if (null != properties && !properties.isEmpty()) {
PropertiesTableComponent propertiesTableComponent = new PropertiesTableComponent(context);
propertiesTableComponent.apply(schemaDocument, properties, schema.getRequired());
}
return schemaDocument;
}
@SuppressWarnings("rawtypes")
public static class Parameters {
private final Schema schema;
public Parameters(Schema schema) {
this.schema = schema;
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
public class SecurityRequirementTableComponent extends MarkupComponent<StructuralNode, SecurityRequirementTableComponent.Parameters, StructuralNode> {
public SecurityRequirementTableComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
}
public static SecurityRequirementTableComponent.Parameters parameters(List<SecurityRequirement> securityRequirements, boolean addTitle) {
return new SecurityRequirementTableComponent.Parameters(securityRequirements, addTitle);
}
public StructuralNode apply(StructuralNode document, List<SecurityRequirement> securityRequirements, boolean addTitle) {
return apply(document, parameters(securityRequirements, addTitle));
}
@Override
public StructuralNode apply(StructuralNode node, SecurityRequirementTableComponent.Parameters parameters) {
List<SecurityRequirement> securityRequirements = parameters.securityRequirements;
if (securityRequirements == null || securityRequirements.isEmpty()) return node;
TableImpl securityRequirementsTable = new TableImpl(node, new HashMap<>(), new ArrayList<>());
securityRequirementsTable.setOption("header");
securityRequirementsTable.setAttribute("caption", "", true);
securityRequirementsTable.setAttribute("cols", ".^3a,.^4a,.^13a", true);
if (parameters.addTitle) {
securityRequirementsTable.setTitle(labels.getLabel(TABLE_TITLE_SECURITY));
}
securityRequirementsTable.setHeaderRow(
labels.getLabel(TABLE_HEADER_TYPE),
labels.getLabel(TABLE_HEADER_NAME),
labels.getLabel(TABLE_HEADER_SCOPES));
securityRequirements.forEach(securityRequirement ->
securityRequirement.forEach((name, scopes) ->
securityRequirementsTable.addRow(
generateInnerDoc(securityRequirementsTable, boldUnconstrained(scopes.isEmpty() ? "apiKey" : "oauth2")),
generateInnerDoc(securityRequirementsTable, name),
generateInnerDoc(securityRequirementsTable, String.join(", ", scopes))
)
)
);
node.append(securityRequirementsTable);
return node;
}
public static class Parameters {
private final List<SecurityRequirement> securityRequirements;
private final boolean addTitle;
public Parameters(List<SecurityRequirement> securityRequirements, boolean addTitle) {
this.securityRequirements = securityRequirements;
this.addTitle = addTitle;
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2017 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.swagger2markup.internal.component;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.swagger.v3.oas.models.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.Section;
import java.util.Collections;
import java.util.List;
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_TAGS;
public class TagsComponent extends MarkupComponent<Document, TagsComponent.Parameters, Document> {
private final ExternalDocumentationComponent externalDocumentationComponent;
public TagsComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
}
public static TagsComponent.Parameters parameters(List<Tag> tags) {
return new TagsComponent.Parameters(tags);
}
public Document apply(Document document, List<Tag> tags) {
return apply(document, parameters(tags));
}
@Override
public Document apply(Document document, TagsComponent.Parameters parameters) {
List<Tag> openAPITags = parameters.tags;
if (null == openAPITags || openAPITags.isEmpty()) return document;
Section tagsSection = new SectionImpl(document);
tagsSection.setTitle(labels.getLabel(SECTION_TITLE_TAGS));
DescriptionListImpl tagsList = new DescriptionListImpl(tagsSection);
openAPITags.forEach(tag -> {
DescriptionListEntryImpl tagEntry = new DescriptionListEntryImpl(tagsList, Collections.singletonList(new ListItemImpl(tagsList, tag.getName())));
String description = tag.getDescription();
if(StringUtils.isNotBlank(description)){
ListItemImpl tagDesc = new ListItemImpl(tagEntry, "");
tagDesc.setSource(description);
externalDocumentationComponent.apply(tagDesc, tag.getExternalDocs());
tagEntry.setDescription(tagDesc);
}
tagsList.addEntry(tagEntry);
});
tagsSection.append(tagsList);
document.append(tagsSection);
return document;
}
public static class Parameters {
private final List<Tag> tags;
public Parameters(List<Tag> tags) {
this.tags = tags;
}
}
}

View File

@@ -0,0 +1,122 @@
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.github.swagger2markup.internal.component.*;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.links.Link;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.Section;
import org.asciidoctor.ast.StructuralNode;
import java.util.Map;
import static io.github.swagger2markup.config.OpenAPILabels.*;
public class ComponentsDocument extends MarkupComponent<Document, ComponentsDocument.Parameters, Document> {
private final ParametersComponent parametersComponent;
private final ResponseComponent responseComponent;
private final HeadersComponent headersComponent;
private final SchemaComponent schemaComponent;
private final LinkComponent linkComponent;
public ComponentsDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.parametersComponent = new ParametersComponent(context);
this.responseComponent = new ResponseComponent(context);
this.headersComponent = new HeadersComponent(context);
this.schemaComponent = new SchemaComponent(context);
this.linkComponent = new LinkComponent(context);
}
public static Parameters parameters(Components components) {
return new Parameters(components);
}
@Override
public Document apply(Document document, ComponentsDocument.Parameters parameters) {
appendComponentsSection(document, parameters.components);
return document;
}
public static class Parameters {
private final Components components;
public Parameters(Components components) {
this.components = Validate.notNull(components, "Schema must not be null");
}
}
private void appendComponentsSection(Document document, Components components) {
if (null == components) return;
Section componentsSection = new SectionImpl(document);
componentsSection.setTitle(labels.getLabel(SECTION_TITLE_COMPONENTS));
String componentSectionId = "_components";
componentsSection.setId(componentSectionId);
appendComponentsSchemasSection(componentsSection, componentSectionId, components.getSchemas());
Map<String, Parameter> parameters = components.getParameters();
if (null != parameters && !parameters.isEmpty()) {
appendSubSection(componentsSection, componentSectionId, parametersComponent, SECTION_TITLE_PARAMETERS,
new ParametersComponent.Parameters(parameters));
}
Map<String, ApiResponse> responses = components.getResponses();
if (null != responses && !responses.isEmpty()) {
appendSubSection(componentsSection, componentSectionId, responseComponent, SECTION_TITLE_RESPONSES,
new ResponseComponent.Parameters(responses));
}
Map<String, Header> headers = components.getHeaders();
if (null != headers && !headers.isEmpty()) {
appendSubSection(componentsSection, componentSectionId, headersComponent, SECTION_TITLE_HEADERS,
new HeadersComponent.Parameters(headers));
}
Map<String, Link> links = components.getLinks();
if (null != links && !links.isEmpty()) {
appendSubSection(componentsSection, componentSectionId, linkComponent, SECTION_TITLE_LINKS,
new LinkComponent.Parameters(links));
}
document.append(componentsSection);
}
private void appendComponentsSchemasSection(
Section componentsSection, String componentSectionId,
@SuppressWarnings("rawtypes") Map<String, Schema> schemas) {
if (null == schemas || schemas.isEmpty()) return;
SectionImpl schemasSection = new SectionImpl(componentsSection);
String schemasSectionId = componentSectionId + "_schemas";
schemasSection.setTitle(labels.getLabel(SECTION_TITLE_SCHEMAS));
schemasSection.setId(schemasSectionId);
schemas.forEach((name, schema) -> {
String schemaDocumentId = schemasSectionId + "_" + name;
Document schemaDocument = schemaComponent.apply(schemasSection, schema);
schemaDocument.setTitle(name);
schemaDocument.setId(schemaDocumentId);
schemasSection.append(schemaDocument);
});
componentsSection.append(schemasSection);
}
private <T> void appendSubSection(Section componentsSection, String componentSectionId,
MarkupComponent<StructuralNode, T, StructuralNode> markupComponent,
String sectionLabel, T parameters) {
SectionImpl parametersSection = new SectionImpl(componentsSection);
String parametersSectionId = componentSectionId + "_parameters";
parametersSection.setTitle(labels.getLabel(sectionLabel));
parametersSection.setId(parametersSectionId);
markupComponent.apply(parametersSection, parameters);
componentsSection.append(parametersSection);
}
}

View File

@@ -0,0 +1,138 @@
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.BlockImpl;
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.github.swagger2markup.extension.OverviewDocumentExtension;
import io.github.swagger2markup.internal.component.ExternalDocumentationComponent;
import io.github.swagger2markup.internal.component.TagsComponent;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Block;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.Section;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Optional;
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_TERMS_OF_SERVICE;
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_OVERVIEW;
import static io.github.swagger2markup.extension.OverviewDocumentExtension.Context;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.appendDescription;
public class OverviewDocument extends MarkupComponent<Document, OverviewDocument.Parameters, Document> {
private final TagsComponent tagsComponent;
private final ExternalDocumentationComponent externalDocumentationComponent;
public OverviewDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
tagsComponent = new TagsComponent(context);
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
}
public static OverviewDocument.Parameters parameters(OpenAPI schema) {
return new OverviewDocument.Parameters(schema);
}
@Override
public Document apply(Document document, Parameters parameters) {
Info apiInfo = parameters.openAPI.getInfo();
document.setAttribute("openapi", parameters.openAPI.getOpenapi(), true);
addDocumentTitle(document, apiInfo);
addAuthorInfo(document, apiInfo);
addVersionInfo(document, apiInfo);
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_BEFORE, document));
Document subDocument = new DocumentImpl(document);
Section overviewDoc = new SectionImpl(subDocument, "section", new HashMap<>(), new ArrayList<>(),
null, new ArrayList<>(), 1, "", new ArrayList<>(),
null, null, "", "", false, false);
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_BEGIN, subDocument));
overviewDoc.setTitle(labels.getLabel(SECTION_TITLE_OVERVIEW));
appendDescription(overviewDoc, apiInfo.getDescription());
appendTermsOfServiceInfo(overviewDoc, apiInfo);
appendLicenseInfo(overviewDoc, apiInfo);
subDocument.append(overviewDoc);
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_END, subDocument));
document.append(subDocument);
externalDocumentationComponent.apply(document, parameters.openAPI.getExternalDocs());
tagsComponent.apply(document, parameters.openAPI.getTags());
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_AFTER, document));
return document;
}
private void applyOverviewDocumentExtension(Context context) {
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.apply(context));
}
private void addDocumentTitle(Document rootDocument, Info apiInfo) {
String title = apiInfo.getTitle();
if (StringUtils.isNotBlank(title)) {
rootDocument.setTitle(title);
}
}
private void addVersionInfo(Document rootDocument, Info info) {
String version = info.getVersion();
if (StringUtils.isNotBlank(version)) {
rootDocument.setAttribute("revnumber", version, true);
}
}
private void addAuthorInfo(Document rootDocument, Info info) {
Contact contact = info.getContact();
if (null != contact) {
String author = Optional.ofNullable(contact.getName()).orElse("");
String email = contact.getEmail();
if (StringUtils.isNotBlank(email)) {
rootDocument.setAttribute("email", email, true);
}
rootDocument.setAttribute("author", author, true);
rootDocument.setAttribute("authorcount", 1L, true);
}
}
private void appendLicenseInfo(Section overviewDoc, Info info) {
License license = info.getLicense();
if (null != license) {
StringBuilder sb = new StringBuilder();
if (StringUtils.isNotBlank(license.getUrl())) {
sb.append(license.getUrl()).append("[");
}
sb.append(license.getName());
if (StringUtils.isNotBlank(license.getUrl())) {
sb.append("]");
}
BlockImpl paragraph = new ParagraphBlockImpl(overviewDoc);
paragraph.setSource(sb.toString());
overviewDoc.append(paragraph);
}
}
private void appendTermsOfServiceInfo(Section overviewDoc, Info info) {
String termsOfService = info.getTermsOfService();
if (StringUtils.isNotBlank(termsOfService)) {
Block paragraph = new ParagraphBlockImpl(overviewDoc);
paragraph.setSource(termsOfService + "[" + labels.getLabel(LABEL_TERMS_OF_SERVICE) + "]");
overviewDoc.append(paragraph);
}
}
public static class Parameters {
private final OpenAPI openAPI;
public Parameters(OpenAPI openAPI) {
this.openAPI = Validate.notNull(openAPI, "Schema must not be null");
}
}
}

View File

@@ -0,0 +1,116 @@
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.github.swagger2markup.internal.component.ExternalDocumentationComponent;
import io.github.swagger2markup.internal.component.ParametersComponent;
import io.github.swagger2markup.internal.component.ResponseComponent;
import io.github.swagger2markup.internal.component.SecurityRequirementTableComponent;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.oas.models.servers.ServerVariables;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.Section;
import org.asciidoctor.ast.StructuralNode;
import java.util.*;
import static io.github.swagger2markup.config.OpenAPILabels.*;
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
public class PathsDocument extends MarkupComponent<Document, PathsDocument.Parameters, Document> {
private final ParametersComponent parametersComponent;
private final ExternalDocumentationComponent externalDocumentationComponent;
private final ResponseComponent responseComponent;
private final SecurityRequirementTableComponent securityRequirementTableComponent;
public PathsDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.parametersComponent = new ParametersComponent(context);
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
this.responseComponent = new ResponseComponent(context);
this.securityRequirementTableComponent = new SecurityRequirementTableComponent(context);
}
public static Parameters parameters(OpenAPI schema) {
return new Parameters(schema);
}
@Override
public Document apply(Document document, Parameters parameters) {
Paths apiPaths = parameters.schema.getPaths();
if (null == apiPaths || apiPaths.isEmpty()) return document;
SectionImpl allPathsSection = new SectionImpl(document);
allPathsSection.setTitle(labels.getLabel(SECTION_TITLE_PATHS));
apiPaths.forEach((name, pathItem) ->
pathItem.readOperationsMap().forEach(((httpMethod, operation) -> {
SectionImpl operationSection = new SectionImpl(allPathsSection);
String summary = Optional.ofNullable(operation.getSummary()).orElse("");
operationSection.setTitle((italicUnconstrained(httpMethod.name().toUpperCase()) + " " + monospaced(name) + " " + summary).trim());
appendDescription(operationSection, operation.getDescription());
externalDocumentationComponent.apply(operationSection, operation.getExternalDocs());
parametersComponent.apply(operationSection, operation.getParameters());
responseComponent.apply(operationSection, operation.getResponses());
appendServersSection(operationSection, operation.getServers());
securityRequirementTableComponent.apply(operationSection, operation.getSecurity(), false);
allPathsSection.append(operationSection);
})));
document.append(allPathsSection);
return document;
}
private void appendServersSection(StructuralNode node, List<Server> servers) {
if (null == servers || servers.isEmpty()) return;
Section serversSection = new SectionImpl(node);
serversSection.setTitle(labels.getLabel(SECTION_TITLE_SERVERS));
servers.forEach(server -> {
Section serverSection = new SectionImpl(serversSection);
serverSection.setTitle(italicUnconstrained(labels.getLabel(LABEL_SERVER)) + ": " + server.getUrl());
appendDescription(serverSection, server.getDescription());
ServerVariables variables = server.getVariables();
appendVariables(serverSection, variables);
serversSection.append(serverSection);
});
node.append(serversSection);
}
private void appendVariables(Section serverSection, ServerVariables variables) {
if (null == variables || variables.isEmpty()) return;
TableImpl serverVariables = new TableImpl(serverSection, new HashMap<String, Object>() {{
put("header-option", "");
put("cols", ".^2a,.^9a,.^3a,.^4a");
}}, new ArrayList<>());
serverVariables.setTitle(labels.getLabel(TABLE_TITLE_SERVER_VARIABLES));
serverVariables.setHeaderRow(labels.getLabel(TABLE_HEADER_VARIABLE), labels.getLabel(TABLE_HEADER_DESCRIPTION),
labels.getLabel(TABLE_HEADER_POSSIBLE_VALUES), labels.getLabel(TABLE_HEADER_DEFAULT)
);
variables.forEach((name, variable) -> {
String possibleValues = String.join(", ", Optional.ofNullable(variable.getEnum()).orElse(Collections.singletonList("Any")));
serverVariables.addRow(name, Optional.ofNullable(variable.getDescription()).orElse(""), possibleValues, variable.getDefault());
});
serverSection.append(serverVariables);
}
public static class Parameters {
private final OpenAPI schema;
public Parameters(OpenAPI schema) {
this.schema = Validate.notNull(schema, "Schema must not be null");
}
}
}

View File

@@ -0,0 +1,49 @@
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.OpenAPI2MarkupConverter;
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
import io.github.swagger2markup.extension.MarkupComponent;
import io.github.swagger2markup.internal.component.SecurityRequirementTableComponent;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import org.apache.commons.lang3.Validate;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.Section;
import java.util.List;
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_SECURITY;
public class SecurityDocument extends MarkupComponent<Document, SecurityDocument.Parameters, Document> {
private final SecurityRequirementTableComponent securityRequirementTableComponent;
public SecurityDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
super(context);
this.securityRequirementTableComponent = new SecurityRequirementTableComponent(context);
}
public static Parameters parameters(OpenAPI schema) {
return new Parameters(schema);
}
@Override
public Document apply(Document document, SecurityDocument.Parameters parameters) {
List<SecurityRequirement> securityRequirements = parameters.schema.getSecurity();
if (null == securityRequirements || securityRequirements.isEmpty()) return document;
Section securityRequirementsSection = new SectionImpl(document);
securityRequirementsSection.setTitle(labels.getLabel(SECTION_TITLE_SECURITY));
securityRequirementTableComponent.apply(securityRequirementsSection, securityRequirements, false);
document.append(securityRequirementsSection);
return document;
}
public static class Parameters {
private final OpenAPI schema;
public Parameters(OpenAPI schema) {
this.schema = Validate.notNull(schema, "Schema must not be null");
}
}
}

View File

@@ -0,0 +1,115 @@
package io.github.swagger2markup.internal.helper;
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.Block;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.ast.Table;
import java.util.List;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
public class OpenApiHelpers {
public static void appendDescription(StructuralNode node, String description) {
if (StringUtils.isNotBlank(description)) {
Block paragraph = new ParagraphBlockImpl(node);
paragraph.setSource(description);
node.append(paragraph);
}
}
public static Document generateInnerDoc(Table table, String documentContent) {
return generateInnerDoc(table, documentContent, "");
}
public static Document generateInnerDoc(Table table, String documentContent, String id) {
Document innerDoc = new DocumentImpl(table);
if (StringUtils.isNotBlank(id)) {
innerDoc.setId(id);
}
Block paragraph = new ParagraphBlockImpl(innerDoc);
paragraph.setSource(documentContent);
innerDoc.append(paragraph);
return innerDoc;
}
public static String requiredIndicator(boolean isRequired, String labelRequired, String labelOptional) {
return italicUnconstrained(isRequired ? labelRequired : labelOptional).toLowerCase();
}
public static String superScript(String str) {
return "^" + str + "^";
}
public static String subScript(String str) {
return "~" + str + "~";
}
public static String italicUnconstrained(String str) {
return "__" + str + "__";
}
public static String boldUnconstrained(String str) {
return "**" + str + "**";
}
public static String monospaced(String str) {
return "`" + str + "`";
}
public static String getSchemaTypeAsString(Schema schema) {
StringBuilder stringBuilder = new StringBuilder();
if (schema instanceof ArraySchema) {
stringBuilder.append("< ");
Schema<?> items = ((ArraySchema) schema).getItems();
stringBuilder.append(getSchemaType(items));
stringBuilder.append(" > ");
stringBuilder.append(schema.getType());
} else {
List enumList = schema.getEnum();
if (enumList != null) {
stringBuilder.append("enum (");
for (Object value : enumList) {
stringBuilder.append(value.toString());
stringBuilder.append(",");
}
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append(')');
} else {
stringBuilder.append(getSchemaType(schema));
String format = schema.getFormat();
if (format != null) {
stringBuilder.append(' ');
stringBuilder.append('(');
stringBuilder.append(format);
stringBuilder.append(')');
}
}
}
return stringBuilder.toString();
}
private static String getSchemaType(Schema<?> schema) {
String type = schema.getType();
if (StringUtils.isNotEmpty(type)) {
return type;
} else {
return generateRefLink(schema.get$ref());
}
}
private static String generateRefLink(String ref) {
if (StringUtils.isNotBlank(ref)) {
String anchor = ref.toLowerCase().replaceFirst("#", "").replaceAll("/", "_");
return "<<" + anchor + ">>" + LINE_SEPARATOR;
}
return "";
}
}

View File

@@ -0,0 +1,43 @@
swagger2markup.markupLanguage=ASCIIDOC
swagger2markup.swaggerMarkupLanguage=ASCIIDOC
swagger2markup.hostnameEnabled=false
swagger2markup.basePathPrefixEnabled=false
swagger2markup.operationExtensionsEnabled=false
swagger2markup.definitionExtensionsEnabled=false
swagger2markup.separatedDefinitionsEnabled=false
swagger2markup.separatedOperationsEnabled=false
swagger2markup.pathsGroupedBy=AS_IS
swagger2markup.outputLanguage=EN
swagger2markup.inlineSchemaEnabled=true
swagger2markup.interDocumentCrossReferencesEnabled=false
swagger2markup.flatBodyEnabled=false
swagger2markup.pathSecuritySectionEnabled=true
swagger2markup.overviewDocument=overview
swagger2markup.pathsDocument=paths
swagger2markup.definitionsDocument=definitions
swagger2markup.securityDocument=security
swagger2markup.separatedOperationsFolder=operations
swagger2markup.separatedDefinitionsFolder=definitions
swagger2markup.tagOrderBy=NATURAL
swagger2markup.operationOrderBy=NATURAL
swagger2markup.definitionOrderBy=NATURAL
swagger2markup.parameterOrderBy=NATURAL
swagger2markup.propertyOrderBy=NATURAL
swagger2markup.responseOrderBy=NATURAL
swagger2markup.listDelimiterEnabled=false
swagger2markup.listDelimiter=,
swagger2markup.asciidoc.pegdown.timeoutMillis=2000
swagger2markup.generatedExamplesEnabled=false
# basic, curl, invoke-webrequest
swagger2markup.requestExamplesFormat=basic
# default, bash, powershell, etc.
swagger2markup.requestExamplesSourceFormat=default
# hide, inherit or hostname
swagger2markup.requestExamplesHost=hide
# hide, inherit or schema (e.g. https, https, etc.)
swagger2markup.requestExamplesSchema=hide
swagger2markup.requestExamplesHideBasePath=true
swagger2markup.requestExamplesIncludeAllQueryParams=false
# single, commaSeparated, multiple, multiple[]
swagger2markup.requestExamplesQueryArrayStyle=single

View File

@@ -0,0 +1,58 @@
label_content=Content
label_default=Default
label_deprecated=Deprecated
label_example=Example
label_examples=Examples
label_exclusive_maximum=Exclusive Maximum
label_exclusive_minimum=Exclusive Minimum
label_external_value=External Value
label_format=Format
label_maximum=Maximum
label_max_items=Maximum Items
label_max_length=Maximum Length
label_max_properties=Maximum Properties
label_minimum=Minimum
label_min_items=Minimum Items
label_min_length=Minimum Length
label_min_properties=Minimum Properties
label_multiple_of=Multiple Of
label_no_links=No Links
label_nullable=Nullable
label_operation=Operation
label_optional=Optional
label_parameters=Parameters
label_read_only=Read Only
label_required=Required
label_server=Server
label_terms_of_service=Terms Of Service
label_title=Title
label_type=Type
label_unique_items=Unique Items
label_write_only=Write Only
section_title_components=Components
section_title_parameters=Parameters
section_title_paths=Paths
section_title_schemas=Schemas
section_title_security=Security
section_title_servers=Servers
section_title_overview=Overview
section_title_tags=Tags
section_title_responses=Responses
section_title_headers=Headers
section_title_links=Links
table_header_default=Default
table_header_description=Description
table_header_http_code=Code
table_header_links=Links
table_header_name=Name
table_header_possible_values=Possible Values
table_header_schema=Schema
table_header_scopes=Scopes
table_header_type=Type
table_header_variable=Variable
table_title_headers=Headers
table_title_parameters=Parameters
table_title_properties=Properties
table_title_responses=Responses
table_title_security=Security
table_title_server_variables=Server Variables

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2017 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.swagger2markup;
import io.github.swagger2markup.assertions.DiffUtils;
import org.apache.commons.io.FileUtils;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import java.net.URISyntaxException;
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.assertThat;
public class AsciidocConverterTest {
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 testToString() throws URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
//When
String asciiDocAsString = OpenAPI2MarkupConverter.from(file).build()
.toString();
//Then
Assertions.assertThat(asciiDocAsString).isNotEmpty();
System.out.println(asciiDocAsString);
}
@Test
public void testToFolder() throws URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/to_folder");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
OpenAPI2MarkupConverter.from(file).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_folder").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testToFolder.html");
}
}

View File

@@ -0,0 +1,49 @@
package io.github.swagger2markup;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.ParseOptions;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Arrays;
import static org.junit.Assert.assertNotNull;
@RunWith(Parameterized.class)
public class OpenApi2AsciiDocTest {
final private String openApiFile;
final private String expectedAsciiDoc;
public OpenApi2AsciiDocTest(String openApiFile, String expectedAsciiDoc) throws IOException {
this.openApiFile = "./src/test/resources/open_api/" + openApiFile;
this.expectedAsciiDoc = IOUtils.toString(getClass().getResourceAsStream("/asciidoc/" + expectedAsciiDoc), StandardCharsets.UTF_8);
}
@Parameterized.Parameters(name = "Run {index}: open api={0}, asciidoc={1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{"simple.yaml", "simple.adoc"},
{"petstore.yaml", "petstore.adoc"}
});
}
@Test
public void converts_open_api_v3_to_asciidoc() {
ParseOptions options = new ParseOptions();
options.setResolve(true);
SwaggerParseResult result = new OpenAPIV3Parser().readLocation(openApiFile, null, options);
OpenAPI swagger = result.getOpenAPI();
assertNotNull(swagger);
OpenAPI2MarkupConverter converter = OpenAPI2MarkupConverter.from(swagger).build();
converter.toFolder(Paths.get("build/test/asciidoc"));
}
}

View File

@@ -1,6 +1,6 @@
/*
*
* Copyright 2016 Robert Winkler
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,276 @@
= Simple Inventory API
<you@your-company.com>
v1.0.0
:revnumber: 1.0.0
:openapi: 3.0.0
:authorcount: 1
:email: you@your-company.com
== Overview
This is a simple API
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
== Tags
admins::
Secured Admin-only calls
developers::
Operations available to regular developers
== Servers
=== __Server__: /
== Paths
=== __GET__ `/inventory` searches inventory
By passing in the appropriate options, you can search for
available inventory in the system
.Parameters
[%header,caption=,cols=".^2a,.^3a,.^10a,.^5a"]
|===
<.<|Type
<.<|Name
<.<|Description
<.<|Schema
<.<|**query**
<.<|**searchString** +
__optional__
<.<|pass an optional search string for looking up inventory
<.<|type: string
<.<|**query**
<.<|**limit** +
__optional__
<.<|maximum number of records to return
<.<|minimum: 0 +
type: integer +
maximum: 50 +
format: int32
<.<|**query**
<.<|**skip** +
__optional__
<.<|number of records to skip for pagination
<.<|minimum: 0 +
type: integer +
format: int32
|===
.Responses
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|===
<.<|Code
<.<|Description
<.<|Links
<.<|200
<.<|search results matching criteria
.Content
application/json::
+
type: array
<.<|No Links
<.<|400
<.<|bad input parameter
<.<|No Links
|===
=== __POST__ `/inventory` adds an inventory item
Adds an item to the system
.Responses
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|===
<.<|Code
<.<|Description
<.<|Links
<.<|201
<.<|item created
<.<|No Links
<.<|400
<.<|invalid input, object invalid
<.<|No Links
<.<|409
<.<|an existing item already exists
<.<|No Links
|===
[[_components]]
== Components
[[_components_schemas]]
=== Schemas
[[_components_schemas_inventoryitem]]
==== InventoryItem
type: object
.Properties
[%header,caption=,cols=".^4a,.^16a"]
|===
<.<|Name
<.<|Schema
<.<|id
__required__
<.<|type: string +
format: uuid
<.<|name
__required__
<.<|type: string
<.<|releaseDate
__required__
<.<|type: string +
format: date-time
<.<|manufacturer
__required__
<.<|<<_components_schemas_Manufacturer,Manufacturer>>
|===
[[_components_schemas_manufacturer]]
==== Manufacturer
type: object
.Properties
[%header,caption=,cols=".^4a,.^16a"]
|===
<.<|Name
<.<|Schema
<.<|name
__required__
<.<|type: string
<.<|homePage
__optional__
<.<|type: string +
format: url
<.<|phone
__optional__
<.<|type: string
|===

View File

@@ -0,0 +1,351 @@
[[_components]]
== Components
[[_components_schemas]]
=== Schemas
[[_components_schemas_user]]
==== User
.Properties
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|===
<.<|Name
<.<|Description
<.<|Schema
<.<|id
__optional__
<.<|
<.<|integer (int64)
<.<|username
__optional__
<.<|
<.<|string
<.<|firstName
__optional__
<.<|
<.<|string
<.<|lastName
__optional__
<.<|
<.<|string
<.<|email
__optional__
<.<|
<.<|string
<.<|password
__optional__
<.<|
<.<|string
<.<|phone
__optional__
<.<|
<.<|string
<.<|userStatus
__optional__
<.<|User Status
<.<|integer (int32)
|===
[[_components_schemas_category]]
==== Category
.Properties
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|===
<.<|Name
<.<|Description
<.<|Schema
<.<|id
__optional__
<.<|
<.<|integer (int64)
<.<|name
__optional__
<.<|The name of the category
**Maximum Length**: 255 +
**Minimum Length**: 0 +
**Default**: DefaultCategory
<.<|string
|===
[[_components_schemas_pet]]
==== Pet
.Properties
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|===
<.<|Name
<.<|Description
<.<|Schema
<.<|id
__optional__
<.<|
<.<|integer (int64)
<.<|category
__optional__
<.<|
<.<|<<_components_schemas_category>>
<.<|name
__required__
<.<|
<.<|string
<.<|photoUrls
__required__
<.<|
<.<|< string > array
<.<|tags
__optional__
<.<|
<.<|< <<_components_schemas_tag>>
> array
<.<|status
__optional__
<.<|pet status in the store,
<.<|enum (Dead,Alive)
|===
[[_components_schemas_tag]]
==== Tag
.Properties
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|===
<.<|Name
<.<|Description
<.<|Schema
<.<|id
__optional__
<.<|
<.<|integer (int64)
<.<|name
__optional__
<.<|
<.<|string
|===
[[_components_schemas_order]]
==== Order
.Properties
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|===
<.<|Name
<.<|Description
<.<|Schema
<.<|id
__optional__
<.<|
<.<|integer (int64)
<.<|petId
__optional__
<.<|
<.<|integer (int64)
<.<|quantity
__optional__
<.<|**Maximum**: 10000 +
**Minimum**: 0 +
**Default**: 0
<.<|integer (int32)
<.<|shipDate
__optional__
<.<|
<.<|string (date-time)
<.<|status
__optional__
<.<|Order Status
<.<|enum (Ordered,Cancelled)
<.<|complete
__optional__
<.<|
<.<|boolean
|===
[[_components_parameters]]
=== Responses
.Responses
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|===
<.<|Code
<.<|Description
<.<|Links
<.<|InvalidId
<.<|Invalid ID supplied
<.<|No Links
|===

View File

@@ -0,0 +1,30 @@
= Swagger Petstore
apiteam@swagger.io
v1.0.0
:revnumber: 1.0.0
:openapi: 3.0.0
:author: apiteam@swagger.io
:authorcount: 1
== 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
http://helloreverb.com/terms/[Terms Of Service]
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
http://swagger.io[Find out more about Swagger]
== Tags
pet::
Pet resource
store::
Store resource
user::
User resource

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="io.github.swagger2markup" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@@ -0,0 +1,732 @@
openapi: 3.0.0
servers:
- url: 'http://localhost:8000/v2/api'
info:
description: >-
This is a sample server Petstore server. You can find out more about
Swagger at http://swagger.io or on
irc.freenode.net, #swagger. For this sample, you can use the api key
"special-key" to test the authorization filters
version: 1.0.0
title: Swagger Petstore
termsOfService: 'http://swagger.io/terms/'
contact:
name: apiteam@swagger.io
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
externalDocs:
description: Find more info here
url: 'https://swagger.io'
tags:
- name: pet
description: Pet Operations
externalDocs:
url: 'http://swagger.io'
- name: user
description: All about the Users
paths:
/pet/add:
post:
tags:
- pet
summary: Add a new pet to the store
description: ''
operationId: createPet
responses:
'200':
description: This is a sample
content:
text/plain:
schema:
type: string
example: 'whoa!'
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
put:
tags:
- pet
summary: Update an existing pet
description: ''
operationId: updatePet
responses:
'400':
description: Invalid ID supplied
'404':
description: Pet not found
'405':
description: Validation exception
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
/pet/findByStatus:
get:
tags:
- pet
summary: Finds Pets by status
description: Multiple status values can be provided with comma seperated strings
operationId: findPetsByStatus
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: false
style: pipeDelimited
schema:
type: array
items:
type: string
default: available
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/PetArray'
application/xml:
schema:
$ref: '#/components/schemas/PetArray'
'400':
description: Invalid status value
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
/pet/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
parameters:
- name: tags
in: query
description: Tags to filter by
required: false
explode: true
schema:
type: array
items:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid tag value
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
'/pet/{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
parameters:
- name: petId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/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
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: string
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
delete:
tags:
- pet
summary: Deletes a pet
description: ''
operationId: deletePet
parameters:
- name: api_key
in: header
description: ''
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
'400':
description: Invalid pet value
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: Pet extra params that needs to be deleted
'/pet/{petId}/uploadImage':
post:
tags:
- pet
summary: uploads an image
description: ''
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/ApiResponse"
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
additionalMetadata:
description: Additional data to pass to server
type: string
file:
description: file to upload
type: string
format: binary
/store/inventory:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: get inventory+1
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: object
additionalProperties:
type: integer
format: int32
application/xml:
schema:
type: object
additionalProperties:
type: integer
format: int32
security:
- api_key: []
/store/order:
post:
tags:
- store
summary: Place an order for a pet
description: ''
operationId: placeOrder
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
application/xml:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid Order
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
description: order placed for purchasing the pet
'/store/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
parameters:
- name: orderId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
application/xml:
schema:
$ref: '#/components/schemas/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
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid ID supplied
'404':
description: Order not found
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
responses:
200:
content:
'application/json':
schema:
type: object
properties:
id:
# default is text/plain
type: string
format: text
examples:
foo:
value: {"foo": "bar"}
bar:
summary: A bar example
value: {"bar": "baz"}
default:
description: successful operation
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Created user object
/user/createWithArray:
post:
tags:
- user
summary: Creates list of users with given input array
description: ''
operationId: createUsersWithArrayInput
responses:
default:
description: successful operation
requestBody:
$ref: '#/components/requestBodies/UserArray'
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: ''
operationId: createUsersWithListInput
responses:
default:
description: successful operation
requestBody:
$ref: '#/components/requestBodies/UserArray'
/user/login:
get:
tags:
- user
security:
- https
summary: Logs user into the system
description: ''
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: false
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: false
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: string
application/xml:
schema:
type: string
'400':
description: Invalid username/password supplied
/user/logout:
get:
tags:
- user
security:
- https
summary: Logs out current logged in user session
description: ''
operationId: logoutUser
responses:
default:
description: successful operation
'/user/{username}':
get:
tags:
- user
summary: Get user by user name
description: ''
operationId: getUserByName
parameters:
- name: username
in: path
description: 'The name that needs to be fetched. Use user1 for testing.'
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/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
parameters:
- name: username
in: path
description: name that need to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid user supplied
'404':
description: User not found
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Updated user object
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid username supplied
'404':
description: User not found
security:
- foo:
- bar
- baz
a:
- b
- c
components:
parameters:
sharedSkip:
name: skip
in: query
description: Results to skip
required: false
schema:
type: integer
format: int32
responses:
veryBad:
description: failed
requestBodies:
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
description: List of user object
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
securitySchemes:
api_key:
type: apiKey
name: api_key
in: header
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
schemas:
User:
properties:
id:
type: integer
format: int64
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
xml:
name: User
Category:
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Category
Pet:
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
xml:
name: Pet
Tag:
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Tag
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
xml:
name: Order
PetArray:
type: array
items:
$ref: '#/components/schemas/Pet'

View File

@@ -0,0 +1,115 @@
openapi: 3.0.0
info:
description: This is a simple API
version: "1.0.0"
title: Simple Inventory API
contact:
email: you@your-company.com
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: admins
description: Secured Admin-only calls
- name: developers
description: Operations available to regular developers
paths:
/inventory:
get:
tags:
- developers
summary: searches inventory
operationId: searchInventory
description: |
By passing in the appropriate options, you can search for
available inventory in the system
parameters:
- in: query
name: searchString
description: pass an optional search string for looking up inventory
required: false
schema:
type: string
- in: query
name: skip
description: number of records to skip for pagination
schema:
type: integer
format: int32
minimum: 0
- in: query
name: limit
description: maximum number of records to return
schema:
type: integer
format: int32
minimum: 0
maximum: 50
responses:
'200':
description: search results matching criteria
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/InventoryItem'
'400':
description: bad input parameter
post:
tags:
- admins
summary: adds an inventory item
operationId: addInventory
description: Adds an item to the system
responses:
'201':
description: item created
'400':
description: 'invalid input, object invalid'
'409':
description: an existing item already exists
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/InventoryItem'
description: Inventory item to add
components:
schemas:
InventoryItem:
type: object
required:
- id
- name
- manufacturer
- releaseDate
properties:
id:
type: string
format: uuid
example: d290f1ee-6c54-4b01-90e6-d701748f0851
name:
type: string
example: Widget Adapter
releaseDate:
type: string
format: date-time
example: '2016-08-29T09:12:33.001Z'
manufacturer:
$ref: '#/components/schemas/Manufacturer'
Manufacturer:
required:
- name
properties:
name:
type: string
example: ACME Corporation
homePage:
type: string
format: url
example: 'https://www.acme-corp.com'
phone:
type: string
example: 408-867-5309
type: object

View File

@@ -0,0 +1,693 @@
openapi: 3.0.0
info:
description: >
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: 1.0.0
title: Swagger Petstore
termsOfService: http://helloreverb.com/terms/
contact:
name: apiteam@swagger.io
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
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
requestBody:
$ref: "#/components/requestBodies/Pet"
responses:
"405":
description: Invalid input
security:
- petstore_auth:
- write_pets
- read_pets
put:
tags:
- pet
summary: Update an existing pet
description: ""
operationId: updatePet
requestBody:
$ref: "#/components/requestBodies/Pet"
responses:
"400":
$ref: "#/components/responses/InvalidId"
"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
parameters:
- in: query
name: status
description: Status values that need to be considered for filter
required: false
explode: true
schema:
type: array
items:
type: string
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
"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
parameters:
- in: query
name: tags
description: Tags to filter by
required: false
example: adorable
explode: true
schema:
type: array
items:
type: string
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
"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
parameters:
- in: path
name: petId
description: ID of pet that needs to be fetched
required: true
example: 30
schema:
type: integer
format: int64
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
$ref: "#/components/schemas/Pet"
"400":
$ref: "#/components/responses/InvalidId"
"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
parameters:
- in: path
name: petId
description: ID of pet that needs to be updated
required: true
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
required:
- name
- status
responses:
"405":
description: Invalid input
security:
- petstore_auth:
- write_pets
- read_pets
delete:
tags:
- pet
summary: Deletes a pet
description: ""
operationId: deletePet
parameters:
- in: header
name: api_key
description: ""
required: true
schema:
type: string
- in: path
name: petId
description: Pet id to delete
required: true
schema:
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
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
description: order placed for purchasing the pet
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
application/xml:
schema:
$ref: "#/components/schemas/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
parameters:
- in: path
name: orderId
description: ID of pet that needs to be fetched
required: true
schema:
type: string
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
application/xml:
schema:
$ref: "#/components/schemas/Order"
"400":
$ref: "#/components/responses/InvalidId"
"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
parameters:
- in: path
name: orderId
description: ID of the order that needs to be deleted
required: true
schema:
type: string
responses:
"400":
$ref: "#/components/responses/InvalidId"
"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
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/User"
description: Created user object
responses:
default:
description: successful operation
/users/createWithArray:
post:
tags:
- user
summary: Creates list of users with given input array
description: ""
operationId: createUsersWithArrayInput
requestBody:
$ref: "#/components/requestBodies/UserArray"
responses:
default:
description: successful operation
/users/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: ""
operationId: createUsersWithListInput
requestBody:
$ref: "#/components/requestBodies/UserArray"
responses:
default:
description: successful operation
/users/login:
get:
tags:
- user
summary: Logs user into the system
description: ""
operationId: loginUser
parameters:
- in: query
name: username
description: The user name for login
required: false
schema:
type: string
- in: query
name: password
description: The password for login in clear text
required: false
schema:
type: string
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
type: string
application/xml:
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
responses:
default:
description: successful operation
"/users/{username}":
get:
tags:
- user
summary: Get user by user name
description: ""
operationId: getUserByName
parameters:
- in: path
name: username
description: The name that needs to be fetched. Use user1 for testing.
required: true
schema:
type: string
responses:
"200":
description: successful operation
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
X-Rate-Limit-Remaining:
description: The number of remaining requests in the current period
schema:
type: integer
X-Rate-Limit-Reset:
description: The number of seconds left in the current period
schema:
type: integer
content:
application/json:
schema:
$ref: "#/components/schemas/User"
application/xml:
schema:
$ref: "#/components/schemas/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
parameters:
- in: path
name: username
description: name that need to be deleted
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/User"
description: Updated user object
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
parameters:
- in: path
name: username
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
"400":
description: Invalid username supplied
"404":
description: User not found
externalDocs:
description: Find out more about Swagger
url: http://swagger.io
servers:
- url: http://petstore.swagger.io/v2
components:
responses:
InvalidId:
description: Invalid ID supplied
requestBodies:
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
description: List of user object
Pet:
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
$ref: "#/components/schemas/Pet"
description: Pet object that needs to be added to the store
securitySchemes:
api_key:
type: apiKey
name: api_key
in: header
description: This is another description
petstore_auth:
type: oauth2
description: This is a standard oauth flow
flows:
implicit:
authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
scopes:
write_pets: modify pets in your account
read_pets: read your pets
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
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
Category:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
description: The name of the category
minLength: 0
maxLength: 255
pattern: "[A-Za-zäöüÄÖÜß]{0,255}"
default: DefaultCategory
example: FoobarCategory
Pet:
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: "#/components/schemas/Category"
name:
type: string
example: doggie
photoUrls:
type: array
items:
type: string
tags:
type: array
items:
$ref: "#/components/schemas/Tag"
status:
type: string
description: pet status in the store,
enum:
- Dead
- Alive
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
Order:
type: object
properties:
id:
type: integer
format: int64
petId:
type: integer
format: int64
quantity:
type: integer
format: int32
minimum: 0
maximum: 10000
default: 0
example: 10
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- Ordered
- Cancelled
complete:
type: boolean

87
publishing.gradle Normal file
View File

@@ -0,0 +1,87 @@
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
}
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,10 @@
rootProject.name = 'swagger2markup'
rootProject.name = 'swagger2markup'
include 'swagger2markup-asciidoc'
include 'swagger2markup-bom'
include 'swagger2markup-builder'
include 'swagger2markup-documentation'
include 'swagger2markup'
include 'swagger2markup-core'
include 'openapi2markup'

View File

@@ -1,744 +0,0 @@
/*
* Copyright 2016 Robert Winkler
* Modified December 12 2016 by Cas Eliëns
*
* 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.swagger2markup.builder;
import com.google.common.collect.Ordering;
import io.github.swagger2markup.*;
import io.github.swagger2markup.Swagger2MarkupProperties;
import io.github.swagger2markup.markup.builder.LineSeparator;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.HttpMethod;
import io.swagger.models.parameters.Parameter;
import org.apache.commons.configuration2.*;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import static io.github.swagger2markup.Swagger2MarkupProperties.*;
public class Swagger2MarkupConfigBuilder {
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(PathOperation::getMethod);
static final Ordering<PathOperation> OPERATION_PATH_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(PathOperation::getPath);
static final Ordering<Parameter> PARAMETER_IN_NATURAL_ORDERING = Ordering
.explicit("header", "path", "query", "formData", "body")
.onResultOf(Parameter::getIn);
static final Ordering<Parameter> PARAMETER_NAME_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(Parameter::getName);
private static final String PROPERTIES_DEFAULT = "io/github/swagger2markup/config/default.properties";
DefaultSwagger2MarkupConfig config = new DefaultSwagger2MarkupConfig();
public Swagger2MarkupConfigBuilder() {
this(new PropertiesConfiguration());
}
public Swagger2MarkupConfigBuilder(Properties properties) {
this(ConfigurationConverter.getConfiguration(properties));
}
public Swagger2MarkupConfigBuilder(Map<String, String> map) {
this(new MapConfiguration(map));
}
public Swagger2MarkupConfigBuilder(Configuration configuration) {
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
compositeConfiguration.addConfiguration(new SystemConfiguration());
compositeConfiguration.addConfiguration(configuration);
compositeConfiguration.addConfiguration(getDefaultConfiguration());
Swagger2MarkupProperties swagger2MarkupProperties = new Swagger2MarkupProperties(compositeConfiguration);
config.markupLanguage = swagger2MarkupProperties.getRequiredMarkupLanguage(MARKUP_LANGUAGE);
config.swaggerMarkupLanguage = swagger2MarkupProperties.getRequiredMarkupLanguage(SWAGGER_MARKUP_LANGUAGE);
config.generatedExamplesEnabled = swagger2MarkupProperties.getRequiredBoolean(GENERATED_EXAMPLES_ENABLED);
config.basePathPrefixEnabled = swagger2MarkupProperties.getRequiredBoolean(BASE_PATH_PREFIX_ENABLED);
config.separatedDefinitionsEnabled = swagger2MarkupProperties.getRequiredBoolean(SEPARATED_DEFINITIONS_ENABLED);
config.separatedOperationsEnabled = swagger2MarkupProperties.getRequiredBoolean(SEPARATED_OPERATIONS_ENABLED);
config.pathsGroupedBy = swagger2MarkupProperties.getGroupBy(PATHS_GROUPED_BY);
config.outputLanguage = swagger2MarkupProperties.getLanguage(OUTPUT_LANGUAGE);
config.inlineSchemaEnabled = swagger2MarkupProperties.getRequiredBoolean(INLINE_SCHEMA_ENABLED);
config.interDocumentCrossReferencesEnabled = swagger2MarkupProperties.getRequiredBoolean(INTER_DOCUMENT_CROSS_REFERENCES_ENABLED);
config.interDocumentCrossReferencesPrefix = swagger2MarkupProperties.getString(INTER_DOCUMENT_CROSS_REFERENCES_PREFIX, null);
config.flatBodyEnabled = swagger2MarkupProperties.getRequiredBoolean(FLAT_BODY_ENABLED);
config.pathSecuritySectionEnabled = swagger2MarkupProperties.getRequiredBoolean(PATH_SECURITY_SECTION_ENABLED);
config.anchorPrefix = swagger2MarkupProperties.getString(ANCHOR_PREFIX, null);
config.overviewDocument = swagger2MarkupProperties.getRequiredString(OVERVIEW_DOCUMENT);
config.pathsDocument = swagger2MarkupProperties.getRequiredString(PATHS_DOCUMENT);
config.definitionsDocument = swagger2MarkupProperties.getRequiredString(DEFINITIONS_DOCUMENT);
config.securityDocument = swagger2MarkupProperties.getRequiredString(SECURITY_DOCUMENT);
config.separatedOperationsFolder = swagger2MarkupProperties.getRequiredString(SEPARATED_OPERATIONS_FOLDER);
config.separatedDefinitionsFolder = swagger2MarkupProperties.getRequiredString(SEPARATED_DEFINITIONS_FOLDER);
config.tagOrderBy = swagger2MarkupProperties.getOrderBy(TAG_ORDER_BY);
config.operationOrderBy = swagger2MarkupProperties.getOrderBy(OPERATION_ORDER_BY);
config.definitionOrderBy = swagger2MarkupProperties.getOrderBy(DEFINITION_ORDER_BY);
config.parameterOrderBy = swagger2MarkupProperties.getOrderBy(PARAMETER_ORDER_BY);
config.propertyOrderBy = swagger2MarkupProperties.getOrderBy(PROPERTY_ORDER_BY);
config.responseOrderBy = swagger2MarkupProperties.getOrderBy(RESPONSE_ORDER_BY);
Optional<String> lineSeparator = swagger2MarkupProperties.getString(LINE_SEPARATOR);
if (lineSeparator.isPresent() && StringUtils.isNoneBlank(lineSeparator.get())) {
config.lineSeparator = LineSeparator.valueOf(lineSeparator.get());
}
config.pageBreakLocations = swagger2MarkupProperties.getPageBreakLocations(PAGE_BREAK_LOCATIONS);
Optional<Pattern> headerPattern = swagger2MarkupProperties.getHeaderPattern(HEADER_REGEX);
config.headerPattern = headerPattern.orElse(null);
Configuration swagger2markupConfiguration = compositeConfiguration.subset(PROPERTIES_PREFIX);
Configuration extensionsConfiguration = swagger2markupConfiguration.subset(EXTENSION_PREFIX);
config.extensionsProperties = new Swagger2MarkupProperties(extensionsConfiguration);
}
/**
* Loads the default properties from the classpath.
*
* @return the default properties
*/
private Configuration getDefaultConfiguration() {
Configurations configs = new Configurations();
try {
return configs.properties(PROPERTIES_DEFAULT);
} catch (ConfigurationException e) {
throw new RuntimeException(String.format("Can't load default properties '%s'", PROPERTIES_DEFAULT), e);
}
}
/**
* Builds the Swagger2MarkupConfig.
*
* @return the Swagger2MarkupConfig
*/
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 Swagger2MarkupConfigBuilder withMarkupLanguage(MarkupLanguage markupLanguage) {
Validate.notNull(markupLanguage, "%s must not be null", "markupLanguage");
config.markupLanguage = markupLanguage;
return this;
}
/**
* Specifies the markup language used in Swagger descriptions.
*
* @param swaggerMarkupLanguage the markup language used in Swagger descriptions
* @return this builder
*/
public Swagger2MarkupConfigBuilder withSwaggerMarkupLanguage(MarkupLanguage swaggerMarkupLanguage) {
Validate.notNull(swaggerMarkupLanguage, "%s must not be null", "swaggerMarkupLanguage");
config.swaggerMarkupLanguage = swaggerMarkupLanguage;
return this;
}
/**
* Include generated examples into the documents.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withGeneratedExamples() {
config.generatedExamplesEnabled = true;
return this;
}
/**
* In addition to the Definitions file, also create separate definition files for each model definition.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withSeparatedDefinitions() {
config.separatedDefinitionsEnabled = true;
return this;
}
/**
* In addition to the Paths file, also create separate operation files for each operation.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder withPathsGroupedBy(GroupBy pathsGroupedBy) {
Validate.notNull(pathsGroupedBy, "%s must not be null", "pathsGroupedBy");
config.pathsGroupedBy = pathsGroupedBy;
return this;
}
/**
* Specifies the regex pattern to use for grouping paths.
*
* @param headerRegex regex pattern string containing one capture group
* @return this builder
* @throws PatternSyntaxException when pattern cannot be compiled
*/
public Swagger2MarkupConfigBuilder withHeaderRegex(String headerRegex) {
Validate.notNull(headerRegex, "%s must not be null", headerRegex);
config.headerPattern = Pattern.compile(headerRegex);
return this;
}
/**
* Specifies labels language of output files.
*
* @param language the enum
* @return this builder
*/
public Swagger2MarkupConfigBuilder withOutputLanguage(Language language) {
Validate.notNull(language, "%s must not be null", "language");
config.outputLanguage = language;
return this;
}
/**
* Disable inline schema support.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withoutInlineSchema() {
config.inlineSchemaEnabled = false;
return this;
}
/**
* Specifies tag ordering.<br>
* By default tag ordering == {@link io.github.swagger2markup.OrderBy#NATURAL}.<br>
* Use {@link #withTagOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy tag ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder 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.swagger2markup.OrderBy#AS_IS}.<br>
* Use {@link #withOperationOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy operation ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder 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.swagger2markup.OrderBy#NATURAL}.<br>
* Use {@link #withDefinitionOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy definition ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder 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 OrderBy#NATURAL}.<br>
* Use {@link #withParameterOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy parameter ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder 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.swagger2markup.OrderBy#NATURAL}.<br>
* Use {@link #withPropertyOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy property ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 properties.
*
* @param propertyOrdering property ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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.swagger2markup.OrderBy#NATURAL}.<br>
* Use {@link #withResponseOrdering(Comparator)} to set a custom ordering.
*
* @param orderBy response ordering
* @return this builder
*/
public Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder 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 Swagger2MarkupConfigBuilder withInterDocumentCrossReferences() {
config.interDocumentCrossReferencesEnabled = true;
return this;
}
/**
* Optionally isolate the body parameter, if any, from other parameters.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withFlatBody() {
config.flatBodyEnabled = true;
return this;
}
/**
* Optionally disable the security section for path sections
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withoutPathSecuritySection() {
config.pathSecuritySectionEnabled = false;
return this;
}
/**
* Prepend the base path to all paths.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withBasePathPrefix() {
config.basePathPrefixEnabled = true;
return this;
}
/**
* Optionally prefix all anchors for uniqueness.
*
* @param anchorPrefix anchor prefix.
* @return this builder
*/
public Swagger2MarkupConfigBuilder withAnchorPrefix(String anchorPrefix) {
Validate.notNull(anchorPrefix, "%s must not be null", "anchorPrefix");
config.anchorPrefix = anchorPrefix;
return this;
}
/**
* Set the page break locations
*
* @param locations List of locations to create new pages
* @return this builder
*/
public Swagger2MarkupConfigBuilder withPageBreaks(List<PageBreakLocations> locations) {
Validate.notNull(locations, "%s must not be null", "locations");
config.pageBreakLocations = locations;
return this;
}
/**
* Specifies the line separator which should be used.
*
* @param lineSeparator the lineSeparator
* @return this builder
*/
public Swagger2MarkupConfigBuilder withLineSeparator(LineSeparator lineSeparator) {
Validate.notNull(lineSeparator, "%s must no be null", "lineSeparator");
config.lineSeparator = lineSeparator;
return this;
}
static class DefaultSwagger2MarkupConfig implements Swagger2MarkupConfig {
private MarkupLanguage markupLanguage;
private MarkupLanguage swaggerMarkupLanguage;
private boolean generatedExamplesEnabled;
private boolean basePathPrefixEnabled;
private boolean separatedDefinitionsEnabled;
private boolean separatedOperationsEnabled;
private GroupBy pathsGroupedBy;
private Language outputLanguage;
private boolean inlineSchemaEnabled;
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 boolean pathSecuritySectionEnabled;
private String anchorPrefix;
private LineSeparator lineSeparator;
private String overviewDocument;
private String pathsDocument;
private String definitionsDocument;
private String securityDocument;
private String separatedOperationsFolder;
private String separatedDefinitionsFolder;
private List<PageBreakLocations> pageBreakLocations;
private Pattern headerPattern;
private Swagger2MarkupProperties extensionsProperties;
@Override
public MarkupLanguage getMarkupLanguage() {
return markupLanguage;
}
@Override
public MarkupLanguage getSwaggerMarkupLanguage() {
return swaggerMarkupLanguage;
}
@Override
public boolean isGeneratedExamplesEnabled() {
return generatedExamplesEnabled;
}
@Override
public boolean isSeparatedDefinitionsEnabled() {
return separatedDefinitionsEnabled;
}
@Override
public boolean isSeparatedOperationsEnabled() {
return separatedOperationsEnabled;
}
@Override
public GroupBy getPathsGroupedBy() {
return pathsGroupedBy;
}
@Override
public Language getOutputLanguage() {
return outputLanguage;
}
@Override
public boolean isInlineSchemaEnabled() {
return inlineSchemaEnabled;
}
@Override
public OrderBy getTagOrderBy() {
return tagOrderBy;
}
@Override
public Pattern getHeaderPattern() {
return headerPattern;
}
@Override
public Comparator<String> getTagOrdering() {
return tagOrdering;
}
@Override
public OrderBy getOperationOrderBy() {
return operationOrderBy;
}
@Override
public Comparator<PathOperation> getOperationOrdering() {
return operationOrdering;
}
@Override
public OrderBy getDefinitionOrderBy() {
return definitionOrderBy;
}
@Override
public Comparator<String> getDefinitionOrdering() {
return definitionOrdering;
}
@Override
public OrderBy getParameterOrderBy() {
return parameterOrderBy;
}
@Override
public Comparator<Parameter> getParameterOrdering() {
return parameterOrdering;
}
@Override
public OrderBy getPropertyOrderBy() {
return propertyOrderBy;
}
@Override
public Comparator<String> getPropertyOrdering() {
return propertyOrdering;
}
@Override
public OrderBy getResponseOrderBy() {
return responseOrderBy;
}
@Override
public Comparator<String> getResponseOrdering() {
return responseOrdering;
}
@Override
public boolean isInterDocumentCrossReferencesEnabled() {
return interDocumentCrossReferencesEnabled;
}
@Override
public String getInterDocumentCrossReferencesPrefix() {
return interDocumentCrossReferencesPrefix;
}
@Override
public boolean isFlatBodyEnabled() {
return flatBodyEnabled;
}
@Override
public boolean isPathSecuritySectionEnabled() {
return pathSecuritySectionEnabled;
}
@Override
public String getAnchorPrefix() {
return anchorPrefix;
}
@Override
public String getOverviewDocument() {
return overviewDocument;
}
@Override
public String getPathsDocument() {
return pathsDocument;
}
@Override
public String getDefinitionsDocument() {
return definitionsDocument;
}
@Override
public String getSecurityDocument() {
return securityDocument;
}
@Override
public String getSeparatedOperationsFolder() {
return separatedOperationsFolder;
}
@Override
public String getSeparatedDefinitionsFolder() {
return separatedDefinitionsFolder;
}
@Override
public LineSeparator getLineSeparator() {
return lineSeparator;
}
@Override
public Swagger2MarkupProperties getExtensionsProperties() {
return extensionsProperties;
}
@Override
public boolean isBasePathPrefixEnabled() {
return basePathPrefixEnabled;
}
@Override
public List<PageBreakLocations> getPageBreakLocations() {
return pageBreakLocations;
}
}
}

View File

@@ -1,80 +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.swagger2markup.model;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import static org.apache.commons.lang3.StringUtils.isBlank;
public class PathOperation {
private HttpMethod method;
private String path;
private 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,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.swagger2markup.internal.component;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.assertions.DiffUtils;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentResolverFromOperation;
import io.github.swagger2markup.internal.resolver.SecurityDocumentResolver;
import io.github.swagger2markup.internal.utils.PathUtils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.Swagger;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class PathOperationComponentTest extends AbstractComponentTest {
@Test
public void testPathOperationComponent() throws URISyntaxException {
String COMPONENT_NAME = "path_operation";
Path outputDirectory = getOutputFile(COMPONENT_NAME);
FileUtils.deleteQuietly(outputDirectory.toFile());
//Given
Path file = Paths.get(PathOperationComponentTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(file).build();
Swagger swagger = converter.getContext().getSwagger();
io.swagger.models.Path path = swagger.getPaths().get("/pets");
List<PathOperation> pathOperations = PathUtils.toPathOperationsList("/pets", path);
Swagger2MarkupConverter.Context context = converter.getContext();
MarkupDocBuilder markupDocBuilder = context.createMarkupDocBuilder();
//When
markupDocBuilder = new PathOperationComponent(context,
new DefinitionDocumentResolverFromOperation(context),
new SecurityDocumentResolver(context)).
apply(markupDocBuilder, PathOperationComponent.parameters(pathOperations.get(0)));
markupDocBuilder.writeToFileWithoutExtension(outputDirectory, StandardCharsets.UTF_8);
//Then
Path expectedFile = getExpectedFile(COMPONENT_NAME);
DiffUtils.assertThatFileIsEqual(expectedFile, outputDirectory, getReportName(COMPONENT_NAME));
}
@Test
public void testInlineSchema() throws URISyntaxException {
String COMPONENT_NAME = "path_operation_inline_schema";
Path outputDirectory = getOutputFile(COMPONENT_NAME);
FileUtils.deleteQuietly(outputDirectory.toFile());
//Given
Path file = Paths.get(PathOperationComponentTest.class.getResource("/yaml/swagger_inlineSchema.yaml").toURI());
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(file).build();
Swagger swagger = converter.getContext().getSwagger();
io.swagger.models.Path path = swagger.getPaths().get("/LaunchCommand");
List<PathOperation> pathOperations = PathUtils.toPathOperationsList("/LaunchCommand", path);
Swagger2MarkupConverter.Context context = converter.getContext();
MarkupDocBuilder markupDocBuilder = context.createMarkupDocBuilder();
//When
markupDocBuilder = new PathOperationComponent(context,
new DefinitionDocumentResolverFromOperation(context),
new SecurityDocumentResolver(context)).
apply(markupDocBuilder, PathOperationComponent.parameters(pathOperations.get(0)));
markupDocBuilder.writeToFileWithoutExtension(outputDirectory, StandardCharsets.UTF_8);
//Then
Path expectedFile = getExpectedFile(COMPONENT_NAME);
DiffUtils.assertThatFileIsEqual(expectedFile, outputDirectory, getReportName(COMPONENT_NAME));
}
}

View File

@@ -1,67 +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.swagger2markup.internal.component;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.assertions.DiffUtils;
import io.github.swagger2markup.internal.document.OverviewDocument;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.swagger.models.Swagger;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SecuritySchemeDefinitionComponentTest extends AbstractComponentTest {
private static final String COMPONENT_NAME = "security_scheme_definition";
private Path outputDirectory;
@Before
public void setUp() {
outputDirectory = getOutputFile(COMPONENT_NAME);
FileUtils.deleteQuietly(outputDirectory.toFile());
}
@Test
public void testSecuritySchemeDefinitionComponent() throws URISyntaxException {
//Given
Path file = Paths.get(SecuritySchemeDefinitionComponentTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(file).build();
Swagger swagger = converter.getContext().getSwagger();
SecuritySchemeDefinition securitySchemeDefinition = swagger.getSecurityDefinitions().get("petstore_auth");
Swagger2MarkupConverter.Context context = converter.getContext();
MarkupDocBuilder markupDocBuilder = context.createMarkupDocBuilder();
markupDocBuilder = new SecuritySchemeDefinitionComponent(context).apply(
markupDocBuilder, SecuritySchemeDefinitionComponent.parameters("petstore_auth",
securitySchemeDefinition,
OverviewDocument.SECTION_TITLE_LEVEL));
markupDocBuilder.writeToFileWithoutExtension(outputDirectory, StandardCharsets.UTF_8);
Path expectedFile = getExpectedFile(COMPONENT_NAME);
DiffUtils.assertThatFileIsEqual(expectedFile, outputDirectory, getReportName(COMPONENT_NAME));
}
}

View File

@@ -1,57 +0,0 @@
[[_paths]]
== Paths
[[_createstate]]
=== Create state
....
POST /state
....
==== Description
Return state
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**oldState** +
__required__|Old State as raw string|enum (ADDED, REMOVED, CHANGED)
|**Body**|**StateModel** +
__optional__|State as enum in object|<<_createstate_statemodel,StateModel>>
|===
[[_createstate_statemodel]]
**StateModel**
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|**value** +
__optional__|State value|enum (ADDED, REMOVED, CHANGED)
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|OK|enum (ADDED, REMOVED, CHANGED)
|===
==== Consumes
* `application/json`
==== Produces
* `*/*`

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

View File

@@ -0,0 +1,309 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.ContentNode;
import org.asciidoctor.ast.Document;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("SuspiciousMethodCalls")
public abstract class ContentNodeImpl implements ContentNode {
private String id;
private final String context;
private final Map<String, Object> attributes;
private final List<String> roles;
private final ContentNode parent;
public ContentNodeImpl(ContentNode parent, String context) {
this(parent, context, new HashMap<>(), new ArrayList<>());
}
public ContentNodeImpl(ContentNode parent, String context, Map<String, Object> attributes, List<String> roles) {
this.parent = parent;
this.context = context;
this.attributes = attributes;
this.roles = roles;
}
@Override
@Deprecated
public String id() {
return getId();
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id.toLowerCase().replaceAll("\\s+", "_");
}
@Override
@Deprecated
public String context() {
return getContext();
}
@Override
public String getContext() {
return context;
}
@Override
@Deprecated
public ContentNode parent() {
return getParent();
}
@Override
public ContentNode getParent() {
return parent;
}
@Override
@Deprecated
public Document document() {
return getDocument();
}
@Override
public Document getDocument() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String getNodeName() {
return getContext();
}
@Override
public boolean isInline() {
return false;
}
@Override
public boolean isBlock() {
return false;
}
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@Override
@Deprecated
public Object getAttr(Object name, Object defaultValue, boolean inherit) {
return getAttribute(name, defaultValue, inherit);
}
@Override
@Deprecated
public Object getAttr(Object name, Object defaultValue) {
return getAttribute(name, defaultValue);
}
@Override
@Deprecated
public Object getAttr(Object name) {
return getAttribute(name);
}
@Override
public Object getAttribute(Object name, Object defaultValue, boolean inherit) {
return getAttribute(name, defaultValue);
}
@Override
public Object getAttribute(Object name, Object defaultValue) {
return attributes.getOrDefault(name, defaultValue);
}
@Override
public Object getAttribute(Object name) {
return attributes.get(name);
}
@Override
@Deprecated
public boolean isAttr(Object name, Object expected, boolean inherit) {
return isAttribute(name, expected, inherit);
}
@Override
@Deprecated
public boolean isAttr(Object name, Object expected) {
return isAttribute(name, expected);
}
@Override
public boolean isAttribute(Object name, Object expected, boolean inherit) {
return isAttribute(name, expected);
}
@Override
public boolean isAttribute(Object name, Object expected) {
try {
if (attributes.containsKey(name)) {
return attributes.get(name).equals(expected);
} else return false;
} catch (Exception e) {
return false;
}
}
@Override
@Deprecated
public boolean hasAttr(Object name) {
return hasAttribute(name);
}
@Override
@Deprecated
public boolean hasAttr(Object name, boolean inherited) {
return hasAttribute(name, inherited);
}
@Override
public boolean hasAttribute(Object name) {
return attributes.containsKey(name);
}
@Override
public boolean hasAttribute(Object name, boolean inherited) {
return hasAttribute(name);
}
@Override
@Deprecated
public boolean setAttr(Object name, Object value, boolean overwrite) {
return setAttribute(name, value, overwrite);
}
@Override
public boolean setAttribute(Object name, Object value, boolean overwrite) {
return setAttribute((String)name, value, overwrite);
}
public boolean setAttribute(String name, Object value, boolean overwrite) {
try {
if (overwrite) {
attributes.put(name, value);
} else {
attributes.putIfAbsent(name, value);
}
return true;
} catch (Exception e) {
return false;
}
}
public Object removeAttribute(String name){
return attributes.remove(name);
}
public boolean removeAttribute(String name, Object value){
return attributes.remove(name, value);
}
@Override
public boolean isOption(Object name) {
try {
Object o = attributes.get(name + "-option");
return null != o && o.toString().equals("");
}catch (Exception ignored){
return false;
}
}
public boolean setOption(String name){
return setAttribute(name + "-option", "", true);
}
public Object removeOption(String name){
return removeAttribute(name + "-option");
}
@Override
public boolean isRole() {
return false;
}
@Override
public String getRole() {
return String.join(",", roles);
}
@Override
@Deprecated
public String role() {
return getRole();
}
@Override
public List<String> getRoles() {
return roles;
}
@Override
public boolean hasRole(String role) {
return roles.contains(role);
}
@Override
public void addRole(String role) {
roles.add(role);
}
@Override
public void removeRole(String role) {
roles.remove(role);
}
@Override
public boolean isReftext() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String getReftext() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String iconUri(String name) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String mediaUri(String target) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String imageUri(String targetImage) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String imageUri(String targetImage, String assetDirKey) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String readAsset(String path, Map<Object, Object> opts) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String normalizeWebPath(String path, String start, boolean preserveUriTarget) {
throw new UnsupportedOperationException("Not implemented, yet");
}
}

View File

@@ -0,0 +1,36 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Cursor;
public class CursorImpl implements Cursor {
private int lineno;
public CursorImpl() {
}
@Override
public int getLineNumber() {
return lineno;
}
@Override
public String getPath() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String getDir() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String getFile() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public String toString() {
throw new UnsupportedOperationException("Not implemented, yet");
}
}

View File

@@ -0,0 +1,66 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.DescriptionListEntry;
import org.asciidoctor.ast.ListItem;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DescriptionListEntryImpl extends StructuralNodeImpl implements DescriptionListEntry {
private final List<ListItem> terms;
private ListItem description;
public DescriptionListEntryImpl(StructuralNode parent) {
this(parent, new ArrayList<>());
}
public DescriptionListEntryImpl(StructuralNode parent, List<ListItem> terms) {
this(parent, terms, null);
}
public DescriptionListEntryImpl(StructuralNode parent, List<ListItem> terms, ListItem description) {
this(parent, null, terms, description);
}
public DescriptionListEntryImpl(StructuralNode parent, Object content, List<ListItem> terms, ListItem description) {
this(parent, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), terms, description);
}
public DescriptionListEntryImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs,
List<ListItem> terms, ListItem description) {
this(parent, attributes, roles, content, blocks, null != parent ? parent.getLevel() : 1, contentModel, subs, terms, description);
}
public DescriptionListEntryImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, Integer level, String contentModel,
List<String> subs, List<ListItem> terms, ListItem description) {
super(parent, "dlist_item", attributes, roles, content, blocks, level, contentModel, subs);
this.terms = terms;
this.description = description;
}
@Override
public List<ListItem> getTerms() {
return terms;
}
public boolean addTerm(ListItem term) {
return terms.add(term);
}
@Override
public ListItem getDescription() {
return description;
}
public void setDescription(final ListItem description) {
this.description = description;
}
}

View File

@@ -0,0 +1,72 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.DescriptionList;
import org.asciidoctor.ast.DescriptionListEntry;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DescriptionListImpl extends StructuralNodeImpl implements DescriptionList {
public static final String CONTEXT = "dlist";
private List<DescriptionListEntry> items;
public DescriptionListImpl(StructuralNode parent) {
this(parent, new ArrayList<>());
}
public DescriptionListImpl(StructuralNode parent, List<DescriptionListEntry> items) {
this(parent, null, items);
}
public DescriptionListImpl(StructuralNode parent, Object content, List<DescriptionListEntry> items) {
this(parent, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), items);
}
public DescriptionListImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, String contentModel,
List<String> subs, List<DescriptionListEntry> items) {
this(parent, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs, items);
}
public DescriptionListImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, Integer level,
String contentModel, List<String> subs, List<DescriptionListEntry> items) {
super(parent, CONTEXT, attributes, roles, content, blocks, level, contentModel, subs);
this.items = items;
}
@Override
public List<DescriptionListEntry> getItems() {
return items;
}
public void setItems(List<DescriptionListEntry> items) {
this.items = items;
}
public void addEntry(DescriptionListEntry entry) {
this.items.add(entry);
}
@Override
public boolean hasItems() {
return !items.isEmpty();
}
@Override
@Deprecated
public String render() {
return convert();
}
protected static Integer calculateLevel(StructuralNode parent) {
int level = 1;
if (parent instanceof DescriptionList)
level = parent.getLevel() + 1;
return level;
}
}

View File

@@ -0,0 +1,89 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.ast.Title;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DocumentImpl extends StructuralNodeImpl implements Document {
public DocumentImpl() {
this(null);
}
public DocumentImpl(StructuralNode parent) {
this(parent, "document", "");
}
public DocumentImpl(StructuralNode parent, String context, Object content) {
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
}
public DocumentImpl(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, null != parent ? parent.getLevel() + 1 : 0, contentModel, subs);
}
public DocumentImpl(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);
}
@Override
public boolean isBasebackend(String backend) {
return isAttribute("basebackend", backend);
}
@Override
@Deprecated
public boolean basebackend(String backend) {
return isBasebackend(backend);
}
@Override
public Map<Object, Object> getOptions() {
return null;
}
@Override
public Title getStructuredDoctitle() {
return (Title) getOptions().get("doctitle");
}
@Override
public String getDoctitle() {
return getTitle();
}
@Override
@Deprecated
public String doctitle() {
return getDoctitle();
}
@Override
public int getAndIncrementCounter(String name) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public int getAndIncrementCounter(String name, int initialValue) {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public boolean isSourcemap() {
throw new UnsupportedOperationException("Not implemented, yet");
}
@Override
public void setSourcemap(boolean state) {
throw new UnsupportedOperationException("Not implemented, yet");
}
}

View File

@@ -0,0 +1,56 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.List;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ListImpl extends StructuralNodeImpl implements List {
private final java.util.List<StructuralNode> items;
public ListImpl(StructuralNode parent, String context) {
this(parent, context, new ArrayList<>());
}
public ListImpl(StructuralNode parent, String context, java.util.List<StructuralNode> items) {
this(parent, context, null, items);
}
public ListImpl(StructuralNode parent, String context, Object content, java.util.List<StructuralNode> items) {
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), items);
}
public ListImpl(StructuralNode parent, String context, Map<String, Object> attributes, java.util.List<String> roles,
Object content, java.util.List<StructuralNode> blocks,
String contentModel, java.util.List<String> subs, java.util.List<StructuralNode> items) {
this(parent, context, attributes, roles, content, blocks, null != parent ? parent.getLevel() + 1 : 0, contentModel, subs, items);
}
public ListImpl(StructuralNode parent, String context, Map<String, Object> attributes, java.util.List<String> roles,
Object content, java.util.List<StructuralNode> blocks,
Integer level, String contentModel, java.util.List<String> subs, java.util.List<StructuralNode> items) {
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
this.items = items;
}
@Override
public java.util.List<StructuralNode> getItems() {
return items;
}
@Override
public boolean hasItems() {
return !items.isEmpty();
}
@Override
@Deprecated
public String render() {
return convert();
}
}

View File

@@ -0,0 +1,63 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.ListItem;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ListItemImpl extends StructuralNodeImpl implements ListItem {
private final String marker;
private String text;
public ListItemImpl(StructuralNode parent, String text) {
this(parent, "list_item", null, "*", text);
}
public ListItemImpl(StructuralNode parent, String context, Object content, String marker, String text) {
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), marker, text);
}
public ListItemImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, String contentModel,
List<String> subs, String marker, String text) {
this(parent, context, attributes, roles, content, blocks, null != parent ? parent.getLevel() : 1, contentModel, subs, marker, text);
}
public ListItemImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, Integer level,
String contentModel, List<String> subs, String marker, String text) {
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
this.marker = marker;
this.text = text;
}
@Override
public String getMarker() {
return marker;
}
@Override
public String getText() {
return text;
}
@Override
public String getSource() {
return text;
}
@Override
public void setSource(String source) {
this.text = source;
}
@Override
public boolean hasText() {
return StringUtils.isNotBlank(text);
}
}

View File

@@ -0,0 +1,38 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.StructuralNode;
import java.util.List;
import java.util.Map;
public class ParagraphBlockImpl extends BlockImpl {
public static final String CONTEXT = "paragraph";
public ParagraphBlockImpl(StructuralNode parent) {
super(parent, CONTEXT);
}
public ParagraphBlockImpl(StructuralNode parent, Object content) {
super(parent, CONTEXT, content);
}
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes) {
super(parent, CONTEXT, attributes);
}
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes, Object content) {
super(parent, CONTEXT, attributes, content);
}
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs) {
super(parent, CONTEXT, attributes, roles, content, blocks, contentModel, subs);
}
public ParagraphBlockImpl(StructuralNode parent, 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);
}
}

View File

@@ -0,0 +1,50 @@
package io.github.swagger2markup.adoc.ast.impl;
import io.github.swagger2markup.adoc.AsciidocConverter;
import org.asciidoctor.ast.ContentNode;
import org.asciidoctor.ast.PhraseNode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PhraseNodeImpl extends ContentNodeImpl implements PhraseNode {
private final String type;
private final String text;
private final String target;
private final AsciidocConverter converter = new AsciidocConverter(AsciidocConverter.NAME, new HashMap<>());
public PhraseNodeImpl(ContentNode parent, String context, Map<String, Object> attributes, List<String> roles, String type, String text, String target) {
super(parent, context, attributes, roles);
this.type = type;
this.text = text;
this.target = target;
}
@Override
@Deprecated
public String render() {
return convert();
}
@Override
public String convert() {
return converter.convert(this, null, new HashMap<>());
}
@Override
public String getType() {
return type;
}
@Override
public String getText() {
return text;
}
@Override
public String getTarget() {
return target;
}
}

View File

@@ -0,0 +1,21 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Cell;
import org.asciidoctor.ast.Row;
import java.util.List;
public class RowImpl implements Row {
private final List<Cell> cells;
public RowImpl(List<Cell> cells) {
this.cells = cells;
}
@Override
public List<Cell> getCells() {
return cells;
}
}

View File

@@ -0,0 +1,118 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Section;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SectionImpl extends StructuralNodeImpl implements Section {
private final Integer index;
private final Integer number;
private final String numeral;
private final String sectionName;
private final boolean special;
private final boolean numbered;
public SectionImpl(StructuralNode parent) {
this(parent, new HashMap<>());
}
public SectionImpl(StructuralNode parent, Map<String, Object> attributes) {
this(parent, "section", null, "");
}
public SectionImpl(StructuralNode parent, String context, Object content, String sectionName) {
this(parent, context, content, null, null, "", sectionName, false, false);
}
public SectionImpl(StructuralNode parent, String context, Object content, Integer index, Integer number, String numeral,
String sectionName, boolean special, boolean numbered) {
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(),
"", new ArrayList<>(), index, number, numeral, sectionName, special, numbered);
}
public SectionImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs,
Integer index, Integer number, String numeral, String sectionName, boolean special, boolean numbered) {
this(parent, context, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs, index, number, numeral, sectionName, special, numbered);
}
public SectionImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs,
Integer index, Integer number, String numeral, String sectionName, boolean special, boolean numbered) {
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
this.index = index;
this.number = number;
this.numeral = numeral;
this.sectionName = sectionName;
this.special = special;
this.numbered = numbered;
}
@Override
@Deprecated
public int index() {
return getIndex();
}
@Override
public int getIndex() {
return index;
}
@Override
@Deprecated
public int number() {
return getNumber();
}
@Override
@Deprecated
public int getNumber() {
return number;
}
@Override
public String getNumeral() {
return numeral;
}
@Override
@Deprecated
public String sectname() {
return getSectionName();
}
@Override
public String getSectionName() {
return sectionName;
}
@Override
@Deprecated
public boolean special() {
return isSpecial();
}
@Override
public boolean isSpecial() {
return special;
}
@Override
@Deprecated
public boolean numbered() {
return isNumbered();
}
@Override
public boolean isNumbered() {
return numbered;
}
}

View File

@@ -0,0 +1,179 @@
package io.github.swagger2markup.adoc.ast.impl;
import io.github.swagger2markup.adoc.AsciidocConverter;
import org.asciidoctor.ast.Cursor;
import org.asciidoctor.ast.StructuralNode;
import java.util.*;
public class StructuralNodeImpl extends ContentNodeImpl implements StructuralNode {
private String title;
private String caption;
private String style;
private final Object content;
private final List<StructuralNode> blocks;
private Integer level;
private final String contentModel;
private List<String> subs;
private final AsciidocConverter converter = new AsciidocConverter(AsciidocConverter.NAME, new HashMap<>());
public StructuralNodeImpl(StructuralNode parent, String context) {
this(parent, context, new HashMap<>());
}
public StructuralNodeImpl(StructuralNode parent, String context, Map<String, Object> attributes) {
this(parent, context, attributes, null);
}
public StructuralNodeImpl(StructuralNode parent, String context, Object content) {
this(parent, context, new HashMap<>(), content);
}
public StructuralNodeImpl(StructuralNode parent, String context, Map<String, Object> attributes, Object content) {
this(parent, context, attributes, new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
}
public StructuralNodeImpl(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 StructuralNodeImpl(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);
this.content = content;
this.blocks = blocks;
this.level = level;
this.contentModel = contentModel;
this.subs = subs;
}
@Override
@Deprecated
public String title() {
return getTitle();
}
@Override
public String getTitle() {
return title;
}
@Override
public void setTitle(String title) {
this.title = title;
}
@Override
public String getCaption() {
return caption;
}
@Override
public void setCaption(String caption) {
this.caption = caption;
}
@Override
@Deprecated
public String style() {
return getStyle();
}
@Override
public String getStyle() {
return style;
}
@Override
public void setStyle(String style) {
this.style = style;
}
@Override
@Deprecated
public List<StructuralNode> blocks() {
return getBlocks();
}
@Override
public List<StructuralNode> getBlocks() {
return blocks;
}
@Override
public void append(StructuralNode block) {
blocks.add(block);
}
@Override
@Deprecated
public Object content() {
return getContent();
}
@Override
public Object getContent() {
return content;
}
@Override
public String convert() {
return converter.convert(this, null, new HashMap<>());
}
@Override
public int getLevel() {
return level;
}
@Override
public Cursor getSourceLocation() {
return new CursorImpl();
}
@Override
public String getContentModel() {
return contentModel;
}
@Override
public List<String> getSubstitutions() {
return subs;
}
@Override
public boolean isSubstitutionEnabled(String substitution) {
return subs.contains(substitution);
}
@Override
public void removeSubstitution(String substitution) {
subs.remove(substitution);
}
@Override
public void addSubstitution(String substitution) {
subs.add(substitution);
}
@Override
public void prependSubstitution(String substitution) {
}
@Override
public void setSubstitutions(String... substitutions) {
subs = Arrays.asList(substitutions);
}
@Override
public List<StructuralNode> findBy(Map<Object, Object> selector) {
throw new UnsupportedOperationException("Not implemented, yet");
}
protected static Integer calculateLevel(StructuralNode parent) {
return null != parent ? parent.getLevel() + 1 : 0;
}
}

View File

@@ -0,0 +1,306 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.*;
public class TableImpl extends StructuralNodeImpl implements Table {
public static final String OPTION_UNBREAKABLE = "unbreakable";
public static final String OPTION_BREAKABLE = "breakable";
private Logger logger = LoggerFactory.getLogger(getClass());
public static final String CONTEXT = "table";
private static final String FRAME_ATTR = "frame";
private static final String GRID_ATTR = "grid";
private RowList headerRows;
private RowList bodyRows;
private RowList footerRows;
private List<Column> columns = new ArrayList<>();
public TableImpl(StructuralNode parent) {
this(parent, new HashMap<>(), new ArrayList<>());
}
public TableImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles) {
this(parent, attributes, roles, calculateLevel(parent));
}
public TableImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles, Integer level) {
this(parent, attributes, roles, null, new ArrayList<>(), level, "", new ArrayList<>());
}
public TableImpl(StructuralNode parent, 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.headerRows = new RowList(new ArrayList<>());
this.bodyRows = new RowList(new ArrayList<>());
this.footerRows = new RowList(new ArrayList<>());
}
@Override
public boolean hasHeaderOption() {
return isOption("header");
}
@Override
public String getFrame() {
return (String) getAttribute(FRAME_ATTR, "all");
}
@Override
public void setFrame(String frame) {
setAttribute(FRAME_ATTR, frame, true);
}
@Override
public String getGrid() {
return (String) getAttribute(GRID_ATTR, "all");
}
@Override
public void setGrid(String grid) {
setAttribute(GRID_ATTR, grid, true);
}
@Override
public List<Column> getColumns() {
return columns;
}
@Override
public List<Row> getHeader() {
return headerRows;
}
public void setHeaderRow(Row row) {
headerRows.clear();
headerRows.add(row);
scanRowForColumns(row);
}
public void setHeaderRow(List<Cell> cells) {
setHeaderRow(new RowImpl(cells));
}
public void setHeaderRow(String... documentContents) {
headerRows.clear();
headerRows.add(generateRow(documentContents));
}
public RowImpl generateRow(Document... innerDocs) {
List<Cell> cells = new ArrayList<>();
for (int i = 0; i < innerDocs.length; i++) {
Column column = null;
try {
column = columns.get(i);
} catch (Exception ignored) {
}
if (null == column) {
ColumnImpl newColumn = new ColumnImpl(this);
newColumn.setColumnNumber(i + 1);
column = newColumn;
addColumnAt(column, i);
}
cells.add(new CellImpl(column, innerDocs[i]));
}
return new RowImpl(cells);
}
public RowImpl generateRow(String... documentContents) {
Document[] documents = Arrays.stream(documentContents).map(documentContent -> {
Document innerDoc = new DocumentImpl();
Block paragraph = new ParagraphBlockImpl(innerDoc);
paragraph.setSource(documentContent);
innerDoc.append(paragraph);
return innerDoc;
}).toArray(Document[]::new);
return generateRow(documents);
}
@Override
public List<Row> getBody() {
return bodyRows;
}
public void setBodyRows(List<Row> rows) {
bodyRows.clear();
bodyRows.addAll(rows);
bodyRows.forEach(this::scanRowForColumns);
}
public void addRow(Row row) {
bodyRows.add(row);
scanRowForColumns(row);
}
public void addRow(List<Cell> cells) {
bodyRows.add(new RowImpl(cells));
}
public RowImpl addRow(Document... documentContents) {
RowImpl row = generateRow(documentContents);
bodyRows.add(row);
return row;
}
public RowImpl addRow(String... documentContents) {
RowImpl row = generateRow(documentContents);
bodyRows.add(row);
return row;
}
@Override
public List<Row> getFooter() {
return footerRows;
}
public void setFooterRow(Row row) {
footerRows.clear();
footerRows.add(row);
scanRowForColumns(row);
}
public void setFooterRow(String... documentContents) {
footerRows.clear();
footerRows.add(generateRow(documentContents));
}
private void scanRowForColumns(Row row) {
row.getCells().forEach(cell -> {
Column column = cell.getColumn();
int i = column.getColumnNumber() - 1;
addColumnAt(column, i);
});
}
private void addColumnAt(Column column, int i) {
if (columns.size() >= i) {
columns.add(i, column);
} else {
while (columns.size() < i) {
columns.add(columns.size(), null);
}
columns.add(column);
}
}
public void setFooterRow(List<Cell> cells) {
setFooterRow(new RowImpl(cells));
}
class RowList extends AbstractList<Row> {
private final List<Row> rubyArray;
private RowList(List<Row> rubyArray) {
this.rubyArray = rubyArray;
}
@Override
public int size() {
return rubyArray.size();
}
@Override
public boolean isEmpty() {
return rubyArray.isEmpty();
}
@Override
public boolean contains(Object o) {
return rubyArray.contains(o);
}
@Override
public boolean add(Row row) {
boolean changed = false;
try {
changed = rubyArray.add(row);
setAttribute("rowcount", size(), true);
} catch (Exception e) {
logger.debug("Couldn't add row", e);
}
return changed;
}
@Override
public boolean remove(Object o) {
if (!(o instanceof RowImpl)) {
return false;
}
try {
boolean changed = rubyArray.remove(o);
setAttribute("rowcount", size(), true);
return changed;
} catch (Exception e) {
logger.debug("Couldn't add row", e);
return false;
}
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
rubyArray.clear();
setAttribute("rowcount", size(), true);
}
@Override
public Row get(int index) {
return rubyArray.get(index);
}
@Override
public Row set(int index, Row element) {
Row oldRow = get(index);
rubyArray.set(index, element);
return oldRow;
}
@Override
public void add(int index, Row element) {
rubyArray.add(index, element);
setAttribute("rowcount", size(), true);
}
@Override
public Row remove(int index) {
Row removed = rubyArray.remove(index);
setAttribute("rowcount", size(), true);
return removed;
}
@Override
public int indexOf(Object o) {
if (!(o instanceof RowImpl)) {
return -1;
}
return rubyArray.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
if (!(o instanceof RowImpl)) {
return -1;
}
return rubyArray.lastIndexOf(o);
}
}
protected static Integer calculateLevel(StructuralNode parent) {
int level = 1;
if (parent instanceof Table)
level = parent.getLevel() + 1;
return level;
}
}

View File

@@ -0,0 +1,34 @@
package io.github.swagger2markup.adoc.ast.impl;
import org.asciidoctor.ast.Title;
public class TitleImpl implements Title {
private final String main;
private final String subtitle;
public TitleImpl(String main, String subtitle) {
this.main = main;
this.subtitle = subtitle;
}
@Override
public String getMain() {
return main;
}
@Override
public String getSubtitle() {
return subtitle;
}
@Override
public String getCombined() {
return main + ": " + subtitle;
}
@Override
public boolean isSanitized() {
return false;
}
}

View File

@@ -0,0 +1,50 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.ContentNode;
public class BlockImageNode extends NodeAttributes {
final private String target;
public BlockImageNode(ContentNode node) {
super(node.getAttributes());
target = pop("target").replaceAll("\\s", "{sp}");
}
public String getTarget() {
return target;
}
@Override
public void processPositionalAttributes() {
String attr1 = pop("1", "alt");
if (StringUtils.isNotBlank(attr1)) {
attrs.add(attr1);
}
String attr2 = pop("2", "width");
if (StringUtils.isNotBlank(attr2)) {
attrs.add(attr2);
}
String attr3 = pop("3", "height");
if (StringUtils.isNotBlank(attr3)) {
attrs.add(attr3);
}
}
@Override
void processAttributes() {
attributes.forEach((k, v) -> {
if (!k.equals("role") && null != v) {
attrs.add(k + "=" + v);
}
});
}
@Override
public String processAsciiDocContent() {
return "image::" + target + '[' + String.join(",", attrs) + ']';
}
}

View File

@@ -0,0 +1,31 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.asciidoctor.ast.Block;
import java.util.List;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
public class BlockListingNode extends ParagraphAttributes {
final private Block node;
public BlockListingNode(Block node) {
super(node);
this.node = node;
}
@Override
public String processAsciiDocContent() {
StringBuilder sb = new StringBuilder();
attrsToString(sb, attrs);
sb.append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR).append(node.getSource()).append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR);
return sb.toString();
}
void attrsToString(StringBuilder sb, List<String> list) {
if (!list.isEmpty()) {
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", list)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
}
}
}

View File

@@ -0,0 +1,45 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.StructuralNode;
import java.util.ArrayList;
import java.util.List;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
public class DelimitedBlockNode extends ParagraphAttributes {
public DelimitedBlockNode(StructuralNode node) {
super(node);
}
@Override
public void processPositionalAttributes() {
String source = pop("1", "style");
StringBuilder options = new StringBuilder();
List<String> toRemove = new ArrayList<>();
attributes.forEach((k, v) -> {
if (k.endsWith(OPTION_SUFFIX)) {
toRemove.add(k);
options.append('%').append(k.replace(OPTION_SUFFIX, ""));
}
});
toRemove.forEach(attributes::remove);
source += options.toString();
if (StringUtils.isNotBlank(source)) {
attrs.add(source);
}
super.processPositionalAttributes();
}
@Override
public String processAsciiDocContent() {
StringBuilder sb = new StringBuilder();
if (!attrs.isEmpty()) {
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
}
return sb.toString();
}
}

View File

@@ -0,0 +1,26 @@
package io.github.swagger2markup.adoc.converter.internal;
public class Delimiters {
public static final String ATTRIBUTES_BEGIN = "[";
public static final String ATTRIBUTES_END = "]";
public static final String COLON = ":";
public static final String DELIMITER_BLOCK = "----";
public static final String DELIMITER_EXAMPLE = "====";
public static final String DELIMITER_INNER_TABLE_CELL = "!";
public static final String DELIMITER_INNER_TABLE = "!===";
public static final String DELIMITER_PAGE_BREAK = "<<<";
public static final String DELIMITER_OPEN_BLOCK = "--";
public static final String DELIMITER_SIDEBAR = "****";
public static final String DELIMITER_TABLE = "|===";
public static final String DELIMITER_TABLE_CELL = "|";
public static final String DELIMITER_THEMATIC_BREAK = "'''";
public static final String DELIMITER_VERSE = "____";
public static final String DOCUMENT_TITLE = "=";
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final String MARKER_LIST_ITEM = "*";
public static final String MARKER_D_LIST_ITEM = ":";
public static final String STYLE_HORIZONTAL = "horizontal";
public static final String STYLE_Q_AND_A = "qanda";
public static final String STYLE_SOURCE = "source";
public static final String TITLE = "=";
}

View File

@@ -0,0 +1,38 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.ContentNode;
public class IconNode extends NodeAttributes {
final private String alt;
public IconNode(ContentNode node) {
super(node.getAttributes());
alt = pop("alt", "default-alt");
}
public String getAlt() {
return alt;
}
@Override
void processPositionalAttributes() {
String attr1 = pop("1", "size");
if (StringUtils.isNotBlank(attr1)) {
attrs.add(attr1);
}
}
@Override
void processAttributes() {
attributes.forEach((k, v) -> {
attrs.add(k + "=" + v);
});
}
@Override
String processAsciiDocContent() {
return "icon:" + alt + '[' + String.join(",", attrs) + ']';
}
}

View File

@@ -0,0 +1,64 @@
package io.github.swagger2markup.adoc.converter.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
abstract class NodeAttributes {
public static final String TITLE = "title";
final Map<String, Object> attributes;
List<String> attrs = new ArrayList<>();
NodeAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
}
public String pop(String... keys) {
AtomicReference<String> value = new AtomicReference<>("");
Stream.of(keys).forEach(key -> {
try {
String tmpValue = attributes.remove(key).toString();
if (null != tmpValue && !tmpValue.isEmpty() && value.get().isEmpty()) {
value.set(tmpValue);
}
} catch (NullPointerException ignored) {
}
});
return value.get();
}
String pop(String key) {
try {
String value = attributes.remove(key).toString();
if (null == value) {
value = "";
}
return value;
} catch (NullPointerException ignored) {
return "";
}
}
final public String toAsciiDocContent() {
processPositionalAttributes();
processAttributes();
return processAsciiDocContent();
}
abstract void processPositionalAttributes();
abstract void processAttributes();
String processAsciiDocContent() {
StringBuilder sb = new StringBuilder();
if (!attrs.isEmpty()) {
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
}
return sb.toString();
}
}

View File

@@ -0,0 +1,63 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.StructuralNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class ParagraphAttributes extends NodeAttributes {
public static final String OPTION_SUFFIX = "-option";
private Logger logger = LoggerFactory.getLogger(getClass());
public ParagraphAttributes(StructuralNode node) {
super(node.getAttributes());
}
@Override
public void processPositionalAttributes() {
String attr1 = pop("1", "style");
if (StringUtils.isNotBlank(attr1)) {
attrs.add(attr1);
}
}
@Override
void processAttributes() {
String id = pop("id");
if (StringUtils.isNotBlank(id)) {
id = "#" + id;
}
String roles = String.join(".", pop("role").split(" "));
if (StringUtils.isNotBlank(roles)) {
roles = "." + roles;
}
StringBuilder options = new StringBuilder();
List<String> namedAttributes = new ArrayList<>();
attributes.forEach((k, v) -> {
if (k.equals(TITLE)) {
logger.debug("Skipping attribute: " + TITLE);
} else if (k.endsWith(OPTION_SUFFIX)) {
options.append('%').append(k.replace(OPTION_SUFFIX, ""));
} else if (null != v) {
if(v.toString().contains(" ") || v.toString().contains(",")) {
namedAttributes.add(k + "=\"" + v +"\"");
} else {
namedAttributes.add(k + "=" + v);
}
} else {
logger.warn("Don't know how to handle key: " + k);
}
});
String nonNamedAttributes = id + roles + options.toString();
if (StringUtils.isNotBlank(nonNamedAttributes)) {
attrs.add(nonNamedAttributes);
}
attrs.addAll(namedAttributes);
}
}

View File

@@ -0,0 +1,53 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
import org.asciidoctor.ast.Block;
import java.util.ArrayList;
import java.util.List;
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
public class SourceNode extends BlockListingNode {
private List<String> sourceAttrs = new ArrayList<>();
private final Block node;
public SourceNode(Block node) {
super(node);
this.node = node;
}
@Override
public void processPositionalAttributes() {
String source = pop("1", "style");
String language = pop("2", "language");
StringBuilder options = new StringBuilder();
List<String> toRemove = new ArrayList<>();
attributes.forEach((k, v) -> {
if (k.endsWith(OPTION_SUFFIX)) {
toRemove.add(k);
options.append('%').append(k.replace(OPTION_SUFFIX, ""));
}
});
toRemove.forEach(attributes::remove);
source += options.toString();
if (StringUtils.isNotBlank(source)) {
sourceAttrs.add(source);
}
if (StringUtils.isNotBlank(language)) {
sourceAttrs.add(language);
}
super.processPositionalAttributes();
}
@Override
public String processAsciiDocContent() {
StringBuilder sb = new StringBuilder();
attrsToString(sb, attrs);
attrsToString(sb, sourceAttrs);
sb.append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR).append(node.getSource()).append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR);
return sb.toString();
}
}

View File

@@ -0,0 +1,35 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
public enum Style {
ASCIIDOC("a"), EMPHASIS("e"), HEADER("h"), LITERAL("l"), MONOSPACED("m"), NONE("d"), STRONG("s"), VERSE("v");
String shortHand;
Style(String h) {
this.shortHand = h;
}
public static Style fromString(String text) {
if(StringUtils.isNotBlank(text)) {
for (Style s : Style.values()) {
if (s.shortHand.equalsIgnoreCase(text)) {
return s;
}
}
}
return null;
}
public static Style fromName(String text) {
if(StringUtils.isNotBlank(text)) {
return valueOf(text.toUpperCase());
}
return null;
}
public String getShortHand() {
return shortHand;
}
}

View File

@@ -0,0 +1,35 @@
package io.github.swagger2markup.adoc.converter.internal;
import org.apache.commons.lang3.StringUtils;
public enum TableCellHorizontalAlignment {
LEFT("<"), CENTER("^"), RIGHT(">");
String delimiter;
TableCellHorizontalAlignment(String s) {
this.delimiter = s;
}
public static TableCellHorizontalAlignment fromString(String text) {
if(StringUtils.isNotBlank(text)) {
for (TableCellHorizontalAlignment a : TableCellHorizontalAlignment.values()) {
if (a.delimiter.equalsIgnoreCase(text)) {
return a;
}
}
}
return null;
}
public static TableCellHorizontalAlignment fromName(String text) {
if(StringUtils.isNotBlank(text)) {
return valueOf(text.toUpperCase());
}
return null;
}
public String getDelimiter() {
return delimiter;
}
}

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