Compare commits
701 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac22f63404 | ||
|
|
aeaab37c8a | ||
|
|
8dd6426f90 | ||
|
|
198bcfe22f | ||
|
|
3614b469d6 | ||
|
|
7d28f3344c | ||
|
|
32a42b1da5 | ||
|
|
a9e18732c8 | ||
|
|
5b56e1af8a | ||
|
|
352977eef5 | ||
|
|
743624ee77 | ||
|
|
5f910fd564 | ||
|
|
fb03267275 | ||
|
|
c665d1f5cd | ||
|
|
da23c929c0 | ||
|
|
7141fc094b | ||
|
|
f6152f6c9b | ||
|
|
9f89c40280 | ||
|
|
f60999dd9f | ||
|
|
a45caa4d19 | ||
|
|
9de5ad0157 | ||
|
|
61df613cd2 | ||
|
|
b70d6ca9ca | ||
|
|
0e15676cb7 | ||
|
|
5f419a0d02 | ||
|
|
a0efe7dd26 | ||
|
|
21afb5adcd | ||
|
|
7d0d73cd51 | ||
|
|
e8a51345a8 | ||
|
|
f471774da9 | ||
|
|
0facccf009 | ||
|
|
835c8fec03 | ||
|
|
eea093acd4 | ||
|
|
b32bfb3e54 | ||
|
|
65f330baae | ||
|
|
b43a677744 | ||
|
|
4b69d6a150 | ||
|
|
4a3ee6c5ca | ||
|
|
69baeb6339 | ||
|
|
f7fe2b0cca | ||
|
|
f853550748 | ||
|
|
75fa8f788c | ||
|
|
7a86fdaba3 | ||
|
|
1566b22489 | ||
|
|
ed026f3587 | ||
|
|
6e8e4ce780 | ||
|
|
60b7d90ad2 | ||
|
|
da83465f19 | ||
|
|
7ae0b64d8e | ||
|
|
f8cbf7801d | ||
|
|
7fbd49c5ea | ||
|
|
8717e26f76 | ||
|
|
483d6c3d17 | ||
|
|
03fb52fb8e | ||
|
|
e574f0e65f | ||
|
|
e9b04c712d | ||
|
|
b4c7c8860c | ||
|
|
815c161b7e | ||
|
|
ecaaaeb049 | ||
|
|
647846762d | ||
|
|
655a15c722 | ||
|
|
6297b859dd | ||
|
|
19f05c68f8 | ||
|
|
5a12bd9cce | ||
|
|
e22b374bdd | ||
|
|
fe3749d499 | ||
|
|
85ef7f252d | ||
|
|
f16b563a82 | ||
|
|
8e22dd817e | ||
|
|
569f3c02cd | ||
|
|
e8c2099e4c | ||
|
|
1646fefd56 | ||
|
|
aad387802e | ||
|
|
034d0a2f50 | ||
|
|
d2c78304c6 | ||
|
|
247857a843 | ||
|
|
038ff3a40e | ||
|
|
6d8776332f | ||
|
|
4ea24b0297 | ||
|
|
12570ecb00 | ||
|
|
7b68aecbd7 | ||
|
|
7ce62a8a3d | ||
|
|
d8c3cf725d | ||
|
|
aecc531d84 | ||
|
|
f107779542 | ||
|
|
70bf17011c | ||
|
|
86ae19fe2a | ||
|
|
e8235c4c35 | ||
|
|
63b5cd3bfb | ||
|
|
12e851c127 | ||
|
|
20fa72b613 | ||
|
|
36bee8070a | ||
|
|
9a85612b8a | ||
|
|
2bc18f7d90 | ||
|
|
6f6428543d | ||
|
|
d03087c1b8 | ||
|
|
d2d47cf8ee | ||
|
|
7a0f4490de | ||
|
|
d2b3c9472a | ||
|
|
3a0b9a00a3 | ||
|
|
d5cf4ad9e5 | ||
|
|
2899b2f263 | ||
|
|
7475321e97 | ||
|
|
88a24d7bdd | ||
|
|
f798a51edc | ||
|
|
81edab38f3 | ||
|
|
039607a294 | ||
|
|
2f33522e6d | ||
|
|
76c54a713a | ||
|
|
dcebed2d42 | ||
|
|
dbf9afa8da | ||
|
|
f7f397b5f2 | ||
|
|
44f852ad42 | ||
|
|
e1be2f2130 | ||
|
|
8468607703 | ||
|
|
f981318142 | ||
|
|
e1d0d7b293 | ||
|
|
d118a0cf74 | ||
|
|
7cb1095465 | ||
|
|
595b885b9a | ||
|
|
b1c219bc1b | ||
|
|
852b2ac3b4 | ||
|
|
937cded2aa | ||
|
|
022d2453d2 | ||
|
|
e5a187cc24 | ||
|
|
83bb63321a | ||
|
|
cd5b5c9240 | ||
|
|
2096ec0d5d | ||
|
|
25d4311237 | ||
|
|
7e07c2fc81 | ||
|
|
5a8a618e6b | ||
|
|
f072fc99b9 | ||
|
|
54e881fc58 | ||
|
|
cd6a3ed724 | ||
|
|
5a00dde912 | ||
|
|
876d7b2f7b | ||
|
|
4b74ec0e54 | ||
|
|
a719e33332 | ||
|
|
86a727f097 | ||
|
|
2670780076 | ||
|
|
ebf9912269 | ||
|
|
11549ab64e | ||
|
|
d128146952 | ||
|
|
686abd8842 | ||
|
|
551aeed835 | ||
|
|
5b1a1a2bcf | ||
|
|
09d2474a9a | ||
|
|
5c00e5493c | ||
|
|
c343af8f5a | ||
|
|
4af7eb5b89 | ||
|
|
aa9a340144 | ||
|
|
35ae68ceee | ||
|
|
560fb4ece6 | ||
|
|
8eb494cd5b | ||
|
|
0766336a56 | ||
|
|
24352f4d1c | ||
|
|
adb0fee973 | ||
|
|
13a7113aa7 | ||
|
|
e882975726 | ||
|
|
12209fe923 | ||
|
|
8a63744198 | ||
|
|
5871f0c9b0 | ||
|
|
908f524c64 | ||
|
|
9fa0ee3def | ||
|
|
35e9450f74 | ||
|
|
6033ea5a98 | ||
|
|
6f24c3cb39 | ||
|
|
e975e49d3e | ||
|
|
c5cfe10fa6 | ||
|
|
7c988460f0 | ||
|
|
21f1892de0 | ||
|
|
b97344849d | ||
|
|
935d48d4cc | ||
|
|
73ba233f9e | ||
|
|
ff955d392b | ||
|
|
19fde31f67 | ||
|
|
b3f368ac37 | ||
|
|
c5efb401b4 | ||
|
|
f386e6ed91 | ||
|
|
55b323c063 | ||
|
|
6f286b52d8 | ||
|
|
4850673b96 | ||
|
|
353af537ba | ||
|
|
2367d86eb7 | ||
|
|
1aec46a57c | ||
|
|
f650fb7b3e | ||
|
|
568d6a6441 | ||
|
|
630e86cd31 | ||
|
|
0e3e229434 | ||
|
|
f41d1cbcb0 | ||
|
|
20b653086d | ||
|
|
ae4cf35de4 | ||
|
|
86fc9a9746 | ||
|
|
1b4626d9ca | ||
|
|
7528b34ba3 | ||
|
|
ebecde1768 | ||
|
|
2301de6466 | ||
|
|
f7efad2480 | ||
|
|
c23bd01495 | ||
|
|
7e5986237a | ||
|
|
1bf26c95e3 | ||
|
|
3888e67d02 | ||
|
|
54e17321b6 | ||
|
|
90f56cfe61 | ||
|
|
44e33ad6f3 | ||
|
|
65d4e0c225 | ||
|
|
d37a374d02 | ||
|
|
5bb5e5ff29 | ||
|
|
de1f84d2aa | ||
|
|
aa35c0169c | ||
|
|
b53727842a | ||
|
|
f88e3d2ed4 | ||
|
|
eefda62d99 | ||
|
|
592446f714 | ||
|
|
3275a07325 | ||
|
|
1c2b9eee26 | ||
|
|
3a5533447b | ||
|
|
2fcd2d1a79 | ||
|
|
07d878be35 | ||
|
|
7a75d7874b | ||
|
|
99c3044218 | ||
|
|
fec5fb54bb | ||
|
|
031051f1f9 | ||
|
|
d432c398cf | ||
|
|
8eb44c26d2 | ||
|
|
3a76a3e920 | ||
|
|
52e80e7af6 | ||
|
|
1eac6a63d9 | ||
|
|
6e379042a0 | ||
|
|
8367195315 | ||
|
|
7de954958d | ||
|
|
a161924a7f | ||
|
|
9568f3a960 | ||
|
|
fdb24fdf33 | ||
|
|
3c0f935e99 | ||
|
|
826f4ff762 | ||
|
|
ed926139b8 | ||
|
|
cb23bfe1a4 | ||
|
|
ab7d355fe4 | ||
|
|
87ccc182f1 | ||
|
|
ff21d7c985 | ||
|
|
b69797ef51 | ||
|
|
f1614fe81a | ||
|
|
d5c9116dc7 | ||
|
|
5aaff59f71 | ||
|
|
a20ed66400 | ||
|
|
6312c2f3e0 | ||
|
|
2e2bd7d6c5 | ||
|
|
dd7de8fe08 | ||
|
|
934039bcd4 | ||
|
|
98efe9543d | ||
|
|
b68c0031a7 | ||
|
|
a587899976 | ||
|
|
4528f2aa0e | ||
|
|
b2e6f498be | ||
|
|
d32179009d | ||
|
|
c815318972 | ||
|
|
7cbb52094d | ||
|
|
7c8dfb520f | ||
|
|
6395adddb6 | ||
|
|
01a63f895c | ||
|
|
5d2ba5b21e | ||
|
|
6e4c0c1498 | ||
|
|
dce6b4183a | ||
|
|
1bf36592ef | ||
|
|
24d9218d14 | ||
|
|
9ee6c96a3a | ||
|
|
507307308d | ||
|
|
14d4268cc3 | ||
|
|
aade4453e1 | ||
|
|
232a635c06 | ||
|
|
545cf13584 | ||
|
|
b7ef781fda | ||
|
|
3f18a446af | ||
|
|
391bb20de2 | ||
|
|
aafac7821c | ||
|
|
103aef6cd6 | ||
|
|
6282459905 | ||
|
|
293132e6a4 | ||
|
|
0e4b193d70 | ||
|
|
277e452a73 | ||
|
|
80e96933b0 | ||
|
|
1ab4f8ff6c | ||
|
|
9a67581ad9 | ||
|
|
9ef34dd853 | ||
|
|
b37c173e07 | ||
|
|
105ac545b3 | ||
|
|
ae3f9aa353 | ||
|
|
3e9fca8a0d | ||
|
|
1a45054b5d | ||
|
|
be56290257 | ||
|
|
64195e095b | ||
|
|
5a33b3473e | ||
|
|
df23dc09e8 | ||
|
|
2a3ac1e6d0 | ||
|
|
bad8cde186 | ||
|
|
d9adcc2016 | ||
|
|
7b59a069ef | ||
|
|
310a2e47b6 | ||
|
|
954e302467 | ||
|
|
abb77b7c5f | ||
|
|
aaac78f985 | ||
|
|
e959c9ed59 | ||
|
|
1965110df9 | ||
|
|
1300249555 | ||
|
|
05a4ee230c | ||
|
|
78411de398 | ||
|
|
e697815c0c | ||
|
|
fbd22779ee | ||
|
|
b13c57ea35 | ||
|
|
0b38f2a91c | ||
|
|
db36397e81 | ||
|
|
066fd597da | ||
|
|
e979d2b45b | ||
|
|
4fa9f0d645 | ||
|
|
fecf6c6161 | ||
|
|
7eecba583d | ||
|
|
9c6111da3e | ||
|
|
f10882d14d | ||
|
|
0ac9e13948 | ||
|
|
fb3ef974a3 | ||
|
|
65522e4569 | ||
|
|
ae8961d43c | ||
|
|
c131a8cad8 | ||
|
|
7ad8ef8d18 | ||
|
|
539520903f | ||
|
|
566300a598 | ||
|
|
b64bbee4b4 | ||
|
|
8c005466c6 | ||
|
|
d222e01466 | ||
|
|
d692f616ba | ||
|
|
656ebde58c | ||
|
|
4973f9674a | ||
|
|
9fe3bf9ec0 | ||
|
|
074794830f | ||
|
|
1f4fd9f115 | ||
|
|
82ac10c7a5 | ||
|
|
505b9047ba | ||
|
|
735123749e | ||
|
|
df3c8f51d5 | ||
|
|
6de159fa7d | ||
|
|
119b190585 | ||
|
|
14c0be59dd | ||
|
|
fd2ae92663 | ||
|
|
a57b16504f | ||
|
|
ee36c1b9f3 | ||
|
|
928ec8b325 | ||
|
|
3d720f2c81 | ||
|
|
040c60a9ba | ||
|
|
2e874957fb | ||
|
|
3ed94986ed | ||
|
|
32f7561e26 | ||
|
|
dbaaa195b5 | ||
|
|
7f01e9beaa | ||
|
|
2e95cf6b25 | ||
|
|
23314507db | ||
|
|
cfbff5402c | ||
|
|
6c6c625273 | ||
|
|
a66560a255 | ||
|
|
5ff5fc8f0f | ||
|
|
f001b5bb7c | ||
|
|
403b8fcfc7 | ||
|
|
456625ae4b | ||
|
|
5dd9163610 | ||
|
|
3953b3328a | ||
|
|
124be6c37a | ||
|
|
6fc474ac09 | ||
|
|
49ccad694e | ||
|
|
370fa5eb8d | ||
|
|
df61f140ca | ||
|
|
b80b16d03f | ||
|
|
97c75c306f | ||
|
|
30258c7e75 | ||
|
|
e66feb5a27 | ||
|
|
972f2c2d6d | ||
|
|
fcf46c1588 | ||
|
|
cd38ed01a4 | ||
|
|
5f965e6378 | ||
|
|
d20bce81f0 | ||
|
|
d9e2397f48 | ||
|
|
6fe35c34be | ||
|
|
05924c5813 | ||
|
|
b931d7f3af | ||
|
|
5b970eb2c8 | ||
|
|
52b5bf2361 | ||
|
|
8eee21baf0 | ||
|
|
e99656704f | ||
|
|
235e5b7ddf | ||
|
|
69e7992f3e | ||
|
|
29bfddc8d2 | ||
|
|
3fc8a897a1 | ||
|
|
451e377cac | ||
|
|
6379b3ccf1 | ||
|
|
456f27c85b | ||
|
|
c739649f20 | ||
|
|
3dceb21bd5 | ||
|
|
23331930cc | ||
|
|
da48f49a25 | ||
|
|
3775f26458 | ||
|
|
365d3278ff | ||
|
|
7cc9742530 | ||
|
|
0648a9cbea | ||
|
|
7766276abc | ||
|
|
19bc2dd0e2 | ||
|
|
6126260aae | ||
|
|
cdd0bc52e2 | ||
|
|
ccf3ee8e7d | ||
|
|
54147bbddb | ||
|
|
914fa2da0f | ||
|
|
d41b14bbff | ||
|
|
354d2167fb | ||
|
|
9eb7c671cd | ||
|
|
aee7708cd1 | ||
|
|
e3f946ecf8 | ||
|
|
c25b6be1f3 | ||
|
|
eff69079a6 | ||
|
|
8d8d4cd5d0 | ||
|
|
4bce1234af | ||
|
|
d892f0b39d | ||
|
|
831e949d91 | ||
|
|
d48b9c217b | ||
|
|
124a66aaa9 | ||
|
|
08eb6841fc | ||
|
|
e74ac9fda5 | ||
|
|
d4bbcc3acc | ||
|
|
9655e113c0 | ||
|
|
54c7682f00 | ||
|
|
7c8efa1060 | ||
|
|
0caf2d7a43 | ||
|
|
533590656f | ||
|
|
fe0fa8a9ce | ||
|
|
a85b695c80 | ||
|
|
251a6b7e73 | ||
|
|
08b0d085db | ||
|
|
0b95f35a61 | ||
|
|
4073b7627d | ||
|
|
2c2b599528 | ||
|
|
eb86d6f1d0 | ||
|
|
2d74e441dc | ||
|
|
8145dea0d5 | ||
|
|
a4a217a223 | ||
|
|
cd023a99b5 | ||
|
|
a339e78135 | ||
|
|
1425414b4a | ||
|
|
a8e189408a | ||
|
|
fbb535d241 | ||
|
|
7d6fc09c24 | ||
|
|
00f62124af | ||
|
|
138be996db | ||
|
|
722b2b24b7 | ||
|
|
d90d68332f | ||
|
|
0470d984cc | ||
|
|
c001452abf | ||
|
|
b25378463c | ||
|
|
63d3a95529 | ||
|
|
1c1eb106d6 | ||
|
|
916d2515b0 | ||
|
|
caff7db0d4 | ||
|
|
85006b2c15 | ||
|
|
727c6c6467 | ||
|
|
12fc80c8b0 | ||
|
|
97ae3df30d | ||
|
|
3189043b7f | ||
|
|
9f01adfb25 | ||
|
|
5155e6510f | ||
|
|
37d99eb86f | ||
|
|
014e9354ce | ||
|
|
c8ecab6d78 | ||
|
|
2e7e10aaae | ||
|
|
9f197074ef | ||
|
|
5b054761cf | ||
|
|
be3ae6bd0d | ||
|
|
71980aafeb | ||
|
|
d1c20ed325 | ||
|
|
16f559cd70 | ||
|
|
d0dc6188cd | ||
|
|
e79f6c49a4 | ||
|
|
4ec11f8359 | ||
|
|
52c1780f79 | ||
|
|
c6becb9995 | ||
|
|
194efab1f6 | ||
|
|
34af7a4899 | ||
|
|
2b6c699828 | ||
|
|
e376b972fe | ||
|
|
445a04b9d6 | ||
|
|
4283b2489d | ||
|
|
c6e21b9ed1 | ||
|
|
c61a94495f | ||
|
|
99049d156a | ||
|
|
f8d331fc8b | ||
|
|
667a883fb0 | ||
|
|
2bd1719637 | ||
|
|
d9d62dec6b | ||
|
|
f3fdd45019 | ||
|
|
ded1cd6b06 | ||
|
|
854dcf48b2 | ||
|
|
0916fa38e2 | ||
|
|
c590f5102c | ||
|
|
9bda5b7941 | ||
|
|
ebba92368a | ||
|
|
3e5df92223 | ||
|
|
2d17071c8c | ||
|
|
38d4bff7f4 | ||
|
|
fc5434cb3d | ||
|
|
3c0e545661 | ||
|
|
c0f758ba9b | ||
|
|
e96dd94ee9 | ||
|
|
8a913d075d | ||
|
|
bbaf3a05b3 | ||
|
|
61c4f8861f | ||
|
|
1e7c51a2cb | ||
|
|
21620917f7 | ||
|
|
cc65055f3c | ||
|
|
71fab0ca94 | ||
|
|
b272e812d0 | ||
|
|
cb9092492f | ||
|
|
0a79020e59 | ||
|
|
4e4fa960b6 | ||
|
|
c28fddb4f6 | ||
|
|
e36587f61a | ||
|
|
40c53cf27b | ||
|
|
09c78a1cee | ||
|
|
b2d9e5ab73 | ||
|
|
a630c1a161 | ||
|
|
1771330890 | ||
|
|
02fed86851 | ||
|
|
46ae248056 | ||
|
|
5730a3be09 | ||
|
|
462df0032e | ||
|
|
d058a99874 | ||
|
|
2399cc25ca | ||
|
|
c7fe39bf21 | ||
|
|
a5bf4c64bb | ||
|
|
3fd97ea471 | ||
|
|
3dae4dd155 | ||
|
|
a510740fa3 | ||
|
|
91ba9e7fd3 | ||
|
|
f3056d316f | ||
|
|
0e9f556994 | ||
|
|
b9727c9275 | ||
|
|
d649fb0d87 | ||
|
|
1aa8221931 | ||
|
|
cbb541f1a3 | ||
|
|
8b215d7425 | ||
|
|
52ef344ba4 | ||
|
|
44eff18b3e | ||
|
|
a0c8d47369 | ||
|
|
d19a0020fd | ||
|
|
5494ad911e | ||
|
|
5ead0975c1 | ||
|
|
34cd890cd9 | ||
|
|
329756d664 | ||
|
|
8ebc4f603f | ||
|
|
07bcdf220d | ||
|
|
2f71a011c3 | ||
|
|
e6244fc3f8 | ||
|
|
9eb713cefb | ||
|
|
714c0aa8c9 | ||
|
|
91a0aeec9d | ||
|
|
a28c1d4efe | ||
|
|
a6af12ae06 | ||
|
|
910b2ff187 | ||
|
|
64adbfaab6 | ||
|
|
d60b8d4b83 | ||
|
|
684fc221b1 | ||
|
|
cf96642db5 | ||
|
|
ab6628b1ab | ||
|
|
06beab3865 | ||
|
|
bd77f4400f | ||
|
|
deebb2be9a | ||
|
|
22c6cab910 | ||
|
|
ea771c80d1 | ||
|
|
861b97c4ff | ||
|
|
b1ffe7cfc2 | ||
|
|
852ea15dc2 | ||
|
|
45768a5bba | ||
|
|
76b5a83511 | ||
|
|
c0d1da781f | ||
|
|
1a80a7a8eb | ||
|
|
cd66661026 | ||
|
|
b88e4eea56 | ||
|
|
f64a0d199d | ||
|
|
5f47f49cf4 | ||
|
|
7a0c8d81f6 | ||
|
|
427efca6f8 | ||
|
|
54546185ab | ||
|
|
493f045764 | ||
|
|
fd79e98ed7 | ||
|
|
40bf5762bb | ||
|
|
c291991236 | ||
|
|
7cb9b97bfb | ||
|
|
eddbd9610e | ||
|
|
a66ebec28f | ||
|
|
cdad18194e | ||
|
|
17f69b2bbc | ||
|
|
84176e5e27 | ||
|
|
67a3b924e8 | ||
|
|
84c86873fb | ||
|
|
2a486a2939 | ||
|
|
0550128e1d | ||
|
|
ff867c9ba4 | ||
|
|
c5fada0a62 | ||
|
|
7316ae0ce4 | ||
|
|
c8919e9844 | ||
|
|
4e340466de | ||
|
|
2fceda6f09 | ||
|
|
2aa29fde8a | ||
|
|
a76b7c545a | ||
|
|
8178bf1380 | ||
|
|
63ca190a32 | ||
|
|
836d9fbae7 | ||
|
|
9df1c73641 | ||
|
|
1899efd209 | ||
|
|
9d90766592 | ||
|
|
bd9d3ee4c3 | ||
|
|
20fac6ab26 | ||
|
|
5be5a7d8e3 | ||
|
|
35f0192ecb | ||
|
|
69949d6257 | ||
|
|
94ad45d2b0 | ||
|
|
c62f6085f7 | ||
|
|
2a300a2ef6 | ||
|
|
a77a0f281d | ||
|
|
d794cd989b | ||
|
|
60c687f3f8 | ||
|
|
8da5d3a770 | ||
|
|
ead3e0bc22 | ||
|
|
a0c1f20fc3 | ||
|
|
8e6586d4e4 | ||
|
|
b2f4229f70 | ||
|
|
2425074855 | ||
|
|
7d53a8aedb | ||
|
|
a16617880f | ||
|
|
650431b8ce | ||
|
|
a6654b65a9 | ||
|
|
4f15ea9ed7 | ||
|
|
aa34532b33 | ||
|
|
3fe711a3ba | ||
|
|
93e2175435 | ||
|
|
5c61006d11 | ||
|
|
6da74af830 | ||
|
|
93ba67c405 | ||
|
|
04fed3d4d5 | ||
|
|
1ead6614ba | ||
|
|
887e63464d | ||
|
|
47e5d5e56e | ||
|
|
c505c1e88e | ||
|
|
6a8c04c031 | ||
|
|
33f68a7f41 | ||
|
|
c5af8676e5 | ||
|
|
618898cb09 | ||
|
|
36bdcc57d9 | ||
|
|
eb418c07f5 | ||
|
|
9a265fbbc3 | ||
|
|
cf32d6cf29 | ||
|
|
9d216e3dc2 | ||
|
|
9d387b3e80 | ||
|
|
1e6be2f26d | ||
|
|
e56f824cd2 | ||
|
|
d38014f4b5 | ||
|
|
b331062fa6 | ||
|
|
88df748451 | ||
|
|
5384197bd1 | ||
|
|
2b5d4b7fe9 | ||
|
|
c15d074488 | ||
|
|
b0c3aa71b9 | ||
|
|
32d85ffb55 | ||
|
|
59fcd61738 | ||
|
|
7ce969882d | ||
|
|
ee70cdb94f | ||
|
|
f21fce7730 | ||
|
|
c426c7b341 | ||
|
|
1231d1e0c2 | ||
|
|
66073aebb8 | ||
|
|
882d9e5709 | ||
|
|
ba9ec45d9e | ||
|
|
f2787a41ae | ||
|
|
3469523225 | ||
|
|
1dc9a07cb9 | ||
|
|
a34807e5c9 | ||
|
|
85ef33a720 | ||
|
|
3163c077a1 | ||
|
|
fbb446875d | ||
|
|
e8cdcabffe | ||
|
|
832813d40a | ||
|
|
e2f28bca7d | ||
|
|
3ed894688c | ||
|
|
bb7422d755 | ||
|
|
b2f3f4a6c7 | ||
|
|
f21794a253 | ||
|
|
ffa96e56a5 | ||
|
|
38e50dfe77 | ||
|
|
1d3ec2d5a3 | ||
|
|
495751433b | ||
|
|
de7d73eae9 | ||
|
|
f825cf9613 | ||
|
|
6e32056c26 | ||
|
|
85bc2aa8f9 | ||
|
|
d56de83368 | ||
|
|
065e65a31c | ||
|
|
a68980bc76 |
82
.github/workflows/gradle-build.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# This workflow will build a Java project with Gradle
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
jobs:
|
||||
validation:
|
||||
name: "Gradle wrapper validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.5
|
||||
- uses: gradle/wrapper-validation-action@v1.0.4
|
||||
build:
|
||||
name: "Build and publish"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.5
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
- name: Cache SonarCloud packages
|
||||
uses: actions/cache@v2.1.6
|
||||
if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
restore-keys: ${{ runner.os }}-sonar
|
||||
- name: Build
|
||||
id: gradle
|
||||
uses: eskatos/gradle-command-action@v1
|
||||
with:
|
||||
arguments: check
|
||||
wrapper-cache-enabled: true
|
||||
dependencies-cache-enabled: true
|
||||
configuration-cache-enabled: true
|
||||
- name: "Comment build scan url"
|
||||
uses: actions/github-script@v5
|
||||
if: github.event_name == 'pull_request' && failure()
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
github.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: '❌ ${{ github.workflow }} failed: ${{ steps.gradle.outputs.build-scan-url }}'
|
||||
})
|
||||
- name: Publish Unit Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action/composite@v1
|
||||
if: always()
|
||||
with:
|
||||
files: '**/test-results/**/*.xml'
|
||||
- name: Analyze with SonarCloud
|
||||
continue-on-error: true
|
||||
if: env.SONAR_TOKEN != null && env.SONAR_TOKEN != ''
|
||||
uses: eskatos/gradle-command-action@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
with:
|
||||
arguments: sonarqube -Psonar.organization=swagger2markup
|
||||
dependencies-cache-enabled: true
|
||||
configuration-cache-enabled: true
|
||||
- name: Publish to Sonatype
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: eskatos/gradle-command-action@v1
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USER }}
|
||||
ORG_GRADLE_PROJECT_sonatypePassword : ${{ secrets.SONATYPE_PASSWORD }}
|
||||
with:
|
||||
arguments: publishToSonatype
|
||||
dependencies-cache-enabled: true
|
||||
configuration-cache-enabled: true
|
||||
6
.gitignore
vendored
@@ -2,3 +2,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
build
|
||||
/bin/
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings/
|
||||
*.ipr
|
||||
*.iws
|
||||
15
.travis.yml
@@ -1,15 +0,0 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk7
|
||||
before_install:
|
||||
- chmod +x gradlew
|
||||
after_success:
|
||||
- ./gradlew jacocoTestReport coveralls
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/9c620e84679284b7d621
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: false # default: false
|
||||
Your unique webhook url for this service:
|
||||
5
ISSUE_TEMPLATE
Normal file
@@ -0,0 +1,5 @@
|
||||
Thanks for raising a Swagger2Markup issue. Please provide a brief description of your problem along with the Swagger2Markup version you are using. If possible, please also consider putting together a complete Swagger specification that reproduces the issue. It's better if the Swagger specification is small and isolate the issue.
|
||||
|
||||
Swagger2Markup version:
|
||||
|
||||
Problem description:
|
||||
410
README.adoc
@@ -1,398 +1,72 @@
|
||||
= Swagger2Markup
|
||||
:author: Robert Winkler
|
||||
:version: 0.6.3
|
||||
:hardbreaks:
|
||||
|
||||
image:https://travis-ci.org/RobWin/swagger2markup.svg?branch=master["Build Status", link="https://travis-ci.org/RobWin/swagger2markup"] image:https://coveralls.io/repos/RobWin/swagger2markup/badge.svg["Coverage Status", link="https://coveralls.io/r/RobWin/swagger2markup"] image:https://api.bintray.com/packages/robwin/maven/swagger2markup/images/download.svg[link="https://bintray.com/robwin/maven/swagger2markup/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/RobWin/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
|
||||
image:https://coveralls.io/repos/Swagger2Markup/swagger2markup/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup"] image:https://api.codacy.com/project/badge/grade/498a6a39d7d84ff687546359f58ee18d["Codacy code quality", link="https://www.codacy.com/app/robwin/swagger2markup"] image:https://api.bintray.com/packages/swagger2markup/Maven/swagger2markup/images/download.svg[link="https://bintray.com/swagger2markup/Maven/swagger2markup/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/RobWin/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
|
||||
|
||||
|
||||
== Overview
|
||||
|
||||
|
||||
NOTE: Dear community,
|
||||
unfortunately I can't maintain Swagger2Markup alone anymore. There are many interesting new topics:
|
||||
1) Swagger v3 support
|
||||
2) Fixing bugs
|
||||
2) Merge Swagger2Markup repositories and create a new multi-module repository.
|
||||
Any help is welcome.
|
||||
Kind regards,
|
||||
Robert
|
||||
|
||||
|
||||
The primary goal of this project is to *simplify the generation of an up-to-date RESTful API documentation by combining documentation that's been hand-written with auto-generated API documentation* produced by https://github.com/swagger-api[Swagger]. The result is intended to be an *up-to-date, easy-to-read, on- and offline user guide*, comparable to https://developer.github.com/v3/[GitHub's API documentation]. The output of Swagger2Markup can be used as an alternative to https://github.com/swagger-api/swagger-ui[swagger-ui] and can be served as static content.
|
||||
NOTE: The Swagger Specification has been donated to to the https://openapis.org/[Open API Initiative (OAI)] and has been renamed to the https://github.com/OAI/OpenAPI-Specification[OpenAPI Specification].
|
||||
|
||||
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].
|
||||
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/tree/master/samples/java-jersey2[Swagger JAX-RS], https://github.com/springfox/springfox[springfox] or https://github.com/spring-projects/spring-restdocs[spring-restdocs]. See https://github.com/RobWin/swagger2markup#usage-guide[usage guide] below. If you are are Gradle user, you can also use the https://github.com/RobWin/swagger2markup-gradle-plugin[Swagger2Markup Gradle Plugin].
|
||||
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]. You can also use https://github.com/jbake-org/jbake[JBake], https://github.com/tomchristie/mkdocs[MkDocs], https://github.com/rtfd/readthedocs.org[ReadTheDocs] or https://github.com/tripit/slate[slate] to publish your AsciiDoc or Markdown documentation.
|
||||
You can generate your HTML5, PDF and EPUB documentation via https://github.com/asciidoctor/asciidoctorj[asciidoctorj] or even better via the https://github.com/asciidoctor/asciidoctor-gradle-plugin[asciidoctor-gradle-plugin] or https://github.com/asciidoctor/asciidoctor-maven-plugin[asciidoctor-maven-plugin].
|
||||
|
||||
The project requires at least JDK 7.
|
||||
The project requires at least JDK 8.
|
||||
|
||||
== Usage guide
|
||||
== Example
|
||||
|
||||
=== Adding Swagger2Markup to your project
|
||||
The project is published in JCenter and Maven Central.
|
||||
image::swagger2markup-documentation/src/docs/asciidoc/images/Swagger2Markup.PNG[]
|
||||
|
||||
==== Maven
|
||||
image::swagger2markup-documentation/src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[]
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>central</id>
|
||||
<name>bintray</name>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
== Reference documentation
|
||||
- http://swagger2markup.github.io/swagger2markup/1.3.3/[Reference Documentation]
|
||||
- https://github.com/Swagger2Markup/swagger2markup/blob/master/RELEASENOTES.adoc[Release notes]
|
||||
- https://github.com/Swagger2Markup/spring-swagger2markup-demo[Demo using Swagger2Markup, Spring Boot, Springfox and spring-restdocs]
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.robwin</groupId>
|
||||
<artifactId>swagger2markup</artifactId>
|
||||
<version>0.6.3</version>
|
||||
</dependency>
|
||||
----
|
||||
== Contributing
|
||||
|
||||
==== Gradle
|
||||
=== Community contributions
|
||||
|
||||
[source,groovy]
|
||||
----
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
Pull requests are welcome.
|
||||
|
||||
compile "io.github.robwin:swagger2markup:0.6.3"
|
||||
----
|
||||
=== Questions
|
||||
You can ask questions about Swagger2Markup in https://gitter.im/Swagger2Markup/swagger2markup[Gitter].
|
||||
|
||||
=== Using Swagger2Markup
|
||||
=== 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.
|
||||
|
||||
Using the Swagger2MarkupConverter is simple. For example, if you are using https://github.com/spring-projects/spring-boot[Spring Boot] and https://github.com/springfox/springfox[springfox], you can generate your Swagger JSON file during the integration or unit test phase, convert the Swagger JSON file into AsciiDoc, convert AsciiDoc into HTML and PDF, copy the documentation into the Jar file and serve it as static content. That way there is no runtime overhead and there are no additional runtime libraries required.
|
||||
The quickest way to get started is to look at the demo project https://github.com/RobWin/spring-swagger2markup-demo[spring-swagger2markup-demo]. The demo shows how to generate static docs (HTML5 and PDF) with the https://github.com/RobWin/swagger2markup-gradle-plugin[Swagger2Markup Gradle Plugin] and serve them as static content in a Spring Boot App under http://localhost:9080/docs/index.html and http://localhost:9080/docs/index.pdf.
|
||||
=== 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.
|
||||
|
||||
==== Generate Markup during an integration test
|
||||
== Companies who use Swagger2Markup
|
||||
|
||||
Swagger2MarkupConverter can be used to make a request to a Swagger endpoint during an integration test. The Swagger2MarkupConverter writes the generated documents into the folder `src/docs/asciidoc/generated` or `src/docs/markdown/generated`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@IntegrationTest
|
||||
@WebAppConfiguration
|
||||
public class Swagger2MarkupTest {
|
||||
|
||||
@Test
|
||||
public void convertRemoteSwaggerToAsciiDoc() {
|
||||
// Remote Swagger source
|
||||
// Default is AsciiDoc
|
||||
Swagger2MarkupConverter.from("http://localhost:8080/v2/api-docs").build()
|
||||
.intoFolder("src/docs/asciidoc/generated");
|
||||
|
||||
// Then validate that three AsciiDoc files have been created
|
||||
String[] files = new File("src/docs/asciidoc/generated").list();
|
||||
assertThat(files).hasSize(3)
|
||||
.containsAll(Arrays.asList("definitions.adoc", "overview.adoc", "paths.adoc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertRemoteSwaggerToMarkdown() {
|
||||
// Remote Swagger source
|
||||
// Markdown
|
||||
Swagger2MarkupConverter.from("http://localhost:8080/v2/api-docs")
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN).build()
|
||||
.intoFolder("src/docs/markdown/generated");
|
||||
|
||||
// Then validate that three Markdown files have been created
|
||||
String[] files = new File("src/docs/markdown/generated").list();
|
||||
assertThat(files).hasSize(3)
|
||||
.containsAll(Arrays.asList("definitions.md", "overview.md", "paths.md"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertLocalSwaggerToAsciiDoc() {
|
||||
//Local Swagger source
|
||||
//Default is AsciiDoc
|
||||
String location = Swagger2MarkupTest.class.getResource("/json/swagger.json").getPath();
|
||||
Swagger2MarkupConverter.from(location).build()
|
||||
.intoFolder("src/docs/asciidoc/generated");
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
==== Generate Markup during an unit test with springfox-staticdocs
|
||||
|
||||
Spring's MVC Test framework can also be used to make a request to a https://github.com/springfox/springfox[springfox] Swagger endpoint during an unit test. A custom ResultHandler `Swagger2MarkupResultHandler` is used to automatically convert the Swagger JSON response into an AsciiDoc document. The custom ResultHandler is part of `springfox-staticdocs`. That way you also verify that your Swagger endpoint is working.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@WebAppConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = Application.class, loader = SpringApplicationContextLoader.class)
|
||||
public class Swagger2MarkupTest {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertSwaggerToAsciiDoc() throws Exception {
|
||||
this.mockMvc.perform(get("/v2/api-docs")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(Swagger2MarkupResultHandler.outputDirectory("src/docs/asciidoc/generated").build())
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertSwaggerToMarkdown() throws Exception {
|
||||
this.mockMvc.perform(get("/v2/api-docs")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(Swagger2MarkupResultHandler.outputDirectory("src/docs/markdown/generated")
|
||||
.withMarkupLanguage(MarkupLanguage.MARKDOWN).build())
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
==== Gradle dependencies
|
||||
|
||||
[source,groovy]
|
||||
----
|
||||
dependencies {
|
||||
...
|
||||
compile 'io.springfox:springfox-swagger2:2.0.0'
|
||||
testCompile 'io.springfox:springfox-staticdocs:2.0.0'
|
||||
...
|
||||
}
|
||||
----
|
||||
|
||||
==== Springfox configuration
|
||||
|
||||
The following is a complete https://github.com/springfox/springfox[springfox] configuration to use Swagger in a Spring Boot Application.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@SpringBootApplication
|
||||
@EnableSwagger2
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket restApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
.paths(ant("/api/**"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("Petstore API Title")
|
||||
.description("Petstore API Description")
|
||||
.contact("Petstore API Contact Email")
|
||||
.version("1.0.0")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
==== Combine generated documentation with your hand-written documentation
|
||||
|
||||
The following shows how you can combine the generated documentation with your hand-written AsciiDoc documentation. You have to create an `index.adoc` (it must not be necessarily called index). To include the programmatically generated snippets in your documentation, you use Asciidoc's `include` macro. The `generated` variable is configured below.
|
||||
|
||||
image::images/generated_docs.PNG[generated_docs]
|
||||
|
||||
You can generate your HTML5 and PDF documentation via the https://github.com/asciidoctor/asciidoctor-gradle-plugin[asciidoctor-gradle-plugin] or https://github.com/asciidoctor/asciidoctor-maven-plugin[asciidoctor-maven-plugin]. The following listing shows how to configure the Asciidoctor Gradle plugin. By default it searches for AsciiDoc files in `src/docs/asciidoc` and puts the HTML and PDF output into `build/asciidoc/html5` and `build/asciidoc/pdf`. The `generated` attribute is used to replace the variable in the `index.adoc` file and to provide configurable access to the generated snippets.
|
||||
|
||||
[source,groovy]
|
||||
----
|
||||
ext {
|
||||
generatedDocumentation = file('src/docs/asciidoc/generated')
|
||||
}
|
||||
|
||||
test {
|
||||
outputs.dir generatedDocumentation
|
||||
}
|
||||
|
||||
asciidoctor {
|
||||
dependsOn test
|
||||
sources {
|
||||
include 'index.adoc'
|
||||
}
|
||||
backends = ['html5', 'pdf']
|
||||
attributes = [
|
||||
doctype: 'book',
|
||||
toc: 'left',
|
||||
toclevels: '2',
|
||||
numbered: '',
|
||||
sectlinks: '',
|
||||
sectanchors: '',
|
||||
generated: generatedDocumentation
|
||||
]
|
||||
}
|
||||
----
|
||||
|
||||
You can copy the output into your Jar file and serve the documentation as static content under `http://localhost:9080/docs/index.html` and `http://localhost:9080/docs/index.pdf`.
|
||||
|
||||
[source,groovy]
|
||||
----
|
||||
jar {
|
||||
dependsOn asciidoctor
|
||||
from ("${asciidoctor.outputDir}/html5") {
|
||||
into 'static/docs'
|
||||
}
|
||||
from ("${asciidoctor.outputDir}/pdf") {
|
||||
into 'static/docs'
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
==== Include spring-restdocs example snippets
|
||||
|
||||
Swagger2Markup can be used together with https://github.com/spring-projects/spring-restdocs[spring-restdocs]. Swagger2Markup can include the generated CURL request, HTTP request and HTTP response example snippets from spring-restdocs into the generated AsciiDoc document. See https://github.com/spring-projects/spring-restdocs[spring-restdocs] how to configure it. Currently spring-restdocs does only support AsciiDoc.
|
||||
|
||||
Let's say you have a Swagger-annotated Spring RestController method with an ApiOperation value: `Add a new pet to the store`
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RequestMapping(method = POST)
|
||||
@ApiOperation(value = "Add a new pet to the store")
|
||||
@ApiResponses(value = {@ApiResponse(code = 405, message = "Invalid input")})
|
||||
public ResponseEntity<String> addPet(
|
||||
@ApiParam(value = "Pet object that needs to be added to the store", required = true) @RequestBody Pet pet) {
|
||||
petData.add(pet);
|
||||
return Responses.ok("SUCCESS");
|
||||
}
|
||||
----
|
||||
|
||||
By convention the target folder of the generated request and response example files must be similar to the value of the ApiOperation, but with underscores and lowercase. For example a folder for `@ApiOperation(value = "Add a new pet to the store")` must be called `add_a_new_pet_to_the_store`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Test
|
||||
public void findPetById() throws Exception {
|
||||
this.mockMvc.perform(post("/api/pet/").content(createPet())
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(RestDocumentation.document("add_a_new_pet_to_the_store"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
----
|
||||
|
||||
The system property `org.springframework.restdocs.outputDir` is used to control the output base directory where the folder `add_a_new_pet_to_the_store` and the generated snippets are written to. The spring-restdocs output base directory is configured as follows:
|
||||
|
||||
[source,groovy]
|
||||
----
|
||||
ext {
|
||||
generatedDocumentation = file('src/docs/asciidoc/generated')
|
||||
}
|
||||
|
||||
test {
|
||||
systemProperty 'org.springframework.restdocs.outputDir', generatedDocumentation
|
||||
outputs.dir generatedDocumentation
|
||||
}
|
||||
----
|
||||
|
||||
You must specify the base output directory of spring-restdocs with the builder method `withExamples("src/docs/asciidoc/generated")`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Test
|
||||
public void convertToAsciiDoc() throws Exception {
|
||||
this.mockMvc.perform(get("/v2/api-docs")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(Swagger2MarkupResultHandler.outputDirectory("src/docs/asciidoc")
|
||||
.withExamples("src/docs/asciidoc/generated").build())
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
----
|
||||
|
||||
By convention the Swagger2MarkupConverter searches for a method annotated with `@ApiOperation(value = "Add a new pet to the store")` in a folder called `src/docs/asciidoc/generated/add_a_new_pet_to_the_store` and includes the `http-request.adoc` and `http-response.adoc` files, if they are available.
|
||||
|
||||
The AsciiDoc HTML output would look as follows:
|
||||
|
||||
image::images/springrestdocs_examples.PNG[springrestdocs]
|
||||
|
||||
==== Include hand-written descriptions into the generated documentation
|
||||
|
||||
If you don't want to pollute your source code with Swagger annotations just to add descriptions to Operations, Parameters and Model definitions. Like here:
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@RequestMapping(method = PUT)
|
||||
@ApiOperation(value = "Update an existing pet")
|
||||
@ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid ID supplied"),
|
||||
@ApiResponse(code = 404, message = "Pet not found"),
|
||||
@ApiResponse(code = 405, message = "Validation exception")})
|
||||
public ResponseEntity<String> updatePet(
|
||||
@ApiParam(value = "Pet object that needs to be added to the store", required = true) @RequestBody Pet pet) {
|
||||
petData.add(pet);
|
||||
return Responses.ok("SUCCESS");
|
||||
}
|
||||
----
|
||||
|
||||
You can create hand-written descriptions and include them with the builder method `withDescriptions()` into your documentation by specifying the base folder of your documentation.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).withDescriptions("src/docs/asciidoc").build()
|
||||
.intoFolder("src/docs/asciidoc");
|
||||
----
|
||||
|
||||
By convention you need two folders `paths` and `definitions` inside your description base folder.
|
||||
The `paths` folder contains sub folders for all operations. The folder must be named similar to the value of the ApiOperation annotation, but with underscores and lowercase.
|
||||
For example a folder for `@ApiOperation(value = "Update an existing pet")` must be called `update_an_existing_pet`.
|
||||
|
||||
The `definitions` folder contains sub folders for all models. The folder must be named similar to the name of the Model, but lowercase.
|
||||
For example a folder for a model called `User` must be called `user`.
|
||||
|
||||
You can have a global description file for each operation or model. And you can have one description file per operation parameter or model property.
|
||||
For example:
|
||||
|
||||
image::images/handwritten_descriptions.PNG[handwritten_descriptions]
|
||||
|
||||
The AsciiDoc HTML output would look as follows:
|
||||
|
||||
image::images/handwritten_descr_asciidoc.PNG[handwritten_descr_asciidoc]
|
||||
|
||||
==== Include JSON and XML Schema files.
|
||||
Swagger2Markup can also include JSON and XML Schema files into the generated document.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
Swagger2MarkupConverter.from("http://localhost:8080/api-docs").withSchemas("src/docs/schemas").build()
|
||||
.intoFolder("src/docs/asciidoc");
|
||||
----
|
||||
|
||||
You can create the schema files during a unit test as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
RestDocumented restDocumented = RestDocumented.fromProperties();
|
||||
restDocumented.documentJsonSchema(MailStorageQuota.class, "src/docs/schemas");
|
||||
restDocumented.documentXmlSchema(MailStorageQuota.class, "src/docs/schemas");
|
||||
----
|
||||
|
||||
I will make RestDocumented public soon. RestDocumented creates a MailStorageQuota.xsd and MailStorageQuota.json file in the folder `src/docs/schemas`. The Swagger2MarkupConverter will include the JSON and XML Schemas, if a Swagger Operation uses the MailStorageQuota class as input or output.
|
||||
|
||||
== Screenshots
|
||||
|
||||
=== Swagger source
|
||||
image::images/swagger_json.PNG[swagger_json]
|
||||
|
||||
=== Generated AsciiDoc
|
||||
image::images/asciidoc.PNG[asciidoc]
|
||||
|
||||
=== Generated Markdown
|
||||
image::images/markdown.PNG[markdown]
|
||||
|
||||
=== Generated HTML using AsciidoctorJ
|
||||
image::images/asciidoc_html.PNG[asciidoc_html]
|
||||
|
||||
=== Generated PDF using AsciidoctorJ
|
||||
image::images/asciidoc_pdf.PNG[asciidoc_pdf]
|
||||
* 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]
|
||||
* http://taskassure.com[TaskAssure]
|
||||
* https://www.isaac.nl[ISAAC]
|
||||
* https://www.spreadshirt.de[Spreadshirt]
|
||||
|
||||
== License
|
||||
|
||||
|
||||
@@ -1,56 +1,169 @@
|
||||
= 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
|
||||
= Release Notes
|
||||
|
||||
== Version 0.1.0
|
||||
* Initial version with support for AsciiDoc and Markdown
|
||||
|
||||
=== Version 0.1.1
|
||||
* Signed jar files
|
||||
|
||||
=== Version 0.1.2
|
||||
* Removed logback from compile dependency
|
||||
|
||||
=== Version 0.1.3
|
||||
* Removed commons.io from compile dependency
|
||||
|
||||
=== Version 0.1.4
|
||||
* Fixed SECTION_TITLE_LEVEL3 in Markdown enum
|
||||
|
||||
=== Version 0.1.5
|
||||
* Added SECTION_TITLE_LEVEL4
|
||||
|
||||
== Version 0.2.0
|
||||
* This version is not downward compatible. This version supports includes of example files and JSON/XML Schema files. See documentation.
|
||||
|
||||
=== 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
|
||||
|
||||
== Version 1.0.0
|
||||
* New configuration API
|
||||
* New extension SPI
|
||||
* Added new languages: turkish, german, france
|
||||
* New security document
|
||||
* Inline schema support
|
||||
* New configuration options
|
||||
* Support of deprecated path operations
|
||||
|
||||
=== Version 1.0.1
|
||||
* Enhancement: Support to render validation constraints of properties
|
||||
* Enhancement: Possibility to disable rendering of the security chapter below operations
|
||||
|
||||
== Version 1.1.0
|
||||
* PR #177: Fixed rendering of recursive examples
|
||||
* PR #186: Add support for Chinese language
|
||||
* PR #190: Add support for Spanish language
|
||||
* PR #192: Updated min/max value to format correctly based on the data type
|
||||
* PR #193: Added support for exclusiveMin and exclusiveMax
|
||||
* Changed bold to ** and italic to __ so that special chars in the text are possible
|
||||
|
||||
=== Version 1.1.1
|
||||
* Issue #194: Added a config parameter which allows to prepend the basePath to all paths.
|
||||
* Updated swagger-parser from v1.0.16 to v1.0.23
|
||||
* Added javslang v2.0.4 as a dependency
|
||||
* Added paleo-core v0.10.1 as a dependency
|
||||
* Updated markup-document-builder from 1.0.0 to 1.1.0
|
||||
* PR #201: Add support for Brazilian Portuguese language
|
||||
* PR #202: Add support for Japanese language
|
||||
* Issue #205: Fixed the option to influence resource ordering
|
||||
* Issue #198: Chinese chinese language encoding
|
||||
* Issue #207: Properties that start with an underscore are displayed correctly now
|
||||
* Refactored Swagger2Markup to use a Component-Based design. A document can be composed of components and components can be composed of other components.
|
||||
* Added a method to add page breaks.
|
||||
|
||||
== Version 1.1.2
|
||||
* Improve code blocks in markdown
|
||||
|
||||
== Version 1.2.0
|
||||
* Issue #214: Add page break locations
|
||||
* Issue #223: Improve example rendering
|
||||
* Issue #215: Add ability to group operations by RegEx
|
||||
* Added new configuration options: pageBreakLocations, headerRegex
|
||||
* Added new valid value for configuration headerRegex: REGEX
|
||||
* Updated markup-document-builder from 1.1.0 to 1.1.1
|
||||
|
||||
== Version 1.3.0
|
||||
* Updated javslang from 2.0.4 to 2.0.5
|
||||
* Updated paleo-core from 0.10.1 to 0.10.2
|
||||
* Updated swagger-parser from v1.0.23 to v1.0.25
|
||||
* Decimal numbers are formatted into locale-specific strings
|
||||
|
||||
=== Version 1.3.1
|
||||
* PR #247: Fix request path and query params example support.
|
||||
|
||||
=== Version 1.3.2
|
||||
* PR #290: Fixed list parsing in properties file
|
||||
* PR #293: Fixed crash on empty tables
|
||||
* Updated markup-document-builder from 1.1.1 to 1.1.2
|
||||
|
||||
=== Version 1.3.3
|
||||
* Updated swagger-parser from v1.0.25 to 1.0.35
|
||||
* PR #294: Examples always start with a newline if there is other content in the same cell
|
||||
* PR 307: Include required parameters in example request
|
||||
|
||||
=== Version 2.0.0
|
||||
* Added openapi2markup to support OpenAPI v3
|
||||
* Issue #409: Fixed JSON response example
|
||||
|
||||
|
||||
212
build.gradle
@@ -1,121 +1,121 @@
|
||||
buildscript {
|
||||
plugins {
|
||||
id "org.sonarqube" version "2.7"
|
||||
id "me.champeau.gradle.jmh" version "0.4.8"
|
||||
id 'org.asciidoctor.convert' version '1.6.0'
|
||||
id "org.ajoberstar.github-pages" version "1.7.2"
|
||||
id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
|
||||
}
|
||||
apply plugin: 'idea'
|
||||
apply from: "${rootDir}/libraries.gradle"
|
||||
|
||||
ext {
|
||||
releaseVersion = '1.3.3'
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'jacoco'
|
||||
apply plugin: 'me.champeau.gradle.jmh'
|
||||
|
||||
version = '2.0.0-SNAPSHOT'
|
||||
group 'io.github.swagger2markup'
|
||||
description = 'swagger2markup Build'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.2'
|
||||
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.7'
|
||||
classpath 'io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE'
|
||||
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'
|
||||
}
|
||||
}
|
||||
description = 'swagger2markup Build'
|
||||
version = '0.6.3'
|
||||
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: 'io.spring.dependency-management'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
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 {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'io.github.robwin:markup-document-builder'
|
||||
compile 'io.swagger:swagger-compat-spec-parser'
|
||||
compile 'commons-collections:commons-collections'
|
||||
compile 'commons-io:commons-io'
|
||||
compile 'org.slf4j:slf4j-api'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'org.asciidoctor:asciidoctorj:1.5.2'
|
||||
testCompile 'ch.qos.logback:logback-classic'
|
||||
testCompile 'org.assertj:assertj-core'
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
dependencies {
|
||||
dependency "io.github.robwin:markup-document-builder:0.1.4"
|
||||
dependency "io.swagger:swagger-compat-spec-parser:1.0.8"
|
||||
dependency "commons-collections:commons-collections:3.2.1"
|
||||
dependency "commons-io:commons-io:2.4"
|
||||
dependency "junit:junit:4.11"
|
||||
dependency "org.slf4j:slf4j-api:1.7.12"
|
||||
dependency "ch.qos.logback:logback-classic:1.1.2"
|
||||
dependency "org.assertj:assertj-core:2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
//artifactoryPublish.skip = true // apply to all projects except the root
|
||||
|
||||
ext {
|
||||
generatedDocumentation = file('build/docs/asciidoc/generated')
|
||||
}
|
||||
|
||||
asciidoctor {
|
||||
dependsOn test
|
||||
sources {
|
||||
include 'index.adoc'
|
||||
}
|
||||
backends = ['html5', 'pdf']
|
||||
attributes = [
|
||||
doctype: 'book',
|
||||
toc: 'left',
|
||||
toclevels: '2',
|
||||
numbered: '',
|
||||
sectlinks: '',
|
||||
sectanchors: '',
|
||||
hardbreaks: '',
|
||||
generated: generatedDocumentation
|
||||
]
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
reports {
|
||||
xml.enabled = true // coveralls plugin depends on xml format report
|
||||
html.enabled = true
|
||||
coreProjects = subprojects.findAll {
|
||||
p -> !p.name.contains("documentation") && !p.name.endsWith("-bom")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.coveralls {
|
||||
dependsOn 'check'
|
||||
configure(project.coreProjects) {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'maven-publish'
|
||||
apply from: "${rootDir}/publishing.gradle"
|
||||
apply plugin: 'jacoco'
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
sourceCompatibility = "11"
|
||||
targetCompatibility = "11"
|
||||
options.deprecation = true
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs += ["-Xlint:unchecked", "-parameters"]
|
||||
}
|
||||
tasks.withType(Javadoc){
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
jmh {
|
||||
duplicateClassesStrategy = 'warn'
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
failOnVersionConflict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.asciidoctor {
|
||||
dependsOn 'check'
|
||||
nexusPublishing {
|
||||
repositories {
|
||||
sonatype()
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.4'
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.host.url", "https://sonarcloud.io"
|
||||
property "sonar.organization", "swagger2markup"
|
||||
property "sonar.projectName", "swagger2markup"
|
||||
property "sonar.projectKey", "Swagger2Markup_swagger2markup"
|
||||
property "sonar.links.homepage", "https://github.com/Swagger2Markup/swagger2markup"
|
||||
property "sonar.links.ci", "https://travis-ci.org/Swagger2Markup/swagger2markup"
|
||||
property "sonar.links.scm", "https://github.com/Swagger2Markup/swagger2markup"
|
||||
property "sonar.links.issue", "https://github.com/Swagger2Markup/swagger2markup/issues"
|
||||
property "sonar.language", "java"
|
||||
}
|
||||
}
|
||||
def allTestCoverageFile = "$buildDir/jacoco/allTestCoverage.exec"
|
||||
|
||||
task jacocoMergeTest(type: JacocoMerge) {
|
||||
destinationFile = file(allTestCoverageFile)
|
||||
executionData = project.fileTree(dir: '.', include: '**/build/jacoco/test.exec')
|
||||
}
|
||||
|
||||
task jacocoMerge(dependsOn: ['jacocoMergeTest']) {
|
||||
// used to run the other merge tasks
|
||||
}
|
||||
|
||||
subprojects {
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.jacoco.reportPaths", allTestCoverageFile
|
||||
}
|
||||
}
|
||||
afterEvaluate {
|
||||
// exclude subprojects that don't produce a jar file or by design.
|
||||
if (!project.name.equals('swagger2markup-bom') && !project.name.equals('swagger2markup-documentation')) {
|
||||
jar {
|
||||
into("META-INF/maven/$project.group/$project.name") {
|
||||
from {generatePomFileForMavenJavaPublication}
|
||||
rename ".*", "pom.xml"
|
||||
}
|
||||
inputs.property('moduleName', moduleName)
|
||||
manifest.attributes(
|
||||
'Automatic-Module-Name': moduleName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.check.dependsOn tasks.jacocoTestReport
|
||||
|
||||
test {
|
||||
dependsOn(subprojects.test) // required by cobertura to aggregate report
|
||||
}
|
||||
|
||||
2
gradle.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
systemProp.file.encoding=UTF-8
|
||||
systemProp.sun.jnu.encoding=UTF-8
|
||||
@@ -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/RobWin/swagger2markup'
|
||||
issueTrackerUrl = 'https://github.com/RobWin/swagger2markup/issues'
|
||||
vcsUrl = 'https://github.com/RobWin/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/RobWin/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/RobWin/swagger2markup/blob/master/LICENSE.txt')
|
||||
license.appendNode('distribution', 'repo')
|
||||
|
||||
root.appendNode('scm').appendNode('url', 'https://github.com/RobWin/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
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Mon Jun 08 08:20:09 CEST 2015
|
||||
#Mon Oct 21 16:35:38 BST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-all.zip
|
||||
|
||||
110
gradlew
vendored
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,47 +6,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@@ -90,7 +89,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -114,6 +113,7 @@ fi
|
||||
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`
|
||||
@@ -154,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
174
gradlew.bat
vendored
@@ -1,90 +1,84 @@
|
||||
@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
|
||||
@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
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
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 Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_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=%*
|
||||
|
||||
: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
|
||||
|
||||
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 26 KiB |
52
libraries.gradle
Normal file
@@ -0,0 +1,52 @@
|
||||
// Allows centralized definition of the version of artifacts to
|
||||
// use. In that respect it serves a role similar to <dependencyManagement> in Maven
|
||||
ext {
|
||||
implLibraries = [:]
|
||||
testLibraries = [:]
|
||||
dependencyOverrides = [:]
|
||||
}
|
||||
implLibraries = [
|
||||
asciiDocJApi : "org.asciidoctor:asciidoctorj-api:2.2.0",
|
||||
commonsBeanUtils : "commons-beanutils:commons-beanutils:1.9.4",
|
||||
commonsCodec : "commons-codec:commons-codec:1.13",
|
||||
commonsCollections4: "org.apache.commons:commons-collections4:4.4",
|
||||
commonsConf2 : "org.apache.commons:commons-configuration2:2.6",
|
||||
commonsLang3 : "org.apache.commons:commons-lang3:3.9",
|
||||
commonsIO : "commons-io:commons-io:2.6",
|
||||
commonsText : "org.apache.commons:commons-text:1.8",
|
||||
guava : 'com.google.guava:guava:27.0.1-android',
|
||||
jacksonDatabind : 'com.fasterxml.jackson.core:jackson-databind:2.9.10',
|
||||
mark2Ascii : "nl.jworks.markdown_to_asciidoc:markdown_to_asciidoc:1.1",
|
||||
paleo : "ch.netzwerg:paleo-core:0.14.0",
|
||||
pegdown : "org.pegdown:pegdown:1.6.0",
|
||||
slf4j : "org.slf4j:slf4j-api:1.7.28",
|
||||
swaggerV2 : "io.swagger:swagger-parser:1.0.47",
|
||||
swaggerV2Converter : "io.swagger.parser.v3:swagger-parser-v2-converter:2.0.15",
|
||||
swaggerV3 : "io.swagger.parser.v3:swagger-parser:2.0.15",
|
||||
vavr : "io.vavr:vavr:0.10.2"
|
||||
]
|
||||
|
||||
testLibraries = [
|
||||
asciiDocJ : "org.asciidoctor:asciidoctorj:2.2.0",
|
||||
assertj : "org.assertj:assertj-core:3.13.2",
|
||||
assertjDiff: "io.github.robwin:assertj-diff:0.1.1",
|
||||
junit : "junit:junit:4.12",
|
||||
logback : "ch.qos.logback:logback-classic:1.2.3",
|
||||
mockito : "org.mockito:mockito-core:3.1.0"
|
||||
]
|
||||
|
||||
dependencyOverrides = [
|
||||
assertj : testLibraries.assertj,
|
||||
commonsCodec : implLibraries.commonsCodec,
|
||||
commonsIO : implLibraries.commonsIO,
|
||||
commonsLang3 : implLibraries.commonsLang3,
|
||||
findBugs : 'com.google.code.findbugs:jsr305:3.0.2',
|
||||
guava : implLibraries.guava,
|
||||
jaksonCore : 'com.github.fge:jackson-coreutils:1.8',
|
||||
jacksonDatabind: implLibraries.jacksonDatabind,
|
||||
jnrConstants : 'com.github.jnr:jnr-constants:0.9.12',
|
||||
jnrEnxio : 'com.github.jnr:jnr-enxio:0.19',
|
||||
jnrPosix : 'com.github.jnr:jnr-posix:3.0.49',
|
||||
jodaTime : 'joda-time:joda-time:2.9.9',
|
||||
slf4j : implLibraries.slf4j,
|
||||
]
|
||||
34
openapi2markup/build.gradle
Normal file
@@ -0,0 +1,34 @@
|
||||
ext.moduleName="io.github.swagger2markup.openapi2markup"
|
||||
|
||||
dependencies {
|
||||
configurations.all {
|
||||
resolutionStrategy.force dependencyOverrides.commonsCodec
|
||||
resolutionStrategy.force dependencyOverrides.commonsIO
|
||||
resolutionStrategy.force dependencyOverrides.commonsLang3
|
||||
resolutionStrategy.force dependencyOverrides.jnrConstants
|
||||
resolutionStrategy.force dependencyOverrides.jnrEnxio
|
||||
resolutionStrategy.force dependencyOverrides.jnrPosix
|
||||
resolutionStrategy.force dependencyOverrides.jodaTime
|
||||
resolutionStrategy.force dependencyOverrides.slf4j
|
||||
resolutionStrategy.force dependencyOverrides.jacksonDatabind
|
||||
resolutionStrategy.force dependencyOverrides.guava
|
||||
resolutionStrategy.force dependencyOverrides.findBugs
|
||||
resolutionStrategy.force dependencyOverrides.jaksonCore
|
||||
resolutionStrategy.force dependencyOverrides.assertj
|
||||
}
|
||||
// implementation implLibraries.swaggerV2Converter
|
||||
compile project(':swagger2markup-asciidoc')
|
||||
compile project(':swagger2markup-core')
|
||||
implementation implLibraries.asciiDocJApi
|
||||
implementation implLibraries.commonsText
|
||||
implementation implLibraries.commonsBeanUtils
|
||||
implementation implLibraries.slf4j
|
||||
implementation implLibraries.swaggerV3
|
||||
implementation implLibraries.commonsCollections4
|
||||
implementation implLibraries.commonsConf2
|
||||
implementation implLibraries.vavr
|
||||
testImplementation testLibraries.assertj
|
||||
testImplementation testLibraries.assertjDiff
|
||||
testImplementation testLibraries.junit
|
||||
testImplementation testLibraries.logback
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup;
|
||||
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.config.OpenAPILabels;
|
||||
import io.github.swagger2markup.config.builder.OpenAPI2MarkupConfigBuilder;
|
||||
import io.github.swagger2markup.extension.OpenAPI2MarkupExtensionRegistry;
|
||||
import io.github.swagger2markup.extension.builder.OpenAPI2MarkupExtensionRegistryBuilder;
|
||||
import io.github.swagger2markup.internal.document.ComponentsDocument;
|
||||
import io.github.swagger2markup.internal.document.OverviewDocument;
|
||||
import io.github.swagger2markup.internal.document.PathsDocument;
|
||||
import io.github.swagger2markup.internal.document.SecurityDocument;
|
||||
import io.github.swagger2markup.utils.URIUtils;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.parser.OpenAPIV3Parser;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class OpenAPI2MarkupConverter extends AbstractSchema2MarkupConverter<OpenAPI> {
|
||||
private final OverviewDocument overviewDocument;
|
||||
private final PathsDocument pathsDocument;
|
||||
private final ComponentsDocument componentsDocument;
|
||||
private final SecurityDocument securityDocument;
|
||||
private final OpenAPIContext openAPIContext;
|
||||
|
||||
|
||||
public OpenAPI2MarkupConverter(OpenAPIContext context) {
|
||||
super(context);
|
||||
this.openAPIContext = context;
|
||||
this.overviewDocument = new OverviewDocument(context);
|
||||
this.pathsDocument = new PathsDocument(context);
|
||||
this.componentsDocument = new ComponentsDocument(context);
|
||||
this.securityDocument = new SecurityDocument(context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a URI.
|
||||
*
|
||||
* @param swaggerUri the URI
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(URI swaggerUri) {
|
||||
Validate.notNull(swaggerUri, "swaggerUri must not be null");
|
||||
String scheme = swaggerUri.getScheme();
|
||||
if (scheme != null && swaggerUri.getScheme().startsWith("http")) {
|
||||
try {
|
||||
return from(swaggerUri.toURL());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException("Failed to convert URI to URL", e);
|
||||
}
|
||||
} else if (scheme != null && swaggerUri.getScheme().startsWith("file")) {
|
||||
return from(Paths.get(swaggerUri));
|
||||
} else {
|
||||
return from(URIUtils.convertUriWithoutSchemeToFileScheme(swaggerUri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder using a remote URL.
|
||||
*
|
||||
* @param swaggerURL the remote URL
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(URL swaggerURL) {
|
||||
Validate.notNull(swaggerURL, "swaggerURL must not be null");
|
||||
return new Builder(swaggerURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder using a local Path.
|
||||
*
|
||||
* @param swaggerPath the local Path
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(Path swaggerPath) {
|
||||
Validate.notNull(swaggerPath, "swaggerPath must not be null");
|
||||
if (Files.notExists(swaggerPath)) {
|
||||
throw new IllegalArgumentException(String.format("swaggerPath does not exist: %s", swaggerPath));
|
||||
}
|
||||
try {
|
||||
if (Files.isHidden(swaggerPath)) {
|
||||
throw new IllegalArgumentException("swaggerPath must not be a hidden file");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to check if swaggerPath is a hidden file", e);
|
||||
}
|
||||
return new Builder(swaggerPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger model.
|
||||
*
|
||||
* @param openAPI the Swagger source.
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(OpenAPI openAPI) {
|
||||
Validate.notNull(openAPI, "schema must not be null");
|
||||
return new Builder(openAPI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger YAML or JSON String.
|
||||
*
|
||||
* @param swaggerString the Swagger YAML or JSON String.
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(String swaggerString) {
|
||||
Validate.notEmpty(swaggerString, "swaggerString must not be null");
|
||||
return from(new StringReader(swaggerString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger YAML or JSON reader.
|
||||
*
|
||||
* @param schemaReader the schema YAML or JSON reader.
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(Reader schemaReader) {
|
||||
Validate.notNull(schemaReader, "swaggerReader must not be null");
|
||||
OpenAPI openAPI;
|
||||
try {
|
||||
//TODO
|
||||
openAPI = new OpenAPIV3Parser().read(IOUtils.toString(schemaReader));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Swagger source can not be parsed", e);
|
||||
}
|
||||
if (openAPI == null)
|
||||
throw new IllegalArgumentException("Swagger source is in a wrong format");
|
||||
|
||||
return new Builder(openAPI);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void toFolder(Path outputDirectory) {
|
||||
Validate.notNull(outputDirectory, "outputDirectory must not be null");
|
||||
openAPIContext.setOutputPath(outputDirectory);
|
||||
writeToFile(applyOverviewDocument(), outputDirectory.resolve(openAPIContext.config.getOverviewDocument()));
|
||||
writeToFile(applyPathsDocument(), outputDirectory.resolve(openAPIContext.config.getPathsDocument()));
|
||||
writeToFile(applyComponentsDocument(), outputDirectory.resolve(openAPIContext.config.getDefinitionsDocument()));
|
||||
writeToFile(applySecurityDocument(), outputDirectory.resolve(openAPIContext.config.getSecurityDocument()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toFile(Path outputFile) {
|
||||
Validate.notNull(outputFile, "outputFile must not be null");
|
||||
|
||||
writeToFile(applyOverviewDocument(), outputFile);
|
||||
writeToFile(applyPathsDocument(), outputFile);
|
||||
writeToFile(applyComponentsDocument(), outputFile);
|
||||
writeToFile(applySecurityDocument(), outputFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toFileWithoutExtension(Path outputFile) {
|
||||
Validate.notNull(outputFile, "outputFile must not be null");
|
||||
|
||||
writeToFileWithoutExtension(applyOverviewDocument(), outputFile);
|
||||
writeToFileWithoutExtension(applyPathsDocument(), outputFile);
|
||||
writeToFileWithoutExtension(applyComponentsDocument(), outputFile);
|
||||
writeToFileWithoutExtension(applySecurityDocument(), outputFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return applyOverviewDocument().convert() +
|
||||
applyPathsDocument().convert() +
|
||||
applyComponentsDocument().convert() +
|
||||
applySecurityDocument().convert();
|
||||
}
|
||||
|
||||
private Document applyOverviewDocument() {
|
||||
return overviewDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
OverviewDocument.parameters(openAPIContext.getSchema()));
|
||||
}
|
||||
|
||||
private Document applyPathsDocument() {
|
||||
return pathsDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
PathsDocument.parameters(openAPIContext.getSchema()));
|
||||
}
|
||||
|
||||
private Document applyComponentsDocument() {
|
||||
return componentsDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
ComponentsDocument.parameters(openAPIContext.getSchema().getComponents()));
|
||||
}
|
||||
|
||||
private Document applySecurityDocument() {
|
||||
return securityDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
SecurityDocument.parameters(openAPIContext.getSchema()));
|
||||
}
|
||||
|
||||
private void writeToFile(Document document, Path path) {
|
||||
MarkupLanguage markupLanguage = openAPIContext.config.getMarkupLanguage();
|
||||
if (isMarkupLanguageSupported(markupLanguage)) {
|
||||
String fileExtension = markupLanguage.getFileNameExtensions().get(0);
|
||||
writeToFileWithoutExtension(document, path.resolveSibling(path.getFileName().toString() + fileExtension));
|
||||
} else {
|
||||
throw new RuntimeException("Given Markup language '"+markupLanguage+"' is not supported by "+getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMarkupLanguageSupported(MarkupLanguage markupLanguage) {
|
||||
return markupLanguage == MarkupLanguage.ASCIIDOC;
|
||||
}
|
||||
|
||||
private void writeToFileWithoutExtension(Document document, Path file) {
|
||||
if (file.getParent() != null) {
|
||||
try {
|
||||
Files.createDirectories(file.getParent());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed create directory", e);
|
||||
}
|
||||
}
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
|
||||
writer.write(document.convert());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to write file", e);
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Markup document written to: {}", file);
|
||||
}
|
||||
}
|
||||
|
||||
public static class OpenAPIContext extends Context<OpenAPI> {
|
||||
private OpenSchema2MarkupConfig config;
|
||||
private OpenAPI2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
public OpenAPIContext(OpenSchema2MarkupConfig config,
|
||||
OpenAPI2MarkupExtensionRegistry extensionRegistry,
|
||||
OpenAPI schema, URI swaggerLocation, Labels labels) {
|
||||
super(config, extensionRegistry, schema, swaggerLocation, labels);
|
||||
this.config = config;
|
||||
this.extensionRegistry = extensionRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenSchema2MarkupConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenAPI2MarkupExtensionRegistry getExtensionRegistry() {
|
||||
return extensionRegistry;
|
||||
}
|
||||
|
||||
public Document createDocument() {
|
||||
return new DocumentImpl();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final OpenAPI openAPI;
|
||||
private final URI schemaLocation;
|
||||
private OpenSchema2MarkupConfig config;
|
||||
private OpenAPI2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
/**
|
||||
* Creates a Builder from a remote URL.
|
||||
*
|
||||
* @param schemaUrl the remote URL
|
||||
*/
|
||||
Builder(URL schemaUrl) {
|
||||
try {
|
||||
this.schemaLocation = schemaUrl.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException("swaggerURL is in a wrong format", e);
|
||||
}
|
||||
this.openAPI = readSchema(schemaUrl.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder from a local Path.
|
||||
*
|
||||
* @param swaggerPath the local Path
|
||||
*/
|
||||
Builder(Path swaggerPath) {
|
||||
this.schemaLocation = swaggerPath.toAbsolutePath().toUri();
|
||||
this.openAPI = readSchema(swaggerPath.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder using a given Swagger model.
|
||||
*
|
||||
* @param openAPI the Swagger source.
|
||||
*/
|
||||
Builder(OpenAPI openAPI) {
|
||||
this.openAPI = openAPI;
|
||||
this.schemaLocation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the SwaggerParser to read the Swagger source.
|
||||
*
|
||||
* @param schemaLocation the location of the Swagger source
|
||||
* @return the Swagger model
|
||||
*/
|
||||
private OpenAPI readSchema(String schemaLocation) {
|
||||
OpenAPI openAPI = new OpenAPIV3Parser().read(schemaLocation);
|
||||
if (openAPI == null) {
|
||||
throw new IllegalArgumentException("Failed to read the schema");
|
||||
}
|
||||
return openAPI;
|
||||
}
|
||||
|
||||
public Builder withConfig(OpenSchema2MarkupConfig config) {
|
||||
Validate.notNull(config, "config must not be null");
|
||||
this.config = config;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withExtensionRegistry(OpenAPI2MarkupExtensionRegistry registry) {
|
||||
Validate.notNull(registry, "registry must not be null");
|
||||
this.extensionRegistry = registry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupConverter build() {
|
||||
if (config == null)
|
||||
config = new OpenAPI2MarkupConfigBuilder().build();
|
||||
|
||||
if (extensionRegistry == null)
|
||||
extensionRegistry = new OpenAPI2MarkupExtensionRegistryBuilder().build();
|
||||
OpenAPILabels openApiLabels = new OpenAPILabels(config);
|
||||
OpenAPIContext context = new OpenAPIContext(config, extensionRegistry, openAPI, schemaLocation, openApiLabels);
|
||||
|
||||
initExtensions(context);
|
||||
|
||||
applySwaggerExtensions(context);
|
||||
|
||||
return new OpenAPI2MarkupConverter(context);
|
||||
}
|
||||
|
||||
private void initExtensions(OpenAPIContext context) {
|
||||
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getDefinitionsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getSecurityDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
}
|
||||
|
||||
private void applySwaggerExtensions(OpenAPIContext context) {
|
||||
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.apply(context.getSchema()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup;
|
||||
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class OpenAPI2MarkupProperties extends Schema2MarkupProperties {
|
||||
|
||||
public OpenAPI2MarkupProperties(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupProperties(Map<String, String> map) {
|
||||
super(map);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupProperties(Configuration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.github.swagger2markup;
|
||||
|
||||
import io.github.swagger2markup.config.builder.Schema2MarkupConfigBuilder;
|
||||
|
||||
public class OpenSchema2MarkupConfig extends Schema2MarkupConfigBuilder.DefaultSchema2MarkupConfig {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package io.github.swagger2markup.config;
|
||||
|
||||
import io.github.swagger2markup.Labels;
|
||||
import io.github.swagger2markup.OpenSchema2MarkupConfig;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class OpenAPILabels extends Labels {
|
||||
|
||||
public static final String LABEL_CONTENT = "label_content";
|
||||
public static final String LABEL_DEFAULT = "label_default";
|
||||
public static final String LABEL_DEPRECATED = "label_deprecated";
|
||||
public static final String LABEL_EXAMPLE = "label_example";
|
||||
public static final String LABEL_EXAMPLES = "label_examples";
|
||||
public static final String LABEL_EXCLUSIVE_MAXIMUM = "label_exclusive_maximum";
|
||||
public static final String LABEL_EXCLUSIVE_MINIMUM = "label_exclusive_minimum";
|
||||
public static final String LABEL_EXTERNAL_VALUE = "label_external_value";
|
||||
public static final String LABEL_FORMAT = "label_format";
|
||||
public static final String LABEL_MAXIMUM = "label_maximum";
|
||||
public static final String LABEL_MAX_ITEMS = "label_max_items";
|
||||
public static final String LABEL_MAX_LENGTH = "label_max_length";
|
||||
public static final String LABEL_MAX_PROPERTIES = "label_max_properties";
|
||||
public static final String LABEL_MINIMUM = "label_minimum";
|
||||
public static final String LABEL_MIN_ITEMS = "label_min_items";
|
||||
public static final String LABEL_MIN_LENGTH = "label_min_length";
|
||||
public static final String LABEL_MIN_PROPERTIES = "label_min_properties";
|
||||
public static final String LABEL_MULTIPLE_OF = "label_multiple_of";
|
||||
public static final String LABEL_NO_LINKS = "label_no_links";
|
||||
public static final String LABEL_NULLABLE = "label_nullable";
|
||||
public static final String LABEL_OPERATION = "label_operation";
|
||||
public static final String LABEL_OPTIONAL = "label_optional";
|
||||
public static final String LABEL_PARAMETERS = "label_parameters";
|
||||
public static final String LABEL_READ_ONLY = "label_read_only";
|
||||
public static final String LABEL_REQUIRED = "label_required";
|
||||
public static final String LABEL_SERVER = "label_server";
|
||||
public static final String LABEL_TERMS_OF_SERVICE = "label_terms_of_service";
|
||||
public static final String LABEL_TITLE = "label_title";
|
||||
public static final String LABEL_TYPE = "label_type";
|
||||
public static final String LABEL_UNIQUE_ITEMS = "label_unique_items";
|
||||
public static final String LABEL_WRITE_ONLY = "label_write_only";
|
||||
public static final String SECTION_TITLE_COMPONENTS = "section_title_components";
|
||||
public static final String SECTION_TITLE_PARAMETERS = "section_title_parameters";
|
||||
public static final String SECTION_TITLE_PATHS = "section_title_paths";
|
||||
public static final String SECTION_TITLE_SCHEMAS = "section_title_schemas";
|
||||
public static final String SECTION_TITLE_SECURITY = "section_title_security";
|
||||
public static final String SECTION_TITLE_SERVERS = "section_title_servers";
|
||||
public static final String SECTION_TITLE_OVERVIEW = "section_title_overview";
|
||||
public static final String SECTION_TITLE_TAGS = "section_title_tags";
|
||||
public static final String SECTION_TITLE_RESPONSES = "section_title_responses";
|
||||
public static final String SECTION_TITLE_HEADERS = "section_title_headers";
|
||||
public static final String SECTION_TITLE_LINKS = "section_title_links";
|
||||
public static final String TABLE_HEADER_DEFAULT = "table_header_default";
|
||||
public static final String TABLE_HEADER_DESCRIPTION = "table_header_description";
|
||||
public static final String TABLE_HEADER_HTTP_CODE = "table_header_http_code";
|
||||
public static final String TABLE_HEADER_LINKS = "table_header_links";
|
||||
public static final String TABLE_HEADER_NAME = "table_header_name";
|
||||
public static final String TABLE_HEADER_POSSIBLE_VALUES = "table_header_possible_values";
|
||||
public static final String TABLE_HEADER_SCHEMA = "table_header_schema";
|
||||
public static final String TABLE_HEADER_SCOPES = "table_header_scopes";
|
||||
public static final String TABLE_HEADER_TYPE = "table_header_type";
|
||||
public static final String TABLE_HEADER_VARIABLE = "table_header_variable";
|
||||
public static final String TABLE_TITLE_HEADERS = "table_title_headers";
|
||||
public static final String TABLE_TITLE_PARAMETERS = "table_title_parameters";
|
||||
public static final String TABLE_TITLE_PROPERTIES = "table_title_properties";
|
||||
public static final String TABLE_TITLE_RESPONSES = "table_title_responses";
|
||||
public static final String TABLE_TITLE_SECURITY = "table_title_security";
|
||||
public static final String TABLE_TITLE_SERVER_VARIABLES = "table_title_server_variables";
|
||||
|
||||
public OpenAPILabels(OpenSchema2MarkupConfig config) {
|
||||
super(ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getLanguage().toLocale()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.github.swagger2markup.config.builder;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupProperties;
|
||||
import io.github.swagger2markup.OpenSchema2MarkupConfig;
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
import org.apache.commons.configuration2.ConfigurationConverter;
|
||||
import org.apache.commons.configuration2.MapConfiguration;
|
||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class OpenAPI2MarkupConfigBuilder extends Schema2MarkupConfigBuilder<OpenAPI2MarkupConfigBuilder, OpenSchema2MarkupConfig> {
|
||||
|
||||
public OpenAPI2MarkupConfigBuilder() {
|
||||
this(new PropertiesConfiguration());
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupConfigBuilder(Properties properties) {
|
||||
this(ConfigurationConverter.getConfiguration(properties));
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupConfigBuilder(Map<String, String> map) {
|
||||
this(new MapConfiguration(map));
|
||||
}
|
||||
|
||||
private OpenAPI2MarkupConfigBuilder(Configuration configuration) {
|
||||
super(OpenAPI2MarkupConfigBuilder.class,
|
||||
new OpenSchema2MarkupConfig(),
|
||||
new OpenAPI2MarkupProperties(getCompositeConfiguration(configuration)), configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenSchema2MarkupConfig build() {
|
||||
buildNaturalOrdering();
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter.OpenAPIContext;
|
||||
|
||||
/**
|
||||
* An abstract OpenAPI extension which must be extended by an other OpenAPI extensions
|
||||
*/
|
||||
abstract class AbstractExtension implements Extension {
|
||||
|
||||
protected OpenAPIContext globalContext;
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
public void setGlobalContext(OpenAPIContext globalContext) {
|
||||
this.globalContext = globalContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
public class ContentContext {
|
||||
private Document document;
|
||||
|
||||
public ContentContext(Document document) {
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
public Document getDocument() {
|
||||
return document;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import io.swagger.models.Model;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
|
||||
*/
|
||||
public abstract class DefinitionsDocumentExtension extends AbstractExtension {
|
||||
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DOCUMENT_AFTER,
|
||||
DEFINITION_BEFORE,
|
||||
DEFINITION_BEGIN,
|
||||
DEFINITION_END,
|
||||
DEFINITION_AFTER
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private String definitionName;
|
||||
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private Model model;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
* @param definitionName the name of the current definition
|
||||
* @param model the current Model of the definition
|
||||
*/
|
||||
public Context(Position position, Document document, String definitionName, Model model) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DEFINITION_BEFORE, Position.DEFINITION_AFTER, position);
|
||||
Validate.notNull(definitionName);
|
||||
Validate.notNull(model);
|
||||
this.position = position;
|
||||
this.definitionName = definitionName;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<String> getDefinitionName() {
|
||||
return Optional.ofNullable(definitionName);
|
||||
}
|
||||
|
||||
public Optional<Model> getModel() {
|
||||
return Optional.ofNullable(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import static io.github.swagger2markup.OpenAPI2MarkupConverter.OpenAPIContext;
|
||||
|
||||
/**
|
||||
* Extension interface which must be implemented by an OpenAPI extension
|
||||
*/
|
||||
interface Extension {
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
void setGlobalContext(OpenAPIContext globalContext);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import io.github.swagger2markup.OpenSchema2MarkupConfig;
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.Labels;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.vavr.Function2;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class MarkupComponent<D, T, R> implements Function2<D, T, R> {
|
||||
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
protected OpenAPI2MarkupConverter.Context<OpenAPI> context;
|
||||
protected Labels labels;
|
||||
protected OpenSchema2MarkupConfig config;
|
||||
protected OpenAPI2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
public MarkupComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
this.context = context;
|
||||
this.config = context.getConfig();
|
||||
this.extensionRegistry = context.getExtensionRegistry();
|
||||
this.labels = context.getLabels();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Extension points registry interface.
|
||||
*/
|
||||
public interface OpenAPI2MarkupExtensionRegistry extends Schema2MarkupExtensionRegistry {
|
||||
/**
|
||||
* OpenAPIModelExtension extension point can be used to preprocess the Swagger model.
|
||||
*
|
||||
* @return registered extensions extending OpenAPIModelExtension extension point
|
||||
*/
|
||||
List<OpenAPIModelExtension> getSwaggerModelExtensions();
|
||||
|
||||
/**
|
||||
* OverviewDocumentExtension extension point can be used to extend the overview document content.
|
||||
*
|
||||
* @return registered extensions extending OverviewDocumentExtension extension point
|
||||
*/
|
||||
List<OverviewDocumentExtension> getOverviewDocumentExtensions();
|
||||
|
||||
/**
|
||||
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
|
||||
*
|
||||
* @return registered extensions extending DefinitionsDocumentExtension extension point
|
||||
*/
|
||||
List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions();
|
||||
|
||||
/**
|
||||
* SecurityContentExtension extension point can be used to extend the security document content.
|
||||
*
|
||||
* @return registered extensions extending SecurityContentExtension extension point
|
||||
*/
|
||||
List<SecurityDocumentExtension> getSecurityDocumentExtensions();
|
||||
|
||||
/**
|
||||
* PathsDocumentExtension extension point can be used to extend the paths document content.
|
||||
*
|
||||
* @return registered extensions extending PathsDocumentExtension extension point
|
||||
*/
|
||||
List<PathsDocumentExtension> getPathsDocumentExtensions();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
|
||||
/**
|
||||
* OpenAPIModelExtension extension point can be used to preprocess the Swagger model.
|
||||
*/
|
||||
public abstract class OpenAPIModelExtension extends AbstractExtension {
|
||||
|
||||
public abstract void apply(OpenAPI openAPI);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
/**
|
||||
* OverviewDocumentExtension extension point can be used to extend the overview document content.
|
||||
*/
|
||||
public abstract class OverviewDocumentExtension extends AbstractExtension {
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_AFTER,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import io.github.swagger2markup.model.PathOperation;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* PathsDocumentExtension extension point can be used to extend the paths document content.
|
||||
*/
|
||||
public abstract class PathsDocumentExtension extends AbstractExtension {
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DOCUMENT_AFTER,
|
||||
OPERATION_BEFORE,
|
||||
OPERATION_BEGIN,
|
||||
OPERATION_END,
|
||||
OPERATION_AFTER,
|
||||
OPERATION_DESCRIPTION_BEFORE,
|
||||
OPERATION_DESCRIPTION_BEGIN,
|
||||
OPERATION_DESCRIPTION_END,
|
||||
OPERATION_DESCRIPTION_AFTER,
|
||||
OPERATION_PARAMETERS_BEFORE,
|
||||
OPERATION_PARAMETERS_BEGIN,
|
||||
OPERATION_PARAMETERS_END,
|
||||
OPERATION_PARAMETERS_AFTER,
|
||||
OPERATION_RESPONSES_BEFORE,
|
||||
OPERATION_RESPONSES_BEGIN,
|
||||
OPERATION_RESPONSES_END,
|
||||
OPERATION_RESPONSES_AFTER,
|
||||
OPERATION_SECURITY_BEFORE,
|
||||
OPERATION_SECURITY_BEGIN,
|
||||
OPERATION_SECURITY_END,
|
||||
OPERATION_SECURITY_AFTER
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private PathOperation operation;
|
||||
|
||||
/**
|
||||
* Context for positions DOCUMENT_*
|
||||
*
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context for all other positions
|
||||
*
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
* @param operation the current path operation
|
||||
*/
|
||||
public Context(Position position, Document document, PathOperation operation) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.OPERATION_BEFORE, Position.OPERATION_SECURITY_AFTER, position);
|
||||
Validate.notNull(operation);
|
||||
this.position = position;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<PathOperation> getOperation() {
|
||||
return Optional.ofNullable(operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import io.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* SecurityContentExtension extension point can be used to extend the security document content.
|
||||
*/
|
||||
public abstract class SecurityDocumentExtension extends AbstractExtension {
|
||||
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DOCUMENT_AFTER,
|
||||
SECURITY_SCHEME_BEFORE,
|
||||
SECURITY_SCHEME_BEGIN,
|
||||
SECURITY_SCHEME_END,
|
||||
SECURITY_SCHEME_AFTER
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private String securitySchemeName;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private SecuritySchemeDefinition securityScheme;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document the MarkupDocBuilder
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document the MarkupDocBuilder
|
||||
* @param securitySchemeName the name of the current securityScheme
|
||||
* @param securityScheme the current security scheme securityScheme
|
||||
*/
|
||||
public Context(Position position, Document document, String securitySchemeName, SecuritySchemeDefinition securityScheme) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.SECURITY_SCHEME_BEFORE, Position.SECURITY_SCHEME_AFTER, position);
|
||||
Validate.notNull(securitySchemeName);
|
||||
Validate.notNull(securityScheme);
|
||||
this.position = position;
|
||||
this.securitySchemeName = securitySchemeName;
|
||||
this.securityScheme = securityScheme;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<String> getSecuritySchemeName() {
|
||||
return Optional.ofNullable(securitySchemeName);
|
||||
}
|
||||
|
||||
public Optional<SecuritySchemeDefinition> getSecurityScheme() {
|
||||
return Optional.ofNullable(securityScheme);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.github.swagger2markup.extension.builder;
|
||||
|
||||
import io.github.swagger2markup.extension.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.ServiceLoader.load;
|
||||
import static org.apache.commons.collections4.IteratorUtils.toList;
|
||||
|
||||
public class OpenAPI2MarkupExtensionRegistryBuilder {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder() {
|
||||
List<OpenAPIModelExtension> openAPIModelExtensions = toList(load(OpenAPIModelExtension.class).iterator());
|
||||
List<OverviewDocumentExtension> overviewDocumentExtensions = toList(load(OverviewDocumentExtension.class).iterator());
|
||||
List<DefinitionsDocumentExtension> definitionsDocumentExtensions = toList(load(DefinitionsDocumentExtension.class).iterator());
|
||||
List<PathsDocumentExtension> pathsDocumentExtensions = toList(load(PathsDocumentExtension.class).iterator());
|
||||
List<SecurityDocumentExtension> securityDocumentExtensions = toList(load(SecurityDocumentExtension.class).iterator());
|
||||
context = new Context(
|
||||
openAPIModelExtensions,
|
||||
overviewDocumentExtensions,
|
||||
definitionsDocumentExtensions,
|
||||
pathsDocumentExtensions,
|
||||
securityDocumentExtensions);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistry build() {
|
||||
return new DefaultOpenAPI2MarkupExtensionRegistry(context);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withSwaggerModelExtension(OpenAPIModelExtension extension) {
|
||||
context.openAPIModelExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withOverviewDocumentExtension(OverviewDocumentExtension extension) {
|
||||
context.overviewDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withDefinitionsDocumentExtension(DefinitionsDocumentExtension extension) {
|
||||
context.definitionsDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withPathsDocumentExtension(PathsDocumentExtension extension) {
|
||||
context.pathsDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withSecurityDocumentExtension(SecurityDocumentExtension extension) {
|
||||
context.securityDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
static class DefaultOpenAPI2MarkupExtensionRegistry implements OpenAPI2MarkupExtensionRegistry {
|
||||
|
||||
private Context context;
|
||||
|
||||
DefaultOpenAPI2MarkupExtensionRegistry(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OpenAPIModelExtension> getSwaggerModelExtensions() {
|
||||
return context.openAPIModelExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OverviewDocumentExtension> getOverviewDocumentExtensions() {
|
||||
return context.overviewDocumentExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions() {
|
||||
return context.definitionsDocumentExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SecurityDocumentExtension> getSecurityDocumentExtensions() {
|
||||
return context.securityDocumentExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PathsDocumentExtension> getPathsDocumentExtensions() {
|
||||
return context.pathsDocumentExtensions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Context {
|
||||
final List<OpenAPIModelExtension> openAPIModelExtensions;
|
||||
final List<OverviewDocumentExtension> overviewDocumentExtensions;
|
||||
final List<DefinitionsDocumentExtension> definitionsDocumentExtensions;
|
||||
final List<PathsDocumentExtension> pathsDocumentExtensions;
|
||||
final List<SecurityDocumentExtension> securityDocumentExtensions;
|
||||
|
||||
Context(List<OpenAPIModelExtension> openAPIModelExtensions,
|
||||
List<OverviewDocumentExtension> overviewDocumentExtensions,
|
||||
List<DefinitionsDocumentExtension> definitionsDocumentExtensions,
|
||||
List<PathsDocumentExtension> pathsDocumentExtensions,
|
||||
List<SecurityDocumentExtension> securityDocumentExtensions) {
|
||||
this.openAPIModelExtensions = openAPIModelExtensions;
|
||||
this.overviewDocumentExtensions = overviewDocumentExtensions;
|
||||
this.definitionsDocumentExtensions = definitionsDocumentExtensions;
|
||||
this.pathsDocumentExtensions = pathsDocumentExtensions;
|
||||
this.securityDocumentExtensions = securityDocumentExtensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.media.Encoding;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLES;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.italicUnconstrained;
|
||||
|
||||
public class EncodingComponent extends MarkupComponent<StructuralNode, EncodingComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final HeadersComponent headersComponent;
|
||||
|
||||
public EncodingComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.headersComponent = new HeadersComponent(context);
|
||||
}
|
||||
|
||||
public static EncodingComponent.Parameters parameters(Map<String, Encoding> encodings) {
|
||||
return new EncodingComponent.Parameters(encodings);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Map<String, Encoding> encodings) {
|
||||
return apply(node, parameters(encodings));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, EncodingComponent.Parameters parameters) {
|
||||
Map<String, Encoding> encodings = parameters.encodings;
|
||||
if (encodings == null || encodings.isEmpty()) return node;
|
||||
|
||||
DescriptionListImpl encodingList = new DescriptionListImpl(node);
|
||||
encodingList.setTitle(labels.getLabel(LABEL_EXAMPLES));
|
||||
|
||||
encodings.forEach((name, encoding) -> {
|
||||
DescriptionListEntryImpl encodingEntry = new DescriptionListEntryImpl(encodingList, Collections.singletonList(new ListItemImpl(encodingList, name)));
|
||||
ListItemImpl tagDesc = new ListItemImpl(encodingEntry, "");
|
||||
ParagraphBlockImpl encodingBlock = new ParagraphBlockImpl(tagDesc);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String contentType = encoding.getContentType();
|
||||
if(StringUtils.isNotBlank(contentType)){
|
||||
sb.append("Content-Type:").append(contentType).append(LINE_SEPARATOR);
|
||||
}
|
||||
if(encoding.getAllowReserved()){
|
||||
sb.append(italicUnconstrained("Allow Reserved").toLowerCase()).append(LINE_SEPARATOR);
|
||||
}
|
||||
if(encoding.getExplode()){
|
||||
sb.append(italicUnconstrained("Explode").toLowerCase()).append(LINE_SEPARATOR);
|
||||
}
|
||||
Encoding.StyleEnum style = encoding.getStyle();
|
||||
if(style != null){
|
||||
sb.append("style").append(style).append(LINE_SEPARATOR);
|
||||
}
|
||||
encodingBlock.setSource(sb.toString());
|
||||
tagDesc.append(encodingBlock);
|
||||
headersComponent.apply(tagDesc, encoding.getHeaders());
|
||||
|
||||
encodingEntry.setDescription(tagDesc);
|
||||
|
||||
encodingList.addEntry(encodingEntry);
|
||||
});
|
||||
node.append(encodingList);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Encoding> encodings;
|
||||
|
||||
public Parameters(Map<String, Encoding> encodings) {
|
||||
this.encodings = encodings;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.examples.Example;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLES;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXTERNAL_VALUE;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.appendDescription;
|
||||
|
||||
public class ExamplesComponent extends MarkupComponent<StructuralNode, ExamplesComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final MediaTypeExampleComponent mediaTypeExampleComponent;
|
||||
|
||||
public ExamplesComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.mediaTypeExampleComponent = new MediaTypeExampleComponent(context);
|
||||
}
|
||||
|
||||
public static ExamplesComponent.Parameters parameters(Map<String, Example> examples) {
|
||||
return new ExamplesComponent.Parameters(examples);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Map<String, Example> examples) {
|
||||
return apply(node, parameters(examples));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, ExamplesComponent.Parameters parameters) {
|
||||
Map<String, Example> examples = parameters.examples;
|
||||
if (examples == null || examples.isEmpty()) return node;
|
||||
|
||||
DescriptionListImpl examplesList = new DescriptionListImpl(node);
|
||||
examplesList.setTitle(labels.getLabel(LABEL_EXAMPLES));
|
||||
|
||||
examples.forEach((name, example) -> {
|
||||
DescriptionListEntryImpl exampleEntry = new DescriptionListEntryImpl(examplesList, Collections.singletonList(new ListItemImpl(examplesList, name)));
|
||||
ListItemImpl tagDesc = new ListItemImpl(exampleEntry, "");
|
||||
|
||||
ParagraphBlockImpl exampleBlock = new ParagraphBlockImpl(tagDesc);
|
||||
|
||||
appendDescription(exampleBlock, example.getSummary());
|
||||
appendDescription(exampleBlock, example.getDescription());
|
||||
mediaTypeExampleComponent.apply(tagDesc, example.getValue());
|
||||
|
||||
ParagraphBlockImpl paragraphBlock = new ParagraphBlockImpl(tagDesc);
|
||||
String source = "";
|
||||
generateRefLink(source, example.getExternalValue(), labels.getLabel(LABEL_EXTERNAL_VALUE));
|
||||
generateRefLink(source, example.get$ref(), "");
|
||||
if(StringUtils.isNotBlank(source)){
|
||||
paragraphBlock.setSource(source);
|
||||
tagDesc.append(paragraphBlock);
|
||||
}
|
||||
|
||||
exampleEntry.setDescription(tagDesc);
|
||||
|
||||
examplesList.addEntry(exampleEntry);
|
||||
});
|
||||
node.append(examplesList);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private String generateRefLink(String source, String ref, String alt) {
|
||||
if (StringUtils.isNotBlank(ref)) {
|
||||
if (StringUtils.isBlank(alt)) {
|
||||
alt = ref.substring(ref.lastIndexOf('/') + 1);
|
||||
}
|
||||
String anchor = ref.replaceFirst("#", "").replaceAll("/", "_");
|
||||
source += "<<" + anchor + "," + alt + ">>" + LINE_SEPARATOR;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Example> examples;
|
||||
|
||||
public Parameters(Map<String, Example> examples) {
|
||||
this.examples = examples;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.swagger.v3.oas.models.ExternalDocumentation;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
|
||||
public class ExternalDocumentationComponent extends MarkupComponent<StructuralNode, ExternalDocumentationComponent.Parameters, StructuralNode> {
|
||||
|
||||
public ExternalDocumentationComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(ExternalDocumentation externalDocs) {
|
||||
return new Parameters(externalDocs);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, ExternalDocumentation externalDocs) {
|
||||
return apply(node, parameters(externalDocs));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, Parameters params) {
|
||||
ExternalDocumentation externalDocs = params.externalDocs;
|
||||
if (externalDocs == null) return node;
|
||||
|
||||
String url = externalDocs.getUrl();
|
||||
if (StringUtils.isNotBlank(url)) {
|
||||
Block paragraph = new ParagraphBlockImpl(node);
|
||||
String desc = externalDocs.getDescription();
|
||||
paragraph.setSource(url + (StringUtils.isNotBlank(desc) ? "[" + desc + "]" : ""));
|
||||
node.append(paragraph);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final ExternalDocumentation externalDocs;
|
||||
|
||||
public Parameters(ExternalDocumentation externalDocs) {
|
||||
this.externalDocs = externalDocs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.headers.Header;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.generateInnerDoc;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.getSchemaTypeAsString;
|
||||
|
||||
public class HeadersComponent extends MarkupComponent<StructuralNode, HeadersComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final SchemaComponent schemaComponent;
|
||||
|
||||
public HeadersComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
}
|
||||
|
||||
public static HeadersComponent.Parameters parameters(Map<String, Header> headers) {
|
||||
return new HeadersComponent.Parameters(headers);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Map<String, Header> headers) {
|
||||
return apply(node, parameters(headers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, HeadersComponent.Parameters parameters) {
|
||||
Map<String, Header> headers = parameters.headers;
|
||||
if (null == headers || headers.isEmpty()) return node;
|
||||
|
||||
TableImpl responseHeadersTable = new TableImpl(node, new HashMap<>(), new ArrayList<>());
|
||||
responseHeadersTable.setOption("header");
|
||||
responseHeadersTable.setAttribute("caption", "", true);
|
||||
responseHeadersTable.setAttribute("cols", ".^2a,.^14a,.^4a", true);
|
||||
responseHeadersTable.setTitle(labels.getLabel(TABLE_TITLE_HEADERS));
|
||||
responseHeadersTable.setHeaderRow(labels.getLabel(TABLE_HEADER_NAME), labels.getLabel(TABLE_HEADER_DESCRIPTION), labels.getLabel(TABLE_HEADER_SCHEMA));
|
||||
headers.forEach((name, header) ->
|
||||
responseHeadersTable.addRow(
|
||||
generateInnerDoc(responseHeadersTable, name),
|
||||
generateInnerDoc(responseHeadersTable, Optional.ofNullable(header.getDescription()).orElse("")),
|
||||
generateInnerDoc(responseHeadersTable, getSchemaTypeAsString(header.getSchema()))
|
||||
));
|
||||
node.append(responseHeadersTable);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Header> headers;
|
||||
|
||||
public Parameters(Map<String, Header> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.links.Link;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.italicUnconstrained;
|
||||
|
||||
public class LinkComponent extends MarkupComponent<StructuralNode, LinkComponent.Parameters, StructuralNode> {
|
||||
|
||||
public LinkComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static LinkComponent.Parameters parameters(Map<String, Link> links) {
|
||||
return new LinkComponent.Parameters(links);
|
||||
}
|
||||
|
||||
public Document apply(StructuralNode parent, Map<String, Link> links) {
|
||||
return apply(parent, parameters(links));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(StructuralNode parent, LinkComponent.Parameters parameters) {
|
||||
DocumentImpl linksDocument = new DocumentImpl(parent);
|
||||
ParagraphBlockImpl linkParagraph = new ParagraphBlockImpl(linksDocument);
|
||||
|
||||
Map<String, Link> links = parameters.links;
|
||||
if (null == links || links.isEmpty()) {
|
||||
linkParagraph.setSource(labels.getLabel(LABEL_NO_LINKS));
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
links.forEach((name, link) -> {
|
||||
sb.append(name).append(" +").append(LINE_SEPARATOR);
|
||||
sb.append(italicUnconstrained(labels.getLabel(LABEL_OPERATION))).append(' ')
|
||||
.append(italicUnconstrained(link.getOperationId())).append(" +").append(LINE_SEPARATOR);
|
||||
Map<String, String> linkParameters = link.getParameters();
|
||||
if (null != linkParameters && !linkParameters.isEmpty()) {
|
||||
sb.append(italicUnconstrained(labels.getLabel(LABEL_PARAMETERS))).append(" {").append(" +").append(LINE_SEPARATOR);
|
||||
linkParameters.forEach((param, value) ->
|
||||
sb.append('"').append(param).append("\": \"").append(value).append('"').append(" +").append(LINE_SEPARATOR)
|
||||
);
|
||||
sb.append('}').append(" +").append(LINE_SEPARATOR);
|
||||
}
|
||||
});
|
||||
linkParagraph.setSource(sb.toString());
|
||||
}
|
||||
linksDocument.append(linkParagraph);
|
||||
return linksDocument;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final Map<String, Link> links;
|
||||
|
||||
public Parameters(Map<String, Link> links) {
|
||||
this.links = links;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.media.Content;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_CONTENT;
|
||||
|
||||
public class MediaContentComponent extends MarkupComponent<StructuralNode, MediaContentComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final MediaTypeExampleComponent mediaTypeExampleComponent;
|
||||
private final ExamplesComponent examplesComponent;
|
||||
private final SchemaComponent schemaComponent;
|
||||
private final EncodingComponent encodingComponent;
|
||||
|
||||
public MediaContentComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.mediaTypeExampleComponent = new MediaTypeExampleComponent(context);
|
||||
this.examplesComponent = new ExamplesComponent(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
this.encodingComponent = new EncodingComponent(context);
|
||||
}
|
||||
|
||||
public static MediaContentComponent.Parameters parameters(Content content) {
|
||||
return new MediaContentComponent.Parameters(content);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Content content) {
|
||||
return apply(node, parameters(content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, MediaContentComponent.Parameters parameters) {
|
||||
Content content = parameters.content;
|
||||
if (content == null || content.isEmpty()) return node;
|
||||
|
||||
DescriptionListImpl mediaContentList = new DescriptionListImpl(node);
|
||||
mediaContentList.setTitle(labels.getLabel(LABEL_CONTENT));
|
||||
|
||||
content.forEach((type, mediaType) -> {
|
||||
DescriptionListEntryImpl tagEntry = new DescriptionListEntryImpl(mediaContentList, Collections.singletonList(new ListItemImpl(mediaContentList, type)));
|
||||
ListItemImpl tagDesc = new ListItemImpl(tagEntry, "");
|
||||
|
||||
Document tagDescDocument = schemaComponent.apply(mediaContentList, mediaType.getSchema());
|
||||
mediaTypeExampleComponent.apply(tagDescDocument, mediaType.getExample());
|
||||
examplesComponent.apply(tagDescDocument, mediaType.getExamples());
|
||||
encodingComponent.apply(tagDescDocument, mediaType.getEncoding());
|
||||
tagDesc.append(tagDescDocument);
|
||||
|
||||
tagEntry.setDescription(tagDesc);
|
||||
mediaContentList.addEntry(tagEntry);
|
||||
});
|
||||
node.append(mediaContentList);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Content content;
|
||||
|
||||
public Parameters(Content content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.DELIMITER_BLOCK;
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLE;
|
||||
|
||||
public class MediaTypeExampleComponent extends MarkupComponent<StructuralNode, MediaTypeExampleComponent.Parameters, StructuralNode> {
|
||||
|
||||
public MediaTypeExampleComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static MediaTypeExampleComponent.Parameters parameters(Object example) {
|
||||
return new MediaTypeExampleComponent.Parameters(example);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Object example) {
|
||||
return apply(node, parameters(example));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, MediaTypeExampleComponent.Parameters parameters) {
|
||||
Object example = parameters.example;
|
||||
if (example == null || StringUtils.isBlank(example.toString())) return node;
|
||||
|
||||
ParagraphBlockImpl sourceBlock = new ParagraphBlockImpl(node);
|
||||
sourceBlock.setTitle(labels.getLabel(LABEL_EXAMPLE));
|
||||
sourceBlock.setAttribute("style", "source", true);
|
||||
sourceBlock.setSource(DELIMITER_BLOCK + LINE_SEPARATOR + example + LINE_SEPARATOR + DELIMITER_BLOCK);
|
||||
node.append(sourceBlock);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Object example;
|
||||
|
||||
public Parameters(Object example) {
|
||||
this.example = example;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class ParametersComponent extends MarkupComponent<StructuralNode, ParametersComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final SchemaComponent schemaComponent;
|
||||
|
||||
public ParametersComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
}
|
||||
|
||||
public static ParametersComponent.Parameters parameters(Map<String, Parameter> parameters) {
|
||||
return new ParametersComponent.Parameters(parameters);
|
||||
}
|
||||
|
||||
public static ParametersComponent.Parameters parameters(List<Parameter> parameters) {
|
||||
if(null == parameters) {
|
||||
return new ParametersComponent.Parameters(new HashMap<>());
|
||||
}
|
||||
return new ParametersComponent.Parameters(parameters.stream().collect(Collectors.toMap(Parameter::getName, parameter -> parameter)));
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, List<Parameter> params) {
|
||||
return apply(parent, parameters(params));
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, Map<String, Parameter> params) {
|
||||
return apply(parent, parameters(params));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode parent, ParametersComponent.Parameters componentParameters) {
|
||||
Map<String, Parameter> parameters = componentParameters.parameters;
|
||||
if (null == parameters || parameters.isEmpty()) return parent;
|
||||
|
||||
TableImpl pathParametersTable = new TableImpl(parent, new HashMap<>(), new ArrayList<>());
|
||||
pathParametersTable.setOption("header");
|
||||
pathParametersTable.setAttribute("caption", "", true);
|
||||
pathParametersTable.setAttribute("cols", ".^2a,.^3a,.^10a,.^5a", true);
|
||||
pathParametersTable.setTitle(labels.getLabel(TABLE_TITLE_PARAMETERS));
|
||||
pathParametersTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_TYPE),
|
||||
labels.getLabel(TABLE_HEADER_NAME),
|
||||
labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_SCHEMA));
|
||||
|
||||
parameters.forEach((alt, parameter) ->
|
||||
pathParametersTable.addRow(
|
||||
generateInnerDoc(pathParametersTable, boldUnconstrained(parameter.getIn()), alt),
|
||||
getParameterNameDocument(pathParametersTable, parameter),
|
||||
generateInnerDoc(pathParametersTable, Optional.ofNullable(parameter.getDescription()).orElse("")),
|
||||
generateInnerDoc(pathParametersTable, getSchemaTypeAsString(parameter.getSchema()))
|
||||
));
|
||||
parent.append(pathParametersTable);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
private Document getParameterNameDocument(Table table, Parameter parameter) {
|
||||
String documentContent = boldUnconstrained(parameter.getName()) + " +" + LINE_SEPARATOR + requiredIndicator(parameter.getRequired(),
|
||||
labels.getLabel(LABEL_REQUIRED), labels.getLabel(LABEL_OPTIONAL));
|
||||
return generateInnerDoc(table, documentContent);
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Parameter> parameters;
|
||||
|
||||
public Parameters(Map<String, Parameter> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class PropertiesTableComponent extends MarkupComponent<StructuralNode, PropertiesTableComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final SchemaComponent schemaComponent;
|
||||
|
||||
PropertiesTableComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(@SuppressWarnings("rawtypes") Map<String, Schema> properties, List<String> schemaRequired) {
|
||||
return new Parameters(properties, schemaRequired);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, @SuppressWarnings("rawtypes") Map<String, Schema> properties, List<String> schemaRequired) {
|
||||
return apply(parent, parameters(properties, schemaRequired));
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, Parameters params) {
|
||||
@SuppressWarnings("rawtypes") Map<String, Schema> properties = params.properties;
|
||||
List<String> schemaRequired = params.schemaRequired;
|
||||
|
||||
if (null == properties || properties.isEmpty()) return parent;
|
||||
|
||||
List<String> finalSchemaRequired = (null == schemaRequired) ? new ArrayList<>() : schemaRequired;
|
||||
|
||||
TableImpl propertiesTable = new TableImpl(parent, new HashMap<>(), new ArrayList<>());
|
||||
propertiesTable.setOption("header");
|
||||
propertiesTable.setAttribute("caption", "", true);
|
||||
propertiesTable.setAttribute("cols", ".^4a,.^16a,.^4a", true);
|
||||
propertiesTable.setTitle(labels.getLabel(TABLE_TITLE_PROPERTIES));
|
||||
propertiesTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_NAME),
|
||||
labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_SCHEMA));
|
||||
|
||||
properties.forEach((name, schema) -> propertiesTable.addRow(
|
||||
generateInnerDoc(propertiesTable, name + LINE_SEPARATOR + requiredIndicator(finalSchemaRequired.contains(name),
|
||||
labels.getLabel(LABEL_REQUIRED), labels.getLabel(LABEL_OPTIONAL))),
|
||||
schemaComponent.apply(propertiesTable, schema),
|
||||
generateInnerDoc(propertiesTable, getSchemaTypeAsString(schema))
|
||||
));
|
||||
parent.append(propertiesTable);
|
||||
return parent;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static class Parameters {
|
||||
private final Map<String, Schema> properties;
|
||||
private final List<String> schemaRequired;
|
||||
|
||||
public Parameters(Map<String, Schema> properties, List<String> schemaRequired) {
|
||||
|
||||
this.properties = properties;
|
||||
this.schemaRequired = schemaRequired;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.generateInnerDoc;
|
||||
|
||||
public class ResponseComponent extends MarkupComponent<StructuralNode, ResponseComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final HeadersComponent headersComponent;
|
||||
private final LinkComponent linkComponent;
|
||||
private final MediaContentComponent mediaContentComponent;
|
||||
|
||||
public ResponseComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.headersComponent = new HeadersComponent(context);
|
||||
this.linkComponent = new LinkComponent(context);
|
||||
this.mediaContentComponent = new MediaContentComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(Map<String, ApiResponse> apiResponses) {
|
||||
return new Parameters(apiResponses);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode serverSection, Map<String, ApiResponse> apiResponses) {
|
||||
return apply(serverSection, parameters(apiResponses));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode serverSection, Parameters params) {
|
||||
Map<String, ApiResponse> apiResponses = params.apiResponses;
|
||||
|
||||
if (null == apiResponses || apiResponses.isEmpty()) return serverSection;
|
||||
|
||||
TableImpl pathResponsesTable = new TableImpl(serverSection, new HashMap<>(), new ArrayList<>());
|
||||
pathResponsesTable.setOption("header");
|
||||
pathResponsesTable.setAttribute("caption", "", true);
|
||||
pathResponsesTable.setAttribute("cols", ".^2a,.^14a,.^4a", true);
|
||||
pathResponsesTable.setTitle(labels.getLabel(TABLE_TITLE_RESPONSES));
|
||||
pathResponsesTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_HTTP_CODE),
|
||||
labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_LINKS));
|
||||
|
||||
apiResponses.forEach((httpCode, apiResponse) ->
|
||||
pathResponsesTable.addRow(
|
||||
generateInnerDoc(pathResponsesTable, httpCode),
|
||||
getResponseDescriptionColumnDocument(pathResponsesTable, apiResponse),
|
||||
linkComponent.apply(pathResponsesTable, apiResponse.getLinks())
|
||||
));
|
||||
serverSection.append(pathResponsesTable);
|
||||
return serverSection;
|
||||
}
|
||||
|
||||
private Document getResponseDescriptionColumnDocument(Table table, ApiResponse apiResponse) {
|
||||
Document document = generateInnerDoc(table, Optional.ofNullable(apiResponse.getDescription()).orElse(""));
|
||||
headersComponent.apply(document, apiResponse.getHeaders());
|
||||
mediaContentComponent.apply(document, apiResponse.getContent());
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final Map<String, ApiResponse> apiResponses;
|
||||
|
||||
public Parameters(Map<String, ApiResponse> apiResponses) {
|
||||
|
||||
this.apiResponses = apiResponses;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.helper.OpenApiHelpers;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.boldUnconstrained;
|
||||
|
||||
public class SchemaComponent extends MarkupComponent<StructuralNode, SchemaComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final OpenAPI2MarkupConverter.OpenAPIContext context;
|
||||
|
||||
public SchemaComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static SchemaComponent.Parameters parameters(@SuppressWarnings("rawtypes") Schema schema) {
|
||||
return new SchemaComponent.Parameters(schema);
|
||||
}
|
||||
|
||||
public Document apply(StructuralNode parent, @SuppressWarnings("rawtypes") Schema schema) {
|
||||
return apply(parent, parameters(schema));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public Document apply(StructuralNode parent, SchemaComponent.Parameters parameters) {
|
||||
Document schemaDocument = new DocumentImpl(parent);
|
||||
Schema schema = parameters.schema;
|
||||
if (null == schema) return schemaDocument;
|
||||
|
||||
OpenApiHelpers.appendDescription(schemaDocument, schema.getDescription());
|
||||
|
||||
Map<String, Boolean> schemasBooleanProperties = new HashMap<String, Boolean>() {{
|
||||
put(labels.getLabel(LABEL_DEPRECATED), schema.getDeprecated());
|
||||
put(labels.getLabel(LABEL_NULLABLE), schema.getNullable());
|
||||
put(labels.getLabel(LABEL_READ_ONLY), schema.getReadOnly());
|
||||
put(labels.getLabel(LABEL_WRITE_ONLY), schema.getWriteOnly());
|
||||
put(labels.getLabel(LABEL_UNIQUE_ITEMS), schema.getUniqueItems());
|
||||
put(labels.getLabel(LABEL_EXCLUSIVE_MAXIMUM), schema.getExclusiveMaximum());
|
||||
put(labels.getLabel(LABEL_EXCLUSIVE_MINIMUM), schema.getExclusiveMinimum());
|
||||
}};
|
||||
|
||||
Map<String, Object> schemasValueProperties = new HashMap<String, Object>() {{
|
||||
put(labels.getLabel(LABEL_TITLE), schema.getTitle());
|
||||
put(labels.getLabel(LABEL_DEFAULT), schema.getDefault());
|
||||
put(labels.getLabel(LABEL_MAXIMUM), schema.getMaximum());
|
||||
put(labels.getLabel(LABEL_MINIMUM), schema.getMinimum());
|
||||
put(labels.getLabel(LABEL_MAX_LENGTH), schema.getMaxLength());
|
||||
put(labels.getLabel(LABEL_MIN_LENGTH), schema.getMinLength());
|
||||
put(labels.getLabel(LABEL_MAX_ITEMS), schema.getMaxItems());
|
||||
put(labels.getLabel(LABEL_MIN_ITEMS), schema.getMinItems());
|
||||
put(labels.getLabel(LABEL_MAX_PROPERTIES), schema.getMaxProperties());
|
||||
put(labels.getLabel(LABEL_MIN_PROPERTIES), schema.getMinProperties());
|
||||
put(labels.getLabel(LABEL_MULTIPLE_OF), schema.getMultipleOf());
|
||||
}};
|
||||
|
||||
Stream<String> schemaBooleanStream = schemasBooleanProperties.entrySet().stream()
|
||||
.filter(e -> null != e.getValue() && e.getValue())
|
||||
.map(e -> OpenApiHelpers.italicUnconstrained(e.getKey().toLowerCase()));
|
||||
Stream<String> schemaValueStream = schemasValueProperties.entrySet().stream()
|
||||
.filter(e -> null != e.getValue() && StringUtils.isNotBlank(e.getValue().toString()))
|
||||
.map(e -> boldUnconstrained(e.getKey()) + ": " + e.getValue());
|
||||
|
||||
ParagraphBlockImpl paragraphBlock = new ParagraphBlockImpl(schemaDocument);
|
||||
String source = Stream.concat(schemaBooleanStream, schemaValueStream).collect(Collectors.joining(" +" + LINE_SEPARATOR));
|
||||
paragraphBlock.setSource(source);
|
||||
|
||||
schemaDocument.append(paragraphBlock);
|
||||
|
||||
Map<String, Schema> properties = schema.getProperties();
|
||||
if (null != properties && !properties.isEmpty()) {
|
||||
PropertiesTableComponent propertiesTableComponent = new PropertiesTableComponent(context);
|
||||
propertiesTableComponent.apply(schemaDocument, properties, schema.getRequired());
|
||||
}
|
||||
|
||||
return schemaDocument;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static class Parameters {
|
||||
|
||||
private final Schema schema;
|
||||
|
||||
public Parameters(Schema schema) {
|
||||
this.schema = schema;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class SecurityRequirementTableComponent extends MarkupComponent<StructuralNode, SecurityRequirementTableComponent.Parameters, StructuralNode> {
|
||||
|
||||
public SecurityRequirementTableComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static SecurityRequirementTableComponent.Parameters parameters(List<SecurityRequirement> securityRequirements, boolean addTitle) {
|
||||
return new SecurityRequirementTableComponent.Parameters(securityRequirements, addTitle);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode document, List<SecurityRequirement> securityRequirements, boolean addTitle) {
|
||||
return apply(document, parameters(securityRequirements, addTitle));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, SecurityRequirementTableComponent.Parameters parameters) {
|
||||
List<SecurityRequirement> securityRequirements = parameters.securityRequirements;
|
||||
|
||||
if (securityRequirements == null || securityRequirements.isEmpty()) return node;
|
||||
|
||||
TableImpl securityRequirementsTable = new TableImpl(node, new HashMap<>(), new ArrayList<>());
|
||||
securityRequirementsTable.setOption("header");
|
||||
securityRequirementsTable.setAttribute("caption", "", true);
|
||||
securityRequirementsTable.setAttribute("cols", ".^3a,.^4a,.^13a", true);
|
||||
if (parameters.addTitle) {
|
||||
securityRequirementsTable.setTitle(labels.getLabel(TABLE_TITLE_SECURITY));
|
||||
}
|
||||
securityRequirementsTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_TYPE),
|
||||
labels.getLabel(TABLE_HEADER_NAME),
|
||||
labels.getLabel(TABLE_HEADER_SCOPES));
|
||||
|
||||
securityRequirements.forEach(securityRequirement ->
|
||||
securityRequirement.forEach((name, scopes) ->
|
||||
securityRequirementsTable.addRow(
|
||||
generateInnerDoc(securityRequirementsTable, boldUnconstrained(scopes.isEmpty() ? "apiKey" : "oauth2")),
|
||||
generateInnerDoc(securityRequirementsTable, name),
|
||||
generateInnerDoc(securityRequirementsTable, String.join(", ", scopes))
|
||||
)
|
||||
)
|
||||
);
|
||||
node.append(securityRequirementsTable);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final List<SecurityRequirement> securityRequirements;
|
||||
private final boolean addTitle;
|
||||
|
||||
public Parameters(List<SecurityRequirement> securityRequirements, boolean addTitle) {
|
||||
this.securityRequirements = securityRequirements;
|
||||
this.addTitle = addTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.tags.Tag;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_TAGS;
|
||||
|
||||
|
||||
public class TagsComponent extends MarkupComponent<Document, TagsComponent.Parameters, Document> {
|
||||
|
||||
private final ExternalDocumentationComponent externalDocumentationComponent;
|
||||
|
||||
public TagsComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
|
||||
}
|
||||
|
||||
public static TagsComponent.Parameters parameters(List<Tag> tags) {
|
||||
return new TagsComponent.Parameters(tags);
|
||||
}
|
||||
|
||||
public Document apply(Document document, List<Tag> tags) {
|
||||
return apply(document, parameters(tags));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, TagsComponent.Parameters parameters) {
|
||||
List<Tag> openAPITags = parameters.tags;
|
||||
if (null == openAPITags || openAPITags.isEmpty()) return document;
|
||||
|
||||
Section tagsSection = new SectionImpl(document);
|
||||
tagsSection.setTitle(labels.getLabel(SECTION_TITLE_TAGS));
|
||||
|
||||
DescriptionListImpl tagsList = new DescriptionListImpl(tagsSection);
|
||||
openAPITags.forEach(tag -> {
|
||||
DescriptionListEntryImpl tagEntry = new DescriptionListEntryImpl(tagsList, Collections.singletonList(new ListItemImpl(tagsList, tag.getName())));
|
||||
String description = tag.getDescription();
|
||||
if(StringUtils.isNotBlank(description)){
|
||||
ListItemImpl tagDesc = new ListItemImpl(tagEntry, "");
|
||||
tagDesc.setSource(description);
|
||||
externalDocumentationComponent.apply(tagDesc, tag.getExternalDocs());
|
||||
tagEntry.setDescription(tagDesc);
|
||||
}
|
||||
tagsList.addEntry(tagEntry);
|
||||
});
|
||||
|
||||
tagsSection.append(tagsList);
|
||||
document.append(tagsSection);
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final List<Tag> tags;
|
||||
|
||||
public Parameters(List<Tag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.component.*;
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.headers.Header;
|
||||
import io.swagger.v3.oas.models.links.Link;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
|
||||
public class ComponentsDocument extends MarkupComponent<Document, ComponentsDocument.Parameters, Document> {
|
||||
|
||||
private final ParametersComponent parametersComponent;
|
||||
private final ResponseComponent responseComponent;
|
||||
private final HeadersComponent headersComponent;
|
||||
private final SchemaComponent schemaComponent;
|
||||
private final LinkComponent linkComponent;
|
||||
|
||||
public ComponentsDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.parametersComponent = new ParametersComponent(context);
|
||||
this.responseComponent = new ResponseComponent(context);
|
||||
this.headersComponent = new HeadersComponent(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
this.linkComponent = new LinkComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(Components components) {
|
||||
return new Parameters(components);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, ComponentsDocument.Parameters parameters) {
|
||||
|
||||
appendComponentsSection(document, parameters.components);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final Components components;
|
||||
|
||||
public Parameters(Components components) {
|
||||
this.components = Validate.notNull(components, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendComponentsSection(Document document, Components components) {
|
||||
if (null == components) return;
|
||||
|
||||
Section componentsSection = new SectionImpl(document);
|
||||
componentsSection.setTitle(labels.getLabel(SECTION_TITLE_COMPONENTS));
|
||||
String componentSectionId = "_components";
|
||||
componentsSection.setId(componentSectionId);
|
||||
|
||||
appendComponentsSchemasSection(componentsSection, componentSectionId, components.getSchemas());
|
||||
Map<String, Parameter> parameters = components.getParameters();
|
||||
if (null != parameters && !parameters.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, parametersComponent, SECTION_TITLE_PARAMETERS,
|
||||
new ParametersComponent.Parameters(parameters));
|
||||
}
|
||||
Map<String, ApiResponse> responses = components.getResponses();
|
||||
if (null != responses && !responses.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, responseComponent, SECTION_TITLE_RESPONSES,
|
||||
new ResponseComponent.Parameters(responses));
|
||||
}
|
||||
Map<String, Header> headers = components.getHeaders();
|
||||
if (null != headers && !headers.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, headersComponent, SECTION_TITLE_HEADERS,
|
||||
new HeadersComponent.Parameters(headers));
|
||||
}
|
||||
Map<String, Link> links = components.getLinks();
|
||||
if (null != links && !links.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, linkComponent, SECTION_TITLE_LINKS,
|
||||
new LinkComponent.Parameters(links));
|
||||
}
|
||||
document.append(componentsSection);
|
||||
}
|
||||
|
||||
private void appendComponentsSchemasSection(
|
||||
Section componentsSection, String componentSectionId,
|
||||
@SuppressWarnings("rawtypes") Map<String, Schema> schemas) {
|
||||
if (null == schemas || schemas.isEmpty()) return;
|
||||
|
||||
SectionImpl schemasSection = new SectionImpl(componentsSection);
|
||||
String schemasSectionId = componentSectionId + "_schemas";
|
||||
schemasSection.setTitle(labels.getLabel(SECTION_TITLE_SCHEMAS));
|
||||
schemasSection.setId(schemasSectionId);
|
||||
schemas.forEach((name, schema) -> {
|
||||
String schemaDocumentId = schemasSectionId + "_" + name;
|
||||
Document schemaDocument = schemaComponent.apply(schemasSection, schema);
|
||||
schemaDocument.setTitle(name);
|
||||
schemaDocument.setId(schemaDocumentId);
|
||||
schemasSection.append(schemaDocument);
|
||||
});
|
||||
componentsSection.append(schemasSection);
|
||||
}
|
||||
|
||||
private <T> void appendSubSection(Section componentsSection, String componentSectionId,
|
||||
MarkupComponent<StructuralNode, T, StructuralNode> markupComponent,
|
||||
String sectionLabel, T parameters) {
|
||||
SectionImpl parametersSection = new SectionImpl(componentsSection);
|
||||
String parametersSectionId = componentSectionId + "_parameters";
|
||||
parametersSection.setTitle(labels.getLabel(sectionLabel));
|
||||
parametersSection.setId(parametersSectionId);
|
||||
markupComponent.apply(parametersSection, parameters);
|
||||
componentsSection.append(parametersSection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.BlockImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.extension.OverviewDocumentExtension;
|
||||
import io.github.swagger2markup.internal.component.ExternalDocumentationComponent;
|
||||
import io.github.swagger2markup.internal.component.TagsComponent;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_TERMS_OF_SERVICE;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_OVERVIEW;
|
||||
import static io.github.swagger2markup.extension.OverviewDocumentExtension.Context;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.appendDescription;
|
||||
|
||||
public class OverviewDocument extends MarkupComponent<Document, OverviewDocument.Parameters, Document> {
|
||||
private final TagsComponent tagsComponent;
|
||||
private final ExternalDocumentationComponent externalDocumentationComponent;
|
||||
|
||||
public OverviewDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
tagsComponent = new TagsComponent(context);
|
||||
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
|
||||
}
|
||||
|
||||
public static OverviewDocument.Parameters parameters(OpenAPI schema) {
|
||||
return new OverviewDocument.Parameters(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, Parameters parameters) {
|
||||
Info apiInfo = parameters.openAPI.getInfo();
|
||||
document.setAttribute("openapi", parameters.openAPI.getOpenapi(), true);
|
||||
addDocumentTitle(document, apiInfo);
|
||||
addAuthorInfo(document, apiInfo);
|
||||
addVersionInfo(document, apiInfo);
|
||||
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_BEFORE, document));
|
||||
Document subDocument = new DocumentImpl(document);
|
||||
Section overviewDoc = new SectionImpl(subDocument, "section", new HashMap<>(), new ArrayList<>(),
|
||||
null, new ArrayList<>(), 1, "", new ArrayList<>(),
|
||||
null, null, "", "", false, false);
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_BEGIN, subDocument));
|
||||
overviewDoc.setTitle(labels.getLabel(SECTION_TITLE_OVERVIEW));
|
||||
|
||||
appendDescription(overviewDoc, apiInfo.getDescription());
|
||||
appendTermsOfServiceInfo(overviewDoc, apiInfo);
|
||||
appendLicenseInfo(overviewDoc, apiInfo);
|
||||
subDocument.append(overviewDoc);
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_END, subDocument));
|
||||
document.append(subDocument);
|
||||
|
||||
externalDocumentationComponent.apply(document, parameters.openAPI.getExternalDocs());
|
||||
tagsComponent.apply(document, parameters.openAPI.getTags());
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_AFTER, document));
|
||||
return document;
|
||||
}
|
||||
|
||||
private void applyOverviewDocumentExtension(Context context) {
|
||||
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.apply(context));
|
||||
}
|
||||
|
||||
private void addDocumentTitle(Document rootDocument, Info apiInfo) {
|
||||
String title = apiInfo.getTitle();
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
rootDocument.setTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
private void addVersionInfo(Document rootDocument, Info info) {
|
||||
String version = info.getVersion();
|
||||
if (StringUtils.isNotBlank(version)) {
|
||||
rootDocument.setAttribute("revnumber", version, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAuthorInfo(Document rootDocument, Info info) {
|
||||
Contact contact = info.getContact();
|
||||
if (null != contact) {
|
||||
String author = Optional.ofNullable(contact.getName()).orElse("");
|
||||
String email = contact.getEmail();
|
||||
if (StringUtils.isNotBlank(email)) {
|
||||
rootDocument.setAttribute("email", email, true);
|
||||
}
|
||||
rootDocument.setAttribute("author", author, true);
|
||||
rootDocument.setAttribute("authorcount", 1L, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendLicenseInfo(Section overviewDoc, Info info) {
|
||||
License license = info.getLicense();
|
||||
if (null != license) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(license.getUrl())) {
|
||||
sb.append(license.getUrl()).append("[");
|
||||
}
|
||||
sb.append(license.getName());
|
||||
if (StringUtils.isNotBlank(license.getUrl())) {
|
||||
sb.append("]");
|
||||
}
|
||||
BlockImpl paragraph = new ParagraphBlockImpl(overviewDoc);
|
||||
paragraph.setSource(sb.toString());
|
||||
overviewDoc.append(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTermsOfServiceInfo(Section overviewDoc, Info info) {
|
||||
String termsOfService = info.getTermsOfService();
|
||||
if (StringUtils.isNotBlank(termsOfService)) {
|
||||
Block paragraph = new ParagraphBlockImpl(overviewDoc);
|
||||
paragraph.setSource(termsOfService + "[" + labels.getLabel(LABEL_TERMS_OF_SERVICE) + "]");
|
||||
overviewDoc.append(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final OpenAPI openAPI;
|
||||
|
||||
public Parameters(OpenAPI openAPI) {
|
||||
this.openAPI = Validate.notNull(openAPI, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.component.ExternalDocumentationComponent;
|
||||
import io.github.swagger2markup.internal.component.ParametersComponent;
|
||||
import io.github.swagger2markup.internal.component.ResponseComponent;
|
||||
import io.github.swagger2markup.internal.component.SecurityRequirementTableComponent;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Paths;
|
||||
import io.swagger.v3.oas.models.servers.Server;
|
||||
import io.swagger.v3.oas.models.servers.ServerVariables;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class PathsDocument extends MarkupComponent<Document, PathsDocument.Parameters, Document> {
|
||||
private final ParametersComponent parametersComponent;
|
||||
private final ExternalDocumentationComponent externalDocumentationComponent;
|
||||
private final ResponseComponent responseComponent;
|
||||
private final SecurityRequirementTableComponent securityRequirementTableComponent;
|
||||
|
||||
public PathsDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.parametersComponent = new ParametersComponent(context);
|
||||
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
|
||||
this.responseComponent = new ResponseComponent(context);
|
||||
this.securityRequirementTableComponent = new SecurityRequirementTableComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(OpenAPI schema) {
|
||||
return new Parameters(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, Parameters parameters) {
|
||||
Paths apiPaths = parameters.schema.getPaths();
|
||||
|
||||
if (null == apiPaths || apiPaths.isEmpty()) return document;
|
||||
|
||||
SectionImpl allPathsSection = new SectionImpl(document);
|
||||
allPathsSection.setTitle(labels.getLabel(SECTION_TITLE_PATHS));
|
||||
|
||||
apiPaths.forEach((name, pathItem) ->
|
||||
pathItem.readOperationsMap().forEach(((httpMethod, operation) -> {
|
||||
SectionImpl operationSection = new SectionImpl(allPathsSection);
|
||||
String summary = Optional.ofNullable(operation.getSummary()).orElse("");
|
||||
operationSection.setTitle((italicUnconstrained(httpMethod.name().toUpperCase()) + " " + monospaced(name) + " " + summary).trim());
|
||||
appendDescription(operationSection, operation.getDescription());
|
||||
externalDocumentationComponent.apply(operationSection, operation.getExternalDocs());
|
||||
parametersComponent.apply(operationSection, operation.getParameters());
|
||||
responseComponent.apply(operationSection, operation.getResponses());
|
||||
appendServersSection(operationSection, operation.getServers());
|
||||
securityRequirementTableComponent.apply(operationSection, operation.getSecurity(), false);
|
||||
allPathsSection.append(operationSection);
|
||||
})));
|
||||
|
||||
document.append(allPathsSection);
|
||||
return document;
|
||||
}
|
||||
|
||||
private void appendServersSection(StructuralNode node, List<Server> servers) {
|
||||
if (null == servers || servers.isEmpty()) return;
|
||||
|
||||
Section serversSection = new SectionImpl(node);
|
||||
serversSection.setTitle(labels.getLabel(SECTION_TITLE_SERVERS));
|
||||
|
||||
servers.forEach(server -> {
|
||||
Section serverSection = new SectionImpl(serversSection);
|
||||
serverSection.setTitle(italicUnconstrained(labels.getLabel(LABEL_SERVER)) + ": " + server.getUrl());
|
||||
|
||||
appendDescription(serverSection, server.getDescription());
|
||||
ServerVariables variables = server.getVariables();
|
||||
appendVariables(serverSection, variables);
|
||||
serversSection.append(serverSection);
|
||||
});
|
||||
node.append(serversSection);
|
||||
}
|
||||
|
||||
private void appendVariables(Section serverSection, ServerVariables variables) {
|
||||
if (null == variables || variables.isEmpty()) return;
|
||||
|
||||
TableImpl serverVariables = new TableImpl(serverSection, new HashMap<String, Object>() {{
|
||||
put("header-option", "");
|
||||
put("cols", ".^2a,.^9a,.^3a,.^4a");
|
||||
}}, new ArrayList<>());
|
||||
serverVariables.setTitle(labels.getLabel(TABLE_TITLE_SERVER_VARIABLES));
|
||||
|
||||
serverVariables.setHeaderRow(labels.getLabel(TABLE_HEADER_VARIABLE), labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_POSSIBLE_VALUES), labels.getLabel(TABLE_HEADER_DEFAULT)
|
||||
);
|
||||
|
||||
variables.forEach((name, variable) -> {
|
||||
String possibleValues = String.join(", ", Optional.ofNullable(variable.getEnum()).orElse(Collections.singletonList("Any")));
|
||||
serverVariables.addRow(name, Optional.ofNullable(variable.getDescription()).orElse(""), possibleValues, variable.getDefault());
|
||||
|
||||
});
|
||||
serverSection.append(serverVariables);
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final OpenAPI schema;
|
||||
|
||||
public Parameters(OpenAPI schema) {
|
||||
this.schema = Validate.notNull(schema, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.component.SecurityRequirementTableComponent;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_SECURITY;
|
||||
|
||||
public class SecurityDocument extends MarkupComponent<Document, SecurityDocument.Parameters, Document> {
|
||||
private final SecurityRequirementTableComponent securityRequirementTableComponent;
|
||||
|
||||
public SecurityDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.securityRequirementTableComponent = new SecurityRequirementTableComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(OpenAPI schema) {
|
||||
return new Parameters(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, SecurityDocument.Parameters parameters) {
|
||||
List<SecurityRequirement> securityRequirements = parameters.schema.getSecurity();
|
||||
if (null == securityRequirements || securityRequirements.isEmpty()) return document;
|
||||
|
||||
Section securityRequirementsSection = new SectionImpl(document);
|
||||
securityRequirementsSection.setTitle(labels.getLabel(SECTION_TITLE_SECURITY));
|
||||
securityRequirementTableComponent.apply(securityRequirementsSection, securityRequirements, false);
|
||||
document.append(securityRequirementsSection);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final OpenAPI schema;
|
||||
|
||||
public Parameters(OpenAPI schema) {
|
||||
this.schema = Validate.notNull(schema, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package io.github.swagger2markup.internal.helper;
|
||||
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
|
||||
public class OpenApiHelpers {
|
||||
|
||||
public static void appendDescription(StructuralNode node, String description) {
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
Block paragraph = new ParagraphBlockImpl(node);
|
||||
paragraph.setSource(description);
|
||||
node.append(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
public static Document generateInnerDoc(Table table, String documentContent) {
|
||||
return generateInnerDoc(table, documentContent, "");
|
||||
}
|
||||
|
||||
public static Document generateInnerDoc(Table table, String documentContent, String id) {
|
||||
Document innerDoc = new DocumentImpl(table);
|
||||
if (StringUtils.isNotBlank(id)) {
|
||||
innerDoc.setId(id);
|
||||
}
|
||||
|
||||
Block paragraph = new ParagraphBlockImpl(innerDoc);
|
||||
paragraph.setSource(documentContent);
|
||||
innerDoc.append(paragraph);
|
||||
return innerDoc;
|
||||
}
|
||||
|
||||
public static String requiredIndicator(boolean isRequired, String labelRequired, String labelOptional) {
|
||||
return italicUnconstrained(isRequired ? labelRequired : labelOptional).toLowerCase();
|
||||
}
|
||||
|
||||
public static String superScript(String str) {
|
||||
return "^" + str + "^";
|
||||
}
|
||||
|
||||
public static String subScript(String str) {
|
||||
return "~" + str + "~";
|
||||
}
|
||||
|
||||
public static String italicUnconstrained(String str) {
|
||||
return "__" + str + "__";
|
||||
}
|
||||
|
||||
public static String boldUnconstrained(String str) {
|
||||
return "**" + str + "**";
|
||||
}
|
||||
|
||||
public static String monospaced(String str) {
|
||||
return "`" + str + "`";
|
||||
}
|
||||
|
||||
public static String getSchemaTypeAsString(Schema schema) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (schema instanceof ArraySchema) {
|
||||
stringBuilder.append("< ");
|
||||
Schema<?> items = ((ArraySchema) schema).getItems();
|
||||
stringBuilder.append(getSchemaType(items));
|
||||
stringBuilder.append(" > ");
|
||||
stringBuilder.append(schema.getType());
|
||||
} else {
|
||||
List enumList = schema.getEnum();
|
||||
if (enumList != null) {
|
||||
stringBuilder.append("enum (");
|
||||
for (Object value : enumList) {
|
||||
stringBuilder.append(value.toString());
|
||||
stringBuilder.append(",");
|
||||
}
|
||||
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
|
||||
stringBuilder.append(')');
|
||||
} else {
|
||||
stringBuilder.append(getSchemaType(schema));
|
||||
String format = schema.getFormat();
|
||||
if (format != null) {
|
||||
stringBuilder.append(' ');
|
||||
stringBuilder.append('(');
|
||||
stringBuilder.append(format);
|
||||
stringBuilder.append(')');
|
||||
}
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static String getSchemaType(Schema<?> schema) {
|
||||
String type = schema.getType();
|
||||
if (StringUtils.isNotEmpty(type)) {
|
||||
return type;
|
||||
} else {
|
||||
return generateRefLink(schema.get$ref());
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateRefLink(String ref) {
|
||||
if (StringUtils.isNotBlank(ref)) {
|
||||
String anchor = ref.toLowerCase().replaceFirst("#", "").replaceAll("/", "_");
|
||||
return "<<" + anchor + ">>" + LINE_SEPARATOR;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
swagger2markup.markupLanguage=ASCIIDOC
|
||||
swagger2markup.swaggerMarkupLanguage=ASCIIDOC
|
||||
swagger2markup.hostnameEnabled=false
|
||||
swagger2markup.basePathPrefixEnabled=false
|
||||
swagger2markup.operationExtensionsEnabled=false
|
||||
swagger2markup.definitionExtensionsEnabled=false
|
||||
swagger2markup.separatedDefinitionsEnabled=false
|
||||
swagger2markup.separatedOperationsEnabled=false
|
||||
swagger2markup.pathsGroupedBy=AS_IS
|
||||
swagger2markup.outputLanguage=EN
|
||||
swagger2markup.inlineSchemaEnabled=true
|
||||
swagger2markup.interDocumentCrossReferencesEnabled=false
|
||||
swagger2markup.flatBodyEnabled=false
|
||||
swagger2markup.pathSecuritySectionEnabled=true
|
||||
swagger2markup.overviewDocument=overview
|
||||
swagger2markup.pathsDocument=paths
|
||||
swagger2markup.definitionsDocument=definitions
|
||||
swagger2markup.securityDocument=security
|
||||
swagger2markup.separatedOperationsFolder=operations
|
||||
swagger2markup.separatedDefinitionsFolder=definitions
|
||||
swagger2markup.tagOrderBy=NATURAL
|
||||
swagger2markup.operationOrderBy=NATURAL
|
||||
swagger2markup.definitionOrderBy=NATURAL
|
||||
swagger2markup.parameterOrderBy=NATURAL
|
||||
swagger2markup.propertyOrderBy=NATURAL
|
||||
swagger2markup.responseOrderBy=NATURAL
|
||||
swagger2markup.listDelimiterEnabled=false
|
||||
swagger2markup.listDelimiter=,
|
||||
swagger2markup.asciidoc.pegdown.timeoutMillis=2000
|
||||
|
||||
swagger2markup.generatedExamplesEnabled=false
|
||||
# basic, curl, invoke-webrequest
|
||||
swagger2markup.requestExamplesFormat=basic
|
||||
# default, bash, powershell, etc.
|
||||
swagger2markup.requestExamplesSourceFormat=default
|
||||
# hide, inherit or hostname
|
||||
swagger2markup.requestExamplesHost=hide
|
||||
# hide, inherit or schema (e.g. https, https, etc.)
|
||||
swagger2markup.requestExamplesSchema=hide
|
||||
swagger2markup.requestExamplesHideBasePath=true
|
||||
swagger2markup.requestExamplesIncludeAllQueryParams=false
|
||||
# single, commaSeparated, multiple, multiple[]
|
||||
swagger2markup.requestExamplesQueryArrayStyle=single
|
||||
@@ -0,0 +1,58 @@
|
||||
label_content=Content
|
||||
label_default=Default
|
||||
label_deprecated=Deprecated
|
||||
label_example=Example
|
||||
label_examples=Examples
|
||||
label_exclusive_maximum=Exclusive Maximum
|
||||
label_exclusive_minimum=Exclusive Minimum
|
||||
label_external_value=External Value
|
||||
label_format=Format
|
||||
label_maximum=Maximum
|
||||
label_max_items=Maximum Items
|
||||
label_max_length=Maximum Length
|
||||
label_max_properties=Maximum Properties
|
||||
label_minimum=Minimum
|
||||
label_min_items=Minimum Items
|
||||
label_min_length=Minimum Length
|
||||
label_min_properties=Minimum Properties
|
||||
label_multiple_of=Multiple Of
|
||||
label_no_links=No Links
|
||||
label_nullable=Nullable
|
||||
label_operation=Operation
|
||||
label_optional=Optional
|
||||
label_parameters=Parameters
|
||||
label_read_only=Read Only
|
||||
label_required=Required
|
||||
label_server=Server
|
||||
label_terms_of_service=Terms Of Service
|
||||
label_title=Title
|
||||
label_type=Type
|
||||
label_unique_items=Unique Items
|
||||
label_write_only=Write Only
|
||||
section_title_components=Components
|
||||
section_title_parameters=Parameters
|
||||
section_title_paths=Paths
|
||||
section_title_schemas=Schemas
|
||||
section_title_security=Security
|
||||
section_title_servers=Servers
|
||||
section_title_overview=Overview
|
||||
section_title_tags=Tags
|
||||
section_title_responses=Responses
|
||||
section_title_headers=Headers
|
||||
section_title_links=Links
|
||||
table_header_default=Default
|
||||
table_header_description=Description
|
||||
table_header_http_code=Code
|
||||
table_header_links=Links
|
||||
table_header_name=Name
|
||||
table_header_possible_values=Possible Values
|
||||
table_header_schema=Schema
|
||||
table_header_scopes=Scopes
|
||||
table_header_type=Type
|
||||
table_header_variable=Variable
|
||||
table_title_headers=Headers
|
||||
table_title_parameters=Parameters
|
||||
table_title_properties=Properties
|
||||
table_title_responses=Responses
|
||||
table_title_security=Security
|
||||
table_title_server_variables=Server Variables
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.swagger2markup;
|
||||
|
||||
import io.github.swagger2markup.assertions.DiffUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AsciidocConverterTest {
|
||||
|
||||
private static final String[] EXPECTED_FILES = new String[]{"definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"};
|
||||
private List<String> expectedFiles;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() throws URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
|
||||
//When
|
||||
String asciiDocAsString = OpenAPI2MarkupConverter.from(file).build()
|
||||
.toString();
|
||||
//Then
|
||||
Assertions.assertThat(asciiDocAsString).isNotEmpty();
|
||||
System.out.println(asciiDocAsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToFolder() throws URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/test/asciidoc/to_folder");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
OpenAPI2MarkupConverter.from(file).build()
|
||||
.toFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_folder").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testToFolder.html");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.github.swagger2markup;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.parser.OpenAPIV3Parser;
|
||||
import io.swagger.v3.parser.core.models.ParseOptions;
|
||||
import io.swagger.v3.parser.core.models.SwaggerParseResult;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class OpenApi2AsciiDocTest {
|
||||
|
||||
final private String openApiFile;
|
||||
final private String expectedAsciiDoc;
|
||||
|
||||
public OpenApi2AsciiDocTest(String openApiFile, String expectedAsciiDoc) throws IOException {
|
||||
this.openApiFile = "./src/test/resources/open_api/" + openApiFile;
|
||||
this.expectedAsciiDoc = IOUtils.toString(getClass().getResourceAsStream("/asciidoc/" + expectedAsciiDoc), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "Run {index}: open api={0}, asciidoc={1}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{"simple.yaml", "simple.adoc"},
|
||||
{"petstore.yaml", "petstore.adoc"}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void converts_open_api_v3_to_asciidoc() {
|
||||
ParseOptions options = new ParseOptions();
|
||||
options.setResolve(true);
|
||||
SwaggerParseResult result = new OpenAPIV3Parser().readLocation(openApiFile, null, options);
|
||||
OpenAPI swagger = result.getOpenAPI();
|
||||
assertNotNull(swagger);
|
||||
|
||||
OpenAPI2MarkupConverter converter = OpenAPI2MarkupConverter.from(swagger).build();
|
||||
converter.toFolder(Paths.get("build/test/asciidoc"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.swagger2markup.assertions;
|
||||
|
||||
import io.github.robwin.diff.DiffAssertions;
|
||||
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 expectedDirectory, Path actualDirectory, String reportName) {
|
||||
Path reportPath = Paths.get("build/diff-report/", reportName);
|
||||
try {
|
||||
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(expectedDirectory)) {
|
||||
for (Path expectedFile : directoryStream) {
|
||||
Path actualFile = actualDirectory.resolve(expectedFile.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);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertThatFileIsEqual(Path expectedFile, Path actualFile, String reportName) {
|
||||
Path reportPath = Paths.get("build/diff-report/", reportName);
|
||||
LOGGER.info("Diffing file '{}' with '{}'", actualFile, expectedFile);
|
||||
DiffAssertions.assertThat(actualFile).isEqualTo(expectedFile, reportPath);
|
||||
}
|
||||
}
|
||||
1898
openapi2markup/src/test/resources/asciidoc/petstore.adoc
Normal file
276
openapi2markup/src/test/resources/asciidoc/simple.adoc
Normal file
@@ -0,0 +1,276 @@
|
||||
= Simple Inventory API
|
||||
<you@your-company.com>
|
||||
v1.0.0
|
||||
:revnumber: 1.0.0
|
||||
:openapi: 3.0.0
|
||||
:authorcount: 1
|
||||
:email: you@your-company.com
|
||||
|
||||
== Overview
|
||||
This is a simple API
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
|
||||
|
||||
== Tags
|
||||
admins::
|
||||
Secured Admin-only calls
|
||||
developers::
|
||||
Operations available to regular developers
|
||||
|
||||
== Servers
|
||||
=== __Server__: /
|
||||
|
||||
== Paths
|
||||
=== __GET__ `/inventory` searches inventory
|
||||
By passing in the appropriate options, you can search for
|
||||
available inventory in the system
|
||||
|
||||
.Parameters
|
||||
[%header,caption=,cols=".^2a,.^3a,.^10a,.^5a"]
|
||||
|===
|
||||
<.<|Type
|
||||
|
||||
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|**query**
|
||||
|
||||
|
||||
<.<|**searchString** +
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|pass an optional search string for looking up inventory
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
<.<|**query**
|
||||
|
||||
|
||||
<.<|**limit** +
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|maximum number of records to return
|
||||
|
||||
|
||||
<.<|minimum: 0 +
|
||||
type: integer +
|
||||
maximum: 50 +
|
||||
format: int32
|
||||
|
||||
|
||||
|
||||
<.<|**query**
|
||||
|
||||
|
||||
<.<|**skip** +
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|number of records to skip for pagination
|
||||
|
||||
|
||||
<.<|minimum: 0 +
|
||||
type: integer +
|
||||
format: int32
|
||||
|
||||
|
||||
|
||||
|===
|
||||
.Responses
|
||||
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|
||||
|===
|
||||
<.<|Code
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Links
|
||||
|
||||
|
||||
|
||||
<.<|200
|
||||
|
||||
|
||||
<.<|search results matching criteria
|
||||
|
||||
.Content
|
||||
application/json::
|
||||
+
|
||||
|
||||
type: array
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
<.<|400
|
||||
|
||||
|
||||
<.<|bad input parameter
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
=== __POST__ `/inventory` adds an inventory item
|
||||
Adds an item to the system
|
||||
|
||||
.Responses
|
||||
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|
||||
|===
|
||||
<.<|Code
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Links
|
||||
|
||||
|
||||
|
||||
<.<|201
|
||||
|
||||
|
||||
<.<|item created
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
<.<|400
|
||||
|
||||
|
||||
<.<|invalid input, object invalid
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
<.<|409
|
||||
|
||||
|
||||
<.<|an existing item already exists
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
[[_components]]
|
||||
== Components
|
||||
[[_components_schemas]]
|
||||
=== Schemas
|
||||
[[_components_schemas_inventoryitem]]
|
||||
==== InventoryItem
|
||||
|
||||
type: object
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string +
|
||||
format: uuid
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
<.<|releaseDate
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string +
|
||||
format: date-time
|
||||
|
||||
|
||||
|
||||
<.<|manufacturer
|
||||
__required__
|
||||
|
||||
|
||||
<.<|<<_components_schemas_Manufacturer,Manufacturer>>
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_manufacturer]]
|
||||
==== Manufacturer
|
||||
|
||||
type: object
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
<.<|homePage
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|type: string +
|
||||
format: url
|
||||
|
||||
|
||||
|
||||
<.<|phone
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
|
||||
[[_components]]
|
||||
== Components
|
||||
[[_components_schemas]]
|
||||
=== Schemas
|
||||
[[_components_schemas_user]]
|
||||
==== User
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|username
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|firstName
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|lastName
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|email
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|password
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|phone
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|userStatus
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|User Status
|
||||
|
||||
|
||||
<.<|integer (int32)
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_category]]
|
||||
==== Category
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|The name of the category
|
||||
|
||||
**Maximum Length**: 255 +
|
||||
**Minimum Length**: 0 +
|
||||
**Default**: DefaultCategory
|
||||
|
||||
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_pet]]
|
||||
==== Pet
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|category
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|<<_components_schemas_category>>
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__required__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|photoUrls
|
||||
__required__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|< string > array
|
||||
|
||||
|
||||
|
||||
<.<|tags
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|< <<_components_schemas_tag>>
|
||||
> array
|
||||
|
||||
|
||||
|
||||
<.<|status
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|pet status in the store,
|
||||
|
||||
|
||||
<.<|enum (Dead,Alive)
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_tag]]
|
||||
==== Tag
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_order]]
|
||||
==== Order
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|petId
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|quantity
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|**Maximum**: 10000 +
|
||||
**Minimum**: 0 +
|
||||
**Default**: 0
|
||||
|
||||
|
||||
<.<|integer (int32)
|
||||
|
||||
|
||||
|
||||
<.<|shipDate
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string (date-time)
|
||||
|
||||
|
||||
|
||||
<.<|status
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|Order Status
|
||||
|
||||
|
||||
<.<|enum (Ordered,Cancelled)
|
||||
|
||||
|
||||
|
||||
<.<|complete
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|boolean
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
[[_components_parameters]]
|
||||
=== Responses
|
||||
.Responses
|
||||
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|
||||
|===
|
||||
<.<|Code
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Links
|
||||
|
||||
|
||||
|
||||
<.<|InvalidId
|
||||
|
||||
|
||||
<.<|Invalid ID supplied
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
= Swagger Petstore
|
||||
apiteam@swagger.io
|
||||
v1.0.0
|
||||
:revnumber: 1.0.0
|
||||
:openapi: 3.0.0
|
||||
:author: apiteam@swagger.io
|
||||
:authorcount: 1
|
||||
|
||||
|
||||
== Overview
|
||||
This is a sample server Petstore server.
|
||||
|
||||
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
|
||||
|
||||
For this sample, you can use the api key `special-key` to test the authorization filters
|
||||
|
||||
http://helloreverb.com/terms/[Terms Of Service]
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
|
||||
|
||||
http://swagger.io[Find out more about Swagger]
|
||||
|
||||
== Tags
|
||||
pet::
|
||||
Pet resource
|
||||
store::
|
||||
Store resource
|
||||
user::
|
||||
User resource
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
14
openapi2markup/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true">
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="io.github.swagger2markup" level="DEBUG"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
732
openapi2markup/src/test/resources/open_api/petstore.yaml
Normal file
@@ -0,0 +1,732 @@
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: 'http://localhost:8000/v2/api'
|
||||
info:
|
||||
description: >-
|
||||
This is a sample server Petstore server. You can find out more about
|
||||
Swagger at http://swagger.io or on
|
||||
irc.freenode.net, #swagger. For this sample, you can use the api key
|
||||
"special-key" to test the authorization filters
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
termsOfService: 'http://swagger.io/terms/'
|
||||
contact:
|
||||
name: apiteam@swagger.io
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
externalDocs:
|
||||
description: Find more info here
|
||||
url: 'https://swagger.io'
|
||||
tags:
|
||||
- name: pet
|
||||
description: Pet Operations
|
||||
externalDocs:
|
||||
url: 'http://swagger.io'
|
||||
- name: user
|
||||
description: All about the Users
|
||||
paths:
|
||||
/pet/add:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ''
|
||||
operationId: createPet
|
||||
responses:
|
||||
'200':
|
||||
description: This is a sample
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: 'whoa!'
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
/pet:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ''
|
||||
operationId: addPet
|
||||
responses:
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
put:
|
||||
tags:
|
||||
- pet
|
||||
summary: Update an existing pet
|
||||
description: ''
|
||||
operationId: updatePet
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
'405':
|
||||
description: Validation exception
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/Pet'
|
||||
/pet/findByStatus:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma seperated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: Status values that need to be considered for filter
|
||||
required: false
|
||||
style: pipeDelimited
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default: available
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PetArray'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PetArray'
|
||||
'400':
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
/pet/findByTags:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by tags
|
||||
description: >-
|
||||
Muliple tags can be provided with comma seperated strings. Use tag1,
|
||||
tag2, tag3 for testing.
|
||||
operationId: findPetsByTags
|
||||
parameters:
|
||||
- name: tags
|
||||
in: query
|
||||
description: Tags to filter by
|
||||
required: false
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid tag value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
'/pet/{petId}':
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Find pet by ID
|
||||
description: >-
|
||||
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API
|
||||
error conditions
|
||||
operationId: getPetById
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
security:
|
||||
- api_key: []
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Updates a pet in the store with form data
|
||||
description: ''
|
||||
operationId: updatePetWithForm
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: Updated name of the pet
|
||||
type: string
|
||||
status:
|
||||
description: Updated status of the pet
|
||||
type: string
|
||||
delete:
|
||||
tags:
|
||||
- pet
|
||||
summary: Deletes a pet
|
||||
description: ''
|
||||
operationId: deletePet
|
||||
parameters:
|
||||
- name: api_key
|
||||
in: header
|
||||
description: ''
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: petId
|
||||
in: path
|
||||
description: Pet id to delete
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid pet value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet extra params that needs to be deleted
|
||||
'/pet/{petId}/uploadImage':
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: uploads an image
|
||||
description: ''
|
||||
operationId: uploadFile
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet to update
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponse"
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Additional data to pass to server
|
||||
type: string
|
||||
file:
|
||||
description: file to upload
|
||||
type: string
|
||||
format: binary
|
||||
/store/inventory:
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Returns pet inventories by status
|
||||
description: Returns a map of status codes to quantities
|
||||
operationId: get inventory+1
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
format: int32
|
||||
application/xml:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
format: int32
|
||||
security:
|
||||
- api_key: []
|
||||
/store/order:
|
||||
post:
|
||||
tags:
|
||||
- store
|
||||
summary: Place an order for a pet
|
||||
description: ''
|
||||
operationId: placeOrder
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
'400':
|
||||
description: Invalid Order
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
description: order placed for purchasing the pet
|
||||
'/store/order/{orderId}':
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Find purchase order by ID
|
||||
description: >-
|
||||
For valid response try integer IDs with value <= 5 or > 10. Other values
|
||||
will generated exceptions
|
||||
operationId: getOrderById
|
||||
parameters:
|
||||
- name: orderId
|
||||
in: path
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Order not found
|
||||
delete:
|
||||
tags:
|
||||
- store
|
||||
summary: Delete purchase order by ID
|
||||
description: >-
|
||||
For valid response try integer IDs with value < 1000. Anything above
|
||||
1000 or nonintegers will generate API errors
|
||||
operationId: deleteOrder
|
||||
parameters:
|
||||
- name: orderId
|
||||
in: path
|
||||
description: ID of the order that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Order not found
|
||||
/user:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Create user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: createUser
|
||||
responses:
|
||||
200:
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
# default is text/plain
|
||||
type: string
|
||||
format: text
|
||||
examples:
|
||||
foo:
|
||||
value: {"foo": "bar"}
|
||||
bar:
|
||||
summary: A bar example
|
||||
value: {"bar": "baz"}
|
||||
default:
|
||||
description: successful operation
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: Created user object
|
||||
/user/createWithArray:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ''
|
||||
operationId: createUsersWithArrayInput
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/UserArray'
|
||||
/user/createWithList:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ''
|
||||
operationId: createUsersWithListInput
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/UserArray'
|
||||
/user/login:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
security:
|
||||
- https
|
||||
summary: Logs user into the system
|
||||
description: ''
|
||||
operationId: loginUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: query
|
||||
description: The user name for login
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: password
|
||||
in: query
|
||||
description: The password for login in clear text
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
application/xml:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid username/password supplied
|
||||
/user/logout:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
security:
|
||||
- https
|
||||
summary: Logs out current logged in user session
|
||||
description: ''
|
||||
operationId: logoutUser
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
'/user/{username}':
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Get user by user name
|
||||
description: ''
|
||||
operationId: getUserByName
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: 'The name that needs to be fetched. Use user1 for testing.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
'400':
|
||||
description: Invalid username supplied
|
||||
'404':
|
||||
description: User not found
|
||||
put:
|
||||
tags:
|
||||
- user
|
||||
summary: Updated user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: updateUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: name that need to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid user supplied
|
||||
'404':
|
||||
description: User not found
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: Updated user object
|
||||
delete:
|
||||
tags:
|
||||
- user
|
||||
summary: Delete user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: deleteUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: The name that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid username supplied
|
||||
'404':
|
||||
description: User not found
|
||||
security:
|
||||
- foo:
|
||||
- bar
|
||||
- baz
|
||||
a:
|
||||
- b
|
||||
- c
|
||||
components:
|
||||
parameters:
|
||||
sharedSkip:
|
||||
name: skip
|
||||
in: query
|
||||
description: Results to skip
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
veryBad:
|
||||
description: failed
|
||||
requestBodies:
|
||||
UserArray:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: List of user object
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
securitySchemes:
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
|
||||
scopes:
|
||||
'write:pets': modify pets in your account
|
||||
'read:pets': read your pets
|
||||
schemas:
|
||||
User:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
username:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
phone:
|
||||
type: string
|
||||
userStatus:
|
||||
type: integer
|
||||
format: int32
|
||||
description: User Status
|
||||
xml:
|
||||
name: User
|
||||
Category:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Category
|
||||
Pet:
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
category:
|
||||
$ref: '#/components/schemas/Category'
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
photoUrls:
|
||||
type: array
|
||||
xml:
|
||||
name: photoUrl
|
||||
wrapped: true
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
xml:
|
||||
name: tag
|
||||
wrapped: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Tag'
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store
|
||||
xml:
|
||||
name: Pet
|
||||
Tag:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Tag
|
||||
Order:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
petId:
|
||||
type: integer
|
||||
format: int64
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
shipDate:
|
||||
type: string
|
||||
format: date-time
|
||||
status:
|
||||
type: string
|
||||
description: Order Status
|
||||
complete:
|
||||
type: boolean
|
||||
xml:
|
||||
name: Order
|
||||
PetArray:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
115
openapi2markup/src/test/resources/open_api/simple.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
description: This is a simple API
|
||||
version: "1.0.0"
|
||||
title: Simple Inventory API
|
||||
contact:
|
||||
email: you@your-company.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
tags:
|
||||
- name: admins
|
||||
description: Secured Admin-only calls
|
||||
- name: developers
|
||||
description: Operations available to regular developers
|
||||
paths:
|
||||
/inventory:
|
||||
get:
|
||||
tags:
|
||||
- developers
|
||||
summary: searches inventory
|
||||
operationId: searchInventory
|
||||
description: |
|
||||
By passing in the appropriate options, you can search for
|
||||
available inventory in the system
|
||||
parameters:
|
||||
- in: query
|
||||
name: searchString
|
||||
description: pass an optional search string for looking up inventory
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: skip
|
||||
description: number of records to skip for pagination
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
- in: query
|
||||
name: limit
|
||||
description: maximum number of records to return
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
responses:
|
||||
'200':
|
||||
description: search results matching criteria
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/InventoryItem'
|
||||
'400':
|
||||
description: bad input parameter
|
||||
post:
|
||||
tags:
|
||||
- admins
|
||||
summary: adds an inventory item
|
||||
operationId: addInventory
|
||||
description: Adds an item to the system
|
||||
responses:
|
||||
'201':
|
||||
description: item created
|
||||
'400':
|
||||
description: 'invalid input, object invalid'
|
||||
'409':
|
||||
description: an existing item already exists
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InventoryItem'
|
||||
description: Inventory item to add
|
||||
components:
|
||||
schemas:
|
||||
InventoryItem:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- manufacturer
|
||||
- releaseDate
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: d290f1ee-6c54-4b01-90e6-d701748f0851
|
||||
name:
|
||||
type: string
|
||||
example: Widget Adapter
|
||||
releaseDate:
|
||||
type: string
|
||||
format: date-time
|
||||
example: '2016-08-29T09:12:33.001Z'
|
||||
manufacturer:
|
||||
$ref: '#/components/schemas/Manufacturer'
|
||||
Manufacturer:
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: ACME Corporation
|
||||
homePage:
|
||||
type: string
|
||||
format: url
|
||||
example: 'https://www.acme-corp.com'
|
||||
phone:
|
||||
type: string
|
||||
example: 408-867-5309
|
||||
type: object
|
||||
693
openapi2markup/src/test/resources/yaml/swagger_petstore.yaml
Normal file
@@ -0,0 +1,693 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
description: >
|
||||
This is a sample server Petstore server.
|
||||
|
||||
|
||||
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
|
||||
|
||||
|
||||
For this sample, you can use the api key `special-key` to test the authorization filters
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
termsOfService: http://helloreverb.com/terms/
|
||||
contact:
|
||||
name: apiteam@swagger.io
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
tags:
|
||||
- name: pet
|
||||
description: Pet resource
|
||||
- name: store
|
||||
description: Store resource
|
||||
- name: user
|
||||
description: User resource
|
||||
paths:
|
||||
/pets:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ""
|
||||
operationId: addPet
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/Pet"
|
||||
responses:
|
||||
"405":
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
put:
|
||||
tags:
|
||||
- pet
|
||||
summary: Update an existing pet
|
||||
description: ""
|
||||
operationId: updatePet
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/Pet"
|
||||
responses:
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Pet not found
|
||||
"405":
|
||||
description: Validation exception
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
/pets/findByStatus:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma seperated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- in: query
|
||||
name: status
|
||||
description: Status values that need to be considered for filter
|
||||
required: false
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
"400":
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
/pets/findByTags:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by tags
|
||||
description: Muliple tags can be provided with comma seperated strings. Use tag1,
|
||||
tag2, tag3 for testing.
|
||||
operationId: findPetsByTags
|
||||
parameters:
|
||||
- in: query
|
||||
name: tags
|
||||
description: Tags to filter by
|
||||
required: false
|
||||
example: adorable
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
"400":
|
||||
description: Invalid tag value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
"/pets/{petId}":
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Find pet by ID
|
||||
description: Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API
|
||||
error conditions
|
||||
operationId: getPetById
|
||||
parameters:
|
||||
- in: path
|
||||
name: petId
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
example: 30
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Pet not found
|
||||
security:
|
||||
- api_key: []
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Updates a pet in the store with form data
|
||||
description: ""
|
||||
operationId: updatePetWithForm
|
||||
parameters:
|
||||
- in: path
|
||||
name: petId
|
||||
description: ID of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: Updated name of the pet
|
||||
type: string
|
||||
status:
|
||||
description: Updated status of the pet
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- status
|
||||
responses:
|
||||
"405":
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
delete:
|
||||
tags:
|
||||
- pet
|
||||
summary: Deletes a pet
|
||||
description: ""
|
||||
operationId: deletePet
|
||||
parameters:
|
||||
- in: header
|
||||
name: api_key
|
||||
description: ""
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: petId
|
||||
description: Pet id to delete
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
"400":
|
||||
description: Invalid pet value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
/stores/order:
|
||||
post:
|
||||
tags:
|
||||
- store
|
||||
summary: Place an order for a pet
|
||||
description: ""
|
||||
operationId: placeOrder
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
description: order placed for purchasing the pet
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
"400":
|
||||
description: Invalid Order
|
||||
"/stores/order/{orderId}":
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Find purchase order by ID
|
||||
description: For valid response try integer IDs with value <= 5 or > 10. Other values
|
||||
will generated exceptions
|
||||
operationId: getOrderById
|
||||
parameters:
|
||||
- in: path
|
||||
name: orderId
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Order not found
|
||||
delete:
|
||||
tags:
|
||||
- store
|
||||
summary: Delete purchase order by ID
|
||||
description: For valid response try integer IDs with value < 1000. Anything above
|
||||
1000 or nonintegers will generate API errors
|
||||
operationId: deleteOrder
|
||||
parameters:
|
||||
- in: path
|
||||
name: orderId
|
||||
description: ID of the order that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Order not found
|
||||
/users:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Create user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: createUser
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
description: Created user object
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
/users/createWithArray:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ""
|
||||
operationId: createUsersWithArrayInput
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UserArray"
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
/users/createWithList:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ""
|
||||
operationId: createUsersWithListInput
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UserArray"
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
/users/login:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Logs user into the system
|
||||
description: ""
|
||||
operationId: loginUser
|
||||
parameters:
|
||||
- in: query
|
||||
name: username
|
||||
description: The user name for login
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: password
|
||||
description: The password for login in clear text
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
application/xml:
|
||||
schema:
|
||||
type: string
|
||||
"400":
|
||||
description: Invalid username/password supplied
|
||||
/users/logout:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Logs out current logged in user session
|
||||
description: ""
|
||||
operationId: logoutUser
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
"/users/{username}":
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Get user by user name
|
||||
description: ""
|
||||
operationId: getUserByName
|
||||
parameters:
|
||||
- in: path
|
||||
name: username
|
||||
description: The name that needs to be fetched. Use user1 for testing.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
"400":
|
||||
description: Invalid username supplied
|
||||
"404":
|
||||
description: User not found
|
||||
put:
|
||||
tags:
|
||||
- user
|
||||
summary: Updated user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: updateUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: username
|
||||
description: name that need to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
description: Updated user object
|
||||
responses:
|
||||
"400":
|
||||
description: Invalid user supplied
|
||||
"404":
|
||||
description: User not found
|
||||
delete:
|
||||
tags:
|
||||
- user
|
||||
summary: Delete user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: deleteUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: username
|
||||
description: The name that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"400":
|
||||
description: Invalid username supplied
|
||||
"404":
|
||||
description: User not found
|
||||
externalDocs:
|
||||
description: Find out more about Swagger
|
||||
url: http://swagger.io
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v2
|
||||
components:
|
||||
responses:
|
||||
InvalidId:
|
||||
description: Invalid ID supplied
|
||||
requestBodies:
|
||||
UserArray:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/User"
|
||||
description: List of user object
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
description: Pet object that needs to be added to the store
|
||||
securitySchemes:
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
description: This is another description
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
description: This is a standard oauth flow
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
|
||||
scopes:
|
||||
write_pets: modify pets in your account
|
||||
read_pets: read your pets
|
||||
schemas:
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
username:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
phone:
|
||||
type: string
|
||||
userStatus:
|
||||
type: integer
|
||||
format: int32
|
||||
description: User Status
|
||||
Category:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
description: The name of the category
|
||||
minLength: 0
|
||||
maxLength: 255
|
||||
pattern: "[A-Za-zäöüÄÖÜß]{0,255}"
|
||||
default: DefaultCategory
|
||||
example: FoobarCategory
|
||||
Pet:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
category:
|
||||
$ref: "#/components/schemas/Category"
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
photoUrls:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Tag"
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store,
|
||||
enum:
|
||||
- Dead
|
||||
- Alive
|
||||
Tag:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
Order:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
petId:
|
||||
type: integer
|
||||
format: int64
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 10000
|
||||
default: 0
|
||||
example: 10
|
||||
shipDate:
|
||||
type: string
|
||||
format: date-time
|
||||
status:
|
||||
type: string
|
||||
description: Order Status
|
||||
enum:
|
||||
- Ordered
|
||||
- Cancelled
|
||||
complete:
|
||||
type: boolean
|
||||
87
publishing.gradle
Normal file
@@ -0,0 +1,87 @@
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
Date buildTimeAndDate = new Date()
|
||||
ext {
|
||||
buildDate = new SimpleDateFormat('yyyy-MM-dd').format(buildTimeAndDate)
|
||||
buildTime = new SimpleDateFormat('HH:mm:ss.SSSZ').format(buildTimeAndDate)
|
||||
licenseUrl = 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt'
|
||||
scmUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
|
||||
}
|
||||
|
||||
def projectArtifactId = 'swagger2markup'
|
||||
def projectUrl = 'https://github.com/Swagger2Markup/swagger2markup'
|
||||
def licenseUrl = 'https://github.com/Swagger2Markup/swagger2markup/blob/master/LICENSE.txt'
|
||||
def scmUrl = 'https://github.com/Swagger2Markup/swagger2markup.git'
|
||||
def issuesUrl = 'https://github.com/Swagger2Markup/swagger2markup/issues'
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes(
|
||||
'Built-By': 'Robert Winkler',
|
||||
'Created-By': System.properties['java.version'] + " (" + System.properties['java.vendor'] + " " + System.properties['java.vm.version'] + ")",
|
||||
'Build-Date': project.buildDate,
|
||||
'Build-Time': project.buildTime,
|
||||
'Specification-Title': projectArtifactId,
|
||||
'Specification-Version': project.version,
|
||||
'Implementation-Title': projectArtifactId,
|
||||
'Implementation-Version': project.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from sourceSets.main.allJava
|
||||
archiveClassifier = 'sources'
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
from javadoc
|
||||
archiveClassifier = 'javadoc'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
pom.withXml {
|
||||
def devs = ['RobWin': 'Robert Winkler',
|
||||
'austek': 'Ali Ustek']
|
||||
def root = asNode()
|
||||
|
||||
root.dependencies.'*'.findAll() {
|
||||
it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep ->
|
||||
dep.name == it.artifactId.text()
|
||||
}
|
||||
}.each() {
|
||||
it.scope*.value = 'compile'
|
||||
}
|
||||
|
||||
root.appendNode('name', projectArtifactId)
|
||||
root.appendNode('packaging', 'jar')
|
||||
root.appendNode('url', projectUrl)
|
||||
root.appendNode('description', project.description)
|
||||
|
||||
def license = root.appendNode('licenses').appendNode('license')
|
||||
license.appendNode('name', 'Apache-2.0')
|
||||
license.appendNode('url', licenseUrl)
|
||||
license.appendNode('distribution', 'repo')
|
||||
|
||||
root.appendNode('scm').appendNode('url', scmUrl)
|
||||
|
||||
def developers = root.appendNode('developers')
|
||||
devs.each {
|
||||
def d = developers.appendNode('developer')
|
||||
d.appendNode('id', it.key)
|
||||
d.appendNode('name', it.value)
|
||||
}
|
||||
}
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +1,10 @@
|
||||
rootProject.name = 'swagger2markup'
|
||||
rootProject.name = 'swagger2markup'
|
||||
|
||||
include 'swagger2markup-asciidoc'
|
||||
include 'swagger2markup-bom'
|
||||
include 'swagger2markup-builder'
|
||||
include 'swagger2markup-documentation'
|
||||
include 'swagger2markup'
|
||||
include 'swagger2markup-core'
|
||||
include 'openapi2markup'
|
||||
|
||||
|
||||
@@ -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*
|
||||
@@ -1 +0,0 @@
|
||||
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*
|
||||
@@ -1,2 +0,0 @@
|
||||
This is a hand-written description.
|
||||
AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*
|
||||
@@ -1,5 +0,0 @@
|
||||
This is a hand-written description.
|
||||
AsciiDoc is better suited for descriptions than:
|
||||
|
||||
* JavaDoc
|
||||
* Annotations
|
||||
@@ -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*
|
||||
@@ -1 +0,0 @@
|
||||
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*
|
||||
@@ -1 +0,0 @@
|
||||
This is a hand-written description. AsciiDoc is better suited for descriptions than *JavaDoc* and *Annotations*
|
||||
@@ -1,5 +0,0 @@
|
||||
This is a hand-written description.
|
||||
It is better suited for adding descriptions than:
|
||||
|
||||
* JavaDoc
|
||||
* Annotations
|
||||
@@ -1,251 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.builder.document.DefinitionsDocument;
|
||||
import io.github.robwin.swagger2markup.builder.document.OverviewDocument;
|
||||
import io.github.robwin.swagger2markup.builder.document.PathsDocument;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
import io.swagger.util.Json;
|
||||
import io.swagger.util.Yaml;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class Swagger2MarkupConverter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Swagger2MarkupConverter.class);
|
||||
|
||||
private final Swagger swagger;
|
||||
private final MarkupLanguage markupLanguage;
|
||||
private final String examplesFolderPath;
|
||||
private final String schemasFolderPath;
|
||||
private final String descriptionsFolderPath;
|
||||
private final boolean separatedDefinitions;
|
||||
private static final String OVERVIEW_DOCUMENT = "overview";
|
||||
private static final String PATHS_DOCUMENT = "paths";
|
||||
private static final String DEFINITIONS_DOCUMENT = "definitions";
|
||||
|
||||
/**
|
||||
* @param markupLanguage the markup language which is used to generate the files
|
||||
* @param swagger the Swagger object
|
||||
* @param examplesFolderPath the folderPath where examples are stored
|
||||
* @param schemasFolderPath the folderPath where (XML, JSON)-Schema files are stored
|
||||
* @param descriptionsFolderPath the folderPath where descriptions are stored
|
||||
* @param separatedDefinitions create separate definition files for each model definition.
|
||||
*/
|
||||
Swagger2MarkupConverter(MarkupLanguage markupLanguage, Swagger swagger, String examplesFolderPath, String schemasFolderPath, String descriptionsFolderPath, boolean separatedDefinitions){
|
||||
this.markupLanguage = markupLanguage;
|
||||
this.swagger = swagger;
|
||||
this.examplesFolderPath = examplesFolderPath;
|
||||
this.schemasFolderPath = schemasFolderPath;
|
||||
this.descriptionsFolderPath = descriptionsFolderPath;
|
||||
this.separatedDefinitions = separatedDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Swagger2MarkupConverter.Builder using a given Swagger source.
|
||||
*
|
||||
* @param swaggerLocation the Swagger location. Can be a HTTP url or a path to a local file.
|
||||
* @return a Swagger2MarkupConverter
|
||||
*/
|
||||
public static Builder from(String swaggerLocation){
|
||||
Validate.notEmpty(swaggerLocation, "swaggerLocation must not be empty!");
|
||||
return new Builder(swaggerLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 swagger the Swagger YAML or JSON String.
|
||||
* @return a Swagger2MarkupConverter
|
||||
* @throws java.io.IOException if String can not be parsed
|
||||
*/
|
||||
public static Builder fromString(String swagger) throws IOException {
|
||||
Validate.notEmpty(swagger, "swagger must not be null!");
|
||||
ObjectMapper mapper;
|
||||
if(swagger.trim().startsWith("{")) {
|
||||
mapper = Json.mapper();
|
||||
}else {
|
||||
mapper = Yaml.mapper();
|
||||
}
|
||||
JsonNode rootNode = mapper.readTree(swagger);
|
||||
|
||||
// must have swagger node set
|
||||
JsonNode swaggerNode = rootNode.get("swagger");
|
||||
if(swaggerNode == null)
|
||||
throw new IllegalArgumentException("Swagger String is in the wrong format");
|
||||
|
||||
return new Builder(mapper.convertValue(rootNode, Swagger.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the document with the given markup language and stores
|
||||
* the files in the given folder.
|
||||
*
|
||||
* @param targetFolderPath the target folder
|
||||
* @throws IOException if the files cannot be written
|
||||
*/
|
||||
public void intoFolder(String targetFolderPath) throws IOException {
|
||||
Validate.notEmpty(targetFolderPath, "folderPath must not be null!");
|
||||
buildDocuments(targetFolderPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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{
|
||||
return buildDocuments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds all documents and writes them to a directory
|
||||
|
||||
* @param directory the directory where the generated file should be stored
|
||||
* @throws IOException if a file cannot be written
|
||||
*/
|
||||
private void buildDocuments(String directory) throws IOException {
|
||||
new OverviewDocument(swagger, markupLanguage).build().writeToFile(directory, OVERVIEW_DOCUMENT, StandardCharsets.UTF_8);
|
||||
new PathsDocument(swagger, markupLanguage, examplesFolderPath, descriptionsFolderPath).build().writeToFile(directory, PATHS_DOCUMENT, StandardCharsets.UTF_8);
|
||||
new DefinitionsDocument(swagger, markupLanguage, schemasFolderPath, descriptionsFolderPath, separatedDefinitions, directory).build().writeToFile(directory, DEFINITIONS_DOCUMENT, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all documents as a String
|
||||
|
||||
* @return a the document as a String
|
||||
*/
|
||||
private String buildDocuments() throws IOException {
|
||||
return new OverviewDocument(swagger, markupLanguage).build().toString().concat(
|
||||
new PathsDocument(swagger, markupLanguage, examplesFolderPath, schemasFolderPath).build().toString()
|
||||
.concat(new DefinitionsDocument(swagger, markupLanguage, schemasFolderPath, schemasFolderPath, false, null).build().toString()));
|
||||
}
|
||||
|
||||
|
||||
public static class Builder{
|
||||
private final Swagger swagger;
|
||||
private String examplesFolderPath;
|
||||
private String schemasFolderPath;
|
||||
private String descriptionsFolderPath;
|
||||
private boolean separatedDefinitions;
|
||||
private MarkupLanguage markupLanguage = MarkupLanguage.ASCIIDOC;
|
||||
|
||||
/**
|
||||
* Creates a Builder using a given Swagger source.
|
||||
*
|
||||
* @param swaggerLocation the Swagger location. Can be a HTTP url or a path to a local file.
|
||||
*/
|
||||
Builder(String swaggerLocation){
|
||||
swagger = new SwaggerParser().read(swaggerLocation);
|
||||
if(swagger == null){
|
||||
throw new IllegalArgumentException("Failed to read the Swagger file. ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder using a given Swagger model.
|
||||
*
|
||||
* @param swagger the Swagger source.
|
||||
*/
|
||||
Builder(Swagger swagger){
|
||||
this.swagger = swagger;
|
||||
}
|
||||
|
||||
public Swagger2MarkupConverter build(){
|
||||
return new Swagger2MarkupConverter(markupLanguage, swagger, examplesFolderPath, schemasFolderPath, descriptionsFolderPath, separatedDefinitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withMarkupLanguage(MarkupLanguage markupLanguage){
|
||||
this.markupLanguage = markupLanguage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include hand-written descriptions into the Paths and Definitions document
|
||||
*
|
||||
* @param descriptionsFolderPath the path to the folder where the description documents reside
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withDescriptions(String descriptionsFolderPath){
|
||||
this.descriptionsFolderPath = descriptionsFolderPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* In addition to the definitions file, also create separate definition files for each model definition.
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withSeparatedDefinitions() {
|
||||
this.separatedDefinitions = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include examples into the Paths document
|
||||
*
|
||||
* @param examplesFolderPath the path to the folder where the example documents reside
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withExamples(String examplesFolderPath){
|
||||
this.examplesFolderPath = examplesFolderPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include (JSON, XML) schemas into the Definitions document
|
||||
*
|
||||
* @param schemasFolderPath the path to the folder where the schema documents reside
|
||||
* @return the Swagger2MarkupConverter.Builder
|
||||
*/
|
||||
public Builder withSchemas(String schemasFolderPath){
|
||||
this.schemasFolderPath = schemasFolderPath;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.builder.document;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilders;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.utils.PropertyUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class DefinitionsDocument extends MarkupDocument {
|
||||
|
||||
private static final String DEFINITIONS = "Definitions";
|
||||
private static final List<String> IGNORED_DEFINITIONS = Collections.singletonList("Void");
|
||||
private static final String JSON_SCHEMA = "JSON Schema";
|
||||
private static final String XML_SCHEMA = "XML Schema";
|
||||
private static final String JSON_SCHEMA_EXTENSION = ".json";
|
||||
private static final String XML_SCHEMA_EXTENSION = ".xsd";
|
||||
private static final String JSON = "json";
|
||||
private static final String XML = "xml";
|
||||
private static final String DESCRIPTION_FILE_NAME = "description";
|
||||
private boolean schemasEnabled;
|
||||
private String schemasFolderPath;
|
||||
private boolean handWrittenDescriptionsEnabled;
|
||||
private String descriptionsFolderPath;
|
||||
private boolean separatedDefinitionsEnabled;
|
||||
private String outputDirectory;
|
||||
|
||||
public DefinitionsDocument(Swagger swagger, MarkupLanguage markupLanguage, String schemasFolderPath, String descriptionsFolderPath, boolean separatedDefinitionsEnabled, String outputDirectory){
|
||||
super(swagger, markupLanguage);
|
||||
if(StringUtils.isNotBlank(schemasFolderPath)){
|
||||
this.schemasEnabled = true;
|
||||
this.schemasFolderPath = schemasFolderPath;
|
||||
}
|
||||
if(StringUtils.isNotBlank(descriptionsFolderPath)){
|
||||
this.handWrittenDescriptionsEnabled = true;
|
||||
this.descriptionsFolderPath = descriptionsFolderPath + "/" + DEFINITIONS.toLowerCase();
|
||||
}
|
||||
if(schemasEnabled){
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include schemas is enabled.");
|
||||
}
|
||||
}else{
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include schemas is disabled.");
|
||||
}
|
||||
}
|
||||
if(handWrittenDescriptionsEnabled){
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written descriptions is enabled.");
|
||||
}
|
||||
}else{
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written descriptions is disabled.");
|
||||
}
|
||||
}
|
||||
this.separatedDefinitionsEnabled = separatedDefinitionsEnabled;
|
||||
if(this.separatedDefinitionsEnabled){
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create separated definition files is enabled.");
|
||||
}
|
||||
Validate.notEmpty(outputDirectory, "Output directory is required for separated definition files!");
|
||||
}else{
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Create separated definition files is disabled.");
|
||||
}
|
||||
}
|
||||
this.outputDirectory = outputDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MarkupDocument build() throws IOException {
|
||||
definitions(swagger.getDefinitions(), this.markupDocBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the Swagger definitions.
|
||||
*
|
||||
* @param definitions the Swagger definitions
|
||||
* @param docBuilder the doc builder to use for output
|
||||
*/
|
||||
private void definitions(Map<String, Model> definitions, MarkupDocBuilder docBuilder) throws IOException {
|
||||
if(MapUtils.isNotEmpty(definitions)){
|
||||
docBuilder.sectionTitleLevel1(DEFINITIONS);
|
||||
for(Map.Entry<String, Model> definitionsEntry : definitions.entrySet()){
|
||||
String definitionName = definitionsEntry.getKey();
|
||||
if(StringUtils.isNotBlank(definitionName)) {
|
||||
if (checkThatDefinitionIsNotInIgnoreList(definitionName)) {
|
||||
definition(definitionName, definitionsEntry.getValue(), docBuilder);
|
||||
definitionSchema(definitionName, docBuilder);
|
||||
if (separatedDefinitionsEnabled) {
|
||||
MarkupDocBuilder defDocBuilder = MarkupDocBuilders.documentBuilder(markupLanguage);
|
||||
definition(definitionName, definitionsEntry.getValue(), defDocBuilder);
|
||||
definitionSchema(definitionName, defDocBuilder);
|
||||
defDocBuilder.writeToFile(outputDirectory, definitionName.toLowerCase(), StandardCharsets.UTF_8);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Separate definition file produced: {}", definitionName);
|
||||
}
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Definition processed: {}", definitionName);
|
||||
}
|
||||
}else{
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Definition was ignored: {}", definitionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 definition(String definitionName, Model model, MarkupDocBuilder docBuilder) throws IOException {
|
||||
docBuilder.sectionTitleLevel2(definitionName);
|
||||
descriptionSection(definitionName, model, docBuilder);
|
||||
propertiesSection(definitionName, model, docBuilder);
|
||||
|
||||
}
|
||||
|
||||
private void propertiesSection(String definitionName, Model model, MarkupDocBuilder docBuilder) throws IOException {
|
||||
Map<String, Property> properties = model.getProperties();
|
||||
List<String> headerAndContent = new ArrayList<>();
|
||||
List<String> header = Arrays.asList(NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN);
|
||||
headerAndContent.add(StringUtils.join(header, DELIMITER));
|
||||
if(MapUtils.isNotEmpty(properties)){
|
||||
for (Map.Entry<String, Property> propertyEntry : properties.entrySet()) {
|
||||
Property property = propertyEntry.getValue();
|
||||
String propertyName = propertyEntry.getKey();
|
||||
List<String> content = Arrays.asList(
|
||||
propertyName,
|
||||
propertyDescription(definitionName, propertyName, property),
|
||||
Boolean.toString(property.getRequired()),
|
||||
PropertyUtils.getType(property, markupLanguage),
|
||||
PropertyUtils.getDefaultValue(property));
|
||||
headerAndContent.add(StringUtils.join(content, DELIMITER));
|
||||
}
|
||||
docBuilder.tableWithHeaderRow(headerAndContent);
|
||||
}
|
||||
}
|
||||
|
||||
private void descriptionSection(String definitionName, Model model, MarkupDocBuilder docBuilder) throws IOException {
|
||||
if(handWrittenDescriptionsEnabled){
|
||||
String description = handWrittenPathDescription(definitionName.toLowerCase(), DESCRIPTION_FILE_NAME);
|
||||
if(StringUtils.isNotBlank(description)){
|
||||
docBuilder.paragraph(description);
|
||||
}else{
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Hand-written description cannot be read. Trying to use description from Swagger source.");
|
||||
}
|
||||
modelDescription(model, docBuilder);
|
||||
}
|
||||
}
|
||||
else{
|
||||
modelDescription(model, docBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private void modelDescription(Model model, MarkupDocBuilder docBuilder) {
|
||||
String description = model.getDescription();
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
docBuilder.paragraph(description);
|
||||
}
|
||||
}
|
||||
|
||||
private String propertyDescription(String definitionName, String propertyName, Property property) throws IOException {
|
||||
String description;
|
||||
if(handWrittenDescriptionsEnabled){
|
||||
description = handWrittenPathDescription(definitionName.toLowerCase() + "/" + propertyName.toLowerCase(), DESCRIPTION_FILE_NAME);
|
||||
if(StringUtils.isBlank(description)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Hand-written description file cannot be read. Trying to use description from Swagger source.");
|
||||
}
|
||||
description = StringUtils.defaultString(property.getDescription());
|
||||
}
|
||||
}
|
||||
else{
|
||||
description = StringUtils.defaultString(property.getDescription());
|
||||
}
|
||||
return 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
|
||||
* @throws IOException
|
||||
*/
|
||||
private String handWrittenPathDescription(String descriptionFolder, String descriptionFileName) throws IOException {
|
||||
for (String fileNameExtension : markupLanguage.getFileNameExtensions()) {
|
||||
java.nio.file.Path path = Paths.get(descriptionsFolderPath, descriptionFolder, descriptionFileName + fileNameExtension);
|
||||
if (Files.isReadable(path)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Description file processed: {}", path);
|
||||
}
|
||||
return FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8).trim();
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Description file is not readable: {}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.info("No description file found with correct file name extension in folder: {}", Paths.get(descriptionsFolderPath, descriptionFolder));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void definitionSchema(String definitionName, MarkupDocBuilder docBuilder) throws IOException {
|
||||
if(schemasEnabled) {
|
||||
if (StringUtils.isNotBlank(definitionName)) {
|
||||
schema(JSON_SCHEMA, schemasFolderPath, definitionName + JSON_SCHEMA_EXTENSION, JSON, docBuilder);
|
||||
schema(XML_SCHEMA, schemasFolderPath, definitionName + XML_SCHEMA_EXTENSION, XML, docBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void schema(String title, String schemasFolderPath, String schemaName, String language, MarkupDocBuilder docBuilder) throws IOException {
|
||||
java.nio.file.Path path = Paths.get(schemasFolderPath, schemaName);
|
||||
if (Files.isReadable(path)) {
|
||||
docBuilder.sectionTitleLevel3(title);
|
||||
docBuilder.source(FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8).trim(), language);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Schema file processed: {}", path);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Schema file is not readable: {}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.builder.document;
|
||||
|
||||
import io.swagger.models.Swagger;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilder;
|
||||
import io.github.robwin.markup.builder.MarkupDocBuilders;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public abstract class MarkupDocument {
|
||||
|
||||
protected static final String DELIMITER = "|";
|
||||
protected static final String DEFAULT_COLUMN = "Default";
|
||||
protected static final String REQUIRED_COLUMN = "Required";
|
||||
protected static final String SCHEMA_COLUMN = "Schema";
|
||||
protected static final String NAME_COLUMN = "Name";
|
||||
protected static final String DESCRIPTION_COLUMN = "Description";
|
||||
protected static final String DESCRIPTION = DESCRIPTION_COLUMN;
|
||||
protected static final String PRODUCES = "Produces";
|
||||
protected static final String CONSUMES = "Consumes";
|
||||
protected static final String TAGS = "Tags";
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
protected Swagger swagger;
|
||||
protected MarkupLanguage markupLanguage;
|
||||
protected MarkupDocBuilder markupDocBuilder;
|
||||
|
||||
MarkupDocument(Swagger swagger, MarkupLanguage markupLanguage){
|
||||
this.swagger = swagger;
|
||||
this.markupLanguage = markupLanguage;
|
||||
this.markupDocBuilder = MarkupDocBuilders.documentBuilder(markupLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the MarkupDocument.
|
||||
*
|
||||
* @return the built MarkupDocument
|
||||
* @throws IOException if the files to include are not readable
|
||||
*/
|
||||
public abstract MarkupDocument build() throws IOException ;
|
||||
|
||||
/**
|
||||
* Returns a string representation of the document.
|
||||
*/
|
||||
public String toString(){
|
||||
return markupDocBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the content of the builder to a file and clears the builder.
|
||||
*
|
||||
* @param directory the directory where the generated file should be stored
|
||||
* @param fileName the name of the file
|
||||
* @param charset the the charset to use for encoding
|
||||
* @throws IOException if the file cannot be written
|
||||
*/
|
||||
public void writeToFile(String directory, String fileName, Charset charset) throws IOException{
|
||||
markupDocBuilder.writeToFile(directory, fileName, charset);
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.builder.document;
|
||||
|
||||
import io.swagger.models.*;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OverviewDocument extends MarkupDocument {
|
||||
|
||||
private static final String OVERVIEW = "Overview";
|
||||
private static final String CURRENT_VERSION = "Version information";
|
||||
private static final String VERSION = "Version: ";
|
||||
private static final String CONTACT_INFORMATION = "Contact information";
|
||||
private static final String CONTACT_NAME = "Contact: ";
|
||||
private static final String CONTACT_EMAIL = "Contact Email: ";
|
||||
private static final String LICENSE_INFORMATION = "License information";
|
||||
private static final String LICENSE = "License: ";
|
||||
private static final String LICENSE_URL = "License URL: ";
|
||||
private static final String TERMS_OF_SERVICE = "Terms of service: ";
|
||||
private static final String URI_SCHEME = "URI scheme";
|
||||
private static final String HOST = "Host: ";
|
||||
private static final String BASE_PATH = "BasePath: ";
|
||||
private static final String SCHEMES = "Schemes: ";
|
||||
|
||||
public OverviewDocument(Swagger swagger, MarkupLanguage markupLanguage){
|
||||
super(swagger, markupLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the MarkupDocument.
|
||||
*
|
||||
* @return the built MarkupDocument
|
||||
* @throws java.io.IOException if the files to include are not readable
|
||||
*/
|
||||
@Override
|
||||
public MarkupDocument build() throws IOException {
|
||||
overview();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds the document header of the swagger model
|
||||
*/
|
||||
private void overview() {
|
||||
Info info = swagger.getInfo();
|
||||
this.markupDocBuilder.documentTitle(info.getTitle());
|
||||
this.markupDocBuilder.sectionTitleLevel1(OVERVIEW);
|
||||
if(StringUtils.isNotBlank(info.getDescription())){
|
||||
this.markupDocBuilder.textLine(info.getDescription());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
if(StringUtils.isNotBlank(info.getVersion())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CURRENT_VERSION);
|
||||
this.markupDocBuilder.textLine(VERSION + info.getVersion());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
Contact contact = info.getContact();
|
||||
if(contact != null){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CONTACT_INFORMATION);
|
||||
if(StringUtils.isNotBlank(contact.getName())){
|
||||
this.markupDocBuilder.textLine(CONTACT_NAME + contact.getName());
|
||||
}
|
||||
if(StringUtils.isNotBlank(contact.getEmail())){
|
||||
this.markupDocBuilder.textLine(CONTACT_EMAIL + contact.getEmail());
|
||||
}
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
License license = info.getLicense();
|
||||
if(license != null && (StringUtils.isNotBlank(license.getName()) || StringUtils.isNotBlank(license.getUrl()))) {
|
||||
this.markupDocBuilder.sectionTitleLevel2(LICENSE_INFORMATION);
|
||||
if (StringUtils.isNotBlank(license.getName())) {
|
||||
this.markupDocBuilder.textLine(LICENSE + license.getName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(license.getUrl())) {
|
||||
this.markupDocBuilder.textLine(LICENSE_URL + license.getUrl());
|
||||
}
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
if(StringUtils.isNotBlank(info.getTermsOfService())){
|
||||
this.markupDocBuilder.textLine(TERMS_OF_SERVICE + info.getTermsOfService());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
this.markupDocBuilder.sectionTitleLevel2(URI_SCHEME);
|
||||
if(StringUtils.isNotBlank(swagger.getHost())){
|
||||
this.markupDocBuilder.textLine(HOST + swagger.getHost());
|
||||
}
|
||||
if(StringUtils.isNotBlank(swagger.getBasePath())){
|
||||
this.markupDocBuilder.textLine(BASE_PATH + swagger.getBasePath());
|
||||
}
|
||||
if(CollectionUtils.isNotEmpty(swagger.getSchemes())){
|
||||
List<String> schemes = new ArrayList<>();
|
||||
for(Scheme scheme : swagger.getSchemes()){
|
||||
schemes.add(scheme.toString());
|
||||
}
|
||||
this.markupDocBuilder.textLine(SCHEMES + StringUtils.join(schemes, ", "));
|
||||
|
||||
}
|
||||
this.markupDocBuilder.newLine();
|
||||
|
||||
if(CollectionUtils.isNotEmpty(swagger.getTags())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(TAGS);
|
||||
List<String> tags = new ArrayList<>();
|
||||
for(Tag tag : swagger.getTags()){
|
||||
String name = tag.getName();
|
||||
String description = tag.getDescription();
|
||||
if(StringUtils.isNoneBlank(description)){
|
||||
tags.add(name + ": " + description);
|
||||
}
|
||||
tags.add(name);
|
||||
}
|
||||
this.markupDocBuilder.unorderedList(tags);
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
if(CollectionUtils.isNotEmpty(swagger.getConsumes())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(CONSUMES);
|
||||
this.markupDocBuilder.unorderedList(swagger.getConsumes());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
if(CollectionUtils.isNotEmpty(swagger.getProduces())){
|
||||
this.markupDocBuilder.sectionTitleLevel2(PRODUCES);
|
||||
this.markupDocBuilder.unorderedList(swagger.getProduces());
|
||||
this.markupDocBuilder.newLine();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,381 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.builder.document;
|
||||
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.Path;
|
||||
import io.swagger.models.Response;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import io.github.robwin.swagger2markup.utils.ParameterUtils;
|
||||
import io.github.robwin.swagger2markup.utils.PropertyUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.text.WordUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class PathsDocument extends MarkupDocument {
|
||||
|
||||
private static final String PATHS = "Paths";
|
||||
private static final String PARAMETERS = "Parameters";
|
||||
private static final String RESPONSES = "Responses";
|
||||
private static final String EXAMPLE_CURL = "Example CURL request";
|
||||
private static final String EXAMPLE_REQUEST = "Example HTTP request";
|
||||
private static final String EXAMPLE_RESPONSE = "Example HTTP response";
|
||||
private static final String TYPE_COLUMN = "Type";
|
||||
private static final String HTTP_CODE_COLUMN = "HTTP Code";
|
||||
private static final String REQUEST_EXAMPLE_FILE_NAME = "http-request";
|
||||
private static final String RESPONSE_EXAMPLE_FILE_NAME = "http-response";
|
||||
private static final String CURL_EXAMPLE_FILE_NAME = "curl-request";
|
||||
private static final String DESCRIPTION_FILE_NAME = "description";
|
||||
private static final String PARAMETER = "Parameter";
|
||||
|
||||
private boolean examplesEnabled;
|
||||
private String examplesFolderPath;
|
||||
private boolean handWrittenDescriptionsEnabled;
|
||||
private String descriptionsFolderPath;
|
||||
|
||||
public PathsDocument(Swagger swagger, MarkupLanguage markupLanguage, String examplesFolderPath, String descriptionsFolderPath){
|
||||
super(swagger, markupLanguage);
|
||||
if(StringUtils.isNotBlank(examplesFolderPath)){
|
||||
this.examplesEnabled = true;
|
||||
this.examplesFolderPath = examplesFolderPath;
|
||||
}
|
||||
if(StringUtils.isNotBlank(descriptionsFolderPath)){
|
||||
this.handWrittenDescriptionsEnabled = true;
|
||||
this.descriptionsFolderPath = descriptionsFolderPath + "/" + PATHS.toLowerCase();
|
||||
}
|
||||
if(examplesEnabled){
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include examples is enabled.");
|
||||
}
|
||||
}else{
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include examples is disabled.");
|
||||
}
|
||||
}
|
||||
if(handWrittenDescriptionsEnabled){
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written descriptions is enabled.");
|
||||
}
|
||||
}else{
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Include hand-written descriptions is disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MarkupDocument build() throws IOException {
|
||||
paths();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds all paths of the Swagger model
|
||||
*/
|
||||
private void paths() throws IOException {
|
||||
Map<String, Path> paths = swagger.getPaths();
|
||||
if(MapUtils.isNotEmpty(paths)) {
|
||||
this.markupDocBuilder.sectionTitleLevel1(PATHS);
|
||||
for (Map.Entry<String, Path> entry : paths.entrySet()) {
|
||||
Path path = entry.getValue();
|
||||
if(path != null) {
|
||||
path("GET", entry.getKey(), path.getGet());
|
||||
path("PUT", entry.getKey(), path.getPut());
|
||||
path("DELETE", entry.getKey(), path.getDelete());
|
||||
path("POST", entry.getKey(), path.getPost());
|
||||
path("PATCH", entry.getKey(), path.getPatch());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a path
|
||||
*
|
||||
* @param httpMethod the HTTP method of the path
|
||||
* @param resourcePath the URL of the path
|
||||
* @param operation the Swagger Operation
|
||||
*/
|
||||
private void path(String httpMethod, String resourcePath, Operation operation) throws IOException {
|
||||
if(operation != null){
|
||||
pathTitle(httpMethod, resourcePath, operation);
|
||||
descriptionSection(operation);
|
||||
parametersSection(operation);
|
||||
responsesSection(operation);
|
||||
consumesSection(operation);
|
||||
producesSection(operation);
|
||||
tagsSection(operation);
|
||||
examplesSection(operation);
|
||||
}
|
||||
}
|
||||
|
||||
private void pathTitle(String httpMethod, String resourcePath, Operation operation) {
|
||||
String summary = operation.getSummary();
|
||||
String title;
|
||||
if(StringUtils.isNotBlank(summary)) {
|
||||
title = summary;
|
||||
this.markupDocBuilder.sectionTitleLevel2(title);
|
||||
this.markupDocBuilder.listing(httpMethod + " " + resourcePath);
|
||||
}else{
|
||||
title = httpMethod + " " + resourcePath;
|
||||
this.markupDocBuilder.sectionTitleLevel2(title);
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Path processed: {}", title);
|
||||
}
|
||||
}
|
||||
|
||||
private void descriptionSection(Operation operation) throws IOException {
|
||||
if(handWrittenDescriptionsEnabled){
|
||||
String summary = operation.getSummary();
|
||||
if(StringUtils.isNotBlank(summary)) {
|
||||
String operationFolder = summary.replace(".", "").replace(" ", "_").toLowerCase();
|
||||
String description = handWrittenPathDescription(operationFolder, DESCRIPTION_FILE_NAME);
|
||||
if(StringUtils.isNotBlank(description)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(DESCRIPTION);
|
||||
this.markupDocBuilder.paragraph(description);
|
||||
}else{
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Hand-written description cannot be read. Trying to use description from Swagger source.");
|
||||
}
|
||||
pathDescription(operation);
|
||||
}
|
||||
}else{
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Hand-written description cannot be read, because summary of operation is empty. Trying to use description from Swagger source.");
|
||||
}
|
||||
pathDescription(operation);
|
||||
}
|
||||
}else {
|
||||
pathDescription(operation);
|
||||
}
|
||||
}
|
||||
|
||||
private void pathDescription(Operation operation) {
|
||||
String description = operation.getDescription();
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
this.markupDocBuilder.sectionTitleLevel3(DESCRIPTION);
|
||||
this.markupDocBuilder.paragraph(description);
|
||||
}
|
||||
}
|
||||
|
||||
private void parametersSection(Operation operation) throws IOException {
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
if(CollectionUtils.isNotEmpty(parameters)){
|
||||
List<String> headerAndContent = new ArrayList<>();
|
||||
// Table header row
|
||||
List<String> header = Arrays.asList(TYPE_COLUMN, NAME_COLUMN, DESCRIPTION_COLUMN, REQUIRED_COLUMN, SCHEMA_COLUMN, DEFAULT_COLUMN);
|
||||
headerAndContent.add(StringUtils.join(header, DELIMITER));
|
||||
for(Parameter parameter : parameters){
|
||||
String type = ParameterUtils.getType(parameter, markupLanguage);
|
||||
String parameterType = WordUtils.capitalize(parameter.getIn() + PARAMETER);
|
||||
// Table content row
|
||||
List<String> content = Arrays.asList(
|
||||
parameterType,
|
||||
parameter.getName(),
|
||||
parameterDescription(operation, parameter),
|
||||
Boolean.toString(parameter.getRequired()), type,
|
||||
ParameterUtils.getDefaultValue(parameter));
|
||||
headerAndContent.add(StringUtils.join(content, DELIMITER));
|
||||
}
|
||||
this.markupDocBuilder.sectionTitleLevel3(PARAMETERS);
|
||||
this.markupDocBuilder.tableWithHeaderRow(headerAndContent);
|
||||
}
|
||||
}
|
||||
|
||||
private String parameterDescription(Operation operation, Parameter parameter) throws IOException {
|
||||
String description;
|
||||
if(handWrittenDescriptionsEnabled){
|
||||
String summary = operation.getSummary();
|
||||
String operationFolder = summary.replace(".", "").replace(" ", "_").toLowerCase();
|
||||
String parameterName = parameter.getName();
|
||||
if(StringUtils.isNotBlank(operationFolder) && StringUtils.isNotBlank(parameterName)) {
|
||||
description = handWrittenPathDescription(operationFolder + "/" + parameterName, DESCRIPTION_FILE_NAME);
|
||||
if(StringUtils.isBlank(description)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Hand-written description file cannot be read. Trying to use description from Swagger source.");
|
||||
}
|
||||
description = StringUtils.defaultString(parameter.getDescription());
|
||||
}
|
||||
}else{
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Hand-written description file cannot be read, because summary of operation or name of parameter is empty. Trying to use description from Swagger source.");
|
||||
}
|
||||
description = StringUtils.defaultString(parameter.getDescription());
|
||||
}
|
||||
}else {
|
||||
description = StringUtils.defaultString(parameter.getDescription());
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
private void consumesSection(Operation operation) {
|
||||
List<String> consumes = operation.getConsumes();
|
||||
if(CollectionUtils.isNotEmpty(consumes)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(CONSUMES);
|
||||
this.markupDocBuilder.unorderedList(consumes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void producesSection(Operation operation) {
|
||||
List<String> produces = operation.getProduces();
|
||||
if(CollectionUtils.isNotEmpty(produces)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(PRODUCES);
|
||||
this.markupDocBuilder.unorderedList(produces);
|
||||
}
|
||||
}
|
||||
|
||||
private void tagsSection(Operation operation) {
|
||||
List<String> tags = operation.getTags();
|
||||
if(CollectionUtils.isNotEmpty(tags)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(TAGS);
|
||||
this.markupDocBuilder.unorderedList(tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the example section of a Swagger Operation
|
||||
*
|
||||
* @param operation the Swagger Operation
|
||||
* @throws IOException if the example file is not readable
|
||||
*/
|
||||
private void examplesSection(Operation operation) throws IOException {
|
||||
if(examplesEnabled){
|
||||
String summary = operation.getSummary();
|
||||
if(StringUtils.isNotBlank(summary)) {
|
||||
String exampleFolder = summary.replace(".", "").replace(" ", "_").toLowerCase();
|
||||
String curlExample = example(exampleFolder, CURL_EXAMPLE_FILE_NAME);
|
||||
if(StringUtils.isNotBlank(curlExample)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(EXAMPLE_CURL);
|
||||
this.markupDocBuilder.paragraph(curlExample);
|
||||
}
|
||||
|
||||
String requestExample = example(exampleFolder, REQUEST_EXAMPLE_FILE_NAME);
|
||||
if(StringUtils.isNotBlank(requestExample)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(EXAMPLE_REQUEST);
|
||||
this.markupDocBuilder.paragraph(requestExample);
|
||||
}
|
||||
String responseExample = example(exampleFolder, RESPONSE_EXAMPLE_FILE_NAME);
|
||||
if(StringUtils.isNotBlank(responseExample)){
|
||||
this.markupDocBuilder.sectionTitleLevel3(EXAMPLE_RESPONSE);
|
||||
this.markupDocBuilder.paragraph(responseExample);
|
||||
}
|
||||
}else{
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Example file cannot be read, because summary of operation is empty.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an example
|
||||
*
|
||||
* @param exampleFolder the name of the folder where the example file resides
|
||||
* @param exampleFileName the name of the example file
|
||||
* @return the content of the file
|
||||
* @throws IOException
|
||||
*/
|
||||
private String example(String exampleFolder, String exampleFileName) throws IOException {
|
||||
for (String fileNameExtension : markupLanguage.getFileNameExtensions()) {
|
||||
java.nio.file.Path path = Paths.get(examplesFolderPath, exampleFolder, exampleFileName + fileNameExtension);
|
||||
if (Files.isReadable(path)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Example file processed: {}", path);
|
||||
}
|
||||
return FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8).trim();
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Example file is not readable: {}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.info("No example file found with correct file name extension in folder: {}", Paths.get(examplesFolderPath, exampleFolder));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws IOException
|
||||
*/
|
||||
private String handWrittenPathDescription(String descriptionFolder, String descriptionFileName) throws IOException {
|
||||
for (String fileNameExtension : markupLanguage.getFileNameExtensions()) {
|
||||
java.nio.file.Path path = Paths.get(descriptionsFolderPath, descriptionFolder, descriptionFileName + fileNameExtension);
|
||||
if (Files.isReadable(path)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Description file processed: {}", path);
|
||||
}
|
||||
return FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8).trim();
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Description file is not readable: {}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.info("No description file found with correct file name extension in folder: {}", Paths.get(descriptionsFolderPath, descriptionFolder));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void responsesSection(Operation operation) {
|
||||
Map<String, Response> responses = operation.getResponses();
|
||||
if(MapUtils.isNotEmpty(responses)){
|
||||
List<String> csvContent = new ArrayList<>();
|
||||
csvContent.add(HTTP_CODE_COLUMN + DELIMITER + DESCRIPTION_COLUMN + DELIMITER + SCHEMA_COLUMN);
|
||||
for(Map.Entry<String, Response> entry : responses.entrySet()){
|
||||
Response response = entry.getValue();
|
||||
if(response.getSchema() != null){
|
||||
Property property = response.getSchema();
|
||||
String type = PropertyUtils.getType(property, markupLanguage);
|
||||
csvContent.add(entry.getKey() + DELIMITER + response.getDescription() + DELIMITER + type);
|
||||
}else{
|
||||
csvContent.add(entry.getKey() + DELIMITER + response.getDescription() + DELIMITER + "No Content");
|
||||
}
|
||||
}
|
||||
this.markupDocBuilder.sectionTitleLevel3(RESPONSES);
|
||||
this.markupDocBuilder.tableWithHeaderRow(csvContent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.utils;
|
||||
|
||||
import io.swagger.models.ArrayModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.ModelImpl;
|
||||
import io.swagger.models.RefModel;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public final class ModelUtils {
|
||||
|
||||
public static String getType(Model model, MarkupLanguage markupLanguage) {
|
||||
Validate.notNull(model, "model must not be null!");
|
||||
if (model instanceof ModelImpl) {
|
||||
return ((ModelImpl) model).getType();
|
||||
} else if (model instanceof RefModel) {
|
||||
switch (markupLanguage){
|
||||
case ASCIIDOC: return "<<" + ((RefModel) model).getSimpleRef() + ">>";
|
||||
default: return ((RefModel) model).getSimpleRef();
|
||||
}
|
||||
} else if (model instanceof ArrayModel) {
|
||||
ArrayModel arrayModel = ((ArrayModel) model);
|
||||
return PropertyUtils.getType(arrayModel.getItems(), markupLanguage) + " " + arrayModel.getType();
|
||||
}
|
||||
return "NOT FOUND";
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.utils;
|
||||
|
||||
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 io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public final class ParameterUtils {
|
||||
|
||||
public static String getType(Parameter parameter, MarkupLanguage markupLanguage){
|
||||
Validate.notNull(parameter, "property must not be null!");
|
||||
String type = "NOT FOUND";
|
||||
if(parameter instanceof BodyParameter){
|
||||
BodyParameter bodyParameter = (BodyParameter)parameter;
|
||||
Model model = bodyParameter.getSchema();
|
||||
type = ModelUtils.getType(model, markupLanguage);
|
||||
}
|
||||
else if(parameter instanceof AbstractSerializableParameter){
|
||||
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
|
||||
List enums = serializableParameter.getEnum();
|
||||
if(CollectionUtils.isNotEmpty(enums)){
|
||||
type = "enum" + " (" + StringUtils.join(enums, ", ") + ")";
|
||||
}else{
|
||||
type = getTypeWithFormat(serializableParameter.getType(), serializableParameter.getFormat());
|
||||
}
|
||||
if(type.equals("array")){
|
||||
String collectionFormat = serializableParameter.getCollectionFormat();
|
||||
type = collectionFormat + " " + PropertyUtils.getType(serializableParameter.getItems(), markupLanguage) + " " + type;
|
||||
}
|
||||
}
|
||||
else if(parameter instanceof RefParameter){
|
||||
RefParameter refParameter = (RefParameter)parameter;
|
||||
switch (markupLanguage){
|
||||
case ASCIIDOC: return "<<" + refParameter.getSimpleRef() + ">>";
|
||||
default: return refParameter.getSimpleRef();
|
||||
}
|
||||
}
|
||||
return StringUtils.defaultString(type);
|
||||
}
|
||||
|
||||
private static String getTypeWithFormat(String typeWithoutFormat, String format) {
|
||||
String type;
|
||||
if(StringUtils.isNotBlank(format)){
|
||||
type = StringUtils.defaultString(typeWithoutFormat) + " (" + format + ")";
|
||||
}else{
|
||||
type = StringUtils.defaultString(typeWithoutFormat);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static String getDefaultValue(Parameter parameter){
|
||||
Validate.notNull(parameter, "property must not be null!");
|
||||
String defaultValue = "";
|
||||
if(parameter instanceof AbstractSerializableParameter){
|
||||
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
|
||||
defaultValue = serializableParameter.getDefaultValue();
|
||||
}
|
||||
return StringUtils.defaultString(defaultValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup.utils;
|
||||
|
||||
import io.swagger.models.properties.*;
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class PropertyUtils {
|
||||
|
||||
public static String getType(Property property, MarkupLanguage markupLanguage){
|
||||
Validate.notNull(property, "property must not be null!");
|
||||
String type;
|
||||
if(property instanceof RefProperty){
|
||||
RefProperty refProperty = (RefProperty)property;
|
||||
switch (markupLanguage){
|
||||
case ASCIIDOC: return "<<" + refProperty.getSimpleRef() + ">>";
|
||||
default: return refProperty.getSimpleRef();
|
||||
}
|
||||
}else if(property instanceof ArrayProperty){
|
||||
ArrayProperty arrayProperty = (ArrayProperty)property;
|
||||
Property items = arrayProperty.getItems();
|
||||
type = getType(items, markupLanguage) + " " + arrayProperty.getType();
|
||||
}else if(property instanceof StringProperty){
|
||||
StringProperty stringProperty = (StringProperty)property;
|
||||
List<String> enums = stringProperty.getEnum();
|
||||
if(CollectionUtils.isNotEmpty(enums)){
|
||||
type = "enum" + " (" + StringUtils.join(enums, ", ") + ")";
|
||||
}else{
|
||||
type = property.getType();
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(StringUtils.isNotBlank(property.getFormat())){
|
||||
type = StringUtils.defaultString(property.getType()) + " (" + property.getFormat() + ")";
|
||||
}else{
|
||||
type = property.getType();
|
||||
}
|
||||
}
|
||||
return StringUtils.defaultString(type);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
package io.github.robwin.swagger2markup;
|
||||
|
||||
import io.github.robwin.markup.builder.MarkupLanguage;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.assertj.core.api.BDDAssertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public class Swagger2MarkupConverterTest {
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversion() throws IOException {
|
||||
//Given
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
File outputDirectory = new File("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory);
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).build()
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(3).containsAll(asList("definitions.adoc", "overview.adoc", "paths.adoc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithDescriptionsAndExamples() throws IOException {
|
||||
//Given
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
File outputDirectory = new File("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory);
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).withDescriptions("src/docs/asciidoc")
|
||||
.withExamples("src/docs/asciidoc/paths").build()
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(3).containsAll(asList("definitions.adoc", "overview.adoc", "paths.adoc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversion() throws IOException {
|
||||
//Given
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
File outputDirectory = new File("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory);
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).
|
||||
withMarkupLanguage(MarkupLanguage.MARKDOWN).build()
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(3).containsAll(asList("definitions.md", "overview.md", "paths.md"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversionWithDescriptions() throws IOException {
|
||||
//Given
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
File outputDirectory = new File("build/docs/markdown/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory);
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).withDescriptions("src/docs/markdown").
|
||||
withMarkupLanguage(MarkupLanguage.MARKDOWN).build()
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(3).containsAll(asList("definitions.md", "overview.md", "paths.md"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2AsciiDocConversionWithSeparatedDefinitions() throws IOException {
|
||||
//Given
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
File outputDirectory = new File("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory);
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).withSeparatedDefinitions().build()
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(8).containsAll(
|
||||
asList("definitions.adoc", "overview.adoc", "paths.adoc",
|
||||
"user.adoc", "category.adoc", "pet.adoc", "tag.adoc", "order.adoc"));
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.adoc"))))
|
||||
.contains(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "user.adoc"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwagger2MarkdownConversionWithSeparatedDefinitions() throws IOException {
|
||||
//Given
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
File outputDirectory = new File("build/docs/asciidoc/generated");
|
||||
FileUtils.deleteQuietly(outputDirectory);
|
||||
|
||||
//When
|
||||
Swagger2MarkupConverter.from(file.getAbsolutePath()).withSeparatedDefinitions().
|
||||
withMarkupLanguage(MarkupLanguage.MARKDOWN).build()
|
||||
.intoFolder(outputDirectory.getAbsolutePath());
|
||||
|
||||
//Then
|
||||
String[] directories = outputDirectory.list();
|
||||
assertThat(directories).hasSize(8).containsAll(
|
||||
asList("definitions.md", "overview.md", "paths.md",
|
||||
"user.md", "category.md", "pet.md", "tag.md", "order.md"));
|
||||
assertThat(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "definitions.md"))))
|
||||
.contains(new String(Files.readAllBytes(Paths.get(outputDirectory + File.separator + "user.md"))));
|
||||
}
|
||||
|
||||
/*
|
||||
@Test
|
||||
public void testSwagger2HtmlConversion() throws IOException {
|
||||
File file = new File(Swagger2MarkupConverterTest.class.getResource("/json/swagger.json").getFile());
|
||||
String asciiDoc = Swagger2MarkupConverter.from(file.getAbsolutePath()).build().asString();
|
||||
String path = "build/docs/generated/asciidocAsString";
|
||||
Files.createDirectories(Paths.get(path));
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(path, "swagger.adoc"), StandardCharsets.UTF_8)){
|
||||
writer.write(asciiDoc); }
|
||||
String asciiDocAsHtml = Asciidoctor.Factory.create().convert(asciiDoc,
|
||||
OptionsBuilder.options().backend("html5").headerFooter(true).safe(SafeMode.UNSAFE).docType("book").attributes(AttributesBuilder.attributes()
|
||||
.tableOfContents(true).tableOfContents(Placement.LEFT).sectionNumbers(true).hardbreaks(true).setAnchors(true).attribute("sectlinks")));
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(path, "swagger.html"), StandardCharsets.UTF_8)){
|
||||
writer.write(asciiDocAsHtml);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,850 +0,0 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "This is a sample server Petstore server.\n\n[Learn about Swagger](http://swagger.wordnik.com) or join the IRC channel `#swagger` on irc.freenode.net.\n\nFor this sample, you can use the api key `special-key` to test the authorization filters\n",
|
||||
"version": "1.0.0",
|
||||
"title": "Swagger Petstore API",
|
||||
"termsOfService": "http://helloreverb.com/terms/",
|
||||
"contact": {
|
||||
"name": "apiteam@wordnik.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
}
|
||||
},
|
||||
"host": "petstore.swagger.wordnik.com",
|
||||
"basePath": "/v2",
|
||||
"schemes": [
|
||||
"http"
|
||||
],
|
||||
"paths": {
|
||||
"/pets": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Add a new pet to the store",
|
||||
"description": "",
|
||||
"operationId": "addPet",
|
||||
"consumes": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "Pet object that needs to be added to the store",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Pet"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"405": {
|
||||
"description": "Invalid input"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Update an existing pet",
|
||||
"description": "",
|
||||
"operationId": "updatePet",
|
||||
"consumes": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "Pet object that needs to be added to the store",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Pet"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Invalid ID supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "Pet not found"
|
||||
},
|
||||
"405": {
|
||||
"description": "Validation exception"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/pets/findByStatus": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Finds Pets by status",
|
||||
"description": "Multiple status values can be provided with comma seperated strings",
|
||||
"operationId": "findPetsByStatus",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "status",
|
||||
"description": "Status values that need to be considered for filter",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"collectionFormat": "multi"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Pet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid status value"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/pets/findByTags": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Finds Pets by tags",
|
||||
"description": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
|
||||
"operationId": "findPetsByTags",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "tags",
|
||||
"description": "Tags to filter by",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"collectionFormat": "multi"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Pet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid tag value"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/pets/{petId}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Find pet by ID",
|
||||
"description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions",
|
||||
"operationId": "getPetById",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "petId",
|
||||
"description": "ID of pet that needs to be fetched",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Pet"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid ID supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "Pet not found"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"api_key": []
|
||||
},
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Updates a pet in the store with form data",
|
||||
"description": "",
|
||||
"operationId": "updatePetWithForm",
|
||||
"consumes": [
|
||||
"application/x-www-form-urlencoded"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "petId",
|
||||
"description": "ID of pet that needs to be updated",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "formData",
|
||||
"name": "name",
|
||||
"description": "Updated name of the pet",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "formData",
|
||||
"name": "status",
|
||||
"description": "Updated status of the pet",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"405": {
|
||||
"description": "Invalid input"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"pet"
|
||||
],
|
||||
"summary": "Deletes a pet",
|
||||
"description": "",
|
||||
"operationId": "deletePet",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "header",
|
||||
"name": "api_key",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "petId",
|
||||
"description": "Pet id to delete",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Invalid pet value"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"petstore_auth": [
|
||||
"write_pets",
|
||||
"read_pets"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/stores/order": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"store"
|
||||
],
|
||||
"summary": "Place an order for a pet",
|
||||
"description": "",
|
||||
"operationId": "placeOrder",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "order placed for purchasing the pet",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Order"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Order"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid Order"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/stores/order/{orderId}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"store"
|
||||
],
|
||||
"summary": "Find purchase order by ID",
|
||||
"description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
|
||||
"operationId": "getOrderById",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "orderId",
|
||||
"description": "ID of pet that needs to be fetched",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Order"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid ID supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "Order not found"
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"store"
|
||||
],
|
||||
"summary": "Delete purchase order by ID",
|
||||
"description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
|
||||
"operationId": "deleteOrder",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "orderId",
|
||||
"description": "ID of the order that needs to be deleted",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Invalid ID supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "Order not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Create user",
|
||||
"description": "This can only be done by the logged in user.",
|
||||
"operationId": "createUser",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "Created user object",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/User"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "successful operation"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/createWithArray": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Creates list of users with given input array",
|
||||
"description": "",
|
||||
"operationId": "createUsersWithArrayInput",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "List of user object",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/User"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "successful operation"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/createWithList": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Creates list of users with given input array",
|
||||
"description": "",
|
||||
"operationId": "createUsersWithListInput",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "List of user object",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/User"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "successful operation"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/login": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Logs user into the system",
|
||||
"description": "",
|
||||
"operationId": "loginUser",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "username",
|
||||
"description": "The user name for login",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "testUser"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "password",
|
||||
"description": "The password for login in clear text",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "testPassword"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid username/password supplied"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/logout": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Logs out current logged in user session",
|
||||
"description": "",
|
||||
"operationId": "logoutUser",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "successful operation"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/{username}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Get user by user name",
|
||||
"description": "",
|
||||
"operationId": "getUserByName",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "username",
|
||||
"description": "The name that needs to be fetched. Use user1 for testing.",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"default": "testUser"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid username supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "User not found"
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Updated user",
|
||||
"description": "This can only be done by the logged in user.",
|
||||
"operationId": "updateUser",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "username",
|
||||
"description": "name that need to be deleted",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "Updated user object",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/User"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Invalid user supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "User not found"
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "Delete user",
|
||||
"description": "This can only be done by the logged in user.",
|
||||
"operationId": "deleteUser",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "username",
|
||||
"description": "The name that needs to be deleted",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Invalid username supplied"
|
||||
},
|
||||
"404": {
|
||||
"description": "User not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"api_key": {
|
||||
"type": "apiKey",
|
||||
"name": "api_key",
|
||||
"in": "header"
|
||||
},
|
||||
"petstore_auth": {
|
||||
"type": "oauth2",
|
||||
"authorizationUrl": "http://petstore.swagger.wordnik.com/api/oauth/dialog",
|
||||
"flow": "implicit",
|
||||
"scopes": {
|
||||
"write_pets": "modify pets in your account",
|
||||
"read_pets": "read your pets"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"User": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string"
|
||||
},
|
||||
"userStatus": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "User Status"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Category": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Pet": {
|
||||
"description" : "Test description",
|
||||
"required": [
|
||||
"name",
|
||||
"photoUrls"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"category": {
|
||||
"$ref": "#/definitions/Category"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"example": "doggie"
|
||||
},
|
||||
"photoUrls": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Tag"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "pet status in the store"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Tag": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Order": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"petId": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"shipDate": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Order Status"
|
||||
},
|
||||
"complete": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
swagger2markup-asciidoc/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
||||
ext.moduleName="io.github.swagger2markup.asciidoc"
|
||||
|
||||
dependencies {
|
||||
configurations.all {
|
||||
// resolutionStrategy.force dependencyOverrides.commonsCodec
|
||||
// resolutionStrategy.force dependencyOverrides.commonsIO
|
||||
// resolutionStrategy.force dependencyOverrides.commonsLang3
|
||||
resolutionStrategy.force dependencyOverrides.jnrConstants
|
||||
resolutionStrategy.force dependencyOverrides.jnrEnxio
|
||||
resolutionStrategy.force dependencyOverrides.jnrPosix
|
||||
// resolutionStrategy.force dependencyOverrides.jodaTime
|
||||
resolutionStrategy.force dependencyOverrides.slf4j
|
||||
// resolutionStrategy.force dependencyOverrides.jacksonDatabind
|
||||
// resolutionStrategy.force dependencyOverrides.guava
|
||||
// resolutionStrategy.force dependencyOverrides.findBugs
|
||||
// resolutionStrategy.force dependencyOverrides.jaksonCore
|
||||
}
|
||||
implementation implLibraries.asciiDocJApi
|
||||
implementation implLibraries.commonsText
|
||||
implementation implLibraries.slf4j
|
||||
testImplementation implLibraries.commonsIO
|
||||
testImplementation testLibraries.asciiDocJ
|
||||
testImplementation testLibraries.junit
|
||||
testImplementation testLibraries.logback
|
||||
}
|
||||
@@ -0,0 +1,887 @@
|
||||
package io.github.swagger2markup.adoc;
|
||||
|
||||
import io.github.swagger2markup.adoc.converter.internal.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.asciidoctor.ast.List;
|
||||
import org.asciidoctor.ast.*;
|
||||
import org.asciidoctor.converter.ConverterFor;
|
||||
import org.asciidoctor.converter.StringConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
|
||||
|
||||
@ConverterFor(AsciidocConverter.NAME)
|
||||
public class AsciidocConverter extends StringConverter {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public static final String NAME = "adoc";
|
||||
|
||||
private final Pattern emptyLineOrStartWith = Pattern.compile("(?m)^\\s*(?:\\r?\\n)|(?m)^\\s+");
|
||||
private final Pattern coListItemIdPattern = Pattern.compile(".*-(\\d+)");
|
||||
private final Pattern tableColumnsStylePattern = Pattern.compile("((\\d+)\\*)?([<^>])?(\\.[<^>])?(\\d+)?([adehlmsv])?");
|
||||
|
||||
private static final java.util.List<String> attributeToExclude = Arrays.asList(
|
||||
"localtime",
|
||||
"filetype",
|
||||
"asciidoctor-version",
|
||||
"doctime",
|
||||
"localyear",
|
||||
"docdate",
|
||||
"localdate",
|
||||
"localdatetime",
|
||||
"docdatetime",
|
||||
"backend",
|
||||
"basebackend",
|
||||
"doctitle",
|
||||
"docyear"
|
||||
);
|
||||
|
||||
private static final String[] supportedUrlSchemes = new String[]{
|
||||
"http",
|
||||
"https",
|
||||
"ftp",
|
||||
"irc",
|
||||
"mailto"
|
||||
};
|
||||
|
||||
public AsciidocConverter(String backend, Map<String, Object> opts) {
|
||||
super(backend, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an {@link ContentNode} using the specified transform along
|
||||
* with additional options. If a transform is not specified, implementations
|
||||
* typically derive one from the {@link ContentNode#getNodeName()} property.
|
||||
*
|
||||
* <p>Implementations are free to decide how to carry out the conversion. In
|
||||
* the case of the built-in converters, the tranform value is used to
|
||||
* dispatch to a handler method. The TemplateConverter uses the value of
|
||||
* the transform to select a template to render.
|
||||
*
|
||||
* @param node The concrete instance of FlowNode to convert
|
||||
* @param transform An optional String transform that hints at which transformation
|
||||
* should be applied to this node. If a transform is not specified,
|
||||
* the transform is typically derived from the value of the
|
||||
* node's node_name property. (optional, default: null)
|
||||
* @param opts An optional map of options that provide additional hints about
|
||||
* how to convert the node. (optional, default: empty map)
|
||||
* @return the converted result
|
||||
*/
|
||||
@Override
|
||||
public String convert(ContentNode node, String transform, Map<Object, Object> opts) {
|
||||
if (null == transform) {
|
||||
transform = node.getNodeName();
|
||||
}
|
||||
switch (transform) {
|
||||
case "inline_quoted":
|
||||
return convertInlineQuoted((PhraseNode) node);
|
||||
case "paragraph":
|
||||
return convertParagraph((StructuralNode) node);
|
||||
case "inline_anchor":
|
||||
return convertInlineAnchor((PhraseNode) node);
|
||||
case "section":
|
||||
return convertSection((Section) node);
|
||||
case "listing":
|
||||
return convertListing((Block) node);
|
||||
case "literal":
|
||||
return convertLiteral((StructuralNode) node);
|
||||
case "ulist":
|
||||
return convertUList((List) node);
|
||||
case "olist":
|
||||
return convertOList((List) node);
|
||||
case "dlist":
|
||||
return convertDescriptionList((DescriptionList) node);
|
||||
case "admonition":
|
||||
return convertAdmonition((Block) node);
|
||||
case "colist":
|
||||
return convertCoList((List) node);
|
||||
case "embedded":
|
||||
case "document":
|
||||
return convertEmbedded((Document) node);
|
||||
case "example":
|
||||
return convertExample((Block) node);
|
||||
case "floating_title":
|
||||
return convertFloatingTitle((StructuralNode) node);
|
||||
case "image":
|
||||
return convertImage((StructuralNode) node);
|
||||
case "inline_break":
|
||||
return convertInlineBreak(node);
|
||||
case "inline_button":
|
||||
return convertInlineButton(node);
|
||||
case "inline_callout":
|
||||
return convertInlineCallout(node);
|
||||
case "inline_footnote":
|
||||
return convertInlineFootnote(node);
|
||||
case "inline_image":
|
||||
return convertInlineImage((PhraseNode) node);
|
||||
case "inline_indexterm":
|
||||
return convertInlineIndexTerm(node);
|
||||
case "inline_kbd":
|
||||
return convertInlineKbd(node);
|
||||
case "inline_menu":
|
||||
return convertInlineMenu(node);
|
||||
case "open":
|
||||
return convertOpen((StructuralNode) node);
|
||||
case "page_break":
|
||||
return convertPageBreak(node);
|
||||
case "preamble":
|
||||
return convertPreamble((StructuralNode) node);
|
||||
case "quote":
|
||||
return convertQuote((StructuralNode) node);
|
||||
case "sidebar":
|
||||
return convertSidebar((StructuralNode) node);
|
||||
case "stem":
|
||||
return convertStem(node);
|
||||
case "table":
|
||||
return convertTable((Table) node);
|
||||
case "thematic_break":
|
||||
return convertThematicBreak(node);
|
||||
case "verse":
|
||||
return convertVerse((StructuralNode) node);
|
||||
case "video":
|
||||
return convertVideo(node);
|
||||
case "toc":
|
||||
return convertToc(node);
|
||||
case "pass":
|
||||
return convertPass(node);
|
||||
case "audio":
|
||||
return convertAudio(node);
|
||||
// didn't exist on html converter
|
||||
case "list":
|
||||
return convertList((List) node);
|
||||
case "list_item":
|
||||
return convertListItem((ListItem) node);
|
||||
default:
|
||||
logger.debug("Don't know how to convert transform: [" + transform + "] Node: " + node);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String convertEmbedded(Document node) {
|
||||
logger.debug("convertEmbedded");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendId(node, sb);
|
||||
if (StringUtils.isNotBlank(node.getDoctitle())) {
|
||||
sb.append(repeat(node.getLevel() + 1,DOCUMENT_TITLE)).append(' ').append(StringEscapeUtils.unescapeHtml4(node.getDoctitle())).append(LINE_SEPARATOR);
|
||||
}
|
||||
Map<String, Object> attributes = node.getAttributes();
|
||||
appendAuthors(sb, attributes);
|
||||
appendRevisionDetails(sb, attributes);
|
||||
appendDocumentAttributes(sb, attributes);
|
||||
appendTrailingNewLine(sb);
|
||||
appendChildBlocks(node, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void appendAuthors(StringBuilder sb, Map<String, Object> attributes) {
|
||||
Long authorCount = (Long) attributes.getOrDefault("authorcount", 0L);
|
||||
if (authorCount == 1) {
|
||||
String author = getAuthorDetail(attributes, "author", "email");
|
||||
if (StringUtils.isNotBlank(author)) {
|
||||
sb.append(author).append(LINE_SEPARATOR);
|
||||
}
|
||||
} else if (authorCount > 1) {
|
||||
String authors = LongStream.rangeClosed(1, authorCount)
|
||||
.mapToObj(i -> getAuthorDetail(attributes, "author_" + i, "email_" + i))
|
||||
.collect(Collectors.joining("; "));
|
||||
|
||||
if (StringUtils.isNotBlank(authors)) {
|
||||
sb.append(authors).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendDocumentAttributes(StringBuilder sb, Map<String, Object> attributes) {
|
||||
attributes.forEach((k, v) -> {
|
||||
if (!attributeToExclude.contains(k) && v != null && !v.toString().isEmpty())
|
||||
sb.append(COLON).append(k).append(COLON).append(" ").append(v).append(LINE_SEPARATOR);
|
||||
});
|
||||
}
|
||||
|
||||
private void appendRevisionDetails(StringBuilder sb, Map<String, Object> attributes) {
|
||||
String revDetails = Stream.of(attributes.get("revnumber"), attributes.get("revdate")).filter(Objects::nonNull)
|
||||
.filter(o -> !o.toString().isEmpty()).map(Object::toString)
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
if (!revDetails.isEmpty()) {
|
||||
sb.append("v").append(revDetails).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private String getAuthorDetail(Map<String, Object> attributes, String authorKey, String emailKey) {
|
||||
String author = attributes.getOrDefault(authorKey, "").toString();
|
||||
String email = attributes.getOrDefault(emailKey, "").toString();
|
||||
if (StringUtils.isNotBlank(email)) {
|
||||
email = " <" + email + ">";
|
||||
}
|
||||
|
||||
return (author + email).trim();
|
||||
}
|
||||
|
||||
private String convertInlineAnchor(PhraseNode node) {
|
||||
logger.debug("convertInlineAnchor");
|
||||
String type = node.getType();
|
||||
switch (type) {
|
||||
case "xref": {
|
||||
String attrs;
|
||||
String text;
|
||||
String path = Optional.ofNullable(node.getAttributes().get("path")).orElse("").toString();
|
||||
if (StringUtils.isNotBlank(path)) {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(node.getRole())) {
|
||||
list.add(" class=\"#{node.role}\"");
|
||||
}
|
||||
append_link_constraint_attrs(node, list);
|
||||
attrs = String.join(" ", list);
|
||||
text = StringUtils.isNotBlank(node.getText()) ? node.getText() : path;
|
||||
} else {
|
||||
attrs = StringUtils.isNotBlank(node.getRole()) ? " class=\"" + node.getRole() + "\"" : "";
|
||||
text = node.getText();
|
||||
if (StringUtils.isNotBlank(text)) {
|
||||
text = node.getAttributes().get("refid").toString();
|
||||
}
|
||||
}
|
||||
return node.getTarget() + ATTRIBUTES_BEGIN + text + (StringUtils.isNotBlank(attrs) ? "," + attrs : "") + ATTRIBUTES_END;
|
||||
}
|
||||
case "ref":
|
||||
return node.getId();
|
||||
case "link": {
|
||||
ArrayList<String> attrs = new ArrayList<>();
|
||||
String target = node.getTarget();
|
||||
String includePrefix = !StringUtils.startsWithAny(target, supportedUrlSchemes) ? "include::" : "";
|
||||
|
||||
String text = node.getText();
|
||||
if (!target.equals(text)) {
|
||||
attrs.add(text);
|
||||
}
|
||||
if (StringUtils.isNotBlank(node.getId())) {
|
||||
attrs.add("id=\"" + node.getId() + "\"");
|
||||
}
|
||||
String role = node.getRole();
|
||||
if (StringUtils.isNotBlank(role) && !role.equals("bare")) {
|
||||
attrs.add("role=\"" + role + "\"");
|
||||
}
|
||||
String title = node.getAttribute("title", "").toString();
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
attrs.add("title=\"" + title + "\"");
|
||||
}
|
||||
return includePrefix + target + ATTRIBUTES_BEGIN + String.join(",", attrs) + ATTRIBUTES_END;
|
||||
}
|
||||
case "bibref":
|
||||
return node.getId() + ATTRIBUTES_BEGIN + (StringUtils.isNotBlank(node.getReftext()) ? node.getReftext() : node.getId()) + ATTRIBUTES_END;
|
||||
default:
|
||||
logger.warn("unknown anchor type: " + node.getType());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String convertAdmonition(Block node) {
|
||||
logger.debug("convertAdmonition");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
java.util.List<StructuralNode> blocks = node.getBlocks();
|
||||
if (blocks.isEmpty()) {
|
||||
sb.append(node.getStyle()).append(": ").append(node.getSource());
|
||||
} else {
|
||||
appendTitle(node, sb);
|
||||
sb.append(ATTRIBUTES_BEGIN).append(node.getStyle()).append(ATTRIBUTES_END)
|
||||
.append(LINE_SEPARATOR).append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertInlineQuoted(PhraseNode node) {
|
||||
logger.debug("convertInlineQuoted");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String marker = "";
|
||||
switch (node.getType()) {
|
||||
case "monospaced":
|
||||
marker = "`";
|
||||
break;
|
||||
case "emphasis":
|
||||
marker = "_";
|
||||
break;
|
||||
case "strong":
|
||||
marker = "*";
|
||||
break;
|
||||
case "superscript":
|
||||
marker = "^";
|
||||
break;
|
||||
case "subscript":
|
||||
marker = "~";
|
||||
break;
|
||||
case "double":
|
||||
case "single":
|
||||
case "mark":
|
||||
case "asciimath":
|
||||
case "latexmath":
|
||||
marker = "";
|
||||
break;
|
||||
}
|
||||
sb.append(marker).append(node.getText()).append(marker);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertFloatingTitle(StructuralNode node) {
|
||||
logger.debug("convertFloatingTitle");
|
||||
return ATTRIBUTES_BEGIN + "discrete" + ATTRIBUTES_END + LINE_SEPARATOR +
|
||||
repeat(node.getLevel() + 1, TITLE) + ' ' + node.getTitle() + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertExample(Block node) {
|
||||
logger.debug("convertExample");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertInlineButton(ContentNode node) {
|
||||
logger.debug("convertInlineButton: name" + node.getNodeName());
|
||||
return "convertInlineButton";
|
||||
}
|
||||
|
||||
private String convertInlineCallout(ContentNode node) {
|
||||
logger.debug("convertInlineCallout: name" + node.getNodeName());
|
||||
return "convertInlineCallout";
|
||||
}
|
||||
|
||||
private String convertInlineBreak(ContentNode node) {
|
||||
logger.debug("convertInlineBreak: name" + node.getNodeName());
|
||||
return "convertInlineBreak";
|
||||
}
|
||||
|
||||
private String convertInlineFootnote(ContentNode node) {
|
||||
logger.debug("convertInlineFootnote: name" + node.getNodeName());
|
||||
return "convertInlineFootnote";
|
||||
}
|
||||
|
||||
private String convertInlineImage(PhraseNode node) {
|
||||
logger.debug("convertInlineImage");
|
||||
if (node.getType().equals("icon")) {
|
||||
return (new IconNode(node)).toAsciiDocContent();
|
||||
} else {
|
||||
return (new BlockImageNode(node)).toAsciiDocContent();
|
||||
}
|
||||
}
|
||||
|
||||
private String convertInlineIndexTerm(ContentNode node) {
|
||||
logger.debug("convertInlineIndexTerm: name" + node.getNodeName());
|
||||
return "convertInlineIndexTerm";
|
||||
}
|
||||
|
||||
private String convertInlineKbd(ContentNode node) {
|
||||
logger.debug("convertInlineKbd: name" + node.getNodeName());
|
||||
return "convertInlineKbd";
|
||||
}
|
||||
|
||||
private String convertInlineMenu(ContentNode node) {
|
||||
logger.debug("convertInlineMenu: name" + node.getNodeName());
|
||||
return "convertInlineMenu";
|
||||
}
|
||||
|
||||
private String convertOpen(StructuralNode node) {
|
||||
logger.debug("convertOpen");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
switch (node.getStyle()) {
|
||||
case "abstract":
|
||||
sb.append(ATTRIBUTES_BEGIN).append("abstract").append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
break;
|
||||
case "open":
|
||||
sb.append(DELIMITER_OPEN_BLOCK).append(LINE_SEPARATOR);
|
||||
}
|
||||
sb.append(Optional.ofNullable(((Block) node).getSource()).orElse(""));
|
||||
appendChildBlocks(node, sb);
|
||||
|
||||
if ("open".equals(node.getStyle())) {
|
||||
sb.append(DELIMITER_OPEN_BLOCK).append(LINE_SEPARATOR);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertPageBreak(ContentNode node) {
|
||||
logger.debug("convertPageBreak: name" + node.getNodeName());
|
||||
return DELIMITER_PAGE_BREAK + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertQuote(StructuralNode node) {
|
||||
logger.debug("convertQuote");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(ATTRIBUTES_BEGIN);
|
||||
java.util.List<String> attrs = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(node.getStyle())) {
|
||||
attrs.add("quote");
|
||||
}
|
||||
appendAttributeTo(node, attrs, "attribution");
|
||||
appendAttributeTo(node, attrs, "citetitle");
|
||||
sb.append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
java.util.List<StructuralNode> blocks = node.getBlocks();
|
||||
if (!blocks.isEmpty()) {
|
||||
sb.append("____").append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
sb.append("____").append(LINE_SEPARATOR);
|
||||
} else {
|
||||
sb.append(((Block) node).getSource());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertSidebar(StructuralNode node) {
|
||||
logger.debug("convertSidebar");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
appendChildBlocks(node, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertStem(ContentNode node) {
|
||||
logger.debug("convertStem: name" + node.getNodeName());
|
||||
return "convertStem";
|
||||
}
|
||||
|
||||
private String convertThematicBreak(ContentNode node) {
|
||||
logger.debug("convertThematicBreak: name" + node.getNodeName());
|
||||
return DELIMITER_THEMATIC_BREAK + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertVerse(StructuralNode node) {
|
||||
logger.debug("convertVerse");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(ATTRIBUTES_BEGIN);
|
||||
java.util.List<String> attrs = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(node.getStyle())) {
|
||||
attrs.add("verse");
|
||||
}
|
||||
appendAttributeTo(node, attrs, "attribution");
|
||||
appendAttributeTo(node, attrs, "citetitle");
|
||||
sb.append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
String source = ((Block) node).getSource();
|
||||
boolean matches = emptyLineOrStartWith.matcher(source).find();
|
||||
if (matches) {
|
||||
sb.append(DELIMITER_VERSE).append(LINE_SEPARATOR);
|
||||
}
|
||||
sb.append(source);
|
||||
if (matches) {
|
||||
sb.append(LINE_SEPARATOR).append(DELIMITER_VERSE);
|
||||
}
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertVideo(ContentNode node) {
|
||||
logger.debug("convertVideo: name" + node.getNodeName());
|
||||
return "convertVideo";
|
||||
}
|
||||
|
||||
private String convertToc(ContentNode node) {
|
||||
logger.debug("convertToc: name" + node.getNodeName());
|
||||
return "convertToc";
|
||||
}
|
||||
|
||||
private String convertPass(ContentNode node) {
|
||||
logger.debug("convertPass: name" + node.getNodeName());
|
||||
return "convertPass";
|
||||
}
|
||||
|
||||
private String convertAudio(ContentNode node) {
|
||||
logger.debug("convertAudio: name" + node.getNodeName());
|
||||
return "convertAudio";
|
||||
}
|
||||
|
||||
private String convertCell(Cell node) {
|
||||
logger.debug("convertCell");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String source = node.getSource();
|
||||
if (StringUtils.isNotBlank(source)) {
|
||||
sb.append(source);
|
||||
}
|
||||
Document innerDocument = node.getInnerDocument();
|
||||
if (null != innerDocument) {
|
||||
appendChildBlocks(innerDocument, sb, false);
|
||||
}
|
||||
return sb.toString().replaceAll(LINE_SEPARATOR + LINE_SEPARATOR + "+", LINE_SEPARATOR + LINE_SEPARATOR);
|
||||
}
|
||||
|
||||
private String convertRow(Row node, java.util.List<TableCellStyle> columnStyles, String delimiterTableCell) {
|
||||
logger.debug("convertRow");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
node.getCells().forEach(cell -> {
|
||||
boolean addNewLine = false;
|
||||
int colspan = cell.getColspan();
|
||||
if (colspan != 0) {
|
||||
addNewLine = true;
|
||||
sb.append(colspan).append('+');
|
||||
}
|
||||
int rowspan = cell.getRowspan();
|
||||
if (rowspan != 0) {
|
||||
addNewLine = true;
|
||||
sb.append('.').append(rowspan).append('+');
|
||||
}
|
||||
int index = cell.getColumn().getColumnNumber() - 1;
|
||||
TableCellStyle tableCellStyle = (columnStyles.size() > index) ? columnStyles.get(index) : null;
|
||||
|
||||
boolean hAlignmentAdded = false;
|
||||
TableCellHorizontalAlignment hAlignment = TableCellHorizontalAlignment.fromName(cell.getHorizontalAlignment().name());
|
||||
if ((null != hAlignment) && (null == tableCellStyle || hAlignment != tableCellStyle.horizontalAlignment)) {
|
||||
hAlignmentAdded = true;
|
||||
addNewLine = true;
|
||||
sb.append(hAlignment.getDelimiter());
|
||||
}
|
||||
|
||||
TableCellVerticalAlignment vAlignment = TableCellVerticalAlignment.fromName(cell.getVerticalAlignment().name());
|
||||
if ((null != vAlignment) && (null == tableCellStyle || hAlignmentAdded || vAlignment != tableCellStyle.verticalAlignment)) {
|
||||
addNewLine = true;
|
||||
sb.append(vAlignment.getDelimiter());
|
||||
}
|
||||
|
||||
Style style = Style.fromName(cell.getAttribute("style", "").toString());
|
||||
if (null != style && (null == tableCellStyle || style != tableCellStyle.style)) {
|
||||
addNewLine = true;
|
||||
sb.append(style.getShortHand());
|
||||
}
|
||||
sb.append(delimiterTableCell).append(convertCell(cell));
|
||||
if (addNewLine) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
} else {
|
||||
sb.append(' ');
|
||||
}
|
||||
});
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertTable(Table node) {
|
||||
logger.debug("convertTable");
|
||||
java.util.List<TableCellStyle> columnStyles = new ArrayList<>();
|
||||
for (String col : node.getAttribute("cols", "").toString().split(",")) {
|
||||
Matcher matcher = tableColumnsStylePattern.matcher(col);
|
||||
if (matcher.find()) {
|
||||
int multiplier = 1;
|
||||
String multiplierGroup = matcher.group(2);
|
||||
if (null != multiplierGroup) {
|
||||
try {
|
||||
multiplier = Integer.parseInt(multiplierGroup);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
int width = 0;
|
||||
try {
|
||||
width = Integer.parseInt(matcher.group(5));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
TableCellStyle tableCellStyle = new TableCellStyle(
|
||||
TableCellHorizontalAlignment.fromString(matcher.group(3)),
|
||||
TableCellVerticalAlignment.fromString(matcher.group(4)),
|
||||
Style.fromString(matcher.group(6)),
|
||||
width
|
||||
);
|
||||
for (int i = 0; i < multiplier; i++) {
|
||||
columnStyles.add(tableCellStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(new TableNode(node).toAsciiDocContent());
|
||||
boolean innerTable = isInnerTable(node);
|
||||
String tableDelimiter = innerTable ? DELIMITER_INNER_TABLE : DELIMITER_TABLE;
|
||||
String cellDelimiter = innerTable ? DELIMITER_INNER_TABLE_CELL : DELIMITER_TABLE_CELL;
|
||||
sb.append(tableDelimiter).append(LINE_SEPARATOR);
|
||||
appendRows(node.getHeader(), sb, columnStyles, cellDelimiter);
|
||||
appendRows(node.getBody(), sb, columnStyles, cellDelimiter);
|
||||
appendRows(node.getFooter(), sb, columnStyles, cellDelimiter);
|
||||
sb.append(tableDelimiter).append(LINE_SEPARATOR);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean isInnerTable(ContentNode node) {
|
||||
if(null != node) {
|
||||
ContentNode parent = node.getParent();
|
||||
if (null != parent) {
|
||||
return parent instanceof Table || isInnerTable(parent);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void appendRows(java.util.List<Row> rows, StringBuilder sb, java.util.List<TableCellStyle> columnStyles, String delimiterTableCell) {
|
||||
rows.forEach(row -> sb.append(convertRow(row, columnStyles, delimiterTableCell)).append(LINE_SEPARATOR));
|
||||
}
|
||||
|
||||
private String convertDescriptionList(DescriptionList node) {
|
||||
logger.debug("convertDescriptionList");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
appendTitle(node, sb);
|
||||
String style = Optional.ofNullable(node.getStyle()).orElse("");
|
||||
switch (style) {
|
||||
case STYLE_HORIZONTAL:
|
||||
sb.append(ATTRIBUTES_BEGIN).append(STYLE_HORIZONTAL).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
node.getItems().forEach(item -> sb.append(convertDescriptionListEntry(item, node.getLevel(), false)));
|
||||
break;
|
||||
case STYLE_Q_AND_A:
|
||||
sb.append(ATTRIBUTES_BEGIN).append(STYLE_Q_AND_A).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
default:
|
||||
node.getItems().forEach(item -> sb.append(convertDescriptionListEntry(item, node.getLevel(), true)));
|
||||
break;
|
||||
}
|
||||
appendTrailingNewLine(sb);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertDescriptionListEntry(DescriptionListEntry node, int level, Boolean descriptionOnNewLine) {
|
||||
logger.debug("convertDescriptionListEntry");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String delimiter = repeat(level + 1, MARKER_D_LIST_ITEM);
|
||||
String entryTerms = node.getTerms().stream()
|
||||
.map(term -> Optional.ofNullable(term.getSource()).orElse(""))
|
||||
.collect(Collectors.joining(delimiter + LINE_SEPARATOR, "", delimiter));
|
||||
sb.append(entryTerms);
|
||||
ListItem description = node.getDescription();
|
||||
if (null != description) {
|
||||
if (descriptionOnNewLine) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
}
|
||||
String desc = Optional.ofNullable(description.getSource()).orElse("");
|
||||
if (StringUtils.isNotBlank(desc)) {
|
||||
sb.append(desc).append(LINE_SEPARATOR);
|
||||
}
|
||||
appendChildBlocks(description, sb);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertListing(Block node) {
|
||||
logger.debug("convertListing");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
if (STYLE_SOURCE.equals(node.getStyle())) {
|
||||
sb.append(new SourceNode(node).toAsciiDocContent());
|
||||
} else {
|
||||
sb.append(new BlockListingNode(node).toAsciiDocContent());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertUList(List node) {
|
||||
logger.debug("convertUList");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendStyle(node, sb);
|
||||
appendTitle(node, sb);
|
||||
appendChildBlocks(node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertOList(List node) {
|
||||
logger.debug("convertOList");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
java.util.List<String> attrs = new ArrayList<>();
|
||||
String start = node.getAttribute("start", "").toString();
|
||||
if (StringUtils.isNotBlank(start)) {
|
||||
attrs.add("start=" + start);
|
||||
}
|
||||
if (node.isOption("reversed")) {
|
||||
attrs.add("%reversed");
|
||||
}
|
||||
if (!attrs.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
appendTitle(node, sb);
|
||||
appendChildBlocks(node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertCoList(List node) {
|
||||
logger.debug("convertCoList");
|
||||
StringBuilder result = new StringBuilder();
|
||||
appendChildBlocks(node, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String convertListItem(ListItem node) {
|
||||
logger.debug("convertListItem");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
String marker = Optional.ofNullable(node.getMarker()).orElse(repeat(node.getLevel(), MARKER_LIST_ITEM));
|
||||
|
||||
String coids = node.getAttribute("coids", "").toString();
|
||||
Matcher matcher = coListItemIdPattern.matcher(coids);
|
||||
if (matcher.find()) {
|
||||
marker = marker.replaceAll("\\d+", matcher.group(1));
|
||||
}
|
||||
|
||||
sb.append(marker).append(" ");
|
||||
|
||||
if (node.hasAttribute("checkbox")) {
|
||||
sb.append('[');
|
||||
if (node.hasAttribute("checked")) {
|
||||
sb.append('x');
|
||||
} else {
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(']').append(' ');
|
||||
}
|
||||
|
||||
sb.append(Optional.ofNullable(node.getSource()).orElse(""));
|
||||
appendTrailingNewLine(sb);
|
||||
appendChildBlocks(node, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertList(List node) {
|
||||
logger.debug("convertList");
|
||||
return node.getContent().toString();
|
||||
}
|
||||
|
||||
private String convertPreamble(StructuralNode node) {
|
||||
logger.debug("convertPreamble");
|
||||
return node.getContent().toString();
|
||||
}
|
||||
|
||||
private String convertImage(StructuralNode node) {
|
||||
logger.debug("convertImage");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
appendRoles(node, sb);
|
||||
sb.append(new BlockImageNode(node).toAsciiDocContent());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertLiteral(StructuralNode node) {
|
||||
logger.debug("convertLiteral");
|
||||
return ATTRIBUTES_BEGIN + node.getContext() + ATTRIBUTES_END + LINE_SEPARATOR +
|
||||
StringEscapeUtils.unescapeHtml4(node.getContent().toString()) + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertParagraph(StructuralNode node) {
|
||||
logger.debug("convertParagraph");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(new ParagraphAttributes(node).toAsciiDocContent());
|
||||
appendSource((Block) node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertSection(Section node) {
|
||||
logger.debug("convertSection");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendId(node, sb);
|
||||
sb.append(new DelimitedBlockNode(node).toAsciiDocContent()).append(StringUtils.repeat(TITLE, node.getLevel() + 1))
|
||||
.append(" ").append(StringEscapeUtils.unescapeHtml4(node.getTitle())).append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void append_link_constraint_attrs(ContentNode node, java.util.List<String> attrs) {
|
||||
String rel = node.getAttribute("nofollow-option").toString();
|
||||
String window = node.getAttributes().get("window").toString();
|
||||
if (StringUtils.isNotBlank(window)) {
|
||||
attrs.add("target = \"#{window}\"");
|
||||
if (window.equals("_blank") || (node.getAttributes().containsKey("option-noopener"))) {
|
||||
if (StringUtils.isNotBlank(rel)) {
|
||||
attrs.add("rel = \"" + rel + "noopener\"");
|
||||
} else {
|
||||
attrs.add(" rel=\"noopener\"");
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.isNotBlank(rel)) {
|
||||
attrs.add("rel = " + rel + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
private String repeat(int count, String with) {
|
||||
return new String(new char[count]).replace("\0", with);
|
||||
}
|
||||
|
||||
private void appendChildBlocks(StructuralNode parentNode, StringBuilder sb) {
|
||||
appendChildBlocks(parentNode, sb, true);
|
||||
}
|
||||
|
||||
private void appendChildBlocks(StructuralNode parentNode, StringBuilder sb, boolean addTrailingLineSeparator) {
|
||||
final boolean isParentAListItem = parentNode instanceof ListItem || parentNode instanceof DescriptionListEntry;
|
||||
parentNode.getBlocks().forEach(childNode -> {
|
||||
String childNodeValue = childNode.convert();
|
||||
if (StringUtils.isNotBlank(childNodeValue)) {
|
||||
if (isParentAListItem && (sb.toString().contains("+" + LINE_SEPARATOR) || !(childNode instanceof List || childNode instanceof DescriptionList))) {
|
||||
sb.append('+').append(LINE_SEPARATOR);
|
||||
}
|
||||
sb.append(childNodeValue);
|
||||
if (addTrailingLineSeparator && !StringUtils.endsWith(childNodeValue, LINE_SEPARATOR)) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void appendTrailingNewLine(StringBuilder sb) {
|
||||
if (!sb.toString().endsWith(LINE_SEPARATOR + LINE_SEPARATOR)) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendId(StructuralNode node, StringBuilder sb) {
|
||||
String id = node.getId();
|
||||
if (StringUtils.isNotBlank(id)) {
|
||||
sb.append("[[").append(id).append("]]").append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendSource(Block node, StringBuilder sb) {
|
||||
String source = node.getSource();
|
||||
if (StringUtils.isNotBlank(source)) {
|
||||
sb.append(source).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTitle(StructuralNode node, StringBuilder sb) {
|
||||
String title = node.getTitle();
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
sb.append(".").append(StringEscapeUtils.unescapeHtml4(title)).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendStyle(StructuralNode node, StringBuilder sb) {
|
||||
String style = node.getStyle();
|
||||
if (StringUtils.isNotBlank(style)) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(style).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendRoles(StructuralNode node, StringBuilder sb) {
|
||||
java.util.List<String> roles = node.getRoles();
|
||||
if (!roles.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(".").append(String.join(".", roles))
|
||||
.append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendAttributeTo(StructuralNode node, java.util.List<String> attrs, String name) {
|
||||
String attribution = node.getAttribute(name, "").toString();
|
||||
if (StringUtils.isNotBlank(attribution)) {
|
||||
attrs.add(attribution);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BlockImpl extends StructuralNodeImpl implements Block {
|
||||
|
||||
private List<String> lines;
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context) {
|
||||
this(parent, context, "");
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Object content) {
|
||||
this(parent, context, new HashMap<>(), content);
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes) {
|
||||
this(parent, context, attributes, "");
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, Object content) {
|
||||
this(parent, context, attributes, new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs) {
|
||||
this(parent, context, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs);
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs) {
|
||||
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.lines = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<String> lines() {
|
||||
return getLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLines(List<String> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String source() {
|
||||
return getSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return String.join("\n", lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
setLines(Arrays.asList(source.split("\n")));
|
||||
}
|
||||
}
|
||||