Compare commits
173 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2597a585e | ||
|
|
4df779b4cc | ||
|
|
8b9d3fe588 | ||
|
|
4d4f4ad7d2 | ||
|
|
40467c0186 | ||
|
|
a2dc4080d5 | ||
|
|
76dced1209 | ||
|
|
1060b78622 | ||
|
|
23d3f336d5 | ||
|
|
5a70512c23 | ||
|
|
3c94b8605f | ||
|
|
e17311bd7e | ||
|
|
fecb5e2e61 | ||
|
|
79629d11ae | ||
|
|
6f1efabf94 | ||
|
|
393bbe10fd | ||
|
|
ab0ce79172 | ||
|
|
1311ce90b9 | ||
|
|
e19ed182ff | ||
|
|
8797e00321 | ||
|
|
1721a95e07 | ||
|
|
dac7550bcc | ||
|
|
44c0507b4e | ||
|
|
e69b8295dd | ||
|
|
e8cec2467b | ||
|
|
2cf2593e96 | ||
|
|
f1a1e52988 | ||
|
|
820d6dcb47 | ||
|
|
ea7643fc67 | ||
|
|
72b84a184e | ||
|
|
42b0cf8cf0 | ||
|
|
b0390b1f9a | ||
|
|
634598c5d4 | ||
|
|
e08de663d5 | ||
|
|
76347aa49e | ||
|
|
b0d6183de3 | ||
|
|
67fe8f70b3 | ||
|
|
8bcbb5fcfa | ||
|
|
972497a9a5 | ||
|
|
fbb98fb446 | ||
|
|
27a34c519b | ||
|
|
8ab88d95c8 | ||
|
|
ca60025907 | ||
|
|
184b0222a3 | ||
|
|
b6f4cec736 | ||
|
|
66fad7ea30 | ||
|
|
57fa494b95 | ||
|
|
5ec39bba49 | ||
|
|
9ecad42092 | ||
|
|
8914176db0 | ||
|
|
66757a39fd | ||
|
|
05818f8abf | ||
|
|
f6edc96b49 | ||
|
|
5818025e65 | ||
|
|
cd4a65c3d8 | ||
|
|
6f0e33c6d5 | ||
|
|
8a4ec35d47 | ||
|
|
319a8b68a8 | ||
|
|
109710b94e | ||
|
|
f02606abfc | ||
|
|
324f9a719c | ||
|
|
ac8332f1ed | ||
|
|
0cc153d896 | ||
|
|
9652d91723 | ||
|
|
dfab76f1c2 | ||
|
|
711886bb90 | ||
|
|
4f001e104f | ||
|
|
2befad39d0 | ||
|
|
223250693c | ||
|
|
8e6737fe79 | ||
|
|
667bd30dfd | ||
|
|
4a6c1a6e32 | ||
|
|
b365766cb4 | ||
|
|
7279daf5df | ||
|
|
5af951598d | ||
|
|
ffa27aa177 | ||
|
|
57a61ce839 | ||
|
|
a6576761c7 | ||
|
|
c427efaca3 | ||
|
|
ff2e3654c1 | ||
|
|
86b7577fd0 | ||
|
|
dd04f559d5 | ||
|
|
d828ab31f9 | ||
|
|
586596c5a1 | ||
|
|
00e723fbb8 | ||
|
|
5f844db4c5 | ||
|
|
fe93add209 | ||
|
|
753ad57059 | ||
|
|
c2a8d0d5eb | ||
|
|
36958d78aa | ||
|
|
704e20ef5c | ||
|
|
0104b8cfe8 | ||
|
|
43292024b6 | ||
|
|
ca8cc35004 | ||
|
|
f427e77b78 | ||
|
|
4d876c33a6 | ||
|
|
04f6239fd3 | ||
|
|
156f1ce880 | ||
|
|
836fcd6829 | ||
|
|
4a741acda2 | ||
|
|
857dd34992 | ||
|
|
84ad0ccaa7 | ||
|
|
128710cf50 | ||
|
|
26cd23941a | ||
|
|
d51684196d | ||
|
|
3f2f91f134 | ||
|
|
c62bcb02c2 | ||
|
|
de76eac12e | ||
|
|
dee68deb4d | ||
|
|
df4b6b8684 | ||
|
|
b49b7e01b9 | ||
|
|
12d3a5569a | ||
|
|
839a67aa18 | ||
|
|
c9a4e174db | ||
|
|
92adc61544 | ||
|
|
de24d5811c | ||
|
|
35e953d6b2 | ||
|
|
2728708af3 | ||
|
|
6f75fb6649 | ||
|
|
19dc822316 | ||
|
|
94d08b24d1 | ||
|
|
0a92457e41 | ||
|
|
03f19e7c25 | ||
|
|
4ddab7c8be | ||
|
|
101883f3b3 | ||
|
|
49da3d0fef | ||
|
|
6858dcd424 | ||
|
|
21e37a8cb3 | ||
|
|
7f116674b5 | ||
|
|
9c31fc416c | ||
|
|
0da081c0b4 | ||
|
|
d4973918f6 | ||
|
|
0ecda51555 | ||
|
|
de26a4fec3 | ||
|
|
f6481a7f21 | ||
|
|
f5291e3450 | ||
|
|
ddf3265d4b | ||
|
|
653420fa02 | ||
|
|
a98247adb4 | ||
|
|
f26ba312a7 | ||
|
|
447c4ca3c2 | ||
|
|
6189f710e1 | ||
|
|
5dcb0a3549 | ||
|
|
060f3f859b | ||
|
|
e465c7ff26 | ||
|
|
152083bfa6 | ||
|
|
5b2c34657e | ||
|
|
d0fba73012 | ||
|
|
1703b26626 | ||
|
|
08e445c579 | ||
|
|
da792f6fb8 | ||
|
|
dd606d65ad | ||
|
|
416aefdaf0 | ||
|
|
b725e7324f | ||
|
|
ffb53aac33 | ||
|
|
cbf1b50107 | ||
|
|
92438b20db | ||
|
|
4134a78185 | ||
|
|
ea8829a288 | ||
|
|
268815ac10 | ||
|
|
4ebfda1e94 | ||
|
|
6c7a9ad46e | ||
|
|
857ae5a3f7 | ||
|
|
b881d7f8b5 | ||
|
|
8014c4ba77 | ||
|
|
8443ddc2dc | ||
|
|
a6cf1b51c6 | ||
|
|
5065d4c744 | ||
|
|
7435dc8e1a | ||
|
|
4eb0ee49f6 | ||
|
|
b8984ca5f5 | ||
|
|
b2bceaece0 | ||
|
|
79446a84f1 |
5
.gitignore
vendored
@@ -1,5 +0,0 @@
|
||||
.idea
|
||||
*.iml
|
||||
.gradle
|
||||
build
|
||||
/bin/
|
||||
19
.travis.yml
@@ -1,19 +0,0 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk7
|
||||
before_install:
|
||||
- chmod +x gradlew
|
||||
after_success:
|
||||
- ./gradlew jacocoTestReport coveralls
|
||||
- ./gradlew artifactoryPublish -PbintrayUsername="${BINTRAY_USER}" -PbintrayApiKey="${BINTRAY_KEY}"
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/9c620e84679284b7d621
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: false
|
||||
env:
|
||||
global:
|
||||
- secure: "SPKolgUdjIa/uJ+7/B/GPFlsa8IZg7NuZdFA8zROTaqew/xu+oX7qVGImseeBpPIEPJb02ac6hr7Y3/zvv0GJxIPtIbyDzVh73ImQUhT1ttLYGJfITAWqAPFF7RNNMtuOl3S2DLZ5OMJddkcFp00pa9nyI82Gk47B8GsaGIntAI="
|
||||
- secure: "nXXuHfvFACZwdiFM3Ta0x/f49N7cAgi0AMkgEnQrh/2xWlvQk2z2ySGJQLkhJ7Wy8LDY7Yt1b1GUt6DlP3PuFFMW/cT4iARewqiJRXZXxUQz8fpTDeTo1nmVmW/zzII6Qj3QHM3NRbR/xDOVSJiT30Hnq2hcCBQJWYsTICmzjRk="
|
||||
BIN
1.3.1/images/Swagger2Markup.PNG
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
1.3.1/images/Swagger2Markup_definitions.PNG
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
1.3.1/images/confluence_petstore_screenshot_1024.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
1.3.1/images/overview_extension_points.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
1.3.1/images/titledSwagger.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
1.3.1/images/untitledSwagger.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
3120
1.3.1/index.html
Normal file
BIN
1.3.3/images/Swagger2Markup.PNG
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
1.3.3/images/Swagger2Markup_definitions.PNG
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
1.3.3/images/confluence_petstore_screenshot_1024.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
1.3.3/images/overview_extension_points.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
1.3.3/images/titledSwagger.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
1.3.3/images/untitledSwagger.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
3120
1.3.3/index.html
Normal file
BIN
1.3.4/images/Swagger2Markup.PNG
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
1.3.4/images/Swagger2Markup_definitions.PNG
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
1.3.4/images/confluence_petstore_screenshot_1024.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
1.3.4/images/overview_extension_points.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
1.3.4/images/titledSwagger.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
1.3.4/images/untitledSwagger.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
3206
1.3.4/index.html
Normal file
202
LICENSE.txt
@@ -1,202 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
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.
|
||||
|
||||
73
README.adoc
@@ -1,73 +0,0 @@
|
||||
= Swagger2Markup
|
||||
:author: Robert Winkler
|
||||
:hardbreaks:
|
||||
|
||||
image:https://travis-ci.org/Swagger2Markup/swagger2markup.svg?branch=master["Build Status", link="https://travis-ci.org/Swagger2Markup/swagger2markup"] image:https://coveralls.io/repos/Swagger2Markup/swagger2markup/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup"] image:https://api.bintray.com/packages/robwin/maven/swagger2markup/images/download.svg[link="https://bintray.com/robwin/maven/swagger2markup/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/RobWin/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
|
||||
|
||||
|
||||
== Overview
|
||||
|
||||
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].
|
||||
|
||||
Swagger2Markup converts a Swagger JSON or YAML file into several *AsciiDoc* or *GitHub Flavored Markdown* documents which can be combined with hand-written documentation. The Swagger source file can be located locally or remotely via HTTP. Swagger2Markup supports the Swagger 1.2 and 2.0 specification. Internally it uses the _official_ https://github.com/swagger-api/swagger-parser[swagger-parser] and my https://github.com/RobWin/markup-document-builder[markup-document-builder].
|
||||
|
||||
You can use Swagger2Markup to convert your contract-first Swagger YAML file into a human-readable format and combine it with hand-written documentation. As an alternative, you can choose the code-first approach and use Swagger2Markup together with https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-JAX-RS-Project-Setup-1.5.X[Swagger JAX-RS], https://github.com/springfox/springfox[springfox] or https://github.com/spring-projects/spring-restdocs[spring-restdocs]. If you are Gradle or Maven user, you can also use the https://github.com/RobWin/swagger2markup-gradle-plugin[Swagger2Markup Gradle Plugin] or https://github.com/redowl/swagger2markup-maven-plugin[Swagger2markup Maven Plugin].
|
||||
|
||||
http://asciidoctor.org/docs/asciidoc-writers-guide/[AsciiDoc] is preferable to Markdown as it has more features. AsciiDoc is a text document format for writing documentation, articles, books, ebooks, slideshows, web pages and blogs. AsciiDoc files can be converted to *HTML*, *PDF* and *EPUB*. AsciiDoc is much better suited for describing public APIs than *JavaDoc* or *Annotations*.
|
||||
|
||||
You can generate your HTML5, PDF and EPUB documentation via https://github.com/asciidoctor/asciidoctorj[asciidoctorj] or even better via the https://github.com/asciidoctor/asciidoctor-gradle-plugin[asciidoctor-gradle-plugin] or https://github.com/asciidoctor/asciidoctor-maven-plugin[asciidoctor-maven-plugin].
|
||||
|
||||
The project requires at least JDK 7.
|
||||
|
||||
== Example
|
||||
|
||||
image::src/docs/asciidoc/images/Swagger2Markup.PNG[]
|
||||
|
||||
image::src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[]
|
||||
|
||||
== Reference documentation
|
||||
- http://swagger2markup.readme.io/[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]
|
||||
|
||||
== Contributing
|
||||
|
||||
=== Community contributions
|
||||
|
||||
Pull requests are welcome.
|
||||
|
||||
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/18[Swagger2Markup/swagger2Markup#18] by https://github.com/sg-ad[@sg-ad]: In addition to the definitions.adoc you can also generate separate files for each definition model (ex: person.adoc, address.adoc, purchase.adoc).
|
||||
|
||||
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/21[Swagger2Markup/swagger2Markup#21] by https://github.com/redowl[@redowl]: Support for both reference models and composed models.
|
||||
|
||||
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/27[Swagger2Markup/swagger2Markup#27] by https://github.com/zmitrok[@zmitrok]: Added a hook to preprocess a Swagger Model before it is converted.
|
||||
|
||||
* New feature https://github.com/Swagger2Markup/swagger2markup/issues/48[Swagger2Markup/swagger2Markup#48] by https://github.com/MeteorBoom[@MeteorBoom]: Multi language support.
|
||||
|
||||
=== Questions
|
||||
You can ask questions about Swagger2Markup in https://gitter.im/Swagger2Markup/swagger2markup[Gitter].
|
||||
|
||||
=== Bugs
|
||||
If you believe you have found a bug, please take a moment to search the existing issues. If no one else has reported the problem, please open a new issue that describes the problem in detail and, ideally, includes a test that reproduces it.
|
||||
|
||||
=== Enhancements
|
||||
If you’d like an enhancement to be made to Swagger2Markup, pull requests are most welcome. The source code is on GitHub. You may want to search the existing issues and pull requests to see if the enhancement is already being worked on. You may also want to open a new issue to discuss a possible enhancement before work on it begins.
|
||||
|
||||
== Companies who use Swagger2Markup
|
||||
|
||||
* Deutsche Telekom AG
|
||||
* https://restlet.com/[Restlet] -- Restlet offers an API platform, covering the https://restlet.com/products/restlet-studio/[design], https://restlet.com/products/dhc/[test] and https://restlet.com/products/apispark/[operation] of Web APIs, and uses Swagger2Markup to generate appealing HTML documentation from API definitions.
|
||||
* http://www.qaware.de/[QAware GmbH]
|
||||
* http://www.appdirect.com/[AppDirect] -- The leading commerce platform for selling cloud services.
|
||||
* http://www.wescale.com[wescale]
|
||||
|
||||
== License
|
||||
|
||||
Copyright 2015 Robert Winkler
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
@@ -1,86 +0,0 @@
|
||||
= Release Notes
|
||||
|
||||
== Version 0.1.0
|
||||
* Initial version with support for AsciiDoc and Markdown
|
||||
|
||||
== Version 0.2.0
|
||||
* This version is not downward compatible. This version supports includes of example files and JSON/XML Schema files. See documentation.
|
||||
|
||||
=== Version 0.2.1
|
||||
* Signed jar files and published in Maven Central
|
||||
|
||||
=== Version 0.2.2
|
||||
* Fixed wrong dependency version to io.github.robwin:markup-document-builder
|
||||
|
||||
=== Version 0.2.3
|
||||
* Fixed issue #7: @ApiModelProperty metadata are ignored for definitions file
|
||||
|
||||
=== Version 0.2.4
|
||||
* Fixed issue #8: logback.xml on the classpath
|
||||
* Fixed issue #13: unknown format not supported for properties
|
||||
|
||||
== Version 0.3.0
|
||||
* Support of YAML or JSON String as input.
|
||||
|
||||
== Version 0.4.0
|
||||
* Updated Swagger-Parser from 1.0.0 to 1.0.5
|
||||
* Updated commons-lang to commons-lang3
|
||||
* Swagger2MarkupConverter generates three documents now: overview, paths and definitions
|
||||
* Support for enums in HeaderParameter, QueryParameter, FormParameter and QueryParameter
|
||||
* Support for global consumes, produces and tags
|
||||
|
||||
== Version 0.5.0
|
||||
* Support for including hand-written descriptions instead of using Swagger Annotations for descriptions
|
||||
|
||||
=== Version 0.5.1
|
||||
* Bugfix: Definition name must be lowercase so that descriptions file can be found
|
||||
|
||||
=== Version 0.5.2
|
||||
* Swagger License is not mandatory anymore
|
||||
* Updated markup-document-builder from v0.1.3 to v0.1.4
|
||||
|
||||
=== Version 0.5.3
|
||||
* Fixed compiler warning: [options] bootstrap class path not set in conjunction with -source 1.7
|
||||
|
||||
== Version 0.6.0
|
||||
* Updated swagger-parser from v1.0.5 to v1.0.6
|
||||
* Support for default values in Parameters and Model properties
|
||||
|
||||
=== Version 0.6.1
|
||||
* Updated swagger-parser from v1.0.6 to v1.0.8
|
||||
|
||||
=== Version 0.6.2
|
||||
* curl-request.adoc from spring-restdocs is also added to the example chapters
|
||||
|
||||
=== Version 0.6.3
|
||||
* Added possibility to write object definitions to separate files. Issue #19
|
||||
|
||||
== Version 0.7.0
|
||||
* Added support for both reference models and composed models
|
||||
|
||||
=== Version 0.7.1
|
||||
* Workaround: If the type of a BodyParameter is String and not a Model, the schema is null and lost. Therefore the fallback type of a BodyParameter is String now.
|
||||
|
||||
== Version 0.8.0
|
||||
* Enhancement #26 and #27: Added a pre-process hook to modify a Swagger Model before it is converted.
|
||||
* Bugfix #29: Tags are rendered twice
|
||||
|
||||
== Version 0.9.0
|
||||
* Updated swagger-parser from v1.0.8 to v1.0.13
|
||||
* Support for global responses and parameters
|
||||
|
||||
=== Version 0.9.1
|
||||
* Added support to group the paths by tags or as-is
|
||||
* Added support to order the definitions by natural ordering or as-is
|
||||
|
||||
=== Version 0.9.2
|
||||
* Multi language support. Added russian.
|
||||
|
||||
=== Version 0.9.3
|
||||
* Updated swagger-parser from v1.0.13 to v1.0.16
|
||||
* Enhancement #61 Refactor separated documents logic to support inter-document cross-references
|
||||
* Enhancement #53 : support for tags, paths and methods ordering
|
||||
* Enhancement #51 : Support for separated operations files
|
||||
* Enhancement #52: Markdown generation for inline schemas
|
||||
|
||||
|
||||
134
build.gradle
@@ -1,134 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
|
||||
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.10.1'
|
||||
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.0.1'
|
||||
classpath 'org.asciidoctor:asciidoctorj:1.5.2'
|
||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
|
||||
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.0"
|
||||
}
|
||||
}
|
||||
description = 'swagger2markup Build'
|
||||
version = '1.0.0-SNAPSHOT'
|
||||
group = 'io.github.robwin'
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'org.asciidoctor.convert'
|
||||
apply plugin: 'jacoco'
|
||||
apply plugin: 'com.github.kt3k.coveralls'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: "com.jfrog.artifactory"
|
||||
apply from: 'gradle/publishing.gradle'
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
sourceCompatibility = "1.7"
|
||||
targetCompatibility = "1.7"
|
||||
options.deprecation = true
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs << "-Xlint:unchecked"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://oss.jfrog.org/artifactory/oss-snapshot-local"
|
||||
}
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
//mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'io.github.robwin:markup-document-builder:0.1.6-SNAPSHOT'
|
||||
compile 'io.swagger:swagger-compat-spec-parser:1.0.17'
|
||||
testCompile 'junit:junit:4.11'
|
||||
testCompile 'org.asciidoctor:asciidoctorj:1.5.4'
|
||||
testCompile 'ch.qos.logback:logback-classic:1.1.2'
|
||||
testCompile 'org.assertj:assertj-core:2.2.0'
|
||||
testCompile 'com.sksamuel.diff:diff:1.1.11'
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
|
||||
ext {
|
||||
generatedDocumentation = file('build/docs/asciidoc/generated')
|
||||
}
|
||||
|
||||
asciidoctor {
|
||||
sources {
|
||||
include 'index.adoc'
|
||||
}
|
||||
backends = ['html5', 'pdf']
|
||||
attributes = [
|
||||
doctype: 'book',
|
||||
toc: 'left',
|
||||
toclevels: '3',
|
||||
numbered: '',
|
||||
sectlinks: '',
|
||||
sectanchors: '',
|
||||
hardbreaks: '',
|
||||
generated: generatedDocumentation
|
||||
]
|
||||
}
|
||||
|
||||
artifactory {
|
||||
contextUrl = 'https://oss.jfrog.org'
|
||||
resolve {
|
||||
repository {
|
||||
repoKey = 'libs-release'
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
reports {
|
||||
xml.enabled = true // coveralls plugin depends on xml format report
|
||||
html.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
tasks.coveralls {
|
||||
dependsOn 'check'
|
||||
}
|
||||
|
||||
tasks.artifactoryPublish {
|
||||
dependsOn 'check'
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.10'
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
Date buildTimeAndDate = new Date()
|
||||
ext {
|
||||
buildDate = new SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate)
|
||||
buildTime = new SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate)
|
||||
}
|
||||
|
||||
def projectArtifactId = 'swagger2markup'
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes(
|
||||
'Built-By': 'Robert Winkler',
|
||||
'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")",
|
||||
'Build-Date': project.buildDate,
|
||||
'Build-Time': project.buildTime,
|
||||
'Specification-Title': projectArtifactId,
|
||||
'Specification-Version': project.version,
|
||||
'Implementation-Title': projectArtifactId,
|
||||
'Implementation-Version': project.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (!project.hasProperty('bintrayUsername')) ext.bintrayUsername = ''
|
||||
if (!project.hasProperty('bintrayApiKey')) ext.bintrayApiKey = ''
|
||||
if (!project.hasProperty('gpgPassphrase')) ext.gpgPassphrase = ''
|
||||
if (!project.hasProperty('ossUser')) ext.ossUser = ''
|
||||
if (!project.hasProperty('ossPassword')) ext.ossPassword = ''
|
||||
|
||||
bintray {
|
||||
user = project.bintrayUsername
|
||||
key = project.bintrayApiKey
|
||||
dryRun = false //Whether to run this as dry-run, without deploying
|
||||
publish = true //If version should be auto published after an upload
|
||||
publications = ['mavenJava']
|
||||
pkg {
|
||||
repo = 'maven'
|
||||
name = 'swagger2markup'
|
||||
websiteUrl = 'https://github.com/Swagger2Markup/swagger2markup'
|
||||
issueTrackerUrl = 'https://github.com/Swagger2Markup/swagger2markup/issues'
|
||||
vcsUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
|
||||
desc = 'A Swagger to Markup (AsciiDoc and Markdown) converter.'
|
||||
licenses = ['Apache-2.0']
|
||||
version {
|
||||
vcsTag = project.version
|
||||
gpg {
|
||||
sign = true //Determines whether to GPG sign the files. The default is false
|
||||
passphrase = project.gpgPassphrase //Optional. The passphrase for GPG signing'
|
||||
}
|
||||
mavenCentralSync {
|
||||
sync = true //Optional (true by default). Determines whether to sync the version to Maven Central.
|
||||
user = ossUser //OSS user token
|
||||
password = ossPassword //OSS user password
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
pom.withXml {
|
||||
def devs = ['RobWin': 'Robert Winkler']
|
||||
def root = asNode()
|
||||
|
||||
root.dependencies.'*'.findAll() {
|
||||
it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep ->
|
||||
dep.name == it.artifactId.text()
|
||||
}
|
||||
}.each() {
|
||||
it.scope*.value = 'compile'
|
||||
}
|
||||
|
||||
root.appendNode('name', 'swagger2markup')
|
||||
root.appendNode('packaging', 'jar')
|
||||
root.appendNode('url', 'https://github.com/Swagger2Markup/swagger2markup')
|
||||
root.appendNode('description', 'A Swagger to Markup (AsciiDoc and Markdown) converter.')
|
||||
|
||||
def license = root.appendNode('licenses').appendNode('license')
|
||||
license.appendNode('name', 'Apache-2.0')
|
||||
license.appendNode('url', 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt')
|
||||
license.appendNode('distribution', 'repo')
|
||||
|
||||
root.appendNode('scm').appendNode('url', 'https://github.com/Swagger2Markup/swagger2markup.git')
|
||||
|
||||
def developers = root.appendNode('developers')
|
||||
devs.each {
|
||||
def d = developers.appendNode('developer')
|
||||
d.appendNode('id', it.key)
|
||||
d.appendNode('name', it.value)
|
||||
}
|
||||
}
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +0,0 @@
|
||||
#Wed Feb 10 11:09:13 CET 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
|
||||
160
gradlew
vendored
@@ -1,160 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# 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"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
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=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
gradlew.bat
vendored
@@ -1,90 +0,0 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@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 Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz 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.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
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
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'swagger2markup'
|
||||
@@ -1,36 +0,0 @@
|
||||
== Getting started
|
||||
|
||||
The project is published in JCenter and Maven Central. If you use Gradle or Maven, you can include Swagger2Markup as follows.
|
||||
|
||||
=== Gradle
|
||||
[source,groovy, subs="attributes"]
|
||||
----
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jCenter()
|
||||
}
|
||||
|
||||
compile "io.github.robwin:swagger2markup:{project-version}"
|
||||
----
|
||||
|
||||
=== Maven
|
||||
[source,xml, subs="attributes, verbatim"]
|
||||
----
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
central
|
||||
<name>bintray</name>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.robwin</groupId>
|
||||
<artifactId>swagger2markup</artifactId>
|
||||
<version>{project-version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 124 KiB |
@@ -1,20 +0,0 @@
|
||||
= Swagger2Markup User Guide
|
||||
Robert Winkler
|
||||
:toc: left
|
||||
:toclevels: 3
|
||||
:source-highlighter: coderay
|
||||
:numbered:
|
||||
:hardbreaks:
|
||||
:revnumber: {project-version}
|
||||
:revdate: {localdate}
|
||||
:icons: font
|
||||
:pagenums:
|
||||
|
||||
include::introduction.adoc[]
|
||||
|
||||
include::getting_started.adoc[]
|
||||
|
||||
include::usage_guide.adoc[]
|
||||
|
||||
include::license.adoc[]
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
== Introduction
|
||||
|
||||
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**. 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 https://github.com/OAI/OpenAPI-Specification[OpenAPI Specification].
|
||||
|
||||
Swagger2Markup converts a Swagger JSON or YAML file into several **AsciiDoc** or **GitHub Flavored Markdown** documents which can be combined with hand-written Markup documentation. The Swagger source file can be located locally or remotely via HTTP. Internally Swagger2Markup uses the the __official__ https://github.com/swagger-api/swagger-parser[swagger-parser] and my https://github.com/Swagger2Markup/markup-document-builder[markup-document-builder].
|
||||
|
||||
You can use Swagger2Markup to convert your contract-first Swagger YAML file into Markup. As an alternative, you can choose the code-first approach and use Swagger2Markup together with https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-JAX-RS-Project-Setup-1.5.X[Swagger JAX-RS], https://github.com/springfox/springfox[Springfox] or https://github.com/spring-projects/spring-restdocs[spring-restdocs]. If you are are Gradle or Maven user, you can also use the https://github.com/Swagger2Markup/swagger2markup-gradle-plugin[Swagger2Markup Gradle Plugin] or https://github.com/redowl/swagger2markup-maven-plugin[Swagger2markup Maven Plugin].
|
||||
|
||||
NOTE: The project requires at least JDK 7.
|
||||
|
||||
=== AsciiDoc
|
||||
|
||||
http://asciidoctor.org/docs/asciidoc-writers-guide/[AsciiDoc] is preferable to Markdown as it has more features. AsciiDoc is a text document format for writing documentation, articles, books, ebooks, slideshows, web pages and blogs. AsciiDoc files can be converted to**HTML**, **PDF** and **EPUB**. AsciiDoc is much better suited for describing public APIs than **JavaDoc** or **Annotations**.
|
||||
|
||||
You can generate your HTML5, PDF and EPUB documentation via https://github.com/asciidoctor/asciidoctorj[asciidoctorj] or even better via the https://github.com/asciidoctor/asciidoctor-gradle-plugin[asciidoctor-gradle-plugin] or https://github.com/asciidoctor/asciidoctor-maven-plugin[asciidoctor-maven-plugin].
|
||||
|
||||
=== HTML Example
|
||||
|
||||
image::images/Swagger2Markup.PNG[]
|
||||
|
||||
image::images/Swagger2Markup_definitions.PNG[]
|
||||
@@ -1,9 +0,0 @@
|
||||
== License
|
||||
|
||||
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.
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
public enum GroupBy {
|
||||
AS_IS,
|
||||
TAGS
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Maksim Myshkin
|
||||
*/
|
||||
public enum Language {
|
||||
EN(new Locale("en")),
|
||||
RU(new Locale("ru")),
|
||||
FR(new Locale("fr"));
|
||||
|
||||
private final Locale lang;
|
||||
|
||||
Language(final Locale lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
public Locale toLocale() {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
public enum OrderBy {
|
||||
AS_IS,
|
||||
NATURAL,
|
||||
CUSTOM
|
||||
}
|
||||
@@ -1,764 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.github.robwin.markup.builder.LineSeparator;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.internal.model.PathOperation;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import io.swagger.models.HttpMethod;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
import java.util.Properties;
|
||||
|
||||
public class Swagger2MarkupConfig {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Swagger2MarkupConfig.class);
|
||||
|
||||
private MarkupLanguage markupLanguage;
|
||||
private boolean generatedExamplesEnabled;
|
||||
private boolean operationDescriptionsEnabled;
|
||||
private URI operationDescriptionsUri;
|
||||
private boolean definitionDescriptionsEnabled;
|
||||
private URI definitionDescriptionsUri;
|
||||
private boolean separatedDefinitionsEnabled;
|
||||
private boolean separatedOperationsEnabled;
|
||||
private GroupBy operationsGroupedBy;
|
||||
private Language outputLanguage;
|
||||
private int inlineSchemaDepthLevel;
|
||||
private OrderBy tagOrderBy;
|
||||
private Comparator<String> tagOrdering;
|
||||
private OrderBy operationOrderBy;
|
||||
private Comparator<PathOperation> operationOrdering;
|
||||
private OrderBy definitionOrderBy;
|
||||
private Comparator<String> definitionOrdering;
|
||||
private OrderBy parameterOrderBy;
|
||||
private Comparator<Parameter> parameterOrdering;
|
||||
private OrderBy propertyOrderBy;
|
||||
private Comparator<String> propertyOrdering;
|
||||
private OrderBy responseOrderBy;
|
||||
private Comparator<String> responseOrdering;
|
||||
private boolean interDocumentCrossReferencesEnabled;
|
||||
private String interDocumentCrossReferencesPrefix;
|
||||
private boolean flatBodyEnabled;
|
||||
private String anchorPrefix;
|
||||
private LineSeparator lineSeparator;
|
||||
|
||||
private String overviewDocument;
|
||||
private String pathsDocument;
|
||||
private String definitionsDocument;
|
||||
private String securityDocument;
|
||||
private String separatedOperationsFolder;
|
||||
private String separatedDefinitionsFolder;
|
||||
|
||||
public static Builder ofDefaults() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static Builder ofProperties(Properties properties) {
|
||||
return new Builder(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Partially initialized global context (globalContext.extensionRegistry == null)
|
||||
*/
|
||||
public void setGlobalContext(Swagger2MarkupConverter.Context globalContext) {
|
||||
configureDefaultContentPaths(globalContext.getSwaggerLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically set default path for external content files based on specified {@code swaggerLocation}.<br/>
|
||||
* If {@code swaggerLocation} is null, default path can't be set and features are disabled.<br/>
|
||||
* Paths have to be explicitly set when swaggerLocation.scheme != 'file' to limit the number of URL requests.
|
||||
*
|
||||
* @param swaggerLocation base path to set default paths
|
||||
* @throws RuntimeException if basePath == null and any path is not configured
|
||||
*/
|
||||
private void configureDefaultContentPaths(URI swaggerLocation) {
|
||||
URI baseURI = null;
|
||||
|
||||
if (swaggerLocation != null) {
|
||||
if (swaggerLocation.getScheme().equals("file"))
|
||||
baseURI = IOUtils.uriParent(swaggerLocation);
|
||||
}
|
||||
|
||||
if (operationDescriptionsEnabled && operationDescriptionsUri == null) {
|
||||
if (baseURI == null) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable {} > No explicit '{}' set and no default available > Disable {}", "operationDescriptionsEnabled", "operationDescriptionsUri");
|
||||
operationDescriptionsEnabled = false;
|
||||
} else
|
||||
operationDescriptionsUri = baseURI;
|
||||
}
|
||||
|
||||
if (definitionDescriptionsEnabled && definitionDescriptionsUri == null) {
|
||||
if (baseURI == null) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable {} > No explicit '{}' set and no default available > Disable {}", "definitionDescriptionsEnabled", "definitionDescriptionsUri");
|
||||
definitionDescriptionsEnabled = false;
|
||||
} else
|
||||
definitionDescriptionsUri = baseURI;
|
||||
}
|
||||
}
|
||||
|
||||
public MarkupLanguage getMarkupLanguage() {
|
||||
return markupLanguage;
|
||||
}
|
||||
|
||||
public boolean isGeneratedExamplesEnabled() {
|
||||
return generatedExamplesEnabled;
|
||||
}
|
||||
|
||||
public boolean isOperationDescriptionsEnabled() {
|
||||
return operationDescriptionsEnabled;
|
||||
}
|
||||
|
||||
public URI getOperationDescriptionsUri() {
|
||||
return operationDescriptionsUri;
|
||||
}
|
||||
|
||||
public boolean isDefinitionDescriptionsEnabled() {
|
||||
return definitionDescriptionsEnabled;
|
||||
}
|
||||
|
||||
public URI getDefinitionDescriptionsUri() {
|
||||
return definitionDescriptionsUri;
|
||||
}
|
||||
|
||||
public boolean isSeparatedDefinitionsEnabled() {
|
||||
return separatedDefinitionsEnabled;
|
||||
}
|
||||
|
||||
public boolean isSeparatedOperationsEnabled() {
|
||||
return separatedOperationsEnabled;
|
||||
}
|
||||
|
||||
public GroupBy getOperationsGroupedBy() {
|
||||
return operationsGroupedBy;
|
||||
}
|
||||
|
||||
public Language getOutputLanguage() {
|
||||
return outputLanguage;
|
||||
}
|
||||
|
||||
public int getInlineSchemaDepthLevel() {
|
||||
return inlineSchemaDepthLevel;
|
||||
}
|
||||
|
||||
public OrderBy getTagOrderBy() {
|
||||
return tagOrderBy;
|
||||
}
|
||||
|
||||
public Comparator<String> getTagOrdering() {
|
||||
return tagOrdering;
|
||||
}
|
||||
|
||||
public OrderBy getOperationOrderBy() {
|
||||
return operationOrderBy;
|
||||
}
|
||||
|
||||
public Comparator<PathOperation> getOperationOrdering() {
|
||||
return operationOrdering;
|
||||
}
|
||||
|
||||
public OrderBy getDefinitionOrderBy() {
|
||||
return definitionOrderBy;
|
||||
}
|
||||
|
||||
public Comparator<String> getDefinitionOrdering() {
|
||||
return definitionOrdering;
|
||||
}
|
||||
|
||||
public OrderBy getParameterOrderBy() {
|
||||
return parameterOrderBy;
|
||||
}
|
||||
|
||||
public Comparator<Parameter> getParameterOrdering() {
|
||||
return parameterOrdering;
|
||||
}
|
||||
|
||||
public OrderBy getPropertyOrderBy() {
|
||||
return propertyOrderBy;
|
||||
}
|
||||
|
||||
public Comparator<String> getPropertyOrdering() {
|
||||
return propertyOrdering;
|
||||
}
|
||||
|
||||
public OrderBy getResponseOrderBy() {
|
||||
return responseOrderBy;
|
||||
}
|
||||
|
||||
public Comparator<String> getResponseOrdering() {
|
||||
return responseOrdering;
|
||||
}
|
||||
|
||||
public boolean isInterDocumentCrossReferencesEnabled() {
|
||||
return interDocumentCrossReferencesEnabled;
|
||||
}
|
||||
|
||||
public String getInterDocumentCrossReferencesPrefix() {
|
||||
return interDocumentCrossReferencesPrefix;
|
||||
}
|
||||
|
||||
public boolean isFlatBodyEnabled() {
|
||||
return flatBodyEnabled;
|
||||
}
|
||||
|
||||
public String getAnchorPrefix() {
|
||||
return anchorPrefix;
|
||||
}
|
||||
|
||||
public String getOverviewDocument() {
|
||||
return overviewDocument;
|
||||
}
|
||||
|
||||
public String getPathsDocument() {
|
||||
return pathsDocument;
|
||||
}
|
||||
|
||||
public String getDefinitionsDocument() {
|
||||
return definitionsDocument;
|
||||
}
|
||||
|
||||
public String getSecurityDocument() {
|
||||
return securityDocument;
|
||||
}
|
||||
|
||||
public String getSeparatedOperationsFolder() {
|
||||
return separatedOperationsFolder;
|
||||
}
|
||||
|
||||
public String getSeparatedDefinitionsFolder() {
|
||||
return separatedDefinitionsFolder;
|
||||
}
|
||||
|
||||
public LineSeparator getLineSeparator() {
|
||||
return lineSeparator;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private static final String PROPERTIES_PREFIX = "swagger2markup.";
|
||||
private static final String PROPERTIES_DEFAULT = "/io/github/robwin/swagger2markup/config/default.properties";
|
||||
|
||||
static final Ordering<PathOperation> OPERATION_METHOD_NATURAL_ORDERING = Ordering
|
||||
.explicit(HttpMethod.POST, HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS)
|
||||
.onResultOf(new Function<PathOperation, HttpMethod>() {
|
||||
public HttpMethod apply(PathOperation operation) {
|
||||
return operation.getMethod();
|
||||
}
|
||||
});
|
||||
|
||||
static final Ordering<PathOperation> OPERATION_PATH_NATURAL_ORDERING = Ordering
|
||||
.natural()
|
||||
.onResultOf(new Function<PathOperation, String>() {
|
||||
public String apply(PathOperation operation) {
|
||||
return operation.getPath();
|
||||
}
|
||||
});
|
||||
|
||||
static final Ordering<Parameter> PARAMETER_IN_NATURAL_ORDERING = Ordering
|
||||
.explicit("header", "path", "query", "formData", "body")
|
||||
.onResultOf(new Function<Parameter, String>() {
|
||||
public String apply(Parameter parameter) {
|
||||
return parameter.getIn();
|
||||
}
|
||||
});
|
||||
|
||||
static final Ordering<Parameter> PARAMETER_NAME_NATURAL_ORDERING = Ordering
|
||||
.natural()
|
||||
.onResultOf(new Function<Parameter, String>() {
|
||||
public String apply(Parameter parameter) {
|
||||
return parameter.getName();
|
||||
}
|
||||
});
|
||||
|
||||
Swagger2MarkupConfig config = new Swagger2MarkupConfig();
|
||||
|
||||
Builder() {
|
||||
this(new Properties());
|
||||
}
|
||||
|
||||
Builder(Properties properties) {
|
||||
|
||||
Properties safeProperties = new Properties(defaultProperties());
|
||||
safeProperties.putAll(properties);
|
||||
|
||||
config.markupLanguage = MarkupLanguage.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "markupLanguage"));
|
||||
config.generatedExamplesEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "generatedExamplesEnabled"));
|
||||
config.operationDescriptionsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "operationDescriptionsEnabled"));
|
||||
if (safeProperties.containsKey(PROPERTIES_PREFIX + "operationDescriptionsUri"))
|
||||
config.operationDescriptionsUri = URI.create(safeProperties.getProperty(PROPERTIES_PREFIX + "operationDescriptionsUri"));
|
||||
config.definitionDescriptionsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "definitionDescriptionsEnabled"));
|
||||
if (safeProperties.containsKey(PROPERTIES_PREFIX + "definitionDescriptionsUri"))
|
||||
config.definitionDescriptionsUri = URI.create(safeProperties.getProperty(PROPERTIES_PREFIX + "definitionDescriptionsUri"));
|
||||
config.separatedDefinitionsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "separatedDefinitionsEnabled"));
|
||||
config.separatedOperationsEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "separatedOperationsEnabled"));
|
||||
config.operationsGroupedBy = GroupBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "operationsGroupedBy"));
|
||||
config.outputLanguage = Language.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "outputLanguage"));
|
||||
config.inlineSchemaDepthLevel = Integer.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "inlineSchemaDepthLevel"));
|
||||
config.interDocumentCrossReferencesEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "interDocumentCrossReferencesEnabled"));
|
||||
config.interDocumentCrossReferencesPrefix = safeProperties.getProperty(PROPERTIES_PREFIX + "interDocumentCrossReferencesPrefix");
|
||||
config.flatBodyEnabled = Boolean.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "flatBodyEnabled"));
|
||||
config.anchorPrefix = safeProperties.getProperty(PROPERTIES_PREFIX + "anchorPrefix");
|
||||
config.overviewDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "overviewDocument");
|
||||
config.pathsDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "pathsDocument");
|
||||
config.definitionsDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "definitionsDocument");
|
||||
config.securityDocument = safeProperties.getProperty(PROPERTIES_PREFIX + "securityDocument");
|
||||
config.separatedOperationsFolder = safeProperties.getProperty(PROPERTIES_PREFIX + "separatedOperationsFolder");
|
||||
config.separatedDefinitionsFolder = safeProperties.getProperty(PROPERTIES_PREFIX + "separatedDefinitionsFolder");
|
||||
config.tagOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "tagOrderBy"));
|
||||
config.operationOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "operationOrderBy"));
|
||||
config.definitionOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "definitionOrderBy"));
|
||||
config.parameterOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "parameterOrderBy"));
|
||||
config.propertyOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "propertyOrderBy"));
|
||||
config.responseOrderBy = OrderBy.valueOf(safeProperties.getProperty(PROPERTIES_PREFIX + "responseOrderBy"));
|
||||
String lineSeparator = safeProperties.getProperty(PROPERTIES_PREFIX + "lineSeparator");
|
||||
if(StringUtils.isNoneBlank(lineSeparator)){
|
||||
config.lineSeparator = LineSeparator.valueOf(lineSeparator);
|
||||
}
|
||||
}
|
||||
|
||||
private Properties defaultProperties() {
|
||||
Properties defaultProperties = new Properties();
|
||||
try {
|
||||
InputStream defaultPropertiesStream = Swagger2MarkupConfig.class.getResourceAsStream(PROPERTIES_DEFAULT);
|
||||
if (defaultPropertiesStream == null)
|
||||
throw new RuntimeException(String.format("Can't load default properties '%s'", PROPERTIES_DEFAULT));
|
||||
defaultProperties.load(defaultPropertiesStream);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(String.format("Can't load default properties '%s'", PROPERTIES_DEFAULT), e);
|
||||
}
|
||||
|
||||
return defaultProperties;
|
||||
}
|
||||
|
||||
public Swagger2MarkupConfig build() {
|
||||
buildNaturalOrdering();
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private void buildNaturalOrdering() {
|
||||
if (config.tagOrderBy == OrderBy.NATURAL)
|
||||
config.tagOrdering = Ordering.natural();
|
||||
if (config.operationOrderBy == OrderBy.NATURAL)
|
||||
config.operationOrdering = OPERATION_PATH_NATURAL_ORDERING.compound(OPERATION_METHOD_NATURAL_ORDERING);
|
||||
if (config.definitionOrderBy == OrderBy.NATURAL)
|
||||
config.definitionOrdering = Ordering.natural();
|
||||
if (config.parameterOrderBy == OrderBy.NATURAL)
|
||||
config.parameterOrdering = PARAMETER_IN_NATURAL_ORDERING.compound(PARAMETER_NAME_NATURAL_ORDERING);
|
||||
if (config.propertyOrderBy == OrderBy.NATURAL)
|
||||
config.propertyOrdering = Ordering.natural();
|
||||
if (config.responseOrderBy == OrderBy.NATURAL)
|
||||
config.responseOrdering = Ordering.natural();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the markup language which should be used to generate the files
|
||||
*
|
||||
* @param markupLanguage the markup language which is used to generate the files
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withMarkupLanguage(MarkupLanguage markupLanguage) {
|
||||
Validate.notNull(markupLanguage, "%s must not be null", "markupLanguage");
|
||||
config.markupLanguage = markupLanguage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include generated examples into the Paths document
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withGeneratedExamples() {
|
||||
config.generatedExamplesEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Paths document
|
||||
*
|
||||
* @param operationDescriptionsUri the URI to the folder where the description documents reside.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withOperationDescriptions(URI operationDescriptionsUri) {
|
||||
Validate.notNull(operationDescriptionsUri, "%s must not be null", "operationDescriptionsUri");
|
||||
config.operationDescriptionsEnabled = true;
|
||||
config.operationDescriptionsUri = operationDescriptionsUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Paths document
|
||||
*
|
||||
* @param operationDescriptionsPath the path to the folder where the description documents reside.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withOperationDescriptions(Path operationDescriptionsPath) {
|
||||
Validate.notNull(operationDescriptionsPath, "%s must not be null", "operationDescriptionsPath");
|
||||
return withOperationDescriptions(operationDescriptionsPath.toUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Paths document.<br/>
|
||||
* Use default URI.
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withOperationDescriptions() {
|
||||
config.operationDescriptionsEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Definitions document
|
||||
*
|
||||
* @param definitionDescriptionsUri the URI to the folder where the description documents reside.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withDefinitionDescriptions(URI definitionDescriptionsUri) {
|
||||
Validate.notNull(definitionDescriptionsUri, "%s must not be null", "definitionDescriptionsUri");
|
||||
config.definitionDescriptionsEnabled = true;
|
||||
config.definitionDescriptionsUri = definitionDescriptionsUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Definitions document
|
||||
*
|
||||
* @param definitionDescriptionsPath the path to the folder where the description documents reside.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withDefinitionDescriptions(Path definitionDescriptionsPath) {
|
||||
Validate.notNull(definitionDescriptionsPath, "%s must not be null", "definitionDescriptionsPath");
|
||||
return withDefinitionDescriptions(definitionDescriptionsPath.toUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Definitions document.<br/>
|
||||
* Use default URI.
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withDefinitionDescriptions() {
|
||||
config.definitionDescriptionsEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* In addition to the definitions file, also create separate definition files for each model definition.
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withSeparatedDefinitions() {
|
||||
config.separatedDefinitionsEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In addition to the paths file, also create separate path files for each path.
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withSeparatedOperations() {
|
||||
config.separatedOperationsEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies if the paths should be grouped by tags or stay as-is.
|
||||
*
|
||||
* @param pathsGroupedBy the GroupBy enum
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withPathsGroupedBy(GroupBy pathsGroupedBy) {
|
||||
Validate.notNull(pathsGroupedBy, "%s must not be null", "pathsGroupedBy");
|
||||
config.operationsGroupedBy = pathsGroupedBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies labels language of output files
|
||||
*
|
||||
* @param language the enum
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withOutputLanguage(Language language) {
|
||||
Validate.notNull(language, "%s must not be null", "language");
|
||||
config.outputLanguage = language;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies maximum depth level for inline object schema displaying (0 = no inline schemasEnabled)
|
||||
*
|
||||
* @param inlineSchemaDepthLevel number of recursion levels for inline schemasEnabled display
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withInlineSchemaDepthLevel(int inlineSchemaDepthLevel) {
|
||||
Validate.isTrue(inlineSchemaDepthLevel >= 0, "%s must be >= 0", "inlineSchemaDepthLevel");
|
||||
config.inlineSchemaDepthLevel = inlineSchemaDepthLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies tag ordering.<br/>
|
||||
* By default tag ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
|
||||
* Use {@link #withTagOrdering(Comparator)} to set a custom ordering.
|
||||
*
|
||||
* @param orderBy tag ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withTagOrdering(OrderBy orderBy) {
|
||||
Validate.notNull(orderBy, "%s must not be null", "orderBy");
|
||||
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
config.tagOrderBy = orderBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order tags.
|
||||
*
|
||||
* @param tagOrdering tag ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withTagOrdering(Comparator<String> tagOrdering) {
|
||||
Validate.notNull(tagOrdering, "%s must not be null", "tagOrdering");
|
||||
config.tagOrderBy = OrderBy.CUSTOM;
|
||||
config.tagOrdering = tagOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies operation ordering.<br/>
|
||||
* By default operation ordering == {@link io.github.robwin.swagger2markup.OrderBy#AS_IS}.<br/>
|
||||
* Use {@link #withOperationOrdering(Comparator)} to set a custom ordering.
|
||||
*
|
||||
* @param orderBy operation ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withOperationOrdering(OrderBy orderBy) {
|
||||
Validate.notNull(orderBy, "%s must not be null", "orderBy");
|
||||
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
config.operationOrderBy = orderBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order operations.
|
||||
*
|
||||
* @param operationOrdering operation ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withOperationOrdering(Comparator<PathOperation> operationOrdering) {
|
||||
Validate.notNull(operationOrdering, "%s must not be null", "operationOrdering");
|
||||
config.operationOrderBy = OrderBy.CUSTOM;
|
||||
config.operationOrdering = operationOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies definition ordering.<br/>
|
||||
* By default definition ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
|
||||
* Use {@link #withDefinitionOrdering(Comparator)} to set a custom ordering.
|
||||
*
|
||||
* @param orderBy definition ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withDefinitionOrdering(OrderBy orderBy) {
|
||||
Validate.notNull(orderBy, "%s must not be null", "orderBy");
|
||||
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
config.definitionOrderBy = orderBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order definitions.
|
||||
*
|
||||
* @param definitionOrdering definition ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withDefinitionOrdering(Comparator<String> definitionOrdering) {
|
||||
Validate.notNull(definitionOrdering, "%s must not be null", "definitionOrdering");
|
||||
config.definitionOrderBy = OrderBy.CUSTOM;
|
||||
config.definitionOrdering = definitionOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies parameter ordering.<br/>
|
||||
* By default parameter ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
|
||||
* Use {@link #withParameterOrdering(Comparator)} to set a custom ordering.
|
||||
*
|
||||
* @param orderBy parameter ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withParameterOrdering(OrderBy orderBy) {
|
||||
Validate.notNull(orderBy, "%s must not be null", "orderBy");
|
||||
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
config.parameterOrderBy = orderBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order parameters.
|
||||
*
|
||||
* @param parameterOrdering parameter ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withParameterOrdering(Comparator<Parameter> parameterOrdering) {
|
||||
Validate.notNull(parameterOrdering, "%s must not be null", "parameterOrdering");
|
||||
|
||||
config.parameterOrderBy = OrderBy.CUSTOM;
|
||||
config.parameterOrdering = parameterOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies property ordering.<br/>
|
||||
* By default property ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
|
||||
* Use {@link #withPropertyOrdering(Comparator)} to set a custom ordering.
|
||||
*
|
||||
* @param orderBy property ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withPropertyOrdering(OrderBy orderBy) {
|
||||
Validate.notNull(orderBy, "%s must not be null", "orderBy");
|
||||
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
config.propertyOrderBy = orderBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order propertys.
|
||||
*
|
||||
* @param propertyOrdering property ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withPropertyOrdering(Comparator<String> propertyOrdering) {
|
||||
Validate.notNull(propertyOrdering, "%s must not be null", "propertyOrdering");
|
||||
|
||||
config.propertyOrderBy = OrderBy.CUSTOM;
|
||||
config.propertyOrdering = propertyOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies response ordering.<br/>
|
||||
* By default response ordering == {@link io.github.robwin.swagger2markup.OrderBy#NATURAL}.<br/>
|
||||
* Use {@link #withResponseOrdering(Comparator)} to set a custom ordering.
|
||||
*
|
||||
* @param orderBy response ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withResponseOrdering(OrderBy orderBy) {
|
||||
Validate.notNull(orderBy, "%s must not be null", "orderBy");
|
||||
Validate.isTrue(orderBy != OrderBy.CUSTOM, "You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
config.responseOrderBy = orderBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom comparator function to order responses.
|
||||
*
|
||||
* @param responseOrdering response ordering
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withResponseOrdering(Comparator<String> responseOrdering) {
|
||||
Validate.notNull(responseOrdering, "%s must not be null", "responseOrdering");
|
||||
|
||||
config.responseOrderBy = OrderBy.CUSTOM;
|
||||
config.responseOrdering = responseOrdering;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable use of inter-document cross-references when needed
|
||||
*
|
||||
* @param prefix Prefix to document in all inter-document cross-references.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withInterDocumentCrossReferences(String prefix) {
|
||||
Validate.notNull(prefix, "%s must not be null", "prefix");
|
||||
config.interDocumentCrossReferencesEnabled = true;
|
||||
config.interDocumentCrossReferencesPrefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable use of inter-document cross-references when needed.
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withInterDocumentCrossReferences() {
|
||||
config.interDocumentCrossReferencesEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally isolate the body parameter, if any, from other parameters
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withFlatBody() {
|
||||
config.flatBodyEnabled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally prefix all anchors for unicity
|
||||
*.
|
||||
* @param anchorPrefix anchor prefix.
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withAnchorPrefix(String anchorPrefix) {
|
||||
Validate.notNull(anchorPrefix, "%s must no be null", "anchorPrefix");
|
||||
config.anchorPrefix = anchorPrefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the line separator which should be used .
|
||||
*
|
||||
* @param lineSeparator the lineSeparator
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder withLineSeparator(LineSeparator lineSeparator) {
|
||||
Validate.notNull(lineSeparator, "%s must no be null", "lineSeparator");
|
||||
config.lineSeparator = lineSeparator;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.github.robwin.swagger2markup.internal.document.builder.DefinitionsDocumentBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.document.builder.OverviewDocumentBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.document.builder.PathsDocumentBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.document.builder.SecurityDocumentBuilder;
|
||||
import io.github.robwin.swagger2markup.spi.Extension;
|
||||
import io.github.robwin.swagger2markup.spi.SwaggerModelExtension;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class Swagger2MarkupConverter {
|
||||
|
||||
private Context context;
|
||||
|
||||
public Swagger2MarkupConverter(Context globalContext) {
|
||||
this.context = globalContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global Context
|
||||
*
|
||||
* @return the global Context
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Context getContext(){
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Swagger2MarkupConverter.Builder using a remote URL.
|
||||
*
|
||||
* @param swaggerURL the remote URL
|
||||
* @return a Swagger2MarkupConverter
|
||||
*/
|
||||
public static Builder from(URL swaggerURL){
|
||||
Validate.notNull(swaggerURL, "swaggerURL must not be null");
|
||||
return new Builder(swaggerURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Swagger2MarkupConverter.Builder using a local Path.
|
||||
*
|
||||
* @param swaggerPath the local Path
|
||||
* @return a Swagger2MarkupConverter
|
||||
*/
|
||||
public static Builder from(Path swaggerPath) {
|
||||
Validate.notNull(swaggerPath, "swaggerPath must not be null");
|
||||
return new Builder(swaggerPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Swagger2MarkupConverter.Builder from a given Swagger model.
|
||||
*
|
||||
* @param swagger the Swagger source.
|
||||
* @return a Swagger2MarkupConverter
|
||||
*/
|
||||
public static Builder from(Swagger swagger) {
|
||||
Validate.notNull(swagger, "swagger must not be null");
|
||||
return new Builder(swagger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Swagger2MarkupConverter.Builder from a given Swagger YAML or JSON String.
|
||||
*
|
||||
* @param swaggerString the Swagger YAML or JSON String.
|
||||
* @return a Swagger2MarkupConverter
|
||||
* @throws java.io.IOException if String can not be parsed
|
||||
*/
|
||||
public static Builder from(String swaggerString) throws IOException {
|
||||
Validate.notEmpty(swaggerString, "swaggerString must not be null");
|
||||
return from(new StringReader(swaggerString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Swagger2MarkupConverter.Builder from a given Swagger YAML or JSON reader.
|
||||
*
|
||||
* @param swaggerReader the Swagger YAML or JSON reader.
|
||||
* @return a Swagger2MarkupConverter
|
||||
* @throws java.io.IOException if source can not be parsed
|
||||
*/
|
||||
public static Builder from(Reader swaggerReader) throws IOException {
|
||||
Validate.notNull(swaggerReader, "swaggerReader must not be null");
|
||||
Swagger swagger = new SwaggerParser().parse(IOUtils.toString(swaggerReader));
|
||||
if (swagger == null)
|
||||
throw new IllegalArgumentException("Swagger source is in a wrong format");
|
||||
|
||||
return new Builder(swagger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the document with the given markup language and stores
|
||||
* the files in the given folder.
|
||||
*
|
||||
* @param outputPath the output directory path
|
||||
* @throws IOException if the files cannot be written
|
||||
*/
|
||||
public void intoFolder(Path outputPath) throws IOException {
|
||||
Validate.notNull(outputPath, "outputPath must not be null");
|
||||
|
||||
applySwaggerExtensions();
|
||||
buildDocuments(outputPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the document with the given markup language and returns it as a String
|
||||
*
|
||||
* @return a the document as a String
|
||||
* @throws java.io.IOException if files can not be read
|
||||
*/
|
||||
public String asString() throws IOException {
|
||||
applySwaggerExtensions();
|
||||
return buildDocuments();
|
||||
}
|
||||
|
||||
private void applySwaggerExtensions() {
|
||||
for (SwaggerModelExtension swaggerModelExtension : context.extensionRegistry.getExtensions(SwaggerModelExtension.class)) {
|
||||
swaggerModelExtension.apply(context.getSwagger());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds all documents and writes them to a directory
|
||||
*
|
||||
* @param outputPath the directory path where the generated file should be stored
|
||||
* @throws IOException if a file cannot be written
|
||||
*/
|
||||
private void buildDocuments(Path outputPath) throws IOException {
|
||||
new OverviewDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getOverviewDocument()), StandardCharsets.UTF_8);
|
||||
new PathsDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getPathsDocument()), StandardCharsets.UTF_8);
|
||||
new DefinitionsDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getDefinitionsDocument()), StandardCharsets.UTF_8);
|
||||
new SecurityDocumentBuilder(context, outputPath).build().writeToFile(outputPath.resolve(context.config.getSecurityDocument()), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all documents as a String
|
||||
*
|
||||
* @return a the document as a String
|
||||
*/
|
||||
private String buildDocuments() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(new OverviewDocumentBuilder(context, null).build().toString());
|
||||
sb.append(new PathsDocumentBuilder(context, null).build().toString());
|
||||
sb.append(new DefinitionsDocumentBuilder(context, null).build().toString());
|
||||
sb.append(new SecurityDocumentBuilder(context, null).build().toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Swagger swagger;
|
||||
private final URI swaggerLocation;
|
||||
private Swagger2MarkupConfig config;
|
||||
private Swagger2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
/**
|
||||
* Creates a Builder from a remote URL.
|
||||
*
|
||||
* @param swaggerUrl the remote URL
|
||||
*/
|
||||
Builder(URL swaggerUrl) {
|
||||
try {
|
||||
this.swaggerLocation = swaggerUrl.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException("swaggerURL is in a wrong format", e);
|
||||
}
|
||||
this.swagger = readSwagger(swaggerUrl.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder from a local Path.
|
||||
*
|
||||
* @param swaggerPath the local Path
|
||||
*/
|
||||
Builder(Path swaggerPath) {
|
||||
this.swaggerLocation = swaggerPath.toAbsolutePath().toUri();
|
||||
this.swagger = readSwagger(swaggerPath.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder using a given Swagger model.
|
||||
*
|
||||
* @param swagger the Swagger source.
|
||||
*/
|
||||
Builder(Swagger swagger) {
|
||||
this.swagger = swagger;
|
||||
this.swaggerLocation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the SwaggerParser to read the Swagger source.
|
||||
*
|
||||
* @param swaggerLocation the location of the Swagger source
|
||||
* @return the Swagger model
|
||||
*/
|
||||
private Swagger readSwagger(String swaggerLocation){
|
||||
Swagger swagger = new SwaggerParser().read(swaggerLocation);
|
||||
if (swagger == null) {
|
||||
throw new IllegalArgumentException("Failed to read the Swagger source");
|
||||
}
|
||||
return swagger;
|
||||
}
|
||||
|
||||
public Builder withConfig(Swagger2MarkupConfig config) {
|
||||
Validate.notNull(config, "config must not be null");
|
||||
this.config = config;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withExtensionRegistry(Swagger2MarkupExtensionRegistry registry) {
|
||||
Validate.notNull(config, "registry must not be null");
|
||||
this.extensionRegistry = registry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Swagger2MarkupConverter build() {
|
||||
if (config == null)
|
||||
config = Swagger2MarkupConfig.ofDefaults().build();
|
||||
|
||||
if (extensionRegistry == null)
|
||||
extensionRegistry = Swagger2MarkupExtensionRegistry.ofDefaults().build();
|
||||
|
||||
Context context = new Context(config, extensionRegistry, swagger, swaggerLocation);
|
||||
config.setGlobalContext(context);
|
||||
|
||||
for (Extension extension : extensionRegistry.getExtensions())
|
||||
extension.setGlobalContext(context);
|
||||
return new Swagger2MarkupConverter(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Context {
|
||||
private Swagger2MarkupConfig config;
|
||||
private Swagger2MarkupExtensionRegistry extensionRegistry;
|
||||
private Swagger swagger;
|
||||
private URI swaggerLocation;
|
||||
|
||||
Context(Swagger2MarkupConfig config, Swagger2MarkupExtensionRegistry extensionRegistry, Swagger swagger, URI swaggerLocation) {
|
||||
this.config = config;
|
||||
this.extensionRegistry = extensionRegistry;
|
||||
this.swagger = swagger;
|
||||
this.swaggerLocation = swaggerLocation;
|
||||
}
|
||||
|
||||
public Swagger2MarkupConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public Swagger2MarkupExtensionRegistry getExtensionRegistry() {
|
||||
return extensionRegistry;
|
||||
}
|
||||
|
||||
public Swagger getSwagger() {
|
||||
return swagger;
|
||||
}
|
||||
|
||||
public URI getSwaggerLocation() {
|
||||
return swaggerLocation;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicOverviewDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicSecurityDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.spi.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Swagger2MarkupExtensionRegistry {
|
||||
|
||||
protected static final List<Class<? extends Extension>> EXTENSION_POINTS = Arrays.<Class<? extends Extension>>asList(
|
||||
SwaggerModelExtension.class,
|
||||
OverviewDocumentExtension.class,
|
||||
SecurityDocumentExtension.class,
|
||||
DefinitionsDocumentExtension.class,
|
||||
PathsDocumentExtension.class
|
||||
);
|
||||
|
||||
protected final Multimap<Class<? extends Extension>, Extension> extensions;
|
||||
|
||||
public Swagger2MarkupExtensionRegistry(Multimap<Class<? extends Extension>, Extension> extensions) {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
public static Builder ofEmpty() {
|
||||
return new Builder(false);
|
||||
}
|
||||
|
||||
public static Builder ofDefaults() {
|
||||
return new Builder(true);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final Multimap<Class<? extends Extension>, Extension> extensions;
|
||||
|
||||
Builder(boolean useDefaults) {
|
||||
extensions = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
if (useDefaults) {
|
||||
withExtension(new DynamicOverviewDocumentExtension());
|
||||
withExtension(new DynamicSecurityDocumentExtension());
|
||||
withExtension(new DynamicPathsDocumentExtension());
|
||||
withExtension(new DynamicDefinitionsDocumentExtension());
|
||||
}
|
||||
}
|
||||
|
||||
public Swagger2MarkupExtensionRegistry build() {
|
||||
return new Swagger2MarkupExtensionRegistry(extensions);
|
||||
}
|
||||
|
||||
public Builder withExtension(Extension extension) {
|
||||
registerExtension(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void registerExtension(Extension extension) {
|
||||
for (Class<? extends Extension> extensionPoint : EXTENSION_POINTS) {
|
||||
if (extensionPoint.isInstance(extension)) {
|
||||
extensions.put(extensionPoint, extension);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Provided extension class does not extend any of the supported extension points");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings(value = "unchecked")
|
||||
public <T extends Extension> List<T> getExtensions(Class<T> extensionClass) {
|
||||
List<T> ret = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<Class<? extends Extension>, Extension> entry : extensions.entries()) {
|
||||
if (extensionClass.isAssignableFrom(entry.getKey())) {
|
||||
if (extensionClass.isInstance(entry.getValue()))
|
||||
ret.add((T) entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all extensions
|
||||
* @return all extensions
|
||||
*/
|
||||
public List<Extension> getExtensions() {
|
||||
return getExtensions(Extension.class);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.document;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class MarkupDocument {
|
||||
|
||||
private MarkupDocBuilder markupDocBuilder;
|
||||
|
||||
public MarkupDocument(MarkupDocBuilder markupDocBuilder) {
|
||||
this.markupDocBuilder = markupDocBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the document.
|
||||
*/
|
||||
public String toString() {
|
||||
return markupDocBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the content of the builder to a file.
|
||||
*
|
||||
* @param file the generated file
|
||||
* @param charset the the charset to use for encoding
|
||||
* @throws IOException if the file cannot be written
|
||||
*/
|
||||
public void writeToFile(Path file, Charset charset) throws IOException {
|
||||
markupDocBuilder.writeToFile(file, charset);
|
||||
}
|
||||
}
|
||||
@@ -1,398 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.document.builder;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
|
||||
import io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.internal.type.Type;
|
||||
import io.swagger.models.ComposedModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.RefModel;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.refs.RefFormat;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static io.github.robwin.swagger2markup.internal.utils.IOUtils.normalizeName;
|
||||
import static io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension.*;
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static io.github.robwin.swagger2markup.internal.utils.MapUtils.toKeySet;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class DefinitionsDocumentBuilder extends MarkupDocumentBuilder {
|
||||
|
||||
private static final String DEFINITIONS_ANCHOR = "definitions";
|
||||
private final String DEFINITIONS;
|
||||
private static final List<String> IGNORED_DEFINITIONS = Collections.singletonList("Void");
|
||||
private static final String DESCRIPTION_FILE_NAME = "description";
|
||||
|
||||
public DefinitionsDocumentBuilder(Swagger2MarkupConverter.Context context, Path outputPath) {
|
||||
super(context, outputPath);
|
||||
|
||||
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
|
||||
DEFINITIONS = labels.getString("definitions");
|
||||
|
||||
if (config.isDefinitionDescriptionsEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written definition descriptions is enabled.");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written definition descriptions is disabled.");
|
||||
}
|
||||
}
|
||||
if (config.isSeparatedDefinitionsEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create separated definition files is enabled.");
|
||||
}
|
||||
Validate.notNull(outputPath, "Output directory is required for separated definition files!");
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create separated definition files is disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the definitions MarkupDocument.
|
||||
*
|
||||
* @return the definitions MarkupDocument
|
||||
*/
|
||||
@Override
|
||||
public MarkupDocument build() {
|
||||
Map<String, Model> definitions = globalContext.getSwagger().getDefinitions();
|
||||
if (MapUtils.isNotEmpty(definitions)) {
|
||||
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
|
||||
buildDefinitionsTitle(DEFINITIONS);
|
||||
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
|
||||
buildDefinitionsSection(definitions);
|
||||
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
|
||||
}
|
||||
return new MarkupDocument(markupDocBuilder);
|
||||
}
|
||||
|
||||
private void buildDefinitionsSection(Map<String, Model> definitions) {
|
||||
Set<String> definitionNames = toKeySet(definitions, config.getDefinitionOrdering());
|
||||
for (String definitionName : definitionNames) {
|
||||
Model model = definitions.get(definitionName);
|
||||
if (isNotBlank(definitionName)) {
|
||||
if (checkThatDefinitionIsNotInIgnoreList(definitionName)) {
|
||||
buildDefinition(definitions, definitionName, model);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Definition processed: {}", definitionName);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Definition was ignored: {}", definitionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildDefinitionsTitle(String title) {
|
||||
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, DEFINITIONS_ANCHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply extension context to all DefinitionsContentExtension
|
||||
*
|
||||
* @param context context
|
||||
*/
|
||||
private void applyDefinitionsDocumentExtension(Context context) {
|
||||
for (DefinitionsDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(DefinitionsDocumentExtension.class)) {
|
||||
extension.apply(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the definition filename depending on the generation mode
|
||||
*
|
||||
* @param definitionName definition name
|
||||
* @return definition filename
|
||||
*/
|
||||
private String resolveDefinitionDocument(String definitionName) {
|
||||
if (config.isSeparatedDefinitionsEnabled())
|
||||
return new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(normalizeName(definitionName))).getPath();
|
||||
else
|
||||
return markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate definition files depending on the generation mode
|
||||
*
|
||||
* @param definitions all available definitions to be able to verify references
|
||||
* @param definitionName definition name to process
|
||||
* @param model definition model to process
|
||||
*/
|
||||
private void buildDefinition(Map<String, Model> definitions, String definitionName, Model model) {
|
||||
|
||||
if (config.isSeparatedDefinitionsEnabled()) {
|
||||
MarkupDocBuilder defDocBuilder = this.markupDocBuilder.copy();
|
||||
buildDefinition(definitions, definitionName, model, defDocBuilder);
|
||||
Path definitionFile = outputPath.resolve(resolveDefinitionDocument(definitionName));
|
||||
try {
|
||||
defDocBuilder.writeToFileWithoutExtension(definitionFile, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(String.format("Failed to write definition file: %s", definitionFile), e);
|
||||
}
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Separate definition file produced: {}", definitionFile);
|
||||
}
|
||||
|
||||
definitionRef(definitionName, this.markupDocBuilder);
|
||||
|
||||
} else {
|
||||
buildDefinition(definitions, definitionName, model, this.markupDocBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the definition is not in the list of ignored definitions.
|
||||
*
|
||||
* @param definitionName the name of the definition
|
||||
* @return true if the definition can be processed
|
||||
*/
|
||||
private boolean checkThatDefinitionIsNotInIgnoreList(String definitionName) {
|
||||
return !IGNORED_DEFINITIONS.contains(definitionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a concrete definition
|
||||
*
|
||||
* @param definitionName the name of the definition
|
||||
* @param model the Swagger Model of the definition
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildDefinition(Map<String, Model> definitions, String definitionName, Model model, MarkupDocBuilder docBuilder) {
|
||||
buildDefinitionTitle(definitionName, null, docBuilder);
|
||||
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_BEGIN, docBuilder, definitionName, model));
|
||||
buildDescriptionParagraph(definitionName, model, docBuilder);
|
||||
inlineDefinitions(propertiesSection(definitions, definitionName, model, docBuilder), definitionName, config.getInlineSchemaDepthLevel(), docBuilder);
|
||||
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_END, docBuilder, definitionName, model));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a cross-reference to a separated definition file.
|
||||
*
|
||||
* @param definitionName definition name to target
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void definitionRef(String definitionName, MarkupDocBuilder docBuilder) {
|
||||
buildDefinitionTitle(docBuilder.copy().crossReference(new DefinitionDocumentResolverDefault().apply(definitionName), definitionName, definitionName).toString(), "ref-" + definitionName, docBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds definition title
|
||||
*
|
||||
* @param title definition title
|
||||
* @param anchor optional anchor (null => auto-generate from title)
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
docBuilder.sectionTitleWithAnchorLevel2(title, anchor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override Property description functor for definitions.
|
||||
* This implementation handles optional handwritten descriptions.
|
||||
*/
|
||||
private class DefinitionPropertyDescriptor extends PropertyDescriptor {
|
||||
|
||||
public DefinitionPropertyDescriptor(Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(Property property, String propertyName) {
|
||||
if (config.isDefinitionDescriptionsEnabled()) {
|
||||
Optional<String> description = handWrittenDefinitionDescription(new File(normalizeName(type.getName()), normalizeName(propertyName)).toString(), DESCRIPTION_FILE_NAME);
|
||||
if (description.isPresent()) {
|
||||
return description.get();
|
||||
} else {
|
||||
return defaultString(property.getDescription());
|
||||
}
|
||||
} else {
|
||||
return defaultString(property.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the properties of a definition and inline schemas.
|
||||
*
|
||||
* @param definitions all available definitions
|
||||
* @param definitionName name of the definition to display
|
||||
* @param model model of the definition to display
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
* @return a list of inlined types.
|
||||
*/
|
||||
private List<ObjectType> propertiesSection(Map<String, Model> definitions, String definitionName, Model model, MarkupDocBuilder docBuilder) {
|
||||
Map<String, Property> properties = getAllProperties(definitions, model);
|
||||
ObjectType type = new ObjectType(definitionName, properties);
|
||||
|
||||
return buildPropertiesTable(type, definitionName, 1, new PropertyDescriptor(type), new DefinitionDocumentResolverFromDefinition(), docBuilder);
|
||||
}
|
||||
|
||||
private Map<String, Property> getAllProperties(Map<String, Model> definitions, Model model) {
|
||||
if (model instanceof RefModel) {
|
||||
RefModel refModel = (RefModel) model;
|
||||
String ref;
|
||||
if (refModel.getRefFormat().equals(RefFormat.INTERNAL)) {
|
||||
ref = refModel.getSimpleRef();
|
||||
} else {
|
||||
ref = model.getReference();
|
||||
}
|
||||
return definitions.containsKey(ref)
|
||||
? getAllProperties(definitions, definitions.get(ref))
|
||||
: null;
|
||||
} else if (model instanceof ComposedModel) {
|
||||
ComposedModel composedModel = (ComposedModel) model;
|
||||
Map<String, Property> allProperties = new HashMap<>();
|
||||
if (composedModel.getAllOf() != null) {
|
||||
for (Model innerModel : composedModel.getAllOf()) {
|
||||
Map<String, Property> innerProperties = getAllProperties(definitions, innerModel);
|
||||
if (innerProperties != null) {
|
||||
allProperties.putAll(innerProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ImmutableMap.copyOf(allProperties);
|
||||
} else {
|
||||
return model.getProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildDescriptionParagraph(String definitionName, Model model, MarkupDocBuilder docBuilder) {
|
||||
if (config.isDefinitionDescriptionsEnabled()) {
|
||||
Optional<String> description = handWrittenDefinitionDescription(normalizeName(definitionName), DESCRIPTION_FILE_NAME);
|
||||
if (description.isPresent()) {
|
||||
docBuilder.paragraph(description.get());
|
||||
} else {
|
||||
modelDescription(model, docBuilder);
|
||||
}
|
||||
} else {
|
||||
modelDescription(model, docBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private void modelDescription(Model model, MarkupDocBuilder docBuilder) {
|
||||
String description = model.getDescription();
|
||||
if (isNotBlank(description)) {
|
||||
docBuilder.paragraph(description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a hand-written description
|
||||
*
|
||||
* @param descriptionFolder the name of the folder where the description file resides
|
||||
* @param descriptionFileName the name of the description file
|
||||
* @return the content of the file
|
||||
*/
|
||||
private Optional<String> handWrittenDefinitionDescription(String descriptionFolder, String descriptionFileName) {
|
||||
for (String fileNameExtension : config.getMarkupLanguage().getFileNameExtensions()) {
|
||||
URI contentUri = config.getDefinitionDescriptionsUri().resolve(descriptionFolder).resolve(descriptionFileName + fileNameExtension);
|
||||
|
||||
try (Reader reader = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriReader(contentUri)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Definition description content processed {}", contentUri);
|
||||
}
|
||||
|
||||
return Optional.of(IOUtils.toString(reader).trim());
|
||||
} catch (IOException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to read Operation description content {} > {}", contentUri, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the title of an inline schema.
|
||||
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
|
||||
*
|
||||
* @param title inline schema title
|
||||
* @param anchor inline schema anchor
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
docBuilder.anchor(anchor, null);
|
||||
docBuilder.newLine();
|
||||
docBuilder.boldTextLine(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds inline schema definitions
|
||||
*
|
||||
* @param definitions all inline definitions to display
|
||||
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
|
||||
* @param depth current inline schema depth
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void inlineDefinitions(List<ObjectType> definitions, String uniquePrefix, int depth, MarkupDocBuilder docBuilder) {
|
||||
if (CollectionUtils.isNotEmpty(definitions)) {
|
||||
for (ObjectType definition : definitions) {
|
||||
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
List<ObjectType> localDefinitions = buildPropertiesTable(definition, uniquePrefix, depth, new DefinitionPropertyDescriptor(definition), new DefinitionDocumentResolverFromDefinition(), docBuilder);
|
||||
for (ObjectType localDefinition : localDefinitions)
|
||||
inlineDefinitions(Collections.singletonList(localDefinition), uniquePrefix, depth - 1, docBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides definition document resolver functor for inter-document cross-references from definitions files.
|
||||
* This implementation simplify the path between two definitions because all definitions are in the same path.
|
||||
*/
|
||||
class DefinitionDocumentResolverFromDefinition extends DefinitionDocumentResolverDefault {
|
||||
|
||||
public DefinitionDocumentResolverFromDefinition() {
|
||||
}
|
||||
|
||||
public String apply(String definitionName) {
|
||||
String defaultResolver = super.apply(definitionName);
|
||||
|
||||
if (defaultResolver != null && config.isSeparatedDefinitionsEnabled())
|
||||
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(normalizeName(definitionName));
|
||||
else
|
||||
return defaultResolver;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.document.builder;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilders;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.markup.builder.MarkupTableColumn;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConfig;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
|
||||
import io.github.robwin.swagger2markup.internal.type.DefinitionDocumentResolver;
|
||||
import io.github.robwin.swagger2markup.internal.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.internal.type.RefType;
|
||||
import io.github.robwin.swagger2markup.internal.type.Type;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import io.github.robwin.swagger2markup.internal.utils.PropertyUtils;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.util.Json;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static io.github.robwin.swagger2markup.internal.utils.MapUtils.toKeySet;
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public abstract class MarkupDocumentBuilder {
|
||||
|
||||
protected final String DEFAULT_COLUMN;
|
||||
protected final String EXAMPLE_COLUMN;
|
||||
protected final String REQUIRED_COLUMN;
|
||||
protected final String SCHEMA_COLUMN;
|
||||
protected final String NAME_COLUMN;
|
||||
protected final String DESCRIPTION_COLUMN;
|
||||
protected final String SCOPES_COLUMN;
|
||||
protected final String DESCRIPTION;
|
||||
protected final String PRODUCES;
|
||||
protected final String CONSUMES;
|
||||
protected final String TAGS;
|
||||
protected final String NO_CONTENT;
|
||||
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected Swagger2MarkupConverter.Context globalContext;
|
||||
protected Swagger2MarkupConfig config;
|
||||
protected MarkupDocBuilder markupDocBuilder;
|
||||
protected Path outputPath;
|
||||
|
||||
MarkupDocumentBuilder(Swagger2MarkupConverter.Context globalContext, Path outputPath) {
|
||||
this.globalContext = globalContext;
|
||||
this.config = globalContext.getConfig();
|
||||
this.outputPath = outputPath;
|
||||
|
||||
this.markupDocBuilder = MarkupDocBuilders.documentBuilder(config.getMarkupLanguage(), config.getLineSeparator()).withAnchorPrefix(config.getAnchorPrefix());
|
||||
|
||||
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
|
||||
DEFAULT_COLUMN = labels.getString("default_column");
|
||||
EXAMPLE_COLUMN = labels.getString("example_column");
|
||||
REQUIRED_COLUMN = labels.getString("required_column");
|
||||
SCHEMA_COLUMN = labels.getString("schema_column");
|
||||
NAME_COLUMN = labels.getString("name_column");
|
||||
DESCRIPTION_COLUMN = labels.getString("description_column");
|
||||
SCOPES_COLUMN = labels.getString("scopes_column");
|
||||
DESCRIPTION = DESCRIPTION_COLUMN;
|
||||
PRODUCES = labels.getString("produces");
|
||||
CONSUMES = labels.getString("consumes");
|
||||
TAGS = labels.getString("tags");
|
||||
NO_CONTENT = labels.getString("no_content");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the MarkupDocument.
|
||||
*
|
||||
* @return the built MarkupDocument
|
||||
* @throws IOException if the files to include are not readable
|
||||
*/
|
||||
public abstract MarkupDocument build() throws IOException;
|
||||
|
||||
/**
|
||||
* Build a generic property table for any ObjectType
|
||||
*
|
||||
* @param type to display
|
||||
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
|
||||
* @param depth current inline schema object depth
|
||||
* @param propertyDescriptor property descriptor to apply to properties
|
||||
* @param definitionDocumentResolver definition document resolver to apply to property type cross-reference
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
* @return a list of inline schemas referenced by some properties, for later display
|
||||
*/
|
||||
protected List<ObjectType> buildPropertiesTable(ObjectType type, String uniquePrefix, int depth, PropertyDescriptor propertyDescriptor, DefinitionDocumentResolver definitionDocumentResolver, MarkupDocBuilder docBuilder) {
|
||||
List<ObjectType> localDefinitions = new ArrayList<>();
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
List<MarkupTableColumn> cols = Arrays.asList(
|
||||
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 6).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^6"),
|
||||
new MarkupTableColumn(REQUIRED_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(DEFAULT_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(EXAMPLE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
|
||||
if (MapUtils.isNotEmpty(type.getProperties())) {
|
||||
Set<String> propertyNames = toKeySet(type.getProperties(), config.getPropertyOrdering());
|
||||
for (String propertyName : propertyNames) {
|
||||
Property property = type.getProperties().get(propertyName);
|
||||
Type propertyType = PropertyUtils.getType(property, definitionDocumentResolver);
|
||||
if (depth > 0 && propertyType instanceof ObjectType) {
|
||||
if (MapUtils.isNotEmpty(((ObjectType) propertyType).getProperties())) {
|
||||
propertyType.setName(propertyName);
|
||||
propertyType.setUniqueName(uniquePrefix + " " + propertyName);
|
||||
localDefinitions.add((ObjectType) propertyType);
|
||||
|
||||
propertyType = new RefType(propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
Object example = PropertyUtils.getExample(config.isGeneratedExamplesEnabled(), property, markupDocBuilder);
|
||||
|
||||
List<String> content = Arrays.asList(
|
||||
propertyName,
|
||||
propertyDescriptor.getDescription(property, propertyName),
|
||||
Boolean.toString(property.getRequired()),
|
||||
propertyType.displaySchema(docBuilder),
|
||||
PropertyUtils.getDefaultValue(property),
|
||||
example != null ? Json.pretty(example) : ""
|
||||
);
|
||||
cells.add(content);
|
||||
}
|
||||
docBuilder.tableWithColumnSpecs(cols, cells);
|
||||
} else {
|
||||
docBuilder.textLine(NO_CONTENT);
|
||||
}
|
||||
|
||||
return localDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* A functor to return descriptions for a given property
|
||||
*/
|
||||
class PropertyDescriptor {
|
||||
protected Type type;
|
||||
|
||||
public PropertyDescriptor(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDescription(Property property, String propertyName) {
|
||||
return defaultString(property.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default {@code DefinitionDocumentResolver} functor
|
||||
*/
|
||||
class DefinitionDocumentResolverDefault implements DefinitionDocumentResolver {
|
||||
|
||||
public DefinitionDocumentResolverDefault() {
|
||||
}
|
||||
|
||||
public String apply(String definitionName) {
|
||||
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
|
||||
return null;
|
||||
else if (config.isSeparatedDefinitionsEnabled())
|
||||
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(IOUtils.normalizeName(definitionName))).getPath();
|
||||
else
|
||||
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.document.builder;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
|
||||
import io.github.robwin.swagger2markup.spi.OverviewDocumentExtension;
|
||||
import io.swagger.models.*;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static io.github.robwin.swagger2markup.spi.OverviewDocumentExtension.*;
|
||||
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
public class OverviewDocumentBuilder extends MarkupDocumentBuilder {
|
||||
|
||||
private static final String OVERVIEW_ANCHOR = "overview";
|
||||
private final String OVERVIEW;
|
||||
private final String CURRENT_VERSION;
|
||||
private final String VERSION;
|
||||
private final String CONTACT_INFORMATION;
|
||||
private final String CONTACT_NAME;
|
||||
private final String CONTACT_EMAIL;
|
||||
private final String LICENSE_INFORMATION;
|
||||
private final String LICENSE;
|
||||
private final String LICENSE_URL;
|
||||
private final String TERMS_OF_SERVICE;
|
||||
private final String URI_SCHEME;
|
||||
private final String HOST;
|
||||
private final String BASE_PATH;
|
||||
private final String SCHEMES;
|
||||
|
||||
public OverviewDocumentBuilder(Swagger2MarkupConverter.Context context, Path outputPath){
|
||||
super(context, outputPath);
|
||||
|
||||
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
|
||||
OVERVIEW = labels.getString("overview");
|
||||
CURRENT_VERSION = labels.getString("current_version");
|
||||
VERSION = labels.getString("version");
|
||||
CONTACT_INFORMATION = labels.getString("contact_information");
|
||||
CONTACT_NAME = labels.getString("contact_name");
|
||||
CONTACT_EMAIL = labels.getString("contact_email");
|
||||
LICENSE_INFORMATION = labels.getString("license_information");
|
||||
LICENSE = labels.getString("license");
|
||||
LICENSE_URL = labels.getString("license_url");
|
||||
TERMS_OF_SERVICE = labels.getString("terms_of_service");
|
||||
URI_SCHEME = labels.getString("uri_scheme");
|
||||
HOST = labels.getString("host");
|
||||
BASE_PATH = labels.getString("base_path");
|
||||
SCHEMES = labels.getString("schemes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the overview MarkupDocument.
|
||||
*
|
||||
* @return the overview MarkupDocument
|
||||
*/
|
||||
@Override
|
||||
public MarkupDocument build(){
|
||||
Swagger swagger = globalContext.getSwagger();
|
||||
Info info = swagger.getInfo();
|
||||
buildDocumentTitle(info.getTitle());
|
||||
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
|
||||
buildOverviewTitle(OVERVIEW);
|
||||
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
|
||||
buildDescription(info.getDescription());
|
||||
buildVersionInfoSection(info.getVersion());
|
||||
buildContactInfoSection(info.getContact());
|
||||
buildLicenseInfoSection(info.getLicense(), info.getTermsOfService());
|
||||
buildUriSchemeSection(swagger);
|
||||
buildTagsSection(swagger.getTags());
|
||||
buildConsumesSection(swagger.getConsumes());
|
||||
buildProducesSection(swagger.getProduces());
|
||||
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
|
||||
return new MarkupDocument(markupDocBuilder);
|
||||
}
|
||||
|
||||
private void buildDocumentTitle(String title) {
|
||||
this.markupDocBuilder.documentTitle(title);
|
||||
}
|
||||
|
||||
private void buildOverviewTitle(String title) {
|
||||
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, OVERVIEW_ANCHOR);
|
||||
}
|
||||
|
||||
private void buildVersionInfoSection(String version) {
|
||||
if(isNotBlank(version)){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CURRENT_VERSION);
|
||||
this.markupDocBuilder.textLine(VERSION + " : " + version);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildDescription(String description) {
|
||||
if(isNotBlank(description)){
|
||||
this.markupDocBuilder.textLine(description);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildContactInfoSection(Contact contact) {
|
||||
if(contact != null){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CONTACT_INFORMATION);
|
||||
if(isNotBlank(contact.getName())){
|
||||
this.markupDocBuilder.textLine(CONTACT_NAME + " : " + contact.getName());
|
||||
}
|
||||
if(isNotBlank(contact.getEmail())){
|
||||
this.markupDocBuilder.textLine(CONTACT_EMAIL + " : " + contact.getEmail());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildLicenseInfoSection(License license, String termOfService) {
|
||||
if(license != null && (isNotBlank(license.getName()) || isNotBlank(license.getUrl()))) {
|
||||
this.markupDocBuilder.sectionTitleLevel2(LICENSE_INFORMATION);
|
||||
if (isNotBlank(license.getName())) {
|
||||
this.markupDocBuilder.textLine(LICENSE + " : " + license.getName());
|
||||
}
|
||||
if (isNotBlank(license.getUrl())) {
|
||||
this.markupDocBuilder.textLine(LICENSE_URL + " : " + license.getUrl());
|
||||
}
|
||||
}
|
||||
if(isNotBlank(termOfService)){
|
||||
this.markupDocBuilder.textLine(TERMS_OF_SERVICE + " : " + termOfService);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildUriSchemeSection(Swagger swagger) {
|
||||
if(isNotBlank(swagger.getHost()) || isNotBlank(swagger.getBasePath()) || isNotEmpty(swagger.getSchemes())) {
|
||||
this.markupDocBuilder.sectionTitleLevel2(URI_SCHEME);
|
||||
if (isNotBlank(swagger.getHost())) {
|
||||
this.markupDocBuilder.textLine(HOST + " : " + swagger.getHost());
|
||||
}
|
||||
if (isNotBlank(swagger.getBasePath())) {
|
||||
this.markupDocBuilder.textLine(BASE_PATH + " : " + swagger.getBasePath());
|
||||
}
|
||||
if (isNotEmpty(swagger.getSchemes())) {
|
||||
List<String> schemes = new ArrayList<>();
|
||||
for (Scheme scheme : swagger.getSchemes()) {
|
||||
schemes.add(scheme.toString());
|
||||
}
|
||||
this.markupDocBuilder.textLine(SCHEMES + " : " + join(schemes, ", "));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildTagsSection(List<Tag> tags) {
|
||||
if(isNotEmpty(tags)){
|
||||
this.markupDocBuilder.sectionTitleLevel2(TAGS);
|
||||
List<String> tagsList = new ArrayList<>();
|
||||
for(Tag tag : tags){
|
||||
String name = tag.getName();
|
||||
String description = tag.getDescription();
|
||||
if(isNoneBlank(description)){
|
||||
tagsList.add(name + " : " + description);
|
||||
}else{
|
||||
tagsList.add(name);
|
||||
}
|
||||
}
|
||||
this.markupDocBuilder.unorderedList(tagsList);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildConsumesSection(List<String> consumes) {
|
||||
if (isNotEmpty(consumes)) {
|
||||
this.markupDocBuilder.sectionTitleLevel2(CONSUMES);
|
||||
this.markupDocBuilder.unorderedList(consumes);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildProducesSection(List<String> consumes) {
|
||||
if (isNotEmpty(consumes)) {
|
||||
this.markupDocBuilder.sectionTitleLevel2(PRODUCES);
|
||||
this.markupDocBuilder.unorderedList(consumes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply extension context to all OverviewContentExtension
|
||||
*
|
||||
* @param context context
|
||||
*/
|
||||
private void applyOverviewDocumentExtension(Context context) {
|
||||
for (OverviewDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(OverviewDocumentExtension.class)) {
|
||||
extension.apply(context);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,812 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.document.builder;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Multimap;
|
||||
import io.github.robwin.markup.builder.*;
|
||||
import io.github.robwin.swagger2markup.GroupBy;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
|
||||
import io.github.robwin.swagger2markup.internal.model.PathOperation;
|
||||
import io.github.robwin.swagger2markup.internal.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.internal.type.RefType;
|
||||
import io.github.robwin.swagger2markup.internal.type.Type;
|
||||
import io.github.robwin.swagger2markup.internal.utils.*;
|
||||
import io.github.robwin.swagger2markup.spi.PathsDocumentExtension;
|
||||
import io.swagger.models.*;
|
||||
import io.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.util.Json;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.text.WordUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import static io.github.robwin.swagger2markup.internal.utils.IOUtils.normalizeName;
|
||||
import static io.github.robwin.swagger2markup.internal.utils.ListUtils.*;
|
||||
import static io.github.robwin.swagger2markup.internal.utils.MapUtils.toKeySet;
|
||||
import static io.github.robwin.swagger2markup.internal.utils.TagUtils.convertTagsListToMap;
|
||||
import static io.github.robwin.swagger2markup.internal.utils.TagUtils.getTagDescription;
|
||||
import static io.github.robwin.swagger2markup.spi.PathsDocumentExtension.*;
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class PathsDocumentBuilder extends MarkupDocumentBuilder {
|
||||
|
||||
private final String RESPONSE;
|
||||
private final String REQUEST;
|
||||
private final String PATHS;
|
||||
private final String RESOURCES;
|
||||
private final String PARAMETERS;
|
||||
private final String BODY_PARAMETER;
|
||||
private final String RESPONSES;
|
||||
private final String HEADERS_COLUMN;
|
||||
private final String EXAMPLE_REQUEST;
|
||||
private final String EXAMPLE_RESPONSE;
|
||||
|
||||
private final String SECURITY;
|
||||
private final String TYPE_COLUMN;
|
||||
private final String HTTP_CODE_COLUMN;
|
||||
|
||||
private final String DEPRECATED_OPERATION;
|
||||
private final String UNKNOWN;
|
||||
|
||||
private static final String PATHS_ANCHOR = "paths";
|
||||
private static final String DESCRIPTION_FILE_NAME = "description";
|
||||
|
||||
|
||||
public PathsDocumentBuilder(Swagger2MarkupConverter.Context globalContext, java.nio.file.Path outputPath) {
|
||||
super(globalContext, outputPath);
|
||||
|
||||
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
|
||||
RESPONSE = labels.getString("response");
|
||||
REQUEST = labels.getString("request");
|
||||
PATHS = labels.getString("paths");
|
||||
RESOURCES = labels.getString("resources");
|
||||
PARAMETERS = labels.getString("parameters");
|
||||
BODY_PARAMETER = labels.getString("body_parameter");
|
||||
RESPONSES = labels.getString("responses");
|
||||
HEADERS_COLUMN = labels.getString("headers_column");
|
||||
EXAMPLE_REQUEST = labels.getString("example_request");
|
||||
EXAMPLE_RESPONSE = labels.getString("example_response");
|
||||
SECURITY = labels.getString("security");
|
||||
TYPE_COLUMN = labels.getString("type_column");
|
||||
HTTP_CODE_COLUMN = labels.getString("http_code_column");
|
||||
DEPRECATED_OPERATION = labels.getString("operation.deprecated");
|
||||
UNKNOWN = labels.getString("unknown");
|
||||
|
||||
if (config.isGeneratedExamplesEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include examples is enabled.");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include examples is disabled.");
|
||||
}
|
||||
}
|
||||
if (config.isOperationDescriptionsEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written operation descriptions is enabled.");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written operation descriptions is disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.isSeparatedOperationsEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create separated operation files is enabled.");
|
||||
}
|
||||
Validate.notNull(outputPath, "Output directory is required for separated operation files!");
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create separated operation files is disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the paths MarkupDocument.
|
||||
*
|
||||
* @return the paths MarkupDocument
|
||||
*/
|
||||
@Override
|
||||
public MarkupDocument build() {
|
||||
Map<String, Path> paths = globalContext.getSwagger().getPaths();
|
||||
if (MapUtils.isNotEmpty(paths)) {
|
||||
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
|
||||
buildPathsTitle();
|
||||
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
|
||||
buildsPathsSection(paths);
|
||||
applyPathsDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
|
||||
}
|
||||
return new MarkupDocument(markupDocBuilder);
|
||||
}
|
||||
|
||||
private void buildsPathsSection(Map<String, Path> paths) {
|
||||
Set<PathOperation> pathOperations = toPathOperationsSet(paths);
|
||||
if (CollectionUtils.isNotEmpty(pathOperations)) {
|
||||
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
|
||||
for (PathOperation operation : pathOperations) {
|
||||
buildOperation(operation);
|
||||
}
|
||||
} else {
|
||||
Multimap<String, PathOperation> operationsGroupedByTag = TagUtils.groupOperationsByTag(pathOperations, config.getTagOrdering(), config.getOperationOrdering());
|
||||
Map<String, Tag> tagsMap = convertTagsListToMap(globalContext.getSwagger().getTags());
|
||||
for (String tagName : operationsGroupedByTag.keySet()) {
|
||||
this.markupDocBuilder.sectionTitleLevel2(WordUtils.capitalize(tagName));
|
||||
|
||||
Optional<String> tagDescription = getTagDescription(tagsMap, tagName);
|
||||
if (tagDescription.isPresent()) {
|
||||
this.markupDocBuilder.paragraph(tagDescription.get());
|
||||
}
|
||||
|
||||
for (PathOperation operation : operationsGroupedByTag.get(tagName)) {
|
||||
buildOperation(operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the path title depending on the operationsGroupedBy configuration setting.
|
||||
*/
|
||||
private void buildPathsTitle() {
|
||||
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
|
||||
buildPathsTitle(PATHS);
|
||||
} else {
|
||||
buildPathsTitle(RESOURCES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the Swagger paths into a list PathOperations.
|
||||
*
|
||||
* @param paths the Swagger paths
|
||||
* @return the path operations
|
||||
*/
|
||||
private Set<PathOperation> toPathOperationsSet(Map<String, Path> paths) {
|
||||
Set<PathOperation> pathOperations;
|
||||
if (config.getOperationOrdering() != null) {
|
||||
pathOperations = new TreeSet<>(config.getOperationOrdering());
|
||||
}else{
|
||||
pathOperations = new LinkedHashSet<>();
|
||||
}
|
||||
for (Map.Entry<String, Path> path : paths.entrySet()) {
|
||||
Map<HttpMethod, Operation> operations = path.getValue().getOperationMap(); // TODO AS_IS does not work because of https://github.com/swagger-api/swagger-core/issues/1696
|
||||
if (MapUtils.isNotEmpty(operations)) {
|
||||
for (Map.Entry<HttpMethod, Operation> operation : operations.entrySet()) {
|
||||
pathOperations.add(new PathOperation(operation.getKey(), path.getKey(), operation.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return pathOperations;
|
||||
}
|
||||
|
||||
private void buildPathsTitle(String title) {
|
||||
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, PATHS_ANCHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply extension context to all OperationsContentExtension.
|
||||
*
|
||||
* @param context context
|
||||
*/
|
||||
private void applyPathsDocumentExtension(Context context) {
|
||||
for (PathsDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(PathsDocumentExtension.class)) {
|
||||
extension.apply(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the operation filename depending on the generation mode
|
||||
*
|
||||
* @param operation operation
|
||||
* @return operation filename
|
||||
*/
|
||||
private String resolveOperationDocument(PathOperation operation) {
|
||||
if (config.isSeparatedOperationsEnabled())
|
||||
return new File(config.getSeparatedOperationsFolder(), this.markupDocBuilder.addFileExtension(normalizeName(operation.getId()))).getPath();
|
||||
else
|
||||
return this.markupDocBuilder.addFileExtension(config.getPathsDocument());
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a path operation depending on generation mode.
|
||||
*
|
||||
* @param operation operation
|
||||
*/
|
||||
private void buildOperation(PathOperation operation) {
|
||||
if (config.isSeparatedOperationsEnabled()) {
|
||||
MarkupDocBuilder pathDocBuilder = this.markupDocBuilder.copy();
|
||||
buildOperation(operation, pathDocBuilder);
|
||||
java.nio.file.Path operationFile = outputPath.resolve(resolveOperationDocument(operation));
|
||||
|
||||
try {
|
||||
pathDocBuilder.writeToFileWithoutExtension(operationFile, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(String.format("Failed to write operation file: %s", operationFile), e);
|
||||
}
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Separate operation file produced: {}", operationFile);
|
||||
}
|
||||
|
||||
buildOperationRef(operation, this.markupDocBuilder);
|
||||
|
||||
} else {
|
||||
buildOperation(operation, this.markupDocBuilder);
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Operation processed: {}", operation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operation name depending on available informations.
|
||||
* The summary is used to name the operation, or else the operation summary is used.
|
||||
*
|
||||
* @param operation operation
|
||||
* @return operation name
|
||||
*/
|
||||
private String operationName(PathOperation operation) {
|
||||
return operation.getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a path operation.
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildOperation(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
if (operation != null) {
|
||||
applyPathsDocumentExtension(new Context(Position.OPERATION_BEGIN, docBuilder, operation));
|
||||
buildDeprecatedSection(operation, docBuilder);
|
||||
buildOperationTitle(operation, docBuilder);
|
||||
buildDescriptionSection(operation, docBuilder);
|
||||
inlineDefinitions(buildParametersSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), config.getInlineSchemaDepthLevel(), docBuilder);
|
||||
inlineDefinitions(buildBodyParameterSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), config.getInlineSchemaDepthLevel(), docBuilder);
|
||||
inlineDefinitions(buildResponsesSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), config.getInlineSchemaDepthLevel(), docBuilder);
|
||||
buildConsumesSection(operation, docBuilder);
|
||||
buildProducesSection(operation, docBuilder);
|
||||
buildTagsSection(operation, docBuilder);
|
||||
buildSecuritySchemeSection(operation, docBuilder);
|
||||
buildExamplesSection(operation, docBuilder);
|
||||
applyPathsDocumentExtension(new Context(Position.OPERATION_END, docBuilder, operation));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a cross-reference to a separated operation file
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildOperationRef(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
String document;
|
||||
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
|
||||
document = null;
|
||||
else if (config.isSeparatedOperationsEnabled())
|
||||
document = defaultString(config.getInterDocumentCrossReferencesPrefix()) + resolveOperationDocument(operation);
|
||||
else
|
||||
document = defaultString(config.getInterDocumentCrossReferencesPrefix()) + resolveOperationDocument(operation);
|
||||
String operationName = operationName(operation);
|
||||
|
||||
buildOperationTitle(docBuilder.copy().crossReference(document, operationName, operationName).toString(), "ref-" + operationName, docBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a warning if method is deprecated.
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildDeprecatedSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
Boolean deprecated = operation.getOperation().isDeprecated();
|
||||
if (deprecated != null && deprecated) {
|
||||
docBuilder.block(DEPRECATED_OPERATION, MarkupBlockStyle.EXAMPLE, null, MarkupAdmonition.CAUTION);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the operation title to the document. If the operation has a summary, the title is the summary.
|
||||
* Otherwise the title is the method of the operation and the URL of the operation.
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildOperationTitle(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
String operationName = operationName(operation);
|
||||
|
||||
buildOperationTitle(operationName, null, docBuilder);
|
||||
if (operationName.equals(operation.getOperation().getSummary())) {
|
||||
docBuilder.listing(operation.getMethod() + " " + operation.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a operation title to the document.
|
||||
*
|
||||
* @param title the operation title
|
||||
* @param anchor optional anchor (null => auto-generate from title)
|
||||
* @param docBuilder the MarkupDocBuilder to use
|
||||
*/
|
||||
private void buildOperationTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
|
||||
docBuilder.sectionTitleWithAnchorLevel2(title, anchor);
|
||||
} else {
|
||||
docBuilder.sectionTitleWithAnchorLevel3(title, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a operation section title to the document.
|
||||
*
|
||||
* @param title the section title
|
||||
* @param docBuilder the MarkupDocBuilder to use
|
||||
*/
|
||||
private void buildSectionTitle(String title, MarkupDocBuilder docBuilder) {
|
||||
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
|
||||
docBuilder.sectionTitleLevel3(title);
|
||||
} else {
|
||||
docBuilder.sectionTitleLevel4(title);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a response section title to the document.
|
||||
*
|
||||
* @param title the response title
|
||||
* @param docBuilder the MarkupDocBuilder to use
|
||||
*/
|
||||
private void buildResponseTitle(String title, MarkupDocBuilder docBuilder) {
|
||||
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
|
||||
docBuilder.sectionTitleLevel4(title);
|
||||
} else {
|
||||
docBuilder.sectionTitleLevel5(title);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a operation description to the document.
|
||||
* If hand-written descriptions exist, it tries to load the description from a file.
|
||||
* If the file cannot be read, the description of the operation is returned.
|
||||
* Operation folder search order :
|
||||
* - normalizeOperationFileName(operation.operationId)
|
||||
* - then, normalizeOperationFileName(operation.method + " " + operation.path)
|
||||
* - then, normalizeOperationFileName(operation.summary)
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildDescriptionSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
if (config.isOperationDescriptionsEnabled()) {
|
||||
Optional<String> description = handWrittenOperationDescription(normalizeName(operation.getId()), DESCRIPTION_FILE_NAME);
|
||||
if (!description.isPresent())
|
||||
description = handWrittenOperationDescription(normalizeName(operation.getTitle()), DESCRIPTION_FILE_NAME);
|
||||
|
||||
if (description.isPresent()) {
|
||||
operationDescription(description.get(), docBuilder);
|
||||
} else {
|
||||
operationDescription(operation.getOperation().getDescription(), docBuilder);
|
||||
}
|
||||
} else {
|
||||
operationDescription(operation.getOperation().getDescription(), docBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private void operationDescription(String description, MarkupDocBuilder docBuilder) {
|
||||
if (isNotBlank(description)) {
|
||||
buildSectionTitle(DESCRIPTION, docBuilder);
|
||||
docBuilder.paragraph(description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter parameters to display in parameters section
|
||||
*
|
||||
* @param parameter parameter to filter
|
||||
* @return true if parameter can be displayed
|
||||
*/
|
||||
private boolean filterParameter(Parameter parameter) {
|
||||
return (!config.isFlatBodyEnabled() || !StringUtils.equals(parameter.getIn(), "body"));
|
||||
}
|
||||
|
||||
private List<ObjectType> buildParametersSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
List<Parameter> parameters = operation.getOperation().getParameters();
|
||||
if (config.getParameterOrdering() != null)
|
||||
Collections.sort(parameters, config.getParameterOrdering());
|
||||
List<ObjectType> localDefinitions = new ArrayList<>();
|
||||
|
||||
boolean displayParameters = false;
|
||||
if (CollectionUtils.isNotEmpty(parameters)) {
|
||||
for (Parameter p : parameters) {
|
||||
if (filterParameter(p)) {
|
||||
displayParameters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (displayParameters) {
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
List<MarkupTableColumn> cols = Arrays.asList(
|
||||
new MarkupTableColumn(TYPE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
|
||||
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 6).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^6"),
|
||||
new MarkupTableColumn(REQUIRED_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(DEFAULT_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
|
||||
for (Parameter parameter : parameters) {
|
||||
if (filterParameter(parameter)) {
|
||||
Type type = ParameterUtils.getType(parameter, new DefinitionDocumentResolverFromOperation());
|
||||
|
||||
if (config.getInlineSchemaDepthLevel() > 0 && type instanceof ObjectType) {
|
||||
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
|
||||
String localTypeName = parameter.getName();
|
||||
|
||||
type.setName(localTypeName);
|
||||
type.setUniqueName(operation.getId() + " " + localTypeName);
|
||||
localDefinitions.add((ObjectType) type);
|
||||
type = new RefType(type);
|
||||
}
|
||||
}
|
||||
String parameterType = WordUtils.capitalize(parameter.getIn());
|
||||
|
||||
List<String> content = Arrays.asList(
|
||||
parameterType,
|
||||
parameter.getName(),
|
||||
parameterDescription(operation, parameter),
|
||||
Boolean.toString(parameter.getRequired()),
|
||||
type.displaySchema(markupDocBuilder),
|
||||
ParameterUtils.getDefaultValue(parameter));
|
||||
cells.add(content);
|
||||
}
|
||||
}
|
||||
buildSectionTitle(PARAMETERS, docBuilder);
|
||||
docBuilder.tableWithColumnSpecs(cols, cells);
|
||||
}
|
||||
|
||||
return localDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the body parameter section, if {@code Swagger2MarkupConfig.isIsolatedBody()} is true
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
* @return a list of inlined types.
|
||||
*/
|
||||
private List<ObjectType> buildBodyParameterSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
List<ObjectType> localDefinitions = new ArrayList<>();
|
||||
|
||||
if (config.isFlatBodyEnabled()) {
|
||||
List<Parameter> parameters = operation.getOperation().getParameters();
|
||||
if (CollectionUtils.isNotEmpty(parameters)) {
|
||||
for (Parameter parameter : parameters) {
|
||||
if (StringUtils.equals(parameter.getIn(), "body")) {
|
||||
Type type = ParameterUtils.getType(parameter, new DefinitionDocumentResolverFromOperation());
|
||||
|
||||
buildSectionTitle(BODY_PARAMETER, docBuilder);
|
||||
if (isNotBlank(parameter.getDescription())) {
|
||||
docBuilder.paragraph(parameter.getDescription());
|
||||
}
|
||||
|
||||
MarkupDocBuilder typeInfos = MarkupDocBuilders.documentBuilder(config.getMarkupLanguage(), config.getLineSeparator());
|
||||
typeInfos.italicText(REQUIRED_COLUMN).textLine(": " + parameter.getRequired());
|
||||
typeInfos.italicText(NAME_COLUMN).textLine(": " + parameter.getName());
|
||||
if (!(type instanceof ObjectType)) {
|
||||
typeInfos.italicText(TYPE_COLUMN).textLine(": " + type.displaySchema(docBuilder));
|
||||
|
||||
docBuilder.paragraph(typeInfos.toString());
|
||||
} else {
|
||||
docBuilder.paragraph(typeInfos.toString());
|
||||
|
||||
localDefinitions.addAll(buildPropertiesTable((ObjectType) type, operation.getId(), config.getInlineSchemaDepthLevel(), new PropertyDescriptor(type), new DefinitionDocumentResolverFromOperation(), docBuilder));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return localDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the description of a parameter, or otherwise an empty String.
|
||||
* If hand-written descriptions exist, it tries to load the description from a file.
|
||||
* If the file cannot be read, the description of the parameter is returned.
|
||||
* Operation folder search order :
|
||||
* - normalizeOperationFileName(operation.operationId)
|
||||
* - then, normalizeOperationFileName(operation.method + " " + operation.path)
|
||||
* - then, normalizeOperationFileName(operation.summary)
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param parameter the Swagger Parameter
|
||||
* @return the description of a parameter.
|
||||
*/
|
||||
private String parameterDescription(final PathOperation operation, Parameter parameter) {
|
||||
if (config.isOperationDescriptionsEnabled()) {
|
||||
final String parameterName = parameter.getName();
|
||||
if (isNotBlank(parameterName)) {
|
||||
Optional<String> description = handWrittenOperationDescription(new File(normalizeName(operation.getId()), parameterName).getPath(), DESCRIPTION_FILE_NAME);
|
||||
if (!description.isPresent())
|
||||
description = handWrittenOperationDescription(new File(normalizeName(operation.getTitle()), parameterName).getPath(), DESCRIPTION_FILE_NAME);
|
||||
|
||||
if (description.isPresent()) {
|
||||
return description.get();
|
||||
} else {
|
||||
return defaultString(parameter.getDescription());
|
||||
}
|
||||
} else {
|
||||
return defaultString(parameter.getDescription());
|
||||
}
|
||||
} else {
|
||||
return defaultString(parameter.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
private void buildConsumesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
List<String> consumes = operation.getOperation().getConsumes();
|
||||
if (CollectionUtils.isNotEmpty(consumes)) {
|
||||
buildSectionTitle(CONSUMES, docBuilder);
|
||||
docBuilder.unorderedList(consumes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void buildProducesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
List<String> produces = operation.getOperation().getProduces();
|
||||
if (CollectionUtils.isNotEmpty(produces)) {
|
||||
buildSectionTitle(PRODUCES, docBuilder);
|
||||
docBuilder.unorderedList(produces);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildTagsSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
if (config.getOperationsGroupedBy() == GroupBy.AS_IS) {
|
||||
List<String> tags = operation.getOperation().getTags();
|
||||
if (CollectionUtils.isNotEmpty(tags)) {
|
||||
buildSectionTitle(TAGS, docBuilder);
|
||||
Set<String> tagsSet = toSet(tags, config.getTagOrdering());
|
||||
docBuilder.unorderedList(new ArrayList<>(tagsSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the example section of a Swagger Operation.
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void buildExamplesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
|
||||
Map<String, Object> generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(config.isGeneratedExamplesEnabled(), operation, globalContext.getSwagger().getDefinitions(), markupDocBuilder);
|
||||
Map<String, Object> generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(config.isGeneratedExamplesEnabled(), operation.getOperation(), globalContext.getSwagger().getDefinitions(), markupDocBuilder);
|
||||
|
||||
exampleMap(generatedRequestExampleMap, EXAMPLE_REQUEST, REQUEST, docBuilder);
|
||||
exampleMap(generatedResponseExampleMap, EXAMPLE_RESPONSE, RESPONSE, docBuilder);
|
||||
}
|
||||
|
||||
private void exampleMap(Map<String, Object> exampleMap, String operationSectionTitle, String sectionTile, MarkupDocBuilder docBuilder) {
|
||||
if (exampleMap.size() > 0) {
|
||||
buildSectionTitle(operationSectionTitle, docBuilder);
|
||||
for (Map.Entry<String, Object> entry : exampleMap.entrySet()) {
|
||||
buildSectionTitle(sectionTile + " " + entry.getKey(), docBuilder);
|
||||
docBuilder.listing(Json.pretty(entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the security section of a Swagger Operation.
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @param docBuilder the MarkupDocBuilder document builder
|
||||
*/
|
||||
private void buildSecuritySchemeSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
List<Map<String, List<String>>> securitySchemes = operation.getOperation().getSecurity();
|
||||
if (CollectionUtils.isNotEmpty(securitySchemes)) {
|
||||
buildSectionTitle(SECURITY, docBuilder);
|
||||
Map<String, SecuritySchemeDefinition> securityDefinitions = globalContext.getSwagger().getSecurityDefinitions();
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
List<MarkupTableColumn> cols = Arrays.asList(
|
||||
new MarkupTableColumn(TYPE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
|
||||
new MarkupTableColumn(SCOPES_COLUMN, 6).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^6"));
|
||||
for (Map<String, List<String>> securityScheme : securitySchemes) {
|
||||
for (Map.Entry<String, List<String>> securityEntry : securityScheme.entrySet()) {
|
||||
String securityKey = securityEntry.getKey();
|
||||
String type = UNKNOWN;
|
||||
if (securityDefinitions != null && securityDefinitions.containsKey(securityKey)) {
|
||||
type = securityDefinitions.get(securityKey).getType();
|
||||
}
|
||||
List<String> content = Arrays.asList(type, docBuilder.copy().crossReference(securityKey, securityKey).toString(),
|
||||
Joiner.on(",").join(securityEntry.getValue()));
|
||||
cells.add(content);
|
||||
}
|
||||
}
|
||||
docBuilder.tableWithColumnSpecs(cols, cells);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a hand-written description
|
||||
*
|
||||
* @param descriptionFolder the name of the folder where the description file resides
|
||||
* @param descriptionFileName the name of the description file
|
||||
* @return the content of the file
|
||||
*/
|
||||
private Optional<String> handWrittenOperationDescription(String descriptionFolder, String descriptionFileName) {
|
||||
for (String fileNameExtension : config.getMarkupLanguage().getFileNameExtensions()) {
|
||||
URI contentUri = config.getOperationDescriptionsUri().resolve(descriptionFolder).resolve(descriptionFileName + fileNameExtension);
|
||||
|
||||
try (Reader reader = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriReader(contentUri)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Operation description content processed {}", contentUri);
|
||||
}
|
||||
|
||||
return Optional.of(IOUtils.toString(reader).trim());
|
||||
} catch (IOException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to read Operation description content {} > {}", contentUri, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
private List<ObjectType> buildResponsesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
|
||||
Map<String, Response> responses = operation.getOperation().getResponses();
|
||||
List<ObjectType> localDefinitions = new ArrayList<>();
|
||||
|
||||
if (MapUtils.isNotEmpty(responses)) {
|
||||
buildSectionTitle(RESPONSES, docBuilder);
|
||||
|
||||
List<MarkupTableColumn> responseCols = Arrays.asList(
|
||||
new MarkupTableColumn(HTTP_CODE_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 3).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
|
||||
|
||||
List<MarkupTableColumn> responseHeaderCols = Arrays.asList(
|
||||
new MarkupTableColumn(NAME_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1h"),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 3).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
|
||||
new MarkupTableColumn(SCHEMA_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
|
||||
new MarkupTableColumn(DEFAULT_COLUMN, 1).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"));
|
||||
|
||||
Set<String> responseNames = toKeySet(responses, config.getResponseOrdering());
|
||||
for (String responseName : responseNames) {
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
List<List<String>> responseHeaderCells = new ArrayList<>();
|
||||
Response response = responses.get(responseName);
|
||||
if (response.getSchema() != null) {
|
||||
Property property = response.getSchema();
|
||||
Type type = PropertyUtils.getType(property, new DefinitionDocumentResolverFromOperation());
|
||||
if (config.getInlineSchemaDepthLevel() > 0 && type instanceof ObjectType) {
|
||||
if (MapUtils.isNotEmpty(((ObjectType) type).getProperties())) {
|
||||
String localTypeName = RESPONSE + " " + responseName;
|
||||
|
||||
type.setName(localTypeName);
|
||||
type.setUniqueName(operation.getId() + " " + localTypeName);
|
||||
localDefinitions.add((ObjectType) type);
|
||||
type = new RefType(type);
|
||||
}
|
||||
}
|
||||
cells.add(Arrays.asList(responseName, response.getDescription(), type.displaySchema(markupDocBuilder)));
|
||||
} else {
|
||||
cells.add(Arrays.asList(responseName, response.getDescription(), NO_CONTENT));
|
||||
}
|
||||
|
||||
buildResponseTitle(HTTP_CODE_COLUMN + " " + responseName, docBuilder);
|
||||
docBuilder.tableWithColumnSpecs(responseCols, cells);
|
||||
|
||||
Map<String, Property> headers = response.getHeaders();
|
||||
if(MapUtils.isNotEmpty(headers)) {
|
||||
docBuilder.boldTextLine(HEADERS_COLUMN);
|
||||
for(Map.Entry<String, Property> entry : headers.entrySet()){
|
||||
Property property = entry.getValue();
|
||||
Type propertyType = PropertyUtils.getType(property, null);
|
||||
responseHeaderCells.add(Arrays.asList(entry.getKey(),
|
||||
response.getDescription(),
|
||||
propertyType.displaySchema(markupDocBuilder),
|
||||
PropertyUtils.getDefaultValue(property)));
|
||||
}
|
||||
docBuilder.tableWithColumnSpecs(responseHeaderCols, responseHeaderCells);
|
||||
}
|
||||
}
|
||||
}
|
||||
return localDefinitions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Builds the title of an inline schema.
|
||||
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
|
||||
*
|
||||
* @param title inline schema title
|
||||
* @param anchor inline schema anchor
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
|
||||
docBuilder.anchor(anchor);
|
||||
docBuilder.newLine();
|
||||
docBuilder.boldTextLine(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds inline schema definitions
|
||||
*
|
||||
* @param definitions all inline definitions to display
|
||||
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
|
||||
* @param depth current inline schema depth
|
||||
* @param docBuilder the docbuilder do use for output
|
||||
*/
|
||||
private void inlineDefinitions(List<ObjectType> definitions, String uniquePrefix, int depth, MarkupDocBuilder docBuilder) {
|
||||
if (CollectionUtils.isNotEmpty(definitions)) {
|
||||
for (ObjectType definition : definitions) {
|
||||
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
|
||||
|
||||
List<ObjectType> localDefinitions = buildPropertiesTable(definition, uniquePrefix, depth, new PropertyDescriptor(definition), new DefinitionDocumentResolverFromOperation(), docBuilder);
|
||||
for (ObjectType localDefinition : localDefinitions)
|
||||
inlineDefinitions(Collections.singletonList(localDefinition), uniquePrefix, depth - 1, docBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides definition document resolver functor for inter-document cross-references from operations files.
|
||||
* This implementation adapt the relative paths to definitions files
|
||||
*/
|
||||
class DefinitionDocumentResolverFromOperation extends DefinitionDocumentResolverDefault {
|
||||
|
||||
public DefinitionDocumentResolverFromOperation() {
|
||||
}
|
||||
|
||||
public String apply(String definitionName) {
|
||||
String defaultResolver = super.apply(definitionName);
|
||||
|
||||
if (defaultResolver != null && config.isSeparatedOperationsEnabled())
|
||||
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File("..", defaultResolver).getPath();
|
||||
else
|
||||
return defaultResolver;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.document.builder;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupTableColumn;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.document.MarkupDocument;
|
||||
import io.github.robwin.swagger2markup.spi.SecurityDocumentExtension;
|
||||
import io.swagger.models.auth.ApiKeyAuthDefinition;
|
||||
import io.swagger.models.auth.OAuth2Definition;
|
||||
import io.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static io.github.robwin.swagger2markup.spi.SecurityDocumentExtension.Context;
|
||||
import static io.github.robwin.swagger2markup.spi.SecurityDocumentExtension.Position;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class SecurityDocumentBuilder extends MarkupDocumentBuilder {
|
||||
|
||||
private static final String SECURITY_ANCHOR = "security";
|
||||
private final String SECURITY;
|
||||
private final String TYPE;
|
||||
private final String NAME;
|
||||
private final String IN;
|
||||
private final String FLOW;
|
||||
private final String AUTHORIZATION_URL;
|
||||
private final String TOKEN_URL;
|
||||
|
||||
public SecurityDocumentBuilder(Swagger2MarkupConverter.Context context, Path outputPath) {
|
||||
super(context, outputPath);
|
||||
|
||||
ResourceBundle labels = ResourceBundle.getBundle("io/github/robwin/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
|
||||
SECURITY = labels.getString("security");
|
||||
TYPE = labels.getString("security_type");
|
||||
NAME = labels.getString("security_name");
|
||||
IN = labels.getString("security_in");
|
||||
FLOW = labels.getString("security_flow");
|
||||
AUTHORIZATION_URL = labels.getString("security_authorizationUrl");
|
||||
TOKEN_URL = labels.getString("security_tokenUrl");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the security MarkupDocument.
|
||||
*
|
||||
* @return the security MarkupDocument
|
||||
*/
|
||||
@Override
|
||||
public MarkupDocument build(){
|
||||
Map<String, SecuritySchemeDefinition> definitions = globalContext.getSwagger().getSecurityDefinitions();
|
||||
if (MapUtils.isNotEmpty(definitions)) {
|
||||
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
|
||||
buildSecurityTitle(SECURITY);
|
||||
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
|
||||
buildSecuritySchemeDefinitionsSection(definitions);
|
||||
applySecurityDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
|
||||
}
|
||||
return new MarkupDocument(markupDocBuilder);
|
||||
}
|
||||
|
||||
private void buildSecurityTitle(String title) {
|
||||
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, SECURITY_ANCHOR);
|
||||
|
||||
}
|
||||
|
||||
private void buildSecuritySchemeDefinitionsSection(Map<String, SecuritySchemeDefinition> definitions) {
|
||||
for (Map.Entry<String, SecuritySchemeDefinition> entry : definitions.entrySet()) {
|
||||
String definitionName = entry.getKey();
|
||||
SecuritySchemeDefinition definition = entry.getValue();
|
||||
buildSecuritySchemeDefinitionTitle(definitionName);
|
||||
applySecurityDocumentExtension(new Context(Position.DEFINITION_BEGIN, markupDocBuilder, definitionName, definition));
|
||||
buildDescriptionParagraph(definition.getDescription());
|
||||
buildSecurityScheme(definition);
|
||||
applySecurityDocumentExtension(new Context(Position.DEFINITION_BEGIN, markupDocBuilder, definitionName, definition));
|
||||
}
|
||||
}
|
||||
|
||||
private void buildDescriptionParagraph(String description) {
|
||||
if(StringUtils.isNotBlank(description)) {
|
||||
markupDocBuilder.paragraph(description);
|
||||
}
|
||||
}
|
||||
|
||||
private MarkupDocBuilder buildSecuritySchemeDefinitionTitle(String definitionName) {
|
||||
return markupDocBuilder.sectionTitleLevel2(definitionName);
|
||||
}
|
||||
|
||||
private void buildSecurityScheme(SecuritySchemeDefinition securityScheme) {
|
||||
String type = securityScheme.getType();
|
||||
markupDocBuilder.textLine(TYPE + " : " + type);
|
||||
if (securityScheme instanceof ApiKeyAuthDefinition) {
|
||||
markupDocBuilder.textLine(NAME + " : " + ((ApiKeyAuthDefinition) securityScheme).getName());
|
||||
markupDocBuilder.textLine(IN + " : " + ((ApiKeyAuthDefinition) securityScheme).getIn());
|
||||
} else if (securityScheme instanceof OAuth2Definition) {
|
||||
OAuth2Definition oauth2Scheme = (OAuth2Definition) securityScheme;
|
||||
String flow = oauth2Scheme.getFlow();
|
||||
markupDocBuilder.textLine(FLOW + " : " + flow);
|
||||
if (isNotBlank(oauth2Scheme.getAuthorizationUrl())) {
|
||||
markupDocBuilder.textLine(AUTHORIZATION_URL + " : " + oauth2Scheme.getAuthorizationUrl());
|
||||
}
|
||||
if (isNotBlank(oauth2Scheme.getTokenUrl())) {
|
||||
markupDocBuilder.textLine(TOKEN_URL + " : " + oauth2Scheme.getTokenUrl());
|
||||
}
|
||||
List<List<String>> cells = new ArrayList<>();
|
||||
List<MarkupTableColumn> cols = Arrays.asList(new MarkupTableColumn(NAME_COLUMN, 1),
|
||||
new MarkupTableColumn(DESCRIPTION_COLUMN, 6));
|
||||
for (Map.Entry<String, String> scope : oauth2Scheme.getScopes().entrySet()) {
|
||||
List<String> content = Arrays.asList(scope.getKey(), scope.getValue());
|
||||
cells.add(content);
|
||||
}
|
||||
markupDocBuilder.tableWithColumnSpecs(cols, cells);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply extension context to all SecurityContentExtension
|
||||
*
|
||||
* @param context context
|
||||
*/
|
||||
private void applySecurityDocumentExtension(Context context) {
|
||||
for (SecurityDocumentExtension extension : globalContext.getExtensionRegistry().getExtensions(SecurityDocumentExtension.class)) {
|
||||
extension.apply(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.spi.ContentContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
class ContentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContentExtension.class);
|
||||
|
||||
protected final Swagger2MarkupConverter.Context globalContext;
|
||||
protected final ContentContext contentContext;
|
||||
|
||||
|
||||
ContentExtension(Swagger2MarkupConverter.Context globalContext, ContentContext contentContext) {
|
||||
this.globalContext = globalContext;
|
||||
this.contentContext = contentContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads contents from a file
|
||||
*
|
||||
* @param contentPath content file path
|
||||
* @return content reader
|
||||
*/
|
||||
protected Optional<Reader> readContentPath(Path contentPath) {
|
||||
|
||||
if (Files.isReadable(contentPath)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Content file {} processed", contentPath);
|
||||
}
|
||||
try {
|
||||
Reader contentReader = new FileReader(contentPath.toFile());
|
||||
|
||||
return Optional.of(contentReader);
|
||||
} catch (IOException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to read content file {} > {}", contentPath, e.getMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to read content file {}", contentPath);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads content from an Uri
|
||||
*
|
||||
* @param contentUri content file URI
|
||||
* @return content reader
|
||||
*/
|
||||
protected Optional<Reader> readContentUri(URI contentUri) {
|
||||
try {
|
||||
Reader reader = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriReader(contentUri);
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Content URI {} processed", contentUri);
|
||||
}
|
||||
|
||||
return Optional.of(reader);
|
||||
} catch (IOException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to read content URI {} > {}", contentUri, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.spi.ContentContext;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class DynamicContentExtension extends ContentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicContentExtension.class);
|
||||
|
||||
DynamicContentExtension(Swagger2MarkupConverter.Context globalContext, ContentContext contentContext) {
|
||||
super(globalContext, contentContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds extension sections
|
||||
*
|
||||
* @param contentPath the path where the content files reside
|
||||
* @param prefix extension file prefix
|
||||
* @param levelOffset import markup level offset
|
||||
*/
|
||||
public void extensionsSection(Path contentPath, final String prefix, int levelOffset) {
|
||||
final Collection<String> filenameExtensions = Collections2.transform(globalContext.getConfig().getMarkupLanguage().getFileNameExtensions(), new Function<String, String>() {
|
||||
public String apply(String input) {
|
||||
return StringUtils.stripStart(input, ".");
|
||||
}
|
||||
});
|
||||
|
||||
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
|
||||
@Override
|
||||
public boolean accept(Path entry) throws IOException {
|
||||
String fileName = entry.getFileName().toString();
|
||||
return fileName.startsWith(prefix) && FilenameUtils.isExtension(fileName, filenameExtensions);
|
||||
}
|
||||
};
|
||||
|
||||
try (DirectoryStream<Path> extensionFiles = Files.newDirectoryStream(contentPath, filter)) {
|
||||
|
||||
if (extensionFiles != null) {
|
||||
List<Path> extensions = Lists.newArrayList(extensionFiles);
|
||||
Collections.sort(extensions, Ordering.natural());
|
||||
|
||||
for (Path extension : extensions) {
|
||||
Optional<Reader> extensionContent = readContentPath(extension);
|
||||
|
||||
if (extensionContent.isPresent()) {
|
||||
try {
|
||||
contentContext.getMarkupDocBuilder().importMarkup(extensionContent.get(), levelOffset);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(String.format("Failed to read extension file %s", extension), e);
|
||||
} finally {
|
||||
extensionContent.get().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Failed to read extension files from directory {}", contentPath);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Dynamically search for markup files in {@code contentPath} to append in Definitions, with the format :<br/>
|
||||
* - {@code document-before-*.<markup.ext>} : import before Definitions document with levelOffset = 0<br/>
|
||||
* - {@code document-begin-*.<markup.ext>} : import just after Definitions document main title with levelOffset = 1<br/>
|
||||
* - {@code document-end-*.<markup.ext>} : import at the end of Definitions document with levelOffset = 1<br/>
|
||||
* - {@code definition-begin-*.<markup.ext>} : import just after each definition title with levelOffset = 2<br/>
|
||||
* - {@code definition-end-*.<markup.ext>} : import at the end of each definition with levelOffset = 2<br/>
|
||||
* <p/>
|
||||
* Markup files are appended in the natural order of their names, for each category.
|
||||
*/
|
||||
public final class DynamicDefinitionsDocumentExtension extends DefinitionsDocumentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicDefinitionsDocumentExtension.class);
|
||||
|
||||
protected Path contentPath;
|
||||
|
||||
public DynamicDefinitionsDocumentExtension(Path contentPath) {
|
||||
super();
|
||||
|
||||
Validate.notNull(contentPath);
|
||||
this.contentPath = contentPath;
|
||||
}
|
||||
|
||||
public DynamicDefinitionsDocumentExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
if (contentPath == null) {
|
||||
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable DynamicDefinitionsContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
|
||||
} else {
|
||||
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context) {
|
||||
Validate.notNull(context);
|
||||
|
||||
if (contentPath != null) {
|
||||
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
|
||||
DynamicDefinitionsDocumentExtension.Position position = context.getPosition();
|
||||
switch (position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_END:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DEFINITION_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath.resolve(Paths.get(IOUtils.normalizeName(context.getDefinitionName().get()))), contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DEFINITION_END:
|
||||
dynamicContent.extensionsSection(contentPath.resolve(Paths.get(IOUtils.normalizeName(context.getDefinitionName().get()))), contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String contentPrefix(Position position) {
|
||||
return position.name().toLowerCase().replace('_', '-');
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.spi.OverviewDocumentExtension;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Dynamically search for markup files in {@code contentPath} to append to Overview, with the format :<br/>
|
||||
* - {@code document-before-*.<markup.ext>} : import before Overview document with levelOffset = 0<br/>
|
||||
* - {@code document-begin-*.<markup.ext>} : import just after Overview document main title with levelOffset = 1<br/>
|
||||
* - {@code document-end-*.<markup.ext>} : import at the end of Overview document with levelOffset = 1<br/>
|
||||
* <p/>
|
||||
* Markup files are appended in the natural order of their names, for each category.
|
||||
*/
|
||||
public final class DynamicOverviewDocumentExtension extends OverviewDocumentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicOverviewDocumentExtension.class);
|
||||
|
||||
protected Path contentPath;
|
||||
|
||||
public DynamicOverviewDocumentExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
public DynamicOverviewDocumentExtension(Path contentPath) {
|
||||
super();
|
||||
|
||||
Validate.notNull(contentPath);
|
||||
this.contentPath = contentPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
if (contentPath == null) {
|
||||
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable > DynamicOverviewContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
|
||||
} else {
|
||||
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context) {
|
||||
Validate.notNull(context);
|
||||
|
||||
if (contentPath != null) {
|
||||
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
|
||||
OverviewDocumentExtension.Position position = context.getPosition();
|
||||
switch (position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_END:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String contentPrefix(Position position) {
|
||||
return position.name().toLowerCase().replace('_', '-');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import io.github.robwin.swagger2markup.spi.PathsDocumentExtension;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Dynamically search for markup files in {@code contentPath} to append to Operations, with the format :<br/>
|
||||
* - {@code document-before-*.<markup.ext>} : import before Paths document with levelOffset = 0<br/>
|
||||
* - {@code document-begin-*.<markup.ext>} : import just after Paths document main title with levelOffset = 1<br/>
|
||||
* - {@code document-end-*.<markup.ext>} : import at the end of Paths document with levelOffset = 1<br/>
|
||||
* - {@code operation-begin-*.<markup.ext>} : import just after each operation title with levelOffset = 2(GroupBy.AS_IS) | 3(GroupBy.TAGS)<br/>
|
||||
* - {@code operation-end-*.<markup.ext>} : import at the end of each operation with levelOffset = 2(GroupBy.AS_IS) | 3(GroupBy.TAGS)<br/>
|
||||
* <p/>
|
||||
* Markup files are appended in the natural order of their names, for each category.
|
||||
*/
|
||||
public final class DynamicPathsDocumentExtension extends PathsDocumentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicPathsDocumentExtension.class);
|
||||
|
||||
protected Path contentPath;
|
||||
|
||||
public DynamicPathsDocumentExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
public DynamicPathsDocumentExtension(Path contentPath) {
|
||||
super();
|
||||
|
||||
Validate.notNull(contentPath);
|
||||
this.contentPath = contentPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
if (contentPath == null) {
|
||||
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable DynamicOperationsContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
|
||||
} else {
|
||||
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context) {
|
||||
Validate.notNull(context);
|
||||
|
||||
if (contentPath != null) {
|
||||
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
|
||||
PathsDocumentExtension.Position position = context.getPosition();
|
||||
switch (position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_END:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case OPERATION_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getOperation().get().getId())), contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case OPERATION_END:
|
||||
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getOperation().get().getId())), contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String contentPrefix(Position position) {
|
||||
return position.name().toLowerCase().replace('_', '-');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import io.github.robwin.swagger2markup.spi.SecurityDocumentExtension;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Dynamically search for markup files in {@code contentPath} to append to Overview, with the format :<br/>
|
||||
* - {@code document-before-*.<markup.ext>} : import before Overview document with levelOffset = 0<br/>
|
||||
* - {@code document-begin-*.<markup.ext>} : import just after Overview document main title with levelOffset = 1<br/>
|
||||
* - {@code document-end-*.<markup.ext>} : import at the end of Overview document with levelOffset = 1<br/>
|
||||
* - {@code definition-begin-*.<markup.ext>} : import just after each definition title with levelOffset = 2<br/>
|
||||
* - {@code definition-end-*.<markup.ext>} : import at the end of each definition with levelOffset = 2<br/>
|
||||
* <p/>
|
||||
* Markup files are appended in the natural order of their names, for each category.
|
||||
*/
|
||||
public final class DynamicSecurityDocumentExtension extends SecurityDocumentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicSecurityDocumentExtension.class);
|
||||
|
||||
protected Path contentPath;
|
||||
|
||||
public DynamicSecurityDocumentExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
public DynamicSecurityDocumentExtension(Path contentPath) {
|
||||
super();
|
||||
|
||||
Validate.notNull(contentPath);
|
||||
this.contentPath = contentPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
if (contentPath == null) {
|
||||
if (globalContext.getSwaggerLocation() == null || !globalContext.getSwaggerLocation().getScheme().equals("file")) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable > DynamicSecurityContentExtension > Can't set default contentPath from swaggerLocation. You have to explicitly configure the content path.");
|
||||
} else {
|
||||
contentPath = Paths.get(globalContext.getSwaggerLocation()).getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context) {
|
||||
Validate.notNull(context);
|
||||
|
||||
if (contentPath != null) {
|
||||
DynamicContentExtension dynamicContent = new DynamicContentExtension(globalContext, context);
|
||||
SecurityDocumentExtension.Position position = context.getPosition();
|
||||
switch (position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DOCUMENT_END:
|
||||
dynamicContent.extensionsSection(contentPath, contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DEFINITION_BEGIN:
|
||||
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getDefinitionName().get())), contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
case DEFINITION_END:
|
||||
dynamicContent.extensionsSection(contentPath.resolve(IOUtils.normalizeName(context.getDefinitionName().get())), contentPrefix(position), levelOffset(context));
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String contentPrefix(Position position) {
|
||||
return position.name().toLowerCase().replace('_', '-');
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.spi.DefinitionsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Add external schemas to content.<br/>
|
||||
* Supported formats are :
|
||||
* <ul>
|
||||
* <li>XML Schema (.xsd)</li>
|
||||
* <li>JSON Schema (.json)</li>
|
||||
* </ul>
|
||||
*/
|
||||
public final class SchemaExtension extends DefinitionsDocumentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SchemaExtension.class);
|
||||
|
||||
private static final List<SchemaMetadata> DEFAULT_SCHEMAS = new ArrayList<SchemaMetadata>() {{
|
||||
add(new SchemaMetadata("JSON Schema", "json", "json"));
|
||||
add(new SchemaMetadata("XML Schema", "xsd", "xml"));
|
||||
}};
|
||||
|
||||
protected List<SchemaMetadata> schemas = new ArrayList<>();
|
||||
|
||||
protected URI schemaBaseUri;
|
||||
|
||||
public SchemaExtension(URI schemaBaseUri) {
|
||||
super();
|
||||
|
||||
Validate.notNull(schemaBaseUri);
|
||||
this.schemaBaseUri = schemaBaseUri;
|
||||
}
|
||||
|
||||
public SchemaExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SchemaExtension withDefaultSchemas() {
|
||||
schemas.addAll(DEFAULT_SCHEMAS);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SchemaExtension withSchemas(List<SchemaMetadata> schemas) {
|
||||
schemas.addAll(schemas);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
if (schemaBaseUri == null) {
|
||||
if (globalContext.getSwaggerLocation() == null) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable SchemaExtension > Can't set default schemaBaseUri from swaggerLocation. You have to explicitly configure the schemaBaseUri.");
|
||||
} else {
|
||||
schemaBaseUri = IOUtils.uriParent(globalContext.getSwaggerLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context) {
|
||||
Validate.notNull(context);
|
||||
|
||||
if (schemaBaseUri != null) {
|
||||
switch (context.getPosition()) {
|
||||
case DOCUMENT_BEFORE:
|
||||
case DOCUMENT_BEGIN:
|
||||
case DOCUMENT_END:
|
||||
case DEFINITION_BEGIN:
|
||||
break;
|
||||
case DEFINITION_END:
|
||||
for (SchemaMetadata schema : DEFAULT_SCHEMAS) {
|
||||
schemaSection(context, schema, levelOffset(context));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", context.getPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds snippet URI for the given {@code definitionName} and {@code schema}.<br/>
|
||||
* Default implementation use {@code <schemaBaseUri>/normalizeName(<definitionName>)/schema.<schema.extension>}.<br/>
|
||||
* You can override this method to configure your own folder normalization.
|
||||
*
|
||||
* @param context current context
|
||||
* @param definitionName current definition name
|
||||
* @return subdirectory normalized name
|
||||
*/
|
||||
public URI definitionSchemaUri(Context context, String definitionName, SchemaMetadata schema) {
|
||||
return schemaBaseUri.resolve(IOUtils.normalizeName(definitionName) + "/").resolve("schema" + (schema.extension != null ? "." + schema.extension : ""));
|
||||
}
|
||||
|
||||
private void schemaSection(Context context, SchemaMetadata schema, int levelOffset) {
|
||||
ContentExtension contentExtension = new ContentExtension(globalContext, context);
|
||||
URI schemaUri = definitionSchemaUri(context, context.getDefinitionName().get(), schema);
|
||||
|
||||
try {
|
||||
Optional<Reader> extensionContent = contentExtension.readContentUri(schemaUri);
|
||||
|
||||
if (extensionContent.isPresent()) {
|
||||
try {
|
||||
context.getMarkupDocBuilder().sectionTitleLevel(1 + levelOffset, schema.title);
|
||||
context.getMarkupDocBuilder().listing(org.apache.commons.io.IOUtils.toString(extensionContent.get()).trim(), schema.language);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(String.format("Failed to read schema URI : %s", schemaUri), e);
|
||||
} finally {
|
||||
extensionContent.get().close();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Failed to read schema URI {}", schemaUri);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SchemaMetadata {
|
||||
/**
|
||||
* Schema title
|
||||
*/
|
||||
public String title;
|
||||
|
||||
/**
|
||||
* Schema file extension, without dot (e.g.: xsd).<br/>
|
||||
* Set to null if there's no extension
|
||||
*/
|
||||
public String extension;
|
||||
|
||||
/**
|
||||
* Schema content language (e.g.: xml)
|
||||
*/
|
||||
public String language;
|
||||
|
||||
public SchemaMetadata(String title, String extension, String language) {
|
||||
this.title = title;
|
||||
this.extension = extension;
|
||||
this.language = language;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.extensions;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
import io.github.robwin.swagger2markup.internal.model.PathOperation;
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
import io.github.robwin.swagger2markup.spi.PathsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.utils.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Append Spring Rest docs generated snippets to Operations content.
|
||||
*/
|
||||
public final class SpringRestDocsExtension extends PathsDocumentExtension {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringRestDocsExtension.class);
|
||||
|
||||
private static final Map<String, String> DEFAULT_SNIPPETS = new LinkedHashMap<String, String>() {{
|
||||
put("http-request", "HTTP request");
|
||||
put("http-response", "HTTP response");
|
||||
put("curl-request", "Curl request");
|
||||
}};
|
||||
|
||||
protected URI snippetBaseUri;
|
||||
protected Map<String, String> snippets = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiate extension
|
||||
* @param snippetBaseUri base URI where are snippets are stored
|
||||
*/
|
||||
public SpringRestDocsExtension(URI snippetBaseUri) {
|
||||
super();
|
||||
|
||||
Validate.notNull(snippetBaseUri);
|
||||
this.snippetBaseUri = snippetBaseUri;
|
||||
}
|
||||
|
||||
public SpringRestDocsExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
if (snippetBaseUri == null) {
|
||||
if (globalContext.getSwaggerLocation() == null) {
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Disable SpringRestDocsExtension > Can't set default snippetBaseUri from swaggerLocation. You have to explicitly configure the snippetBaseUri.");
|
||||
} else {
|
||||
snippetBaseUri = IOUtils.uriParent(globalContext.getSwaggerLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add SpringRestDocs default snippets to list
|
||||
* @return this instance
|
||||
*/
|
||||
public SpringRestDocsExtension withDefaultSnippets() {
|
||||
snippets.putAll(DEFAULT_SNIPPETS);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an explicit list of snippets to display.
|
||||
* @param snippets snippets to add. key is snippet name (without extension, e.g.: 'http-request'), value is a custom section title for the snippet.
|
||||
* @return this instance
|
||||
*/
|
||||
public SpringRestDocsExtension withExplicitSnippets(Map<String, String> snippets) {
|
||||
this.snippets.putAll(snippets);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds snippet URI for the given {@code operation} and {@code snippetName}.<br/>
|
||||
* Default implementation use {@code <snippetBaseUri>/<normalizeName(<operation id>)>/<snippetName>.<markup ext>}.<br/>
|
||||
* You can override this method to configure your own folder normalization.
|
||||
*
|
||||
* @param context current context
|
||||
* @param operation current operation
|
||||
* @return subdirectory normalized name
|
||||
*/
|
||||
public URI operationSnippetUri(Context context, PathOperation operation, String snippetName) {
|
||||
return snippetBaseUri.resolve(IOUtils.normalizeName(operation.getId()) + "/").resolve(context.getMarkupDocBuilder().addFileExtension(snippetName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context) {
|
||||
Validate.notNull(context);
|
||||
|
||||
switch (context.getPosition()) {
|
||||
case OPERATION_END:
|
||||
snippets(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void snippets(Context context) {
|
||||
for (Map.Entry<String, String> snippets : this.snippets.entrySet()) {
|
||||
snippetSection(context, snippets.getKey(), snippets.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void snippetSection(Context context, String snippetName, String title) {
|
||||
ContentExtension content = new ContentExtension(globalContext, context);
|
||||
|
||||
URI snippetUri = operationSnippetUri(context, context.getOperation().get(), snippetName);
|
||||
Optional<Reader> snippetContent = content.readContentUri(snippetUri);
|
||||
|
||||
if (snippetContent.isPresent()) {
|
||||
try {
|
||||
context.getMarkupDocBuilder().sectionTitleLevel(1 + levelOffset(context), title);
|
||||
context.getMarkupDocBuilder().importMarkup(snippetContent.get(), levelOffset(context) + 1);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(String.format("Failed to process snippet URI : %s", snippetUri), e);
|
||||
} finally {
|
||||
try {
|
||||
snippetContent.get().close();
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.model;
|
||||
|
||||
import io.swagger.models.HttpMethod;
|
||||
import io.swagger.models.Operation;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
public class PathOperation {
|
||||
|
||||
protected HttpMethod method;
|
||||
protected String path;
|
||||
protected Operation operation;
|
||||
|
||||
public PathOperation(HttpMethod method, String path, Operation operation) {
|
||||
this.method = method;
|
||||
this.path = path;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public HttpMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display title for an operation
|
||||
* @return the operation title
|
||||
*/
|
||||
public String getTitle() {
|
||||
String operationName = operation.getSummary();
|
||||
if (isBlank(operationName)) {
|
||||
operationName = getMethod().toString() + " " + getPath();
|
||||
}
|
||||
return operationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unique id for the operation.<br/>
|
||||
* Use {@code <operation id>}, then {@code <operation path> lowercase(<operation method>)} if operation id is not set.
|
||||
*
|
||||
* @return operation unique id
|
||||
*/
|
||||
public String getId() {
|
||||
String id = operation.getOperationId();
|
||||
|
||||
if (id == null)
|
||||
id = getPath() + " " + getMethod().toString().toLowerCase();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
/**
|
||||
* Array type abstraction
|
||||
*/
|
||||
public class ArrayType extends Type {
|
||||
|
||||
protected String collectionFormat;
|
||||
protected Type ofType;
|
||||
|
||||
public ArrayType(String name, Type ofType) {
|
||||
this(name, ofType, null);
|
||||
}
|
||||
|
||||
public ArrayType(String name, Type ofType, String collectionFormat) {
|
||||
super(name == null ? "array" : name);
|
||||
this.collectionFormat = collectionFormat;
|
||||
this.ofType = ofType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
String collectionFormat = "";
|
||||
if (this.collectionFormat != null)
|
||||
collectionFormat = this.collectionFormat + " ";
|
||||
return collectionFormat + ofType.displaySchema(docBuilder) + " array";
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* Base type abstraction (string, integer, ...)
|
||||
*/
|
||||
public class BasicType extends Type {
|
||||
|
||||
protected String format;
|
||||
|
||||
public BasicType(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
public BasicType(String name, String format) {
|
||||
super(name);
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
if (isNotBlank(this.format))
|
||||
return this.name + "(" + this.format + ")";
|
||||
else
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* A functor to return the document part of an inter-document cross-references, depending on the globalContext.
|
||||
*/
|
||||
public interface DefinitionDocumentResolver extends Function<String, String> {}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.join;
|
||||
|
||||
/**
|
||||
* Enum type abstraction
|
||||
*/
|
||||
public class EnumType extends Type {
|
||||
|
||||
protected List<String> values;
|
||||
|
||||
public EnumType(String name, List<String> values) {
|
||||
super(name == null ? "enum" : name);
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
return "enum" + " (" + join(values, ", ") + ")";
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.swagger.models.properties.Property;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Complex object abstraction
|
||||
*/
|
||||
public class ObjectType extends Type {
|
||||
|
||||
protected Map<String, Property> properties;
|
||||
|
||||
public ObjectType(String name, Map<String, Property> properties) {
|
||||
super(name == null ? "object" : name);
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
if (MapUtils.isEmpty(properties))
|
||||
return "empty object";
|
||||
else
|
||||
return "object";
|
||||
}
|
||||
|
||||
public Map<String, Property> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, Property> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
/**
|
||||
* Reference to a type defined elsewhere
|
||||
*/
|
||||
public class RefType extends Type {
|
||||
|
||||
private String document;
|
||||
|
||||
public RefType(String document, String name) {
|
||||
super(name);
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
public RefType(Type type) {
|
||||
super(type.name, type.uniqueName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displaySchema(MarkupDocBuilder docBuilder) {
|
||||
return docBuilder.copy().crossReference(getDocument(), getUniqueName(), getName()).toString();
|
||||
}
|
||||
|
||||
public String getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
public void setDocument(String document) {
|
||||
this.document = document;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.type;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
/**
|
||||
* Type abstraction for display purpose
|
||||
*/
|
||||
public abstract class Type {
|
||||
|
||||
protected String name;
|
||||
protected String uniqueName;
|
||||
|
||||
public Type(String name, String uniqueName) {
|
||||
Validate.notBlank(name);
|
||||
|
||||
this.name = name;
|
||||
this.uniqueName = uniqueName;
|
||||
}
|
||||
|
||||
public Type(String name) {
|
||||
this(name, name);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUniqueName() {
|
||||
return uniqueName;
|
||||
}
|
||||
|
||||
public void setUniqueName(String uniqueName) {
|
||||
this.uniqueName = uniqueName;
|
||||
}
|
||||
|
||||
public abstract String displaySchema(MarkupDocBuilder docBuilder);
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.model.PathOperation;
|
||||
import io.swagger.models.*;
|
||||
import io.swagger.models.parameters.*;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.properties.RefProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExamplesUtil {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ExamplesUtil.class);
|
||||
|
||||
/**
|
||||
* Generates a Map of response examples
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @return map containing response examples.
|
||||
*/
|
||||
public static Map<String, Object> generateResponseExampleMap(boolean generateMissingExamples, Operation operation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
|
||||
Map<String, Object> examples = new HashMap<>();
|
||||
Map<String, Response> responses = operation.getResponses();
|
||||
for (Map.Entry<String, Response> responseEntry : responses.entrySet()) {
|
||||
Response response = responseEntry.getValue();
|
||||
Object example = response.getExamples();
|
||||
if (example == null) {
|
||||
Property schema = response.getSchema();
|
||||
if (schema != null) {
|
||||
example = schema.getExample();
|
||||
|
||||
if (example == null && schema instanceof RefProperty) {
|
||||
String simpleRef = ((RefProperty) schema).getSimpleRef();
|
||||
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
|
||||
}
|
||||
if (example == null && generateMissingExamples) {
|
||||
example = PropertyUtils.generateExample(schema, markupDocBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (example != null)
|
||||
examples.put(responseEntry.getKey(), example);
|
||||
|
||||
}
|
||||
|
||||
return examples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates examples for request
|
||||
*
|
||||
* @param pathOperation the Swagger Operation
|
||||
* @return an Optional with the example content
|
||||
*/
|
||||
public static Map<String, Object> generateRequestExampleMap(boolean generateMissingExamples, PathOperation pathOperation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
|
||||
Operation operation = pathOperation.getOperation();
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
Map<String, Object> examples = new HashMap<>();
|
||||
|
||||
// Path example should always be included (if generateMissingExamples):
|
||||
if (generateMissingExamples)
|
||||
examples.put("path", pathOperation.getPath());
|
||||
for (Parameter parameter : parameters) {
|
||||
Object example = null;
|
||||
if (parameter instanceof BodyParameter) {
|
||||
example = ((BodyParameter) parameter).getExamples();
|
||||
if (example == null) {
|
||||
Model schema = ((BodyParameter) parameter).getSchema();
|
||||
if (schema instanceof RefModel) {
|
||||
String simpleRef = ((RefModel) schema).getSimpleRef();
|
||||
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
|
||||
} else if (generateMissingExamples) {
|
||||
if (schema instanceof ComposedModel) {
|
||||
example = exampleMapForProperties(getPropertiesForComposedModel(
|
||||
(ComposedModel) schema, definitions), definitions, markupDocBuilder);
|
||||
} else if (schema instanceof ArrayModel) {
|
||||
example = generateExampleForArrayModel((ArrayModel) schema, definitions, markupDocBuilder);
|
||||
} else {
|
||||
example = schema.getExample();
|
||||
if (example == null) {
|
||||
example = exampleMapForProperties(schema.getProperties(), definitions, markupDocBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (parameter instanceof AbstractSerializableParameter) {
|
||||
if (generateMissingExamples) {
|
||||
Object abstractSerializableParameterExample;
|
||||
abstractSerializableParameterExample = ((AbstractSerializableParameter) parameter).getExample();
|
||||
if (abstractSerializableParameterExample == null) {
|
||||
Property item = ((AbstractSerializableParameter) parameter).getItems();
|
||||
if (item != null) {
|
||||
abstractSerializableParameterExample = PropertyUtils.convertExample(item.getExample(), item.getType());
|
||||
if (abstractSerializableParameterExample == null) {
|
||||
abstractSerializableParameterExample = PropertyUtils.generateExample(item, markupDocBuilder);
|
||||
}
|
||||
}
|
||||
if (abstractSerializableParameterExample == null) {
|
||||
abstractSerializableParameterExample = ParameterUtils.generateExample((AbstractSerializableParameter)parameter, markupDocBuilder);
|
||||
}
|
||||
}
|
||||
if (parameter instanceof PathParameter) {
|
||||
String pathExample = (String) examples.get("path");
|
||||
pathExample = pathExample.replace('{' + parameter.getName() + '}', String.valueOf(abstractSerializableParameterExample));
|
||||
example = pathExample;
|
||||
} else {
|
||||
example = abstractSerializableParameterExample;
|
||||
}
|
||||
if (parameter instanceof QueryParameter) {
|
||||
//noinspection unchecked
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> queryExampleMap = (Map<String, Object>) examples.get("query");
|
||||
if (queryExampleMap == null) {
|
||||
queryExampleMap = new HashMap<>();
|
||||
}
|
||||
queryExampleMap.put(parameter.getName(), abstractSerializableParameterExample);
|
||||
example = queryExampleMap;
|
||||
}
|
||||
}
|
||||
} else if (parameter instanceof RefParameter) {
|
||||
String simpleRef = ((RefParameter) parameter).getSimpleRef();
|
||||
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
|
||||
}
|
||||
|
||||
if (example != null)
|
||||
examples.put(parameter.getIn(), example);
|
||||
}
|
||||
|
||||
return examples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an example object from a simple reference
|
||||
*
|
||||
* @param simpleRef the simple reference string
|
||||
* @return returns an Object or Map of examples
|
||||
*/
|
||||
public static Object generateExampleForRefModel(boolean generateMissingExamples, String simpleRef, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
|
||||
Model model = definitions.get(simpleRef);
|
||||
Object example = null;
|
||||
if (model != null) {
|
||||
example = model.getExample();
|
||||
if (example == null && generateMissingExamples) {
|
||||
if (model instanceof ComposedModel) {
|
||||
example = exampleMapForProperties(getPropertiesForComposedModel((ComposedModel) model, definitions), definitions, markupDocBuilder);
|
||||
} else {
|
||||
example = exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
return example;
|
||||
}
|
||||
|
||||
private static Map<String, Property> getPropertiesForComposedModel(ComposedModel model, Map<String, Model> definitions) {
|
||||
Map<String, Property> combinedProperties;
|
||||
if (model.getParent() instanceof RefModel) {
|
||||
Map<String, Property> parentProperties = definitions.get(((RefModel) model.getParent()).getSimpleRef()).getProperties();
|
||||
if (parentProperties == null) {
|
||||
return null;
|
||||
} else {
|
||||
combinedProperties = new LinkedHashMap<>(parentProperties);
|
||||
}
|
||||
|
||||
} else {
|
||||
combinedProperties = new LinkedHashMap<>(model.getParent().getProperties());
|
||||
}
|
||||
Map<String, Property> childProperties;
|
||||
if (model.getChild() instanceof RefModel) {
|
||||
childProperties = definitions.get(((RefModel) model.getChild()).getSimpleRef()).getProperties();
|
||||
} else {
|
||||
childProperties = model.getChild().getProperties();
|
||||
}
|
||||
if (childProperties != null) {
|
||||
combinedProperties.putAll(childProperties);
|
||||
}
|
||||
return combinedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a map of examples from a map of properties. If defined examples are found, those are used. Otherwise,
|
||||
* examples are generated from the type.
|
||||
*
|
||||
* @param properties map of properties
|
||||
* @return a Map of examples
|
||||
*/
|
||||
public static Map<String, Object> exampleMapForProperties(Map<String, Property> properties, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
|
||||
Map<String, Object> exampleMap = new HashMap<>();
|
||||
for (Map.Entry<String, Property> property : properties.entrySet()) {
|
||||
Object exampleObject = PropertyUtils.convertExample(property.getValue().getExample(), property.getValue().getType());
|
||||
if (exampleObject == null) {
|
||||
if (property.getValue() instanceof RefProperty) {
|
||||
exampleObject = generateExampleForRefModel(true, ((RefProperty) property.getValue()).getSimpleRef(), definitions, markupDocBuilder);
|
||||
} else if (property.getValue() instanceof ArrayProperty) {
|
||||
exampleObject = generateExampleForArrayProperty((ArrayProperty) property.getValue(), definitions, markupDocBuilder);
|
||||
} else if (property.getValue() instanceof MapProperty) {
|
||||
exampleObject = generateExampleForMapProperty((MapProperty) property.getValue(), markupDocBuilder);
|
||||
}
|
||||
if (exampleObject == null) {
|
||||
Property valueProperty = property.getValue();
|
||||
exampleObject = PropertyUtils.generateExample(valueProperty, markupDocBuilder);
|
||||
}
|
||||
}
|
||||
exampleMap.put(property.getKey(), exampleObject);
|
||||
}
|
||||
return exampleMap;
|
||||
}
|
||||
|
||||
public static Object generateExampleForMapProperty(MapProperty property, MarkupDocBuilder markupDocBuilder) {
|
||||
if (property.getExample() != null) {
|
||||
return property.getExample();
|
||||
}
|
||||
Map<String, Object> exampleMap = new HashMap<>();
|
||||
Property valueProperty = property.getAdditionalProperties();
|
||||
if (valueProperty.getExample() != null) {
|
||||
return valueProperty.getExample();
|
||||
}
|
||||
exampleMap.put("string", PropertyUtils.generateExample(valueProperty, markupDocBuilder));
|
||||
return exampleMap;
|
||||
}
|
||||
|
||||
public static Object generateExampleForArrayModel(ArrayModel model, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
|
||||
if (model.getExample() != null) {
|
||||
return model.getExample();
|
||||
} else if (model.getProperties() != null) {
|
||||
return new Object[]{exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder)};
|
||||
} else {
|
||||
Property itemProperty = model.getItems();
|
||||
if (itemProperty.getExample() != null) {
|
||||
return new Object[]{PropertyUtils.convertExample(itemProperty.getExample(), itemProperty.getType())};
|
||||
} else if (itemProperty instanceof ArrayProperty) {
|
||||
return new Object[]{generateExampleForArrayProperty((ArrayProperty) itemProperty, definitions, markupDocBuilder)};
|
||||
} else if (itemProperty instanceof RefProperty) {
|
||||
return new Object[]{generateExampleForRefModel(true, ((RefProperty) itemProperty).getSimpleRef(), definitions, markupDocBuilder)};
|
||||
} else {
|
||||
return new Object[]{PropertyUtils.generateExample(itemProperty, markupDocBuilder)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates examples from an ArrayProperty
|
||||
*
|
||||
* @param value ArrayProperty
|
||||
* @return array of Object
|
||||
*/
|
||||
public static Object[] generateExampleForArrayProperty(ArrayProperty value, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
|
||||
Property property = value.getItems();
|
||||
if (property.getExample() != null) {
|
||||
return new Object[]{PropertyUtils.convertExample(property.getExample(), property.getType())};
|
||||
} else if (property instanceof ArrayProperty) {
|
||||
return new Object[]{generateExampleForArrayProperty((ArrayProperty) property, definitions, markupDocBuilder)};
|
||||
} else if (property instanceof RefProperty) {
|
||||
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, markupDocBuilder)};
|
||||
} else {
|
||||
return new Object[]{PropertyUtils.generateExample(property, markupDocBuilder)};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class IOUtils {
|
||||
private static final Pattern NAME_FORBIDDEN_PATTERN = Pattern.compile("[^0-9A-Za-z-_]+");
|
||||
|
||||
/**
|
||||
* Create a normalized name from an arbitrary string.<br/>
|
||||
* Paths separators are replaced, so this function can't be applied on a whole path, but must be called on each path sections.
|
||||
*
|
||||
* @param name current name of the file
|
||||
* @return a normalized filename
|
||||
*/
|
||||
public static String normalizeName(String name) {
|
||||
String fileName = NAME_FORBIDDEN_PATTERN.matcher(name).replaceAll("_");
|
||||
fileName = fileName.replaceAll(String.format("([%1$s])([%1$s]+)", "-_"), "$1");
|
||||
fileName = StringUtils.strip(fileName, "_-");
|
||||
fileName = fileName.trim();
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a reader from specified {@code source}.<br/>
|
||||
* Returned reader should be explicitly closed after use.
|
||||
*
|
||||
* @param uri source URI
|
||||
* @return reader
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Reader uriReader(URI uri) throws IOException {
|
||||
return new BufferedReader(new InputStreamReader(uri.toURL().openStream(), StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URI parent
|
||||
* @param uri source URI
|
||||
* @return URI parent
|
||||
*/
|
||||
public static URI uriParent(URI uri) {
|
||||
return uri.getPath().endsWith("/") ? uri.resolve("..") : uri.resolve(".");
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ListUtils {
|
||||
|
||||
/**
|
||||
* Returns the List as an Set either ordered or as-is, if the comparator is null.
|
||||
*
|
||||
* @param list the List
|
||||
* @param comparator the comparator to use.
|
||||
* @return the Set
|
||||
*/
|
||||
public static Set<String> toSet(List<String> list, Comparator<String> comparator){
|
||||
Set<String> set;
|
||||
if (comparator == null)
|
||||
set = new LinkedHashSet<>();
|
||||
else
|
||||
set = new TreeSet<>(comparator);
|
||||
set.addAll(list);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MapUtils {
|
||||
|
||||
/**
|
||||
* Returns the keys of the Map either ordered or as-is, if the comparator is null.
|
||||
*
|
||||
* @param map the Map
|
||||
* @param comparator the comparator to use.
|
||||
* @return the keySet of the Map
|
||||
*/
|
||||
public static Set<String> toKeySet(Map<String, ?> map, Comparator<String> comparator){
|
||||
Set<String> keys;
|
||||
if (comparator == null)
|
||||
keys = new LinkedHashSet<>();
|
||||
else
|
||||
keys = new TreeSet<>(comparator);
|
||||
keys.addAll(map.keySet());
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import io.github.robwin.swagger2markup.internal.type.ArrayType;
|
||||
import io.github.robwin.swagger2markup.internal.type.ObjectType;
|
||||
import io.github.robwin.swagger2markup.internal.type.RefType;
|
||||
import io.github.robwin.swagger2markup.internal.type.Type;
|
||||
import io.swagger.models.ArrayModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.ModelImpl;
|
||||
import io.swagger.models.RefModel;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public final class ModelUtils {
|
||||
|
||||
/**
|
||||
* Retrieves the type of a model, or otherwise null
|
||||
*
|
||||
* @param model the model
|
||||
* @return the type of the model, or otherwise null
|
||||
*/
|
||||
public static Type getType(Model model, Function<String, String> definitionDocumentResolver) {
|
||||
Validate.notNull(model, "model must not be null!");
|
||||
if (model instanceof ModelImpl) {
|
||||
return new ObjectType(null, model.getProperties());
|
||||
} else if (model instanceof RefModel) {
|
||||
String simpleRef = ((RefModel) model).getSimpleRef();
|
||||
return new RefType(definitionDocumentResolver.apply(simpleRef), simpleRef);
|
||||
} else if (model instanceof ArrayModel) {
|
||||
ArrayModel arrayModel = ((ArrayModel) model);
|
||||
return new ArrayType(null, PropertyUtils.getType(arrayModel.getItems(), definitionDocumentResolver));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.type.*;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.parameters.AbstractSerializableParameter;
|
||||
import io.swagger.models.parameters.BodyParameter;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
import io.swagger.models.parameters.RefParameter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
|
||||
|
||||
public final class ParameterUtils {
|
||||
|
||||
/**
|
||||
* Retrieves the type of a parameter, or otherwise null
|
||||
*
|
||||
* @param parameter the parameter
|
||||
* @return the type of the parameter, or otherwise null
|
||||
*/
|
||||
public static Type getType(Parameter parameter, Function<String, String> definitionDocumentResolver){
|
||||
Validate.notNull(parameter, "parameter must not be null!");
|
||||
Type type = null;
|
||||
if(parameter instanceof BodyParameter){
|
||||
BodyParameter bodyParameter = (BodyParameter)parameter;
|
||||
Model model = bodyParameter.getSchema();
|
||||
if(model != null){
|
||||
type = ModelUtils.getType(model, definitionDocumentResolver);
|
||||
}else{
|
||||
type = new BasicType("string");
|
||||
}
|
||||
|
||||
}
|
||||
else if(parameter instanceof AbstractSerializableParameter){
|
||||
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> enums = serializableParameter.getEnum();
|
||||
if(CollectionUtils.isNotEmpty(enums)){
|
||||
type = new EnumType(null, enums);
|
||||
}else{
|
||||
type = new BasicType(serializableParameter.getType(), serializableParameter.getFormat());
|
||||
}
|
||||
if(type.getName().equals("array")){
|
||||
String collectionFormat = serializableParameter.getCollectionFormat();
|
||||
type = new ArrayType(null, PropertyUtils.getType(serializableParameter.getItems(), definitionDocumentResolver), collectionFormat);
|
||||
}
|
||||
}
|
||||
else if(parameter instanceof RefParameter){
|
||||
String simpleRef = ((RefParameter)parameter).getSimpleRef();
|
||||
type = new RefType(definitionDocumentResolver.apply(simpleRef), simpleRef);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default value of a parameter, or otherwise an empty String
|
||||
*
|
||||
* @param parameter the parameter
|
||||
* @return the default value of the parameter, or otherwise an empty String
|
||||
*/
|
||||
public static String getDefaultValue(Parameter parameter){
|
||||
Validate.notNull(parameter, "parameter must not be null!");
|
||||
String defaultValue = "";
|
||||
if(parameter instanceof AbstractSerializableParameter){
|
||||
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
|
||||
defaultValue = serializableParameter.getDefaultValue();
|
||||
}
|
||||
return defaultString(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a default example value for parameter.
|
||||
*
|
||||
* @param parameter parameter
|
||||
* @param markupDocBuilder doc builder
|
||||
* @return a generated example for the parameter
|
||||
*/
|
||||
public static Object generateExample(AbstractSerializableParameter parameter, MarkupDocBuilder markupDocBuilder) {
|
||||
switch (parameter.getType()) {
|
||||
case "integer":
|
||||
return 0;
|
||||
case "number":
|
||||
return 0.0;
|
||||
case "boolean":
|
||||
return true;
|
||||
case "string":
|
||||
return "string";
|
||||
default:
|
||||
return parameter.getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.swagger2markup.internal.type.*;
|
||||
import io.swagger.models.properties.*;
|
||||
import io.swagger.models.refs.RefFormat;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
public final class PropertyUtils {
|
||||
|
||||
/**
|
||||
* Retrieves the type and format of a property.
|
||||
*
|
||||
* @param property the property
|
||||
* @return the type of the property
|
||||
*/
|
||||
public static Type getType(Property property, Function<String, String> definitionDocumentResolver) {
|
||||
Validate.notNull(property, "property must not be null");
|
||||
Type type;
|
||||
if (property instanceof RefProperty) {
|
||||
RefProperty refProperty = (RefProperty) property;
|
||||
if (refProperty.getRefFormat() == RefFormat.RELATIVE)
|
||||
type = new ObjectType(null, null); // FIXME : Workaround for https://github.com/swagger-api/swagger-parser/issues/177
|
||||
else
|
||||
type = new RefType(definitionDocumentResolver.apply(refProperty.getSimpleRef()), refProperty.getSimpleRef());
|
||||
} else if (property instanceof ArrayProperty) {
|
||||
ArrayProperty arrayProperty = (ArrayProperty) property;
|
||||
Property items = arrayProperty.getItems();
|
||||
type = new ArrayType(null, getType(items, definitionDocumentResolver));
|
||||
} else if (property instanceof StringProperty) {
|
||||
StringProperty stringProperty = (StringProperty) property;
|
||||
List<String> enums = stringProperty.getEnum();
|
||||
if (CollectionUtils.isNotEmpty(enums)) {
|
||||
type = new EnumType(null, enums);
|
||||
} else {
|
||||
type = new BasicType(property.getType());
|
||||
}
|
||||
} else if (property instanceof ObjectProperty) {
|
||||
type = new ObjectType(null, ((ObjectProperty) property).getProperties());
|
||||
} else {
|
||||
if (isNotBlank(property.getFormat())) {
|
||||
type = new BasicType(property.getType(), property.getFormat());
|
||||
} else {
|
||||
type = new BasicType(property.getType());
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default value of a property, or otherwise returns an empty String.
|
||||
*
|
||||
* @param property the property
|
||||
* @return the default value of the property, or otherwise an empty String
|
||||
*/
|
||||
public static String getDefaultValue(Property property) {
|
||||
Validate.notNull(property, "property must not be null");
|
||||
String defaultValue = "";
|
||||
if (property instanceof BooleanProperty) {
|
||||
BooleanProperty booleanProperty = (BooleanProperty) property;
|
||||
defaultValue = Objects.toString(booleanProperty.getDefault(), "");
|
||||
} else if (property instanceof StringProperty) {
|
||||
StringProperty stringProperty = (StringProperty) property;
|
||||
defaultValue = Objects.toString(stringProperty.getDefault(), "");
|
||||
} else if (property instanceof DoubleProperty) {
|
||||
DoubleProperty doubleProperty = (DoubleProperty) property;
|
||||
defaultValue = Objects.toString(doubleProperty.getDefault(), "");
|
||||
} else if (property instanceof FloatProperty) {
|
||||
FloatProperty floatProperty = (FloatProperty) property;
|
||||
defaultValue = Objects.toString(floatProperty.getDefault(), "");
|
||||
} else if (property instanceof IntegerProperty) {
|
||||
IntegerProperty integerProperty = (IntegerProperty) property;
|
||||
defaultValue = Objects.toString(integerProperty.getDefault(), "");
|
||||
} else if (property instanceof LongProperty) {
|
||||
LongProperty longProperty = (LongProperty) property;
|
||||
defaultValue = Objects.toString(longProperty.getDefault(), "");
|
||||
} else if (property instanceof UUIDProperty) {
|
||||
UUIDProperty uuidProperty = (UUIDProperty) property;
|
||||
defaultValue = Objects.toString(uuidProperty.getDefault(), "");
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return example display string for the given {@code property}.
|
||||
*
|
||||
* @param property property
|
||||
* @param markupDocBuilder doc builder
|
||||
* @return property example display string
|
||||
*/
|
||||
public static Object getExample(boolean generateMissingExamples, Property property, MarkupDocBuilder markupDocBuilder) {
|
||||
Validate.notNull(property, "property must not be null");
|
||||
Object examplesValue = null;
|
||||
if (property.getExample() != null) {
|
||||
examplesValue = convertExample(property.getExample(), property.getType());
|
||||
} else if (property instanceof MapProperty) {
|
||||
Property additionalProperty = ((MapProperty) property).getAdditionalProperties();
|
||||
if (additionalProperty.getExample() != null) {
|
||||
examplesValue = additionalProperty.getExample();
|
||||
} else if (generateMissingExamples) {
|
||||
Map<String, Object> exampleMap = new HashMap<>();
|
||||
exampleMap.put("string", generateExample(additionalProperty, markupDocBuilder));
|
||||
examplesValue = exampleMap;
|
||||
}
|
||||
} else if (property instanceof ArrayProperty) {
|
||||
if (generateMissingExamples) {
|
||||
Property itemProperty = ((ArrayProperty) property).getItems();
|
||||
List<Object> exampleArray = new ArrayList<>();
|
||||
exampleArray.add(generateExample(itemProperty, markupDocBuilder));
|
||||
examplesValue = exampleArray;
|
||||
}
|
||||
} else if (generateMissingExamples) {
|
||||
examplesValue = generateExample(property, markupDocBuilder);
|
||||
}
|
||||
|
||||
return examplesValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a default example value for property.
|
||||
*
|
||||
* @param property property
|
||||
* @param markupDocBuilder doc builder
|
||||
* @return a generated example for the property
|
||||
*/
|
||||
public static Object generateExample(Property property, MarkupDocBuilder markupDocBuilder) {
|
||||
switch (property.getType()) {
|
||||
case "integer":
|
||||
return 0;
|
||||
case "number":
|
||||
return 0.0;
|
||||
case "boolean":
|
||||
return true;
|
||||
case "string":
|
||||
return "string";
|
||||
case "ref":
|
||||
if (property instanceof RefProperty) {
|
||||
return markupDocBuilder.copy().crossReference(((RefProperty) property).getSimpleRef()).toString();
|
||||
}
|
||||
default:
|
||||
return property.getType();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string {@code value} to specified {@code type}.
|
||||
*
|
||||
* @param value value to convert
|
||||
* @param type target conversion type
|
||||
* @return converted value as object
|
||||
*/
|
||||
public static Object convertExample(String value, String type) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
case "integer":
|
||||
return Integer.valueOf(value);
|
||||
case "number":
|
||||
return Float.valueOf(value);
|
||||
case "boolean":
|
||||
return Boolean.valueOf(value);
|
||||
case "string":
|
||||
return value;
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new RuntimeException(String.format("Value '%s' cannot be converted to '%s'", value, type), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.internal.utils;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.github.robwin.swagger2markup.internal.model.PathOperation;
|
||||
import io.swagger.models.Tag;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TagUtils {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(TagUtils.class);
|
||||
|
||||
/**
|
||||
* Converts the global Tag list into a Map where the tag name is the key and the Tag the value.
|
||||
*
|
||||
* @param tags the List of tags
|
||||
* @return the Map of tags
|
||||
*/
|
||||
public static Map<String, Tag> convertTagsListToMap(List<Tag> tags) {
|
||||
if (tags == null) {
|
||||
tags = new ArrayList<>();
|
||||
}
|
||||
Map<String, Tag> tagsMap = new HashMap<>();
|
||||
for (Tag tag : tags) tagsMap.put(tag.getName(), tag);
|
||||
return tagsMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the optional description of a tag.
|
||||
*
|
||||
* @param tagsMap the Map of tags
|
||||
* @param tagName the name of the tag
|
||||
* @return the optional description of the tag
|
||||
*/
|
||||
public static Optional<String> getTagDescription(Map<String, Tag> tagsMap, String tagName) {
|
||||
Tag tag = tagsMap.get(tagName);
|
||||
if(tag != null){
|
||||
return Optional.fromNullable(tag.getDescription());
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the operations by tag. The key of the Multimap is the tag name.
|
||||
* The value of the Multimap is a PathOperation
|
||||
*
|
||||
* @param allOperations all operations
|
||||
* @param tagOrdering comparator for tags
|
||||
* @param operationOrdering comparator for operations, for a given tag
|
||||
* @return Operations grouped by Tag
|
||||
*/
|
||||
public static Multimap<String, PathOperation> groupOperationsByTag(Set<PathOperation> allOperations, Comparator<String> tagOrdering, Comparator<PathOperation> operationOrdering) {
|
||||
MultimapBuilder.MultimapBuilderWithKeys<String> multimapBuilderWithKeys;
|
||||
|
||||
if (tagOrdering == null)
|
||||
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(Ordering.<String>natural()); // FIXME as-is sorting not supported because of limitations in MultiMap::hashkeys(). Replaced with Ordering.natural()
|
||||
else
|
||||
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagOrdering);
|
||||
|
||||
Multimap<String, PathOperation> operationsGroupedByTag;
|
||||
if (operationOrdering == null)
|
||||
operationsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build();
|
||||
else
|
||||
operationsGroupedByTag = multimapBuilderWithKeys.treeSetValues(operationOrdering).build();
|
||||
|
||||
for (PathOperation operation : allOperations) {
|
||||
List<String> tags = operation.getOperation().getTags();
|
||||
Validate.notEmpty(tags, "Can't GroupBy.TAGS > Operation '%s' has not tags", operation);
|
||||
for (String tag : tags) {
|
||||
if (LOG.isInfoEnabled()) {
|
||||
LOG.info("Added path operation '{}' to tag '{}'", operation, tag);
|
||||
}
|
||||
operationsGroupedByTag.put(tag, operation);
|
||||
}
|
||||
}
|
||||
|
||||
return operationsGroupedByTag;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
|
||||
/**
|
||||
* An abstract extension which must be extended by an extension
|
||||
*/
|
||||
abstract class AbstractExtension implements Extension {
|
||||
|
||||
protected Swagger2MarkupConverter.Context globalContext;
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
public void setGlobalContext(Swagger2MarkupConverter.Context globalContext) {
|
||||
this.globalContext = globalContext;
|
||||
init(globalContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridable init event listener.
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
public void init(Swagger2MarkupConverter.Context globalContext) {
|
||||
/* must be left empty */
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
public class ContentContext {
|
||||
private MarkupDocBuilder docBuilder;
|
||||
|
||||
ContentContext(MarkupDocBuilder docBuilder) {
|
||||
this.docBuilder = docBuilder;
|
||||
}
|
||||
|
||||
public MarkupDocBuilder getMarkupDocBuilder() {
|
||||
return docBuilder;
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.swagger.models.Model;
|
||||
|
||||
/**
|
||||
* A SecurityContentExtension can be used to extend the definitions document.
|
||||
*/
|
||||
public abstract class DefinitionsDocumentExtension extends AbstractExtension {
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DEFINITION_BEGIN,
|
||||
DEFINITION_END
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOC_*
|
||||
*/
|
||||
private String definitionName;
|
||||
|
||||
/**
|
||||
* null if position == DOC_*
|
||||
*/
|
||||
private Model model;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder) {
|
||||
super(docBuilder);
|
||||
Validate.isTrue(position != Position.DEFINITION_BEGIN && position != Position.DEFINITION_END, "You must provide a definitionName for this position");
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
* @param definitionName the name of the current definition
|
||||
* @param model the current Model of the definition
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder, String definitionName, Model model) {
|
||||
super(docBuilder);
|
||||
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.fromNullable(definitionName);
|
||||
}
|
||||
|
||||
public Optional<Model> getModel() {
|
||||
return Optional.fromNullable(model);
|
||||
}
|
||||
}
|
||||
|
||||
public DefinitionsDocumentExtension() {
|
||||
}
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
/**
|
||||
* Returns title level offset from 1 to apply to content
|
||||
* @param context context
|
||||
* @return title level offset
|
||||
*/
|
||||
protected int levelOffset(Context context) {
|
||||
int levelOffset;
|
||||
switch (context.position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
case DOCUMENT_BEGIN:
|
||||
case DOCUMENT_END:
|
||||
levelOffset = 1;
|
||||
break;
|
||||
case DEFINITION_BEGIN:
|
||||
case DEFINITION_END:
|
||||
levelOffset = 2;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
|
||||
}
|
||||
|
||||
return levelOffset;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
|
||||
|
||||
/**
|
||||
* A marker interface which must be implemented by an extension
|
||||
*/
|
||||
public interface Extension {
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
void setGlobalContext(Swagger2MarkupConverter.Context globalContext);
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
|
||||
/**
|
||||
* A SecurityContentExtension can be used to extend the overview document.
|
||||
*/
|
||||
public abstract class OverviewDocumentExtension extends AbstractExtension {
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder) {
|
||||
super(docBuilder);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
public OverviewDocumentExtension() {
|
||||
}
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
/**
|
||||
* Returns title level offset from 1 to apply to content
|
||||
* @param context context
|
||||
* @return title level offset
|
||||
*/
|
||||
protected int levelOffset(Context context) {
|
||||
int levelOffset;
|
||||
switch (context.position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
case DOCUMENT_BEGIN:
|
||||
case DOCUMENT_END:
|
||||
levelOffset = 1;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
|
||||
}
|
||||
|
||||
return levelOffset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.swagger2markup.GroupBy;
|
||||
import io.github.robwin.swagger2markup.internal.model.PathOperation;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
/**
|
||||
* A SecurityContentExtension can be used to extend the paths document.
|
||||
*/
|
||||
public abstract class PathsDocumentExtension extends AbstractExtension {
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
OPERATION_BEGIN,
|
||||
OPERATION_END
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOC_*
|
||||
*/
|
||||
private PathOperation operation;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder) {
|
||||
super(docBuilder);
|
||||
Validate.isTrue(position != Position.OPERATION_BEGIN && position != Position.OPERATION_END, "You must provide an operation for this position");
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
* @param operation the current path operation
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder, PathOperation operation) {
|
||||
super(docBuilder);
|
||||
Validate.notNull(operation);
|
||||
this.position = position;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<PathOperation> getOperation() {
|
||||
return Optional.fromNullable(operation);
|
||||
}
|
||||
}
|
||||
|
||||
public PathsDocumentExtension() {
|
||||
}
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
/**
|
||||
* Returns title level offset from 1 to apply to content
|
||||
*
|
||||
* @param context context
|
||||
* @return title level offset
|
||||
*/
|
||||
protected int levelOffset(Context context) {
|
||||
int levelOffset;
|
||||
switch (context.position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
case DOCUMENT_BEGIN:
|
||||
case DOCUMENT_END:
|
||||
levelOffset = 1;
|
||||
break;
|
||||
case OPERATION_BEGIN:
|
||||
case OPERATION_END:
|
||||
levelOffset = 2;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
|
||||
}
|
||||
if (globalContext.getConfig().getOperationsGroupedBy() == GroupBy.TAGS) {
|
||||
levelOffset++;
|
||||
}
|
||||
return levelOffset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
/**
|
||||
* A SecurityContentExtension can be used to extend the security document.
|
||||
*/
|
||||
public abstract class SecurityDocumentExtension extends AbstractExtension {
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DEFINITION_BEGIN,
|
||||
DEFINITION_END
|
||||
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOC_*
|
||||
*/
|
||||
private String definitionName;
|
||||
/**
|
||||
* null if position == DOC_*
|
||||
*/
|
||||
private SecuritySchemeDefinition definition;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder) {
|
||||
super(docBuilder);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param docBuilder the MarkupDocBuilder
|
||||
* @param definitionName the name of the current definition
|
||||
* @param definition the current security scheme definition
|
||||
*/
|
||||
public Context(Position position, MarkupDocBuilder docBuilder, String definitionName, SecuritySchemeDefinition definition) {
|
||||
super(docBuilder);
|
||||
Validate.notNull(definitionName);
|
||||
Validate.notNull(definition);
|
||||
this.position = position;
|
||||
this.definitionName = definitionName;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<String> getDefinitionName() {
|
||||
return Optional.fromNullable(definitionName);
|
||||
}
|
||||
|
||||
public Optional<SecuritySchemeDefinition> getDefinition() {
|
||||
return Optional.fromNullable(definition);
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityDocumentExtension() {
|
||||
}
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
/**
|
||||
* Returns title level offset from 1 to apply to content
|
||||
* @param context context
|
||||
* @return title level offset
|
||||
*/
|
||||
protected int levelOffset(Context context) {
|
||||
int levelOffset;
|
||||
switch (context.position) {
|
||||
case DOCUMENT_BEFORE:
|
||||
case DOCUMENT_BEGIN:
|
||||
case DOCUMENT_END:
|
||||
levelOffset = 1;
|
||||
break;
|
||||
case DEFINITION_BEGIN:
|
||||
case DEFINITION_END:
|
||||
levelOffset = 2;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
|
||||
}
|
||||
|
||||
return levelOffset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.swagger.models.Swagger;
|
||||
|
||||
/**
|
||||
* A SwaggerExtension can be used to preprocess the Swagger model.
|
||||
*/
|
||||
public abstract class SwaggerModelExtension extends AbstractExtension {
|
||||
|
||||
public SwaggerModelExtension() {
|
||||
}
|
||||
|
||||
public abstract void apply(Swagger swagger);
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
swagger2markup.markupLanguage=ASCIIDOC
|
||||
swagger2markup.generatedExamplesEnabled=false
|
||||
swagger2markup.operationDescriptionsEnabled=false
|
||||
swagger2markup.definitionDescriptionsEnabled=false
|
||||
swagger2markup.operationExtensionsEnabled=false
|
||||
swagger2markup.definitionExtensionsEnabled=false
|
||||
swagger2markup.separatedDefinitionsEnabled=false
|
||||
swagger2markup.separatedOperationsEnabled=false
|
||||
swagger2markup.operationsGroupedBy=AS_IS
|
||||
swagger2markup.outputLanguage=EN
|
||||
swagger2markup.inlineSchemaDepthLevel=0
|
||||
swagger2markup.interDocumentCrossReferencesEnabled=false
|
||||
swagger2markup.flatBodyEnabled=false
|
||||
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
|
||||
@@ -1,52 +0,0 @@
|
||||
definitions=Definitions
|
||||
|
||||
default_column=Default
|
||||
example_column=Example
|
||||
required_column=Required
|
||||
schema_column=Schema
|
||||
name_column=Name
|
||||
description_column=Description
|
||||
headers_column=Headers
|
||||
scopes_column=Scopes
|
||||
produces=Produces
|
||||
consumes=Consumes
|
||||
tags=Tags
|
||||
|
||||
overview=Overview
|
||||
current_version=Version information
|
||||
version=Version
|
||||
contact_information=Contact information
|
||||
contact_name=Contact
|
||||
contact_email=Contact Email
|
||||
license_information=License information
|
||||
license=License
|
||||
license_url=License URL
|
||||
terms_of_service=Terms of service
|
||||
uri_scheme=URI scheme
|
||||
host=Host
|
||||
base_path=BasePath
|
||||
schemes=Schemes
|
||||
security_type=Type
|
||||
security_name=Name
|
||||
security_in=In
|
||||
security_flow=Flow
|
||||
security_authorizationUrl=Token URL
|
||||
security_tokenUrl=Token URL
|
||||
|
||||
paths=Paths
|
||||
resources=Resources
|
||||
security=Security
|
||||
parameters=Parameters
|
||||
body_parameter=Body parameter
|
||||
responses=Responses
|
||||
response=Response
|
||||
request=Request
|
||||
example_request=Example HTTP request
|
||||
example_response=Example HTTP response
|
||||
type_column=Type
|
||||
http_code_column=HTTP Code
|
||||
parameter=Parameter
|
||||
|
||||
unknown=Unknown
|
||||
no_content=No Content
|
||||
operation.deprecated=This operation is deprecated.
|
||||
@@ -1,52 +0,0 @@
|
||||
definitions=D\u00E9finitions
|
||||
|
||||
default_column=D\u00E9faut
|
||||
example_column=Exemple
|
||||
required_column=Requis
|
||||
schema_column=Sch\u00E9ma
|
||||
name_column=Nom
|
||||
description_column=Description
|
||||
headers_column=En-t\u00EAtes
|
||||
scopes_column=P\u00E9rim\u00E8tre
|
||||
produces=Produit
|
||||
consumes=Consomme
|
||||
tags=Tags
|
||||
|
||||
overview=Vue g\u00E9n\u00E9rale
|
||||
current_version=Information de version
|
||||
version=Version
|
||||
contact_information=Information de contact
|
||||
contact_name=Contact
|
||||
contact_email=Email de contact
|
||||
license_information=Information de licence
|
||||
license=Licence
|
||||
license_url=Licence URL
|
||||
terms_of_service=Conditions de service
|
||||
uri_scheme=Sch\u00E9ma d'URI
|
||||
host=Serveur
|
||||
base_path=Chemin de base
|
||||
schemes=Sch\u00E9ma
|
||||
security_type=Type
|
||||
security_name=Nom
|
||||
security_in=Position
|
||||
security_flow=Flux
|
||||
security_authorizationUrl=URL d'autorisation
|
||||
security_tokenUrl=URL de jeton
|
||||
|
||||
paths=Op\u00E9rations
|
||||
resources=Ressources
|
||||
security=S\u00E9curit\u00E9
|
||||
parameters=Param\u00E8tres
|
||||
body_parameter=Contenu
|
||||
responses=R\u00E9ponses
|
||||
response=R\u00E9ponse
|
||||
request=Requ\u00EAte
|
||||
example_request=Exemple de requ\u00EAte HTTP
|
||||
example_response=Exemple de r\u00E9ponse HTTP
|
||||
type_column=Type
|
||||
http_code_column=Code HTTP
|
||||
parameter=Param\u00E8tre
|
||||
|
||||
unknown=Unknown
|
||||
no_content=Pas de contenu
|
||||
operation.deprecated=Cette op\u00E9ration est obsol\u00E8te.
|
||||
@@ -1,54 +0,0 @@
|
||||
definitions=\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044F
|
||||
json_schema=JSON \u0441\u0445\u0435\u043C\u0430
|
||||
xml_schema=XML \u0441\u0445\u0435\u043C\u0430
|
||||
|
||||
default_column=\u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E
|
||||
required_column=\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E
|
||||
example_column=\u041F\u0440\u0438\u043C\u0435\u0440
|
||||
schema_column=\u0421\u0445\u0435\u043C\u0430
|
||||
name_column=\u0418\u043C\u044F
|
||||
description_column=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435
|
||||
headers_column=Headers
|
||||
scopes_column=\u041E\u0431\u043B\u0430\u0441\u0442\u0438 \u043F\u0440\u0438\u043C\u0435\u043D\u0435\u043D\u0438\u044F
|
||||
produces=\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442
|
||||
consumes=\u041F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442
|
||||
tags=\u0422\u044D\u0433\u0438
|
||||
|
||||
overview=\u041E\u0431\u0437\u043E\u0440
|
||||
current_version=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0432\u0435\u0440\u0441\u0438\u0438
|
||||
version=\u0412\u0435\u0440\u0441\u0438\u044F\:\u0020
|
||||
contact_information=\u041A\u043E\u043D\u0442\u0430\u043A\u0442\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F
|
||||
contact_name=\u041A\u043E\u043D\u0442\u0430\u043A\u0442\:\u0020
|
||||
contact_email=Email \u043A\u043E\u043D\u0442\u0430\u043A\u0442\u0430\:\u0020
|
||||
license_information=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u043B\u0438\u0446\u0435\u043D\u0446\u0438\u0438
|
||||
license=\u041B\u0438\u0446\u0435\u043D\u0437\u0438\u044F\:\u0020
|
||||
license_url=URL \u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0438\:\u0020
|
||||
terms_of_service=\u0423\u0441\u043B\u043E\u0432\u0438\u044F \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\:\u0020
|
||||
uri_scheme=\u0421\u0445\u0435\u043C\u0430 URI
|
||||
host=\u0423\u0437\u0435\u043B\:\u0020
|
||||
base_path=\u041E\u0441\u043D\u043E\u0432\u043D\u043E\u0439 \u043F\u0443\u0442\u044C\:\u0020
|
||||
schemes=\u0421\u0445\u0435\u043C\u044B\:\u0020
|
||||
security_type=\u0422\u0438\u043F\:\u0020
|
||||
security_name=\u0418\u043C\u044F\:\u0020
|
||||
security_in=\u0421\u043E\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044F \u0432\:\u0020
|
||||
security_flow=\u041F\u043E\u0442\u043E\u043A\:\u0020
|
||||
security_authorizationUrl=URL \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u0438\:\u0020
|
||||
security_tokenUrl=URL \u0442\u043E\u043A\u0435\u043D\u0430\:\u0020
|
||||
|
||||
paths=\u041F\u0443\u0442\u0438
|
||||
resources=\u041E\u0442\u0432\u0435\u0442\u044B
|
||||
security=\u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u044C
|
||||
response=\u041E\u0442\u0432\u0435\u0442
|
||||
request=\u0417\u0430\u043F\u0440\u043E\u0441
|
||||
parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B
|
||||
body_parameter=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 \u0442\u0435\u043B\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u0430
|
||||
responses=\u041E\u0442\u0432\u0435\u0442\u044B
|
||||
example_request=\u041F\u0440\u0438\u043C\u0435\u0440 HTTP \u0437\u0430\u043F\u0440\u043E\u0441\u0430
|
||||
example_response=\u041F\u0440\u0438\u043C\u0435\u0440 HTTP \u0437\u0430\u043F\u0440\u043E\u0441\u0430
|
||||
type_column=\u0422\u0438\u043F
|
||||
http_code_column=HTTP \u043A\u043E\u0434
|
||||
parameter=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440
|
||||
|
||||
unknown=Unknown
|
||||
no_content=\u0411\u0435\u0437 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E
|
||||
operation.deprecated=\u042D\u0442\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u0430.
|
||||
@@ -1,459 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import io.github.robwin.swagger2markup.assertions.DiffUtils;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.SchemaExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.SpringRestDocsExtension;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
|
||||
import static org.assertj.core.api.BDDAssertions.assertThat;
|
||||
|
||||
public class AsciidocConverterTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AsciidocConverterTest.class);
|
||||
private static final String[] EXPECTED_FILES = new String[]{"definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"};
|
||||
private List<String> expectedFiles;
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionAsString() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
|
||||
//When
|
||||
String asciiDocAsString = Swagger2MarkupConverter.from(file).build()
|
||||
.asString();
|
||||
//Then
|
||||
assertThat(asciiDocAsString).isNotEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversion() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(file).withConfig(config).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/default").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversion.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionFromString() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/yaml/swagger_petstore.yaml"));
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(swaggerJsonString).withConfig(config).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/default").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversion.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithSpringRestDocsExtension() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/yaml/swagger_petstore.yaml"));
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
|
||||
.withExtension(new SpringRestDocsExtension(Paths.get("src/test/resources/docs/asciidoc/paths").toUri()).withDefaultSnippets())
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(swaggerJsonString)
|
||||
.withConfig(config)
|
||||
.withExtensionRegistry(registry)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/spring_rest_docs").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversionWithSpringRestDocsExtension.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithExamples() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(swaggerJsonString)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/examples").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversionWithExamples.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithGeneratedExamples() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withGeneratedExamples()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(swaggerJsonString)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/generated_examples").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversionWithGeneratedExamples.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocWithInlineSchema() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_inlineSchema.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withInlineSchemaDepthLevel(1)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/inline_schema").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocWithInlineSchema.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocGroupedByTags() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withPathsGroupedBy(GroupBy.TAGS)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/asciidoc/group_by_tags").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocGroupedByTags.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocGroupedByTagsWithMissingTag() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_missing_tag.json").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
//When
|
||||
try {
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withPathsGroupedBy(GroupBy.TAGS)
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
// If NullPointerException was not thrown, test would fail the specified message
|
||||
failBecauseExceptionWasNotThrown(NullPointerException.class);
|
||||
} catch (Exception e) {
|
||||
assertThat(e).hasMessage("Can't GroupBy.TAGS > Operation 'updatePet' has not tags");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithDefinitionDescriptions() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withDefinitionDescriptions(Paths.get("src/test/resources/docs/asciidoc/definitions"))
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionDoesNotContainUriScheme() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_should_not_contain_uri_scheme.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc"))))
|
||||
.doesNotContain("=== URI scheme");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionContainsUriScheme() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_should_contain_uri_scheme.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc"))))
|
||||
.contains("=== URI scheme");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithSeparatedDefinitions() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withSeparatedDefinitions()
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file).withConfig(config).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
expectedFiles.add("definitions");
|
||||
assertThat(files).hasSize(5).containsAll(expectedFiles);
|
||||
|
||||
Path definitionsDirectory = outputDirectory.resolve("definitions");
|
||||
String[] definitions = definitionsDirectory.toFile().list();
|
||||
assertThat(definitions).hasSize(5).containsAll(
|
||||
asList("Category.adoc", "Order.adoc", "Pet.adoc", "Tag.adoc", "User.adoc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithSeparatedOperations() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withSeparatedOperations()
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file).withConfig(config).build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
expectedFiles.add("operations");
|
||||
assertThat(files).hasSize(5).containsAll(expectedFiles);
|
||||
|
||||
Path pathsDirectory = outputDirectory.resolve("operations");
|
||||
String[] paths = pathsDirectory.toFile().list();
|
||||
assertThat(paths).hasSize(18);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithRussianOutputLanguage() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withOutputLanguage(Language.RU)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")), Charset.forName("UTF-8")))
|
||||
.contains("== Определения");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithFrenchOutputLanguage() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withOutputLanguage(Language.FR)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc")), Charset.forName("UTF-8")))
|
||||
.contains("== Sch\u00E9ma d'URI");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocExtensions() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.build();
|
||||
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
|
||||
.withExtension(new DynamicDefinitionsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")))
|
||||
.withExtension(new DynamicPathsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")))
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.withExtensionRegistry(registry)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("paths.adoc")))).contains(
|
||||
"Pet update request extension");
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")))).contains(
|
||||
"Pet extension");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocSchemaExtension() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.build();
|
||||
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
|
||||
.withExtension(new SchemaExtension(Paths.get("src/test/resources/docs/asciidoc/extensions").toUri()))
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.withExtensionRegistry(registry)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")))).contains(
|
||||
"=== Pet");
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")))).contains(
|
||||
"==== XML Schema");
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import io.swagger.models.Swagger;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class GeneralConverterTest {
|
||||
|
||||
@Test
|
||||
public void testConfigDefaultPaths() throws URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(GeneralConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withDefinitionDescriptions()
|
||||
.withOperationDescriptions()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build();
|
||||
|
||||
//Then
|
||||
URI baseUri = io.github.robwin.swagger2markup.internal.utils.IOUtils.uriParent(converter.getContext().getSwaggerLocation());
|
||||
assertThat(converter.getContext().getConfig().getDefinitionDescriptionsUri()).isEqualTo(baseUri);
|
||||
assertThat(converter.getContext().getConfig().getOperationDescriptionsUri()).isEqualTo(baseUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigDefaultPathsWithUri() throws MalformedURLException {
|
||||
//Given
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withDefinitionDescriptions()
|
||||
.withOperationDescriptions()
|
||||
.build();
|
||||
|
||||
Swagger2MarkupConverter converterBuilder = Swagger2MarkupConverter.from(URI.create("http://petstore.swagger.io/v2/swagger.json").toURL())
|
||||
.withConfig(config)
|
||||
.build();
|
||||
|
||||
//Then
|
||||
assertThat(converterBuilder.getContext().getConfig().getDefinitionDescriptionsUri()).isNull();
|
||||
assertThat(converterBuilder.getContext().getConfig().getOperationDescriptionsUri()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultPathsWithoutFile() {
|
||||
//Given
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withDefinitionDescriptions()
|
||||
.build();
|
||||
|
||||
//Then
|
||||
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(new Swagger())
|
||||
.withConfig(config)
|
||||
.build();
|
||||
assertThat(converter.getContext().getConfig().isDefinitionDescriptionsEnabled()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.assertions.DiffUtils;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.assertj.core.api.BDDAssertions.assertThat;
|
||||
|
||||
public class MarkdownConverterTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MarkdownConverterTest.class);
|
||||
|
||||
private static final String[] EXPECTED_FILES = new String[]{"definitions.md", "overview.md", "paths.md", "security.md"};
|
||||
private List<String> expectedFiles;
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversion() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected_results/markdown/default").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(outputDirectory, expectedFilesDirectory, "testSwagger2AsciiDocConversion.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversionWithDescriptions() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withDefinitionDescriptions(Paths.get("src/test/resources/docs/markdown/definitions"))
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversionWithSeparatedDefinitions() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withSeparatedDefinitions()
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
expectedFiles.add("definitions");
|
||||
assertThat(files).hasSize(5).containsAll(expectedFiles);
|
||||
|
||||
Path definitionsDirectory = outputDirectory.resolve("definitions");
|
||||
String[] definitions = definitionsDirectory.toFile().list();
|
||||
assertThat(definitions).hasSize(5).containsAll(
|
||||
asList("Category.md", "Order.md", "Pet.md", "Tag.md", "User.md"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversionHandlesComposition() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withSeparatedDefinitions()
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
// Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
expectedFiles.add("definitions");
|
||||
assertThat(files).hasSize(5).containsAll(expectedFiles);
|
||||
Path definitionsDirectory = outputDirectory.resolve("definitions");
|
||||
verifyMarkdownContainsFieldsInTables(
|
||||
definitionsDirectory.resolve("User.md").toFile(),
|
||||
ImmutableMap.<String, Set<String>>builder()
|
||||
.put("User", ImmutableSet.of("id", "username", "firstName",
|
||||
"lastName", "email", "password", "phone", "userStatus"))
|
||||
.build()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownExtensions() throws IOException, URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults()
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
|
||||
.build();
|
||||
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofEmpty()
|
||||
.withExtension(new DynamicDefinitionsDocumentExtension(Paths.get("src/test/resources/docs/markdown/extensions")))
|
||||
.withExtension(new DynamicPathsDocumentExtension(Paths.get("src/test/resources/docs/markdown/extensions")))
|
||||
.build();
|
||||
Swagger2MarkupConverter.from(file)
|
||||
.withConfig(config)
|
||||
.withExtensionRegistry(registry)
|
||||
.build()
|
||||
.intoFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("paths.md")))).contains(
|
||||
"Pet update request extension");
|
||||
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.md")))).contains(
|
||||
"Pet extension");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a markdown document to search, this checks to see if the specified tables
|
||||
* have all of the expected fields listed.
|
||||
*
|
||||
* @param doc markdown document file to inspect
|
||||
* @param fieldsByTable map of table name (header) to field names expected
|
||||
* to be found in that table.
|
||||
* @throws IOException if the markdown document could not be read
|
||||
*/
|
||||
private static void verifyMarkdownContainsFieldsInTables(File doc, Map<String, Set<String>> fieldsByTable) throws IOException {
|
||||
final List<String> lines = Files.readAllLines(doc.toPath(), Charset.defaultCharset());
|
||||
final Map<String, Set<String>> fieldsLeftByTable = Maps.newHashMap();
|
||||
for (Map.Entry<String, Set<String>> entry : fieldsByTable.entrySet()) {
|
||||
fieldsLeftByTable.put(entry.getKey(), Sets.newHashSet(entry.getValue()));
|
||||
}
|
||||
String inTable = null;
|
||||
for (String line : lines) {
|
||||
// If we've found every field we care about, quit early
|
||||
if (fieldsLeftByTable.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Transition to a new table if we encounter a header
|
||||
final String currentHeader = getTableHeader(line);
|
||||
if (inTable == null || currentHeader != null) {
|
||||
inTable = currentHeader;
|
||||
}
|
||||
|
||||
// If we're in a table that we care about, inspect this potential table row
|
||||
if (inTable != null && fieldsLeftByTable.containsKey(inTable)) {
|
||||
// If we're still in a table, read the row and check for the field name
|
||||
// NOTE: If there was at least one pipe, then there's at least 2 fields
|
||||
String[] parts = line.split("\\|");
|
||||
if (parts.length > 1) {
|
||||
final String fieldName = parts[1];
|
||||
final Set<String> fieldsLeft = fieldsLeftByTable.get(inTable);
|
||||
// Mark the field as found and if this table has no more fields to find,
|
||||
// remove it from the "fieldsLeftByTable" map to mark the table as done
|
||||
if (fieldsLeft.remove(fieldName) && fieldsLeft.isEmpty()) {
|
||||
fieldsLeftByTable.remove(inTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After reading the file, if there were still types, fail
|
||||
if (!fieldsLeftByTable.isEmpty()) {
|
||||
fail(String.format("Markdown file '%s' did not contain expected fields (by table): %s",
|
||||
doc, fieldsLeftByTable));
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTableHeader(String line) {
|
||||
return line.startsWith("###")
|
||||
? line.replace("###", "").trim()
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.assertThat;
|
||||
|
||||
public class Swagger2MarkupConfigTest {
|
||||
|
||||
@Test
|
||||
public void testConfigOfDefaults() {
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofDefaults().build();
|
||||
|
||||
assertThat(config.getAnchorPrefix()).isNull();
|
||||
assertThat(config.getDefinitionOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getDefinitionOrdering()).isEqualTo(Ordering.natural());
|
||||
assertThat(config.getDefinitionsDocument()).isEqualTo("definitions");
|
||||
assertThat(config.isOperationDescriptionsEnabled()).isFalse();
|
||||
assertThat(config.getOperationDescriptionsUri()).isNull();
|
||||
assertThat(config.isDefinitionDescriptionsEnabled()).isFalse();
|
||||
assertThat(config.getDefinitionDescriptionsUri()).isNull();
|
||||
assertThat(config.isGeneratedExamplesEnabled()).isFalse();
|
||||
assertThat(config.getInlineSchemaDepthLevel()).isEqualTo(0);
|
||||
assertThat(config.getInterDocumentCrossReferencesPrefix()).isNull();
|
||||
assertThat(config.getMarkupLanguage()).isEqualTo(MarkupLanguage.ASCIIDOC);
|
||||
assertThat(config.getOperationOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getOperationOrdering()).isNotNull();
|
||||
assertThat(config.getOutputLanguage()).isEqualTo(Language.EN);
|
||||
assertThat(config.getOverviewDocument()).isEqualTo("overview");
|
||||
assertThat(config.getParameterOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getParameterOrdering()).isEqualTo(Swagger2MarkupConfig.Builder.PARAMETER_IN_NATURAL_ORDERING.compound(Swagger2MarkupConfig.Builder.PARAMETER_NAME_NATURAL_ORDERING));
|
||||
assertThat(config.getPathsDocument()).isEqualTo("paths");
|
||||
assertThat(config.getOperationsGroupedBy()).isEqualTo(GroupBy.AS_IS);
|
||||
assertThat(config.getPropertyOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getPropertyOrdering()).isEqualTo(Ordering.natural());
|
||||
assertThat(config.getResponseOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getResponseOrdering()).isEqualTo(Ordering.natural());
|
||||
assertThat(config.getSecurityDocument()).isEqualTo("security");
|
||||
assertThat(config.getSeparatedDefinitionsFolder()).isEqualTo("definitions");
|
||||
assertThat(config.getSeparatedOperationsFolder()).isEqualTo("operations");
|
||||
assertThat(config.getTagOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getTagOrdering()).isEqualTo(Ordering.natural());
|
||||
assertThat(config.isFlatBodyEnabled()).isFalse();
|
||||
assertThat(config.isInterDocumentCrossReferencesEnabled()).isFalse();
|
||||
assertThat(config.isSeparatedDefinitionsEnabled()).isFalse();
|
||||
assertThat(config.isSeparatedOperationsEnabled()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfigOfProperties() throws IOException {
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.load(Swagger2MarkupConfigTest.class.getResourceAsStream("/config/config.properties"));
|
||||
|
||||
Swagger2MarkupConfig config = Swagger2MarkupConfig.ofProperties(properties).build();
|
||||
|
||||
assertThat(config.getAnchorPrefix()).isEqualTo("anchorPrefix");
|
||||
assertThat(config.getDefinitionOrderBy()).isEqualTo(OrderBy.AS_IS);
|
||||
assertThat(config.getDefinitionOrdering()).isNull();
|
||||
assertThat(config.getDefinitionsDocument()).isEqualTo("definitionsTest");
|
||||
assertThat(config.isOperationDescriptionsEnabled()).isTrue();
|
||||
assertThat(config.getOperationDescriptionsUri()).isEqualTo(URI.create("operationDescriptions"));
|
||||
assertThat(config.isDefinitionDescriptionsEnabled()).isTrue();
|
||||
assertThat(config.getDefinitionDescriptionsUri()).isEqualTo(URI.create("definitionDescriptions"));
|
||||
assertThat(config.isGeneratedExamplesEnabled()).isTrue();
|
||||
assertThat(config.getInlineSchemaDepthLevel()).isEqualTo(2);
|
||||
assertThat(config.getInterDocumentCrossReferencesPrefix()).isEqualTo("xrefPrefix");
|
||||
assertThat(config.getMarkupLanguage()).isEqualTo(MarkupLanguage.MARKDOWN);
|
||||
assertThat(config.getOperationOrderBy()).isEqualTo(OrderBy.NATURAL);
|
||||
assertThat(config.getOperationOrdering()).isEqualTo(Swagger2MarkupConfig.Builder.OPERATION_PATH_NATURAL_ORDERING.compound(Swagger2MarkupConfig.Builder.OPERATION_METHOD_NATURAL_ORDERING));
|
||||
assertThat(config.getOutputLanguage()).isEqualTo(Language.RU);
|
||||
assertThat(config.getOverviewDocument()).isEqualTo("overviewTest");
|
||||
assertThat(config.getParameterOrderBy()).isEqualTo(OrderBy.AS_IS);
|
||||
assertThat(config.getParameterOrdering()).isNull();
|
||||
assertThat(config.getPathsDocument()).isEqualTo("pathsTest");
|
||||
assertThat(config.getOperationsGroupedBy()).isEqualTo(GroupBy.TAGS);
|
||||
assertThat(config.getPropertyOrderBy()).isEqualTo(OrderBy.AS_IS);
|
||||
assertThat(config.getPropertyOrdering()).isNull();
|
||||
assertThat(config.getResponseOrderBy()).isEqualTo(OrderBy.AS_IS);
|
||||
assertThat(config.getResponseOrdering()).isNull();
|
||||
assertThat(config.getSecurityDocument()).isEqualTo("securityTest");
|
||||
assertThat(config.getSeparatedDefinitionsFolder()).isEqualTo("definitionsTest");
|
||||
assertThat(config.getSeparatedOperationsFolder()).isEqualTo("operationsTest");
|
||||
assertThat(config.getTagOrderBy()).isEqualTo(OrderBy.AS_IS);
|
||||
assertThat(config.getTagOrdering()).isNull();
|
||||
assertThat(config.isFlatBodyEnabled()).isTrue();
|
||||
assertThat(config.isInterDocumentCrossReferencesEnabled()).isTrue();
|
||||
assertThat(config.isSeparatedDefinitionsEnabled()).isTrue();
|
||||
assertThat(config.isSeparatedOperationsEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigBuilder() {
|
||||
Swagger2MarkupConfig.Builder builder = Swagger2MarkupConfig.ofDefaults();
|
||||
|
||||
try {
|
||||
builder.withTagOrdering(OrderBy.CUSTOM);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
}
|
||||
builder.withTagOrdering(Ordering.<String>natural());
|
||||
assertThat(builder.config.getTagOrderBy()).isEqualTo(OrderBy.CUSTOM);
|
||||
assertThat(builder.config.getTagOrdering()).isEqualTo(Ordering.natural());
|
||||
|
||||
try {
|
||||
builder.withOperationOrdering(OrderBy.CUSTOM);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
}
|
||||
builder.withOperationOrdering(Swagger2MarkupConfig.Builder.OPERATION_PATH_NATURAL_ORDERING);
|
||||
assertThat(builder.config.getOperationOrderBy()).isEqualTo(OrderBy.CUSTOM);
|
||||
assertThat(builder.config.getOperationOrdering()).isEqualTo(Swagger2MarkupConfig.Builder.OPERATION_PATH_NATURAL_ORDERING);
|
||||
|
||||
try {
|
||||
builder.withDefinitionOrdering(OrderBy.CUSTOM);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
}
|
||||
builder.withDefinitionOrdering(Ordering.<String>natural());
|
||||
assertThat(builder.config.getDefinitionOrderBy()).isEqualTo(OrderBy.CUSTOM);
|
||||
assertThat(builder.config.getDefinitionOrdering()).isEqualTo(Ordering.natural());
|
||||
|
||||
try {
|
||||
builder.withParameterOrdering(OrderBy.CUSTOM);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
}
|
||||
builder.withParameterOrdering(Swagger2MarkupConfig.Builder.PARAMETER_NAME_NATURAL_ORDERING);
|
||||
assertThat(builder.config.getParameterOrderBy()).isEqualTo(OrderBy.CUSTOM);
|
||||
assertThat(builder.config.getParameterOrdering()).isEqualTo(Swagger2MarkupConfig.Builder.PARAMETER_NAME_NATURAL_ORDERING);
|
||||
|
||||
try {
|
||||
builder.withPropertyOrdering(OrderBy.CUSTOM);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
}
|
||||
builder.withPropertyOrdering(Ordering.<String>natural());
|
||||
assertThat(builder.config.getPropertyOrderBy()).isEqualTo(OrderBy.CUSTOM);
|
||||
assertThat(builder.config.getPropertyOrdering()).isEqualTo(Ordering.natural());
|
||||
|
||||
try {
|
||||
builder.withResponseOrdering(OrderBy.CUSTOM);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("You must provide a custom comparator if orderBy == OrderBy.CUSTOM");
|
||||
}
|
||||
builder.withResponseOrdering(Ordering.<String>natural());
|
||||
assertThat(builder.config.getResponseOrderBy()).isEqualTo(OrderBy.CUSTOM);
|
||||
assertThat(builder.config.getResponseOrdering()).isEqualTo(Ordering.natural());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.assertions;
|
||||
|
||||
|
||||
import com.sksamuel.diffpatch.DiffMatchPatch;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class DiffAssert extends AbstractAssert<DiffAssert, Path>{
|
||||
|
||||
public DiffAssert(Path actual) {
|
||||
super(actual, DiffAssert.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the content of the actual File is equal to the given one.
|
||||
*
|
||||
* @param expected the given value to compare the actual value to.
|
||||
* @param reportPath the path to the report which should be generated if the files differ.
|
||||
* @return {@code this} assertion object.
|
||||
* @throws AssertionError if the actual value is not equal to the given one or if the actual value is {@code null}..
|
||||
*/
|
||||
public DiffAssert isEqualTo(Path expected, Path reportPath) {
|
||||
LinkedList<DiffMatchPatch.Diff> diffs = diff(actual, expected);
|
||||
boolean allDiffsAreEqual = assertThatAllDiffsAreEqual(diffs);
|
||||
if(!allDiffsAreEqual){
|
||||
writeHtmlReport(reportPath, diffs);
|
||||
}
|
||||
assertThat(allDiffsAreEqual).as("The content of the following files differ. Actual: %s, Expected %s. Check the HTML report for more details: %s", actual.toAbsolutePath(), expected.toAbsolutePath(), reportPath.toAbsolutePath()).isTrue();
|
||||
return myself;
|
||||
}
|
||||
|
||||
public boolean assertThatAllDiffsAreEqual(LinkedList<DiffMatchPatch.Diff> diffs){
|
||||
for(DiffMatchPatch.Diff diff : diffs){
|
||||
if(diff.operation == DiffMatchPatch.Operation.DELETE || diff.operation == DiffMatchPatch.Operation.INSERT){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static LinkedList<DiffMatchPatch.Diff> diff(Path actual, Path expected){
|
||||
DiffMatchPatch differ = new DiffMatchPatch();
|
||||
try {
|
||||
return differ.diff_main(IOUtils.toString(expected.toUri()), IOUtils.toString(actual.toUri()), false);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to diff files.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeHtmlReport(Path reportPath, LinkedList<DiffMatchPatch.Diff> diffs){
|
||||
DiffMatchPatch differ = new DiffMatchPatch();
|
||||
try {
|
||||
Files.createDirectories(reportPath.getParent());
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(reportPath, Charset.forName("UTF-8"))) {
|
||||
writer.write(differ.diff_prettyHtml(diffs));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(String.format("Failed to write report %s", reportPath.toAbsolutePath()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.assertions;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Entry point for assertion methods for diffing files.
|
||||
*
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class DiffAssertions {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>{@link DiffAssert}</code>.
|
||||
*
|
||||
* @param actual the the actual File path.
|
||||
* @return the created assertion object.
|
||||
*/
|
||||
|
||||
public static DiffAssert assertThat(Path actual) {
|
||||
Validate.notNull(actual, "actual must not be null");
|
||||
return new DiffAssert(actual);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.assertions;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class DiffUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DiffUtils.class);
|
||||
|
||||
public static void assertThatAllFilesAreEqual(Path actualDirectory, Path expectedDirectory, String reportName) {
|
||||
Path reportPath = Paths.get("build/diff-report/", reportName);
|
||||
try {
|
||||
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(actualDirectory)) {
|
||||
for (Path actualFile : directoryStream) {
|
||||
Path expectedFile = expectedDirectory.resolve(actualFile.getFileName());
|
||||
LOGGER.info("Diffing file {} with {}", actualFile, expectedFile);
|
||||
DiffAssertions.assertThat(actualFile).isEqualTo(expectedFile, reportPath);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to assert that all files are equal", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.swagger.models.Swagger;
|
||||
|
||||
public class MySwaggerModelExtension extends SwaggerModelExtension {
|
||||
|
||||
public MySwaggerModelExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void apply(Swagger swagger) {
|
||||
swagger.setHost("host.domain.tld");
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.spi;
|
||||
|
||||
import io.github.robwin.swagger2markup.Swagger2MarkupExtensionRegistry;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicDefinitionsDocumentExtension;
|
||||
import io.github.robwin.swagger2markup.internal.extensions.DynamicPathsDocumentExtension;
|
||||
import io.swagger.models.Swagger;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
public class Swagger2MarkupExtensionRegistryTest {
|
||||
|
||||
@Test
|
||||
public void testRegistering() {
|
||||
Swagger2MarkupExtensionRegistry.Builder registryBuilder = Swagger2MarkupExtensionRegistry.ofDefaults();
|
||||
|
||||
registryBuilder.withExtension(new MySwaggerModelExtension());
|
||||
registryBuilder.withExtension(new DynamicDefinitionsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")));
|
||||
registryBuilder.withExtension(new DynamicPathsDocumentExtension(Paths.get("src/test/resources/docs/asciidoc/extensions")));
|
||||
|
||||
try {
|
||||
registryBuilder.withExtension(new AbstractExtension() {
|
||||
});
|
||||
fail("No IllegalArgumentException thrown");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("Provided extension class does not extend any of the supported extension points");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListing() {
|
||||
Extension ext1 = new MySwaggerModelExtension();
|
||||
Extension ext2 = new MySwaggerModelExtension();
|
||||
Extension ext3 = new SwaggerModelExtension() {
|
||||
public void apply(Swagger swagger) {
|
||||
}
|
||||
};
|
||||
|
||||
Swagger2MarkupExtensionRegistry registry = Swagger2MarkupExtensionRegistry.ofDefaults()
|
||||
.withExtension(ext2)
|
||||
.withExtension(ext3)
|
||||
.withExtension(ext1)
|
||||
.build();
|
||||
List<Extension> extensions = registry.getExtensions(Extension.class);
|
||||
assertThat(extensions.size()).isEqualTo(7);
|
||||
assertThat(extensions).contains(ext1, ext2, ext3);
|
||||
assertThat(registry.getExtensions(SwaggerModelExtension.class)).isEqualTo(Arrays.asList(ext2, ext3, ext1));
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
swagger2markup.markupLanguage=MARKDOWN
|
||||
swagger2markup.generatedExamplesEnabled=true
|
||||
swagger2markup.operationDescriptionsEnabled=true
|
||||
swagger2markup.operationDescriptionsUri=operationDescriptions
|
||||
swagger2markup.definitionDescriptionsEnabled=true
|
||||
swagger2markup.definitionDescriptionsUri=definitionDescriptions
|
||||
swagger2markup.separatedDefinitionsEnabled=true
|
||||
swagger2markup.separatedOperationsEnabled=true
|
||||
swagger2markup.operationsGroupedBy=TAGS
|
||||
swagger2markup.outputLanguage=RU
|
||||
swagger2markup.inlineSchemaDepthLevel=2
|
||||
swagger2markup.interDocumentCrossReferencesEnabled=true
|
||||
swagger2markup.interDocumentCrossReferencesPrefix=xrefPrefix
|
||||
swagger2markup.flatBodyEnabled=true
|
||||
swagger2markup.anchorPrefix=anchorPrefix
|
||||
swagger2markup.overviewDocument=overviewTest
|
||||
swagger2markup.pathsDocument=pathsTest
|
||||
swagger2markup.definitionsDocument=definitionsTest
|
||||
swagger2markup.securityDocument=securityTest
|
||||
swagger2markup.separatedOperationsFolder=operationsTest
|
||||
swagger2markup.separatedDefinitionsFolder=definitionsTest
|
||||
swagger2markup.tagOrderBy=AS_IS
|
||||
swagger2markup.operationOrderBy=NATURAL
|
||||
swagger2markup.definitionOrderBy=AS_IS
|
||||
swagger2markup.parameterOrderBy=AS_IS
|
||||
swagger2markup.propertyOrderBy=AS_IS
|
||||
swagger2markup.responseOrderBy=AS_IS
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
This is a hand-written description.
|
||||
AsciiDoc is better suited for descriptions than:
|
||||
|
||||
* JavaDoc
|
||||
* Annotations
|
||||
@@ -1 +0,0 @@
|
||||
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*
|
||||