forked from loafle/openapi-generator-original
Compare commits
485 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c00f4ba805 | ||
|
|
dd3b253e15 | ||
|
|
3969a9f294 | ||
|
|
78f8eaa687 | ||
|
|
fe676c83c0 | ||
|
|
18370b9076 | ||
|
|
70d987666e | ||
|
|
6247dd0cde | ||
|
|
ea7ef990b9 | ||
|
|
83afaffd92 | ||
|
|
d2faa63ebc | ||
|
|
dcec2e7b5d | ||
|
|
940e76f45f | ||
|
|
fecbc3c45d | ||
|
|
a6e4203cd5 | ||
|
|
dd34d75f00 | ||
|
|
1eed1917b9 | ||
|
|
91afec43a6 | ||
|
|
adeff7855c | ||
|
|
e289b858a9 | ||
|
|
7170f7fa01 | ||
|
|
6253a592d9 | ||
|
|
9f842a1295 | ||
|
|
723cf9b823 | ||
|
|
bbb59f93db | ||
|
|
2fcb705826 | ||
|
|
4723f51c63 | ||
|
|
485186e6b6 | ||
|
|
1ac6842b5a | ||
|
|
57e3ea3e9c | ||
|
|
0f75b053c8 | ||
|
|
eee69f1e05 | ||
|
|
9b8a633435 | ||
|
|
dcc47a92b5 | ||
|
|
e9aaa6da36 | ||
|
|
568a7be994 | ||
|
|
214e0186e8 | ||
|
|
7f5cdba606 | ||
|
|
295af57c9a | ||
|
|
bade71c6ba | ||
|
|
9adb077a7b | ||
|
|
10a9c62e2b | ||
|
|
a6bd0773f7 | ||
|
|
b2506ab598 | ||
|
|
a21f08118e | ||
|
|
96380bbc83 | ||
|
|
abe4980449 | ||
|
|
e3151c57a0 | ||
|
|
d2dc333699 | ||
|
|
b41a40f9be | ||
|
|
2f3a2413c7 | ||
|
|
19ea3ecf66 | ||
|
|
5c29562926 | ||
|
|
b827d06077 | ||
|
|
539496d735 | ||
|
|
6b7059d23f | ||
|
|
bff8f96b99 | ||
|
|
5e69d929a0 | ||
|
|
e1ee7065d5 | ||
|
|
aaf1df1971 | ||
|
|
555fd54fbb | ||
|
|
905a7746e7 | ||
|
|
eeaf4071f9 | ||
|
|
84b7302f12 | ||
|
|
1b0963ebe0 | ||
|
|
b054cd3cc6 | ||
|
|
4ea797d0e8 | ||
|
|
002feb3e7c | ||
|
|
89dc4d29ab | ||
|
|
3cf1f1a56a | ||
|
|
b83db8e535 | ||
|
|
eb1e0b5034 | ||
|
|
d7b4f58994 | ||
|
|
e8fbdaabe3 | ||
|
|
b82333aea4 | ||
|
|
7bbb883a00 | ||
|
|
6477a27579 | ||
|
|
ad1626ad2d | ||
|
|
bfa4303e6e | ||
|
|
9508579eed | ||
|
|
9ac980298f | ||
|
|
a2fda604f8 | ||
|
|
8339e4b092 | ||
|
|
90eab19305 | ||
|
|
8a2c34ba7a | ||
|
|
8c5991b793 | ||
|
|
3debd08a32 | ||
|
|
92d1e8a1d9 | ||
|
|
71c5160739 | ||
|
|
3dd0b04fb9 | ||
|
|
04369ddfce | ||
|
|
084e7f7199 | ||
|
|
ab026fdde3 | ||
|
|
e0dfc1b43d | ||
|
|
d5e2aea723 | ||
|
|
d2df310290 | ||
|
|
7db67aa192 | ||
|
|
a1fa0b0834 | ||
|
|
02a9fe2618 | ||
|
|
97a5a8922f | ||
|
|
0802f94d94 | ||
|
|
21eb406140 | ||
|
|
84928abd8d | ||
|
|
1c21730607 | ||
|
|
5a76a1b155 | ||
|
|
bc5a610567 | ||
|
|
860b551e9b | ||
|
|
22218cb132 | ||
|
|
300a0dc82c | ||
|
|
3a66c0c710 | ||
|
|
a94384ca7f | ||
|
|
6d50ce6a77 | ||
|
|
583493f5ca | ||
|
|
6cc17d8508 | ||
|
|
265b4b5945 | ||
|
|
65e63a8c52 | ||
|
|
e4e77d03f5 | ||
|
|
638bbfaf43 | ||
|
|
0b4b5e8839 | ||
|
|
c7b08bc112 | ||
|
|
f1b0cf839a | ||
|
|
988de07c17 | ||
|
|
f603efc419 | ||
|
|
4e7d893a8e | ||
|
|
1ef51e5ad7 | ||
|
|
17545e959a | ||
|
|
5ed52b3e1d | ||
|
|
6ce09ee779 | ||
|
|
7b1799f874 | ||
|
|
43b3acf550 | ||
|
|
d162d48fa3 | ||
|
|
e562b0ae34 | ||
|
|
748460488a | ||
|
|
1fb2a97497 | ||
|
|
15f5eae2a8 | ||
|
|
6fd54d5285 | ||
|
|
00517a1ad3 | ||
|
|
5cd01af350 | ||
|
|
9ecb2e92ae | ||
|
|
6cc5a32d40 | ||
|
|
64fd94262f | ||
|
|
5144c54895 | ||
|
|
9311dcaccb | ||
|
|
a5a6ae72c3 | ||
|
|
c31ed5a30d | ||
|
|
aa0fbada07 | ||
|
|
ab34dc5697 | ||
|
|
edf2642e73 | ||
|
|
d95660aca1 | ||
|
|
297f9e961c | ||
|
|
42b716207f | ||
|
|
7d69107696 | ||
|
|
4d2fb1cc9a | ||
|
|
503ffd06d0 | ||
|
|
725df15dd5 | ||
|
|
8e9e3a6171 | ||
|
|
6ee42bebe6 | ||
|
|
69a346cb57 | ||
|
|
d451d4efb8 | ||
|
|
b7b8b527db | ||
|
|
3bd4502bbf | ||
|
|
733e19c113 | ||
|
|
735cae7b49 | ||
|
|
3b36bbe97d | ||
|
|
228e039046 | ||
|
|
b27663e1ad | ||
|
|
eaddebe220 | ||
|
|
f8485f26d3 | ||
|
|
d9117480f8 | ||
|
|
7b79abef63 | ||
|
|
dbd89092f0 | ||
|
|
6ed7663466 | ||
|
|
d882e9fe0a | ||
|
|
ea1c2809f7 | ||
|
|
3c78e29a12 | ||
|
|
6cb4473526 | ||
|
|
65a9c78544 | ||
|
|
69911a1974 | ||
|
|
761029241e | ||
|
|
1018ca634d | ||
|
|
ff0b0c15a8 | ||
|
|
727c32f2a2 | ||
|
|
3c0eab65f3 | ||
|
|
a72ac99c91 | ||
|
|
4b62a94350 | ||
|
|
12d8f97aee | ||
|
|
acaf1b1cd0 | ||
|
|
c1c3439b86 | ||
|
|
5744bb4053 | ||
|
|
2711e375cc | ||
|
|
25abc15233 | ||
|
|
984b645ea1 | ||
|
|
253c46a0d5 | ||
|
|
7c431a8e11 | ||
|
|
3c98e32765 | ||
|
|
f483f934d8 | ||
|
|
053af7a749 | ||
|
|
d2d6ff661a | ||
|
|
17bdd73891 | ||
|
|
d9bfb884da | ||
|
|
19d8766363 | ||
|
|
e270fdcfd9 | ||
|
|
a2f47672e7 | ||
|
|
90dc0a7bd8 | ||
|
|
2a679f798a | ||
|
|
dbecb9e562 | ||
|
|
4db86003f5 | ||
|
|
d5cf2b6cfe | ||
|
|
6a3108a6bf | ||
|
|
2ea3816e65 | ||
|
|
baca3027f4 | ||
|
|
0e9e2046e7 | ||
|
|
e301020acc | ||
|
|
cf1f113852 | ||
|
|
c26a387d9a | ||
|
|
c70ca9d572 | ||
|
|
6bdfb8810c | ||
|
|
2a5ab78056 | ||
|
|
e5a4ef3ba0 | ||
|
|
9b148be57e | ||
|
|
0380fc5a35 | ||
|
|
597282742b | ||
|
|
5e805c2be6 | ||
|
|
b080abeb01 | ||
|
|
2943f41cdd | ||
|
|
84e0df6115 | ||
|
|
a49826e4d7 | ||
|
|
b8792b6a71 | ||
|
|
5ee86b9816 | ||
|
|
e32272aedb | ||
|
|
ee7f447f77 | ||
|
|
a5fb689615 | ||
|
|
a26cf60a22 | ||
|
|
ed13d7b1b8 | ||
|
|
c59e2b88b1 | ||
|
|
e8d40a146c | ||
|
|
4ef69794a3 | ||
|
|
30fbdd4d05 | ||
|
|
13c079342e | ||
|
|
a284bb7a51 | ||
|
|
44bbe301cb | ||
|
|
69f8274287 | ||
|
|
770ea9d12e | ||
|
|
d09d8bb495 | ||
|
|
85f99934c8 | ||
|
|
66dee928d2 | ||
|
|
d4a94fbf52 | ||
|
|
844cae75b7 | ||
|
|
4e4e9e7893 | ||
|
|
61690d625f | ||
|
|
1cd8141645 | ||
|
|
98ff2d231f | ||
|
|
09add2d871 | ||
|
|
9cbf2d3707 | ||
|
|
0622838947 | ||
|
|
a6df340cdc | ||
|
|
bcbf9c54c7 | ||
|
|
6dcaa890cf | ||
|
|
2b06a81a52 | ||
|
|
956624f1a4 | ||
|
|
b1728aed7c | ||
|
|
8733be9ac9 | ||
|
|
c203854254 | ||
|
|
3dc3af8d18 | ||
|
|
cbc2fb237d | ||
|
|
b7d64d1352 | ||
|
|
047b06ac84 | ||
|
|
f29f5d6f13 | ||
|
|
1863aca0fa | ||
|
|
cf300c09da | ||
|
|
27ab9c2e57 | ||
|
|
c83c564a19 | ||
|
|
8978a0a906 | ||
|
|
6d21422bad | ||
|
|
65cfa735d5 | ||
|
|
e2ce427fb1 | ||
|
|
781458b0d1 | ||
|
|
65f86dbb0f | ||
|
|
cc1c495ea5 | ||
|
|
261ae79528 | ||
|
|
fb14585adf | ||
|
|
27e434d786 | ||
|
|
2a37c48e12 | ||
|
|
85df7c8ed7 | ||
|
|
b3ca9cdbe0 | ||
|
|
477d5c40d9 | ||
|
|
460c8caa8a | ||
|
|
53e13aee19 | ||
|
|
ec05dc4414 | ||
|
|
7eec769654 | ||
|
|
f483b8dfa8 | ||
|
|
2ac41ff080 | ||
|
|
ade61c0701 | ||
|
|
bd63c1d9d9 | ||
|
|
5d1e70544c | ||
|
|
349702adf9 | ||
|
|
88410635b3 | ||
|
|
0262d3c8d2 | ||
|
|
96f4a3ab71 | ||
|
|
b0063d9e9f | ||
|
|
48bd888483 | ||
|
|
1358e33bf6 | ||
|
|
c8edacb25c | ||
|
|
47dc4d7642 | ||
|
|
1ecb8a74c1 | ||
|
|
967c574f5b | ||
|
|
8bb8a7a79a | ||
|
|
1268b0627f | ||
|
|
761f172c2f | ||
|
|
1321d5f9a5 | ||
|
|
35f462f571 | ||
|
|
f21fa08cd6 | ||
|
|
16afd4ee9b | ||
|
|
46f78f2180 | ||
|
|
2e402bba97 | ||
|
|
34f196a144 | ||
|
|
def3f5b3fb | ||
|
|
60e5a34534 | ||
|
|
1eed90f34e | ||
|
|
e34063f0f2 | ||
|
|
dbdcf34044 | ||
|
|
43d71ed10c | ||
|
|
b3db24ead6 | ||
|
|
d21c6f2b45 | ||
|
|
3c3762fd92 | ||
|
|
0edbfeff15 | ||
|
|
4b539a9d6e | ||
|
|
71a3218bb3 | ||
|
|
d37cf6595a | ||
|
|
1bac705876 | ||
|
|
3385082e2c | ||
|
|
2b1a63a7de | ||
|
|
93847d8dc7 | ||
|
|
3514bf14b3 | ||
|
|
e215a1c87f | ||
|
|
5bcd8fb207 | ||
|
|
a8f7708789 | ||
|
|
26c0bfef7d | ||
|
|
12190e0900 | ||
|
|
f340a389e9 | ||
|
|
8b96cdb7d7 | ||
|
|
90307cafc6 | ||
|
|
58c5ecf13c | ||
|
|
e72a53448e | ||
|
|
90b89c6189 | ||
|
|
ee1febcd95 | ||
|
|
6c079e95d9 | ||
|
|
d22398eb73 | ||
|
|
30228dcca5 | ||
|
|
2e30a3af27 | ||
|
|
212d240316 | ||
|
|
ba701be2f2 | ||
|
|
f6d624be2a | ||
|
|
f705e03fc4 | ||
|
|
75bb59572a | ||
|
|
f067b86fa0 | ||
|
|
2822e9ea38 | ||
|
|
435ce7b9d5 | ||
|
|
ab6118afe4 | ||
|
|
8ce06fc898 | ||
|
|
9e8e5db7b3 | ||
|
|
44b5c22cd4 | ||
|
|
6d7557971b | ||
|
|
9af16c0d79 | ||
|
|
027e4c5a20 | ||
|
|
c56d807a15 | ||
|
|
7d4ba27e01 | ||
|
|
c8ed2b0d50 | ||
|
|
1520ec536e | ||
|
|
e434380eae | ||
|
|
5940f46f56 | ||
|
|
7c60e2097f | ||
|
|
fc7cffbab7 | ||
|
|
b099d1e7a2 | ||
|
|
31e8aca357 | ||
|
|
d746894ecb | ||
|
|
2c64e0893b | ||
|
|
3c79a692aa | ||
|
|
72255286b3 | ||
|
|
3112e4ad06 | ||
|
|
38b1e1aad7 | ||
|
|
dfb87abe3a | ||
|
|
b96fdb6766 | ||
|
|
369ceb634d | ||
|
|
92f9b33eb6 | ||
|
|
5b12379a07 | ||
|
|
39b4034958 | ||
|
|
28030cba19 | ||
|
|
e0679c0b14 | ||
|
|
2fd8b8ff16 | ||
|
|
e35be1bd40 | ||
|
|
39ac64d24a | ||
|
|
b846fa5c3e | ||
|
|
3c84847adb | ||
|
|
2b48ec072c | ||
|
|
8114c416b9 | ||
|
|
adee62da7d | ||
|
|
a207251b29 | ||
|
|
265de9654b | ||
|
|
177436e69c | ||
|
|
1331484a0f | ||
|
|
4477009ef8 | ||
|
|
930c5191e0 | ||
|
|
5f811f3ba7 | ||
|
|
74bffbaadb | ||
|
|
cdd104d3fb | ||
|
|
be84f03d14 | ||
|
|
28579cee03 | ||
|
|
32ffab4519 | ||
|
|
e3c6cc3220 | ||
|
|
84346c0ba6 | ||
|
|
acbf3d3cc5 | ||
|
|
5c74146879 | ||
|
|
a59c128f90 | ||
|
|
810bf58c3a | ||
|
|
724683fab0 | ||
|
|
074ba1ea54 | ||
|
|
9e5de7da5e | ||
|
|
50f6067831 | ||
|
|
9453967815 | ||
|
|
fc4fce3731 | ||
|
|
d31013d977 | ||
|
|
ccf0cc8375 | ||
|
|
99ed012fc6 | ||
|
|
8ba4a6d7ad | ||
|
|
60fddcf378 | ||
|
|
cf5982d2c4 | ||
|
|
1378976d37 | ||
|
|
e5811ebdc7 | ||
|
|
d434b7c440 | ||
|
|
8de9e23814 | ||
|
|
b35a7b696e | ||
|
|
587028efd1 | ||
|
|
af8d61cc02 | ||
|
|
1996aa9244 | ||
|
|
f79f8895c5 | ||
|
|
b3d28f07f1 | ||
|
|
570a595ffb | ||
|
|
568b7a4fcd | ||
|
|
1b2f491b0e | ||
|
|
eb21963fa5 | ||
|
|
ab5483cd04 | ||
|
|
392e5172b5 | ||
|
|
52dc7e210c | ||
|
|
15e336b90a | ||
|
|
698ed970dc | ||
|
|
a43d2163a0 | ||
|
|
564dffa7e8 | ||
|
|
68f61d9a37 | ||
|
|
a7c08e680c | ||
|
|
2251a2f892 | ||
|
|
b0c776bbea | ||
|
|
3d89399b58 | ||
|
|
0261121d78 | ||
|
|
c177cf75d2 | ||
|
|
d4b4fe4b47 | ||
|
|
e956495665 | ||
|
|
8408a97aef | ||
|
|
b3afbe73b9 | ||
|
|
85aabbe810 | ||
|
|
3f8dbf416d | ||
|
|
0e0bfde3a8 | ||
|
|
29a2eedc1e | ||
|
|
0d5c066605 | ||
|
|
6820179903 | ||
|
|
617fa43a89 | ||
|
|
dd67287d63 | ||
|
|
6d58d44542 | ||
|
|
0e2e7838ae | ||
|
|
2e3f94c2a5 | ||
|
|
e02a9f1797 | ||
|
|
0d399d3f6a | ||
|
|
030e45982c | ||
|
|
7be6e971fa | ||
|
|
828f8694c8 | ||
|
|
31d948fc16 | ||
|
|
a481db7486 | ||
|
|
7af5db3565 | ||
|
|
47c8597d36 | ||
|
|
5bfae7b78c | ||
|
|
a75b05b952 | ||
|
|
609d915541 | ||
|
|
948cdb3a75 | ||
|
|
4ecc757bea | ||
|
|
3de42afed3 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -41,6 +41,9 @@ target
|
||||
.lib
|
||||
atlassian-ide-plugin.xml
|
||||
.DS_Store
|
||||
packages/
|
||||
.pub
|
||||
.packages
|
||||
|
||||
samples/client/petstore/php/SwaggerClient-php/composer.lock
|
||||
samples/client/petstore/php/SwaggerClient-php/vendor/
|
||||
@@ -50,3 +53,5 @@ samples/client/petstore/silex/SwaggerServer/venodr/
|
||||
|
||||
samples/client/petstore/python/.projectile
|
||||
samples/client/petstore/python/.venv/
|
||||
|
||||
*/.settings
|
||||
|
||||
89
README.md
89
README.md
@@ -1,12 +1,45 @@
|
||||
# Swagger Code Generator
|
||||
|
||||
[](https://travis-ci.org/swagger-api/swagger-codegen)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/io.swagger/swagger-codegen-project)
|
||||
|
||||
## Overview
|
||||
This is the swagger codegen project, which allows generation of client libraries automatically from a Swagger-compliant server.
|
||||
|
||||
Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
|
||||
|
||||
# Table of contents
|
||||
|
||||
- [Swagger Code Generator](#swagger-code-generator)
|
||||
- [Overview](#overview)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- Installation
|
||||
- [Build and run using docker](#build-and-run-using-docker)
|
||||
- [Build a nodejs server stub](#build-a-nodejs-server-stub)
|
||||
- [Compatibility](#compatibility)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [OS X Users](#os-x-users)
|
||||
- [Building](#building)
|
||||
- Generators
|
||||
- [To generate a sample client library](#to-generate-a-sample-client-library)
|
||||
- [Generating libraries from your server](#generating-libraries-from-your-server)
|
||||
- [Modifying the client library format](#modifying-the-client-library-format)
|
||||
- [Making your own codegen modules](#making-your-own-codegen-modules)
|
||||
- [Where is Javascript???](#where-is-javascript)
|
||||
- [Generating a client from local files](#generating-a-client-from-local-files)
|
||||
- [Customizing the generator](#customizing-the-generator)
|
||||
- [Validating your swagger spec](#validating-your-swagger-spec)
|
||||
- [Generating dynamic html api documentation](#generating-dynamic-html-api-documentation)
|
||||
- [Generating static html api documentation](#generating-static-html-api-documentation)
|
||||
- [To build a server stub](#to-build-a-server-stub)
|
||||
- [node.js](#nodejs)
|
||||
- [rails-grape](#rails-grape)
|
||||
- [scala scalatra](#scala-scalatra)
|
||||
- [java jax-rs](#java-jax-rs)
|
||||
- [java spring-mvc](#java-spring-mvc)
|
||||
- [To build the codegen library](#to-build-the-codegen-library)
|
||||
- [License](#license)
|
||||
|
||||
## Build and run using docker
|
||||
|
||||
```
|
||||
@@ -17,7 +50,7 @@ cd swagger-codegen
|
||||
./run-in-docker.sh mvn package
|
||||
```
|
||||
|
||||
Build a nodejs server stub:
|
||||
## Build a nodejs server stub
|
||||
|
||||
```
|
||||
./run-in-docker.sh generate \
|
||||
@@ -31,8 +64,8 @@ The Swagger Specification has undergone 3 revisions since initial creation in 20
|
||||
|
||||
Swagger Codegen Version | Release Date | Swagger Spec compatibility | Notes
|
||||
-------------------------- | ------------ | -------------------------- | -----
|
||||
2.1.3 | | 1.0, 1.1, 1.2, 2.0 | [master](https://github.com/swagger-api/swagger-codegen)
|
||||
2.1.3 (**current stable**) | 2015-08-24 | 1.0, 1.1, 1.2, 2.0 | [master](https://github.com/swagger-api/swagger-codegen/tree/v2.1.3)
|
||||
2.1.5-SNAPSHOT | | 1.0, 1.1, 1.2, 2.0 | [master](https://github.com/swagger-api/swagger-codegen)
|
||||
2.1.4 (**current stable**) | 2015-10-25 | 1.0, 1.1, 1.2, 2.0 | [tag v2.1.4](https://github.com/swagger-api/swagger-codegen/tree/v2.1.3)
|
||||
2.0.17 | 2014-08-22 | 1.1, 1.2 | [tag v2.0.17](https://github.com/swagger-api/swagger-codegen/tree/v2.0.17)
|
||||
1.0.4 | 2012-04-12 | 1.0, 1.1 | [tag v1.0.4](https://github.com/swagger-api/swagger-codegen/tree/swagger-codegen_2.9.1-1.1)
|
||||
|
||||
@@ -169,7 +202,7 @@ static code generation.
|
||||
There is a third-party component called [swagger-js-codegen](https://github.com/wcandillon/swagger-js-codegen) that can generate angularjs or nodejs source code from a swagger specification.
|
||||
|
||||
|
||||
#### Generating a client from flat files (i.e. no remote server calls)
|
||||
#### Generating a client from local files
|
||||
If you don't want to call your server, you can save the swagger spec files into a directory and pass an argument
|
||||
to the code generator like this:
|
||||
|
||||
@@ -179,6 +212,36 @@ to the code generator like this:
|
||||
|
||||
Great for creating libraries on your ci server, from the [Swagger Editor](http://editor.swagger.io)... or while coding on an airplane.
|
||||
|
||||
### Selective generation
|
||||
You may not want to generate *all* models in your project. Likewise you may want just one or two apis to be written. If that's the case, you can use system properties to control the output:
|
||||
|
||||
The default is generate *everything* supported by the specific library. Once you enable a feature, it will restrict the contents generated:
|
||||
|
||||
```
|
||||
# generate only models
|
||||
java -Dmodels {opts}
|
||||
|
||||
# generate only apis
|
||||
java -Dapis {opts}
|
||||
|
||||
# generate only supporting files
|
||||
java -DsupportingFiles
|
||||
|
||||
# generate models and supporting files
|
||||
java -Dmodels -DsupportingFiles
|
||||
```
|
||||
|
||||
To control the specific files being generated, you can pass a CSV list of what you want:
|
||||
```
|
||||
# generate the User and Pet models only
|
||||
-Dmodels=User,Pet
|
||||
|
||||
# generate the User model and the supportingFile `StringUtil.java`:
|
||||
-Dmodels=User -DsupportingFiles=StringUtil.java
|
||||
```
|
||||
|
||||
When using selective generation, _only_ the templates needed for the specific generation will be used.
|
||||
|
||||
### Customizing the generator
|
||||
|
||||
There are different aspects of customizing the code generator beyond just creating or modifying templates. Each language has a supporting configuration file to handle different type mappings, etc:
|
||||
@@ -190,8 +253,8 @@ AkkaScalaClientCodegen.java
|
||||
AndroidClientCodegen.java
|
||||
AsyncScalaClientCodegen.java
|
||||
CSharpClientCodegen.java
|
||||
CodeGenStatus.java
|
||||
CsharpDotNet2ClientCodegen.java
|
||||
DartClientCodegen.java
|
||||
FlashClientCodegen.java
|
||||
JavaClientCodegen.java
|
||||
JavaInflectorServerCodegen.java
|
||||
@@ -200,10 +263,8 @@ NodeJSServerCodegen.java
|
||||
ObjcClientCodegen.java
|
||||
PerlClientCodegen.java
|
||||
PhpClientCodegen.java
|
||||
Python3ClientCodegen.java
|
||||
PythonClientCodegen.java
|
||||
Qt5CPPGenerator.java
|
||||
RetrofitClientCodegen.java
|
||||
RubyClientCodegen.java
|
||||
ScalaClientCodegen.java
|
||||
ScalatraServerCodegen.java
|
||||
@@ -245,6 +306,9 @@ CONFIG OPTIONS
|
||||
apiPackage
|
||||
package for generated api classes
|
||||
|
||||
sortParamsByRequiredFlag
|
||||
Sort method arguments to place required parameters before optional parameters. Default: true
|
||||
|
||||
invokerPackage
|
||||
root package for generated code
|
||||
|
||||
@@ -260,10 +324,18 @@ CONFIG OPTIONS
|
||||
sourceFolder
|
||||
source folder for generated code
|
||||
|
||||
localVariablePrefix
|
||||
prefix for generated code members and local variables
|
||||
|
||||
serializableModel
|
||||
boolean - toggle "implements Serializable" for generated models
|
||||
|
||||
library
|
||||
library template (sub-template) to use:
|
||||
<default> - HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2
|
||||
jersey2 - HTTP client: Jersey client 2.6
|
||||
okhttp-gson - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1
|
||||
retrofit - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)
|
||||
```
|
||||
|
||||
Your config file for java can look like
|
||||
@@ -335,6 +407,7 @@ open index.html
|
||||
You can also use the codegen to generate a server for a couple different frameworks. Take a look here:
|
||||
|
||||
### node.js
|
||||
|
||||
```
|
||||
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
|
||||
-i http://petstore.swagger.io/v2/swagger.json \
|
||||
@@ -343,8 +416,8 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
|
||||
```
|
||||
|
||||
### rails-grape
|
||||
#### Not yet migrated to this branch
|
||||
|
||||
*Not yet migrated to this branch*
|
||||
|
||||
### scala scalatra
|
||||
```
|
||||
|
||||
@@ -25,15 +25,15 @@ cd $APP_DIR
|
||||
./bin/html-petstore.sh
|
||||
./bin/java-petstore.sh
|
||||
./bin/java-petstore-jersey2.sh
|
||||
./bin/java-petstore-okhttp-gson.sh
|
||||
./bin/java-petstore-retrofit.sh
|
||||
./bin/jaxrs-petstore-server.sh
|
||||
./bin/nodejs-petstore-server.sh
|
||||
./bin/objc-petstore.sh
|
||||
./bin/perl-petstore.sh
|
||||
./bin/php-petstore.sh
|
||||
./bin/python-petstore.sh
|
||||
./bin/python3-petstore.sh
|
||||
./bin/qt5-petstore.sh
|
||||
./bin/retrofit-petstore.sh
|
||||
./bin/ruby-petstore.sh
|
||||
./bin/scala-async-petstore.sh
|
||||
./bin/scala-petstore.sh
|
||||
|
||||
@@ -26,6 +26,6 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ generate -t modules/swagger-codegen/src/main/resources/python3 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l python3 -o samples/client/petstore/python3"
|
||||
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l dart -o samples/client/petstore/dart"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
4
bin/java-petstore-okhttp-gson.json
Normal file
4
bin/java-petstore-okhttp-gson.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"library": "okhttp-gson",
|
||||
"artifactId": "swagger-petstore-okhttp-gson"
|
||||
}
|
||||
@@ -26,6 +26,6 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ generate -t modules/swagger-codegen/src/main/resources/retrofit -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l retrofit -o samples/client/petstore/retrofit"
|
||||
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l java -c bin/java-petstore-okhttp-gson.json -o samples/client/petstore/java/okhttp-gson"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
4
bin/java-petstore-retrofit.json
Normal file
4
bin/java-petstore-retrofit.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"library": "retrofit",
|
||||
"artifactId": "swagger-petstore-retrofit"
|
||||
}
|
||||
31
bin/java-petstore-retrofit.sh
Executable file
31
bin/java-petstore-retrofit.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l java -c bin/java-petstore-retrofit.json -o samples/client/petstore/java/retrofit"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<version>2.1.3</version>
|
||||
<version>2.1.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -70,33 +70,34 @@
|
||||
<artifactId>swagger-codegen</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--https://github.com/airlift/airline-->
|
||||
<dependency>
|
||||
<groupId>io.airlift</groupId>
|
||||
<artifactId>airline</artifactId>
|
||||
<version>0.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.googlecode.lambdaj</groupId>
|
||||
<artifactId>lambdaj</artifactId>
|
||||
<version>2.3.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit-version}</version>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>${testng-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jmockit</groupId>
|
||||
<artifactId>jmockit</artifactId>
|
||||
<version>${jmockit-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -4,10 +4,7 @@ import io.airlift.airline.Command;
|
||||
import io.airlift.airline.Option;
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import static java.util.ServiceLoader.load;
|
||||
import io.swagger.codegen.CodegenConfigLoader;
|
||||
|
||||
@Command(name = "config-help", description = "Config help for chosen lang")
|
||||
public class ConfigHelp implements Runnable {
|
||||
@@ -16,32 +13,10 @@ public class ConfigHelp implements Runnable {
|
||||
description = "language to get config help for")
|
||||
private String lang;
|
||||
|
||||
/**
|
||||
* Tries to load config class with SPI first, then with class name directly from classpath
|
||||
*
|
||||
* @param name name of config, or full qualified class name in classpath
|
||||
* @return config class
|
||||
*/
|
||||
private static CodegenConfig forName(String name) {
|
||||
ServiceLoader<CodegenConfig> loader = load(CodegenConfig.class);
|
||||
for (CodegenConfig config : loader) {
|
||||
if (config.getName().equals(name)) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
// else try to load directly
|
||||
try {
|
||||
return (CodegenConfig) Class.forName(name).newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Can't load config class with name ".concat(name), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println();
|
||||
CodegenConfig config = forName(lang);
|
||||
CodegenConfig config = CodegenConfigLoader.forName(lang);
|
||||
System.out.println("CONFIG OPTIONS");
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
System.out.println("\t" + langCliOption.getOpt());
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
package io.swagger.codegen.cmd;
|
||||
|
||||
import config.Config;
|
||||
import config.ConfigParser;
|
||||
import io.airlift.airline.Command;
|
||||
import io.airlift.airline.Option;
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.ClientOptInput;
|
||||
import io.swagger.codegen.ClientOpts;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.DefaultGenerator;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
import io.swagger.codegen.cmd.utils.OptionUtils;
|
||||
import io.swagger.codegen.config.CodegenConfigurator;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.ServiceLoader.load;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
/**
|
||||
@@ -31,10 +30,8 @@ public class Generate implements Runnable {
|
||||
|
||||
public static final Logger LOG = LoggerFactory.getLogger(Generate.class);
|
||||
|
||||
public static final String TEMPLATE_DIR_PARAM = "templateDir";
|
||||
|
||||
@Option(name = {"-v", "--verbose"}, description = "verbose mode")
|
||||
private boolean verbose;
|
||||
private Boolean verbose;
|
||||
|
||||
@Option(name = {"-l", "--lang"}, title = "language", required = true,
|
||||
description = "client language to generate (maybe class name in classpath, required)")
|
||||
@@ -68,101 +65,185 @@ public class Generate implements Runnable {
|
||||
|
||||
@Option(name = {"-s", "--skip-overwrite"}, title = "skip overwrite", description = "specifies if the existing files should be " +
|
||||
"overwritten during the generation.")
|
||||
private boolean skipOverwrite;
|
||||
private Boolean skipOverwrite;
|
||||
|
||||
/**
|
||||
* Tries to load config class with SPI first, then with class name directly from classpath
|
||||
*
|
||||
* @param name name of config, or full qualified class name in classpath
|
||||
* @return config class
|
||||
*/
|
||||
private static CodegenConfig forName(String name) {
|
||||
ServiceLoader<CodegenConfig> loader = load(CodegenConfig.class);
|
||||
for (CodegenConfig config : loader) {
|
||||
if (config.getName().equals(name)) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@Option(name = {"--api-package"}, title = "api package", description = CodegenConstants.API_PACKAGE_DESC)
|
||||
private String apiPackage;
|
||||
|
||||
// else try to load directly
|
||||
try {
|
||||
return (CodegenConfig) Class.forName(name).newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Can't load config class with name ".concat(name), e);
|
||||
}
|
||||
}
|
||||
@Option(name = {"--model-package"}, title = "model package", description = CodegenConstants.MODEL_PACKAGE_DESC)
|
||||
private String modelPackage;
|
||||
|
||||
@Option(name = {"--instantiation-types"}, title = "instantiation types", description = "sets instantiation type mappings in the format of type=instantiatedType,type=instantiatedType." +
|
||||
"For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code.")
|
||||
private String instantiationTypes;
|
||||
|
||||
@Option(name = {"--type-mappings"}, title = "type mappings", description = "sets mappings between swagger spec types and generated code types " +
|
||||
"in the format of swaggerType=generatedType,swaggerType=generatedType. For example: array=List,map=Map,string=String")
|
||||
private String typeMappings;
|
||||
|
||||
@Option(name = {"--additional-properties"}, title = "additional properties", description = "sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value")
|
||||
private String additionalProperties;
|
||||
|
||||
@Option(name = {"--language-specific-primitives"}, title = "language specific primitives",
|
||||
description = "specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double")
|
||||
private String languageSpecificPrimitives;
|
||||
|
||||
@Option(name = {"--import-mappings"}, title = "import mappings",
|
||||
description = "specifies mappings between a given class and the import that should be used for that class in the format of type=import,type=import")
|
||||
private String importMappings;
|
||||
|
||||
@Option(name = {"--invoker-package"}, title = "invoker package", description = CodegenConstants.INVOKER_PACKAGE_DESC)
|
||||
private String invokerPackage;
|
||||
|
||||
@Option(name = {"--group-id"}, title = "group id", description = CodegenConstants.GROUP_ID_DESC)
|
||||
private String groupId;
|
||||
|
||||
@Option(name = {"--artifact-id"}, title = "artifact id", description = CodegenConstants.ARTIFACT_ID_DESC)
|
||||
private String artifactId;
|
||||
|
||||
@Option(name = {"--artifact-version"}, title = "artifact version", description = CodegenConstants.ARTIFACT_VERSION_DESC)
|
||||
private String artifactVersion;
|
||||
|
||||
@Option(name = {"--library"}, title = "library", description = CodegenConstants.LIBRARY_DESC)
|
||||
private String library;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
verbosed(verbose);
|
||||
|
||||
setSystemProperties();
|
||||
//attempt to read from config file
|
||||
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configFile);
|
||||
|
||||
ClientOptInput input = new ClientOptInput();
|
||||
|
||||
if (isNotEmpty(auth)) {
|
||||
input.setAuth(auth);
|
||||
//if a config file wasn't specified or we were unable to read it
|
||||
if(configurator == null) {
|
||||
//createa a fresh configurator
|
||||
configurator = new CodegenConfigurator();
|
||||
}
|
||||
|
||||
CodegenConfig config = forName(lang);
|
||||
config.setOutputDir(new File(output).getAbsolutePath());
|
||||
|
||||
if (null != templateDir) {
|
||||
config.additionalProperties().put(TEMPLATE_DIR_PARAM, new File(templateDir).getAbsolutePath());
|
||||
//now override with any specified parameters
|
||||
if (verbose != null) {
|
||||
configurator.setVerbose(verbose);
|
||||
}
|
||||
|
||||
if (null != configFile) {
|
||||
Config genConfig = ConfigParser.read(configFile);
|
||||
if (null != genConfig) {
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
String opt = langCliOption.getOpt();
|
||||
if (genConfig.hasOption(opt)) {
|
||||
config.additionalProperties().put(opt, genConfig.getOption(opt));
|
||||
// the "library" config option is for library template (sub-template)
|
||||
if ("library".equals(opt)) {
|
||||
config.setLibrary(genConfig.getOption(opt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(skipOverwrite != null) {
|
||||
configurator.setSkipOverwrite(skipOverwrite);
|
||||
}
|
||||
|
||||
config.setSkipOverwrite(skipOverwrite);
|
||||
input.setConfig(config);
|
||||
if(isNotEmpty(spec)) {
|
||||
configurator.setInputSpec(spec);
|
||||
}
|
||||
|
||||
Swagger swagger = new SwaggerParser().read(spec, input.getAuthorizationValues(), true);
|
||||
new DefaultGenerator().opts(input.opts(new ClientOpts()).swagger(swagger)).generate();
|
||||
if(isNotEmpty(lang)) {
|
||||
configurator.setLang(lang);
|
||||
}
|
||||
|
||||
if(isNotEmpty(output)) {
|
||||
configurator.setOutputDir(output);
|
||||
}
|
||||
|
||||
if(isNotEmpty(auth)) {
|
||||
configurator.setAuth(auth);
|
||||
}
|
||||
|
||||
if(isNotEmpty(templateDir)) {
|
||||
configurator.setTemplateDir(templateDir);
|
||||
}
|
||||
|
||||
if(isNotEmpty(apiPackage)) {
|
||||
configurator.setApiPackage(apiPackage);
|
||||
}
|
||||
|
||||
if(isNotEmpty(modelPackage)) {
|
||||
configurator.setModelPackage(modelPackage);
|
||||
}
|
||||
|
||||
if(isNotEmpty(invokerPackage)) {
|
||||
configurator.setInvokerPackage(invokerPackage);
|
||||
}
|
||||
|
||||
if(isNotEmpty(groupId)) {
|
||||
configurator.setGroupId(groupId);
|
||||
}
|
||||
|
||||
if(isNotEmpty(artifactId)) {
|
||||
configurator.setArtifactId(artifactId);
|
||||
}
|
||||
|
||||
if(isNotEmpty(artifactVersion)) {
|
||||
configurator.setArtifactVersion(artifactVersion);
|
||||
}
|
||||
|
||||
if(isNotEmpty(library)) {
|
||||
configurator.setLibrary(library);
|
||||
}
|
||||
|
||||
setSystemProperties(configurator);
|
||||
setInstantiationTypes(configurator);
|
||||
setImportMappings(configurator);
|
||||
setTypeMappings(configurator);
|
||||
setAdditionalProperties(configurator);
|
||||
setLanguageSpecificPrimitives(configurator);
|
||||
|
||||
final ClientOptInput clientOptInput = configurator.toClientOptInput();
|
||||
|
||||
new DefaultGenerator().opts(clientOptInput).generate();
|
||||
}
|
||||
|
||||
private void setSystemProperties() {
|
||||
if (systemProperties != null && systemProperties.length() > 0) {
|
||||
for (String property : systemProperties.split(",")) {
|
||||
int ix = property.indexOf('=');
|
||||
if (ix > 0 && ix < property.length() - 1) {
|
||||
System.setProperty(property.substring(0, ix), property.substring(ix + 1));
|
||||
}
|
||||
}
|
||||
private void setSystemProperties(CodegenConfigurator configurator) {
|
||||
final Map<String, String> map = createMapFromKeyValuePairs(systemProperties);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
configurator.addSystemProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If true parameter, adds system properties which enables debug mode in generator
|
||||
*
|
||||
* @param verbose - if true, enables debug mode
|
||||
*/
|
||||
private void verbosed(boolean verbose) {
|
||||
if (!verbose) {
|
||||
return;
|
||||
private void setInstantiationTypes(CodegenConfigurator configurator) {
|
||||
final Map<String, String> map = createMapFromKeyValuePairs(instantiationTypes);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
configurator.addInstantiationType(entry.getKey(), entry.getValue());
|
||||
}
|
||||
LOG.info("\nVERBOSE MODE: ON. Additional debug options are injected" +
|
||||
"\n - [debugSwagger] prints the swagger specification as interpreted by the codegen" +
|
||||
"\n - [debugModels] prints models passed to the template engine" +
|
||||
"\n - [debugOperations] prints operations passed to the template engine" +
|
||||
"\n - [debugSupportingFiles] prints additional data passed to the template engine");
|
||||
}
|
||||
|
||||
System.setProperty("debugSwagger", "");
|
||||
System.setProperty("debugModels", "");
|
||||
System.setProperty("debugOperations", "");
|
||||
System.setProperty("debugSupportingFiles", "");
|
||||
private void setImportMappings(CodegenConfigurator configurator) {
|
||||
final Map<String, String> map = createMapFromKeyValuePairs(importMappings);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
configurator.addImportMapping(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void setTypeMappings(CodegenConfigurator configurator) {
|
||||
final Map<String, String> map = createMapFromKeyValuePairs(typeMappings);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
configurator.addTypeMapping(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void setAdditionalProperties(CodegenConfigurator configurator) {
|
||||
final Map<String, String> map = createMapFromKeyValuePairs(additionalProperties);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
configurator.addAdditionalProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void setLanguageSpecificPrimitives(CodegenConfigurator configurator) {
|
||||
final Set<String> set = createSetFromCsvList(languageSpecificPrimitives);
|
||||
for (String item : set) {
|
||||
configurator.addLanguageSpecificPrimitive(item);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> createSetFromCsvList(String csvProperty) {
|
||||
final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty);
|
||||
return new HashSet<String>(values);
|
||||
}
|
||||
|
||||
private Map createMapFromKeyValuePairs(String commaSeparatedKVPairs) {
|
||||
final List<Pair<String, String>> pairs = OptionUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs);
|
||||
|
||||
Map result = new HashMap();
|
||||
|
||||
for (Pair<String, String> pair : pairs) {
|
||||
result.put(pair.getLeft(), pair.getRight());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.swagger.codegen.cmd.utils;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
public class OptionUtils {
|
||||
|
||||
public static List<Pair<String, String>> parseCommaSeparatedTuples(String input) {
|
||||
|
||||
List<Pair<String, String>> results = new ArrayList<Pair<String, String>>();
|
||||
|
||||
final List<String> tuples = splitCommaSeparatedList(input);
|
||||
|
||||
for (String tuple : tuples) {
|
||||
int ix = tuple.indexOf('=');
|
||||
if (ix > 0 && ix < tuple.length() - 1) {
|
||||
final Pair<String, String> pair = Pair.of(tuple.substring(0, ix), tuple.substring(ix + 1));
|
||||
results.add(pair);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<String> splitCommaSeparatedList(String input) {
|
||||
|
||||
List<String> results = new ArrayList<String>();
|
||||
|
||||
if(input != null && !input.isEmpty()) {
|
||||
for (String value : input.split(",")) {
|
||||
if(isNotEmpty(value))
|
||||
results.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GenerateTest {
|
||||
|
||||
private static final String TEST_SKIP_OVERWRITE = "testSkipOverwrite";
|
||||
private static final String POM_FILE = "pom.xml";
|
||||
private static final String MODEL_ORDER_FILE = "/src/main/java/io/swagger/client/model/Order.java";
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = new TemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void testSkipOverwrite() throws IOException {
|
||||
final File output = folder.getRoot();
|
||||
|
||||
String[] args = {"generate", "-i", "src/test/resources/petstore.json", "-l", "java", "-o", output.getAbsolutePath()};
|
||||
String[] argsWithSparam = Arrays.copyOf(args, args.length + 1);
|
||||
argsWithSparam[args.length] = "-s";
|
||||
|
||||
//generate content first time without -s flag, so all generated files should be recorded
|
||||
SwaggerCodegen.main(args);
|
||||
final File order = new File(output, MODEL_ORDER_FILE);
|
||||
assertTrue(order.exists());
|
||||
|
||||
//change content of one file
|
||||
changeContent(order);
|
||||
|
||||
//generate content second time without -s flag, so changed file should be rewritten
|
||||
SwaggerCodegen.main(args);
|
||||
//order = new File(output, MODEL_ORDER_FILE);
|
||||
assertTrue(!TEST_SKIP_OVERWRITE.equals(FileUtils.readFileToString(order, StandardCharsets.UTF_8)));
|
||||
|
||||
//change content again
|
||||
changeContent(order);
|
||||
//delete file
|
||||
final File pom = new File(output, POM_FILE);
|
||||
if (!pom.delete()) {
|
||||
fail();
|
||||
}
|
||||
|
||||
//generate content third time with -s flag, so changed file should not be rewritten
|
||||
//and deleted file should be recorded
|
||||
SwaggerCodegen.main(argsWithSparam);
|
||||
assertEquals(FileUtils.readFileToString(order, StandardCharsets.UTF_8), TEST_SKIP_OVERWRITE);
|
||||
assertTrue(pom.exists());
|
||||
}
|
||||
|
||||
private void changeContent(File file) throws IOException {
|
||||
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF_8));
|
||||
out.write(TEST_SKIP_OVERWRITE);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
package io.swagger.codegen.cmd;
|
||||
|
||||
import io.swagger.codegen.ClientOptInput;
|
||||
import io.swagger.codegen.DefaultGenerator;
|
||||
import io.swagger.codegen.SwaggerCodegen;
|
||||
import io.swagger.codegen.config.CodegenConfigurator;
|
||||
import mockit.Expectations;
|
||||
import mockit.FullVerifications;
|
||||
import mockit.Injectable;
|
||||
import mockit.Mocked;
|
||||
import mockit.Verifications;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class GenerateTest {
|
||||
|
||||
@Mocked
|
||||
CodegenConfigurator configurator;
|
||||
|
||||
@Injectable
|
||||
ClientOptInput clientOptInput;
|
||||
|
||||
@Mocked
|
||||
DefaultGenerator generator;
|
||||
|
||||
@Test
|
||||
public void testVerbose() throws Exception {
|
||||
setupAndRunGenericTest("-v");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setVerbose(true);
|
||||
times = 1;
|
||||
}};
|
||||
|
||||
setupAndRunGenericTest("--verbose");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setVerbose(true);
|
||||
times = 1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiredArgs_ShortArgs() throws Exception {
|
||||
setupAndRunTest("-i", "swagger.yaml", "-l", "java", "-o", "src/main/java", false, null);
|
||||
new FullVerifications() {{
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiredArgs_LongArgs() throws Exception {
|
||||
setupAndRunTest("--input-spec", "swagger.yaml", "--lang", "java", "--output", "src/main/java", false, null);
|
||||
new FullVerifications() {{
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemplateDir() throws Exception {
|
||||
|
||||
final String templateDir = "src/main/resources/customTemplates";
|
||||
|
||||
setupAndRunGenericTest("--template-dir", templateDir);
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setTemplateDir(templateDir);
|
||||
times = 1;
|
||||
}};
|
||||
|
||||
setupAndRunGenericTest("-t", templateDir);
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setTemplateDir(templateDir);
|
||||
times = 1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuth() throws Exception {
|
||||
|
||||
final String auth = "hello:world";
|
||||
|
||||
setupAndRunGenericTest("--auth", auth);
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setAuth(auth);
|
||||
times = 1;
|
||||
}};
|
||||
|
||||
setupAndRunGenericTest("-a", auth);
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setAuth(auth);
|
||||
times = 1;
|
||||
}};
|
||||
|
||||
setupAndRunGenericTest();
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.setAuth(anyString);
|
||||
times = 0;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemProperties() throws Exception {
|
||||
|
||||
setupAndRunGenericTest("-D", "hello=world,foo=bar");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addSystemProperty("hello", "world");
|
||||
times = 1;
|
||||
configurator.addSystemProperty("foo", "bar");
|
||||
times = 1;
|
||||
}};
|
||||
|
||||
setupAndRunGenericTest("-D", "hello=world,key=,foo=bar");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addSystemProperty("hello", "world");
|
||||
times = 1;
|
||||
configurator.addSystemProperty("foo", "bar");
|
||||
times = 1;
|
||||
configurator.addSystemProperty("key", anyString);
|
||||
times = 0;
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfig() throws Exception {
|
||||
|
||||
setupAndRunTest("-i", "swagger.yaml", "-l", "java", "-o", "src/main/java", true, "config.json", "-c", "config.json");
|
||||
|
||||
new FullVerifications(){{}};
|
||||
|
||||
setupAndRunTest("-i", "swagger.yaml", "-l", "java", "-o", "src/main/java", true, "config.json", "--config", "config.json");
|
||||
|
||||
new FullVerifications(){{}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipOverwrite() throws Exception {
|
||||
|
||||
setupAndRunGenericTest("-s");
|
||||
new FullVerifications(){{
|
||||
configurator.setSkipOverwrite(true); times=1;
|
||||
}};
|
||||
|
||||
setupAndRunGenericTest("--skip-overwrite");
|
||||
new FullVerifications(){{
|
||||
configurator.setSkipOverwrite(true); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiPackage() throws Exception {
|
||||
final String value = "io.foo.bar.api";
|
||||
setupAndRunGenericTest("--api-package", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setApiPackage(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModelPackage() throws Exception {
|
||||
final String value = "io.foo.bar.api";
|
||||
setupAndRunGenericTest("--model-package", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setModelPackage(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstantiationTypes() throws Exception {
|
||||
|
||||
setupAndRunGenericTest("--instantiation-types", "hello=world,key=,foo=bar");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addInstantiationType("hello", "world");
|
||||
times = 1;
|
||||
configurator.addInstantiationType("foo", "bar");
|
||||
times = 1;
|
||||
configurator.addInstantiationType("key", anyString);
|
||||
times = 0;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeMappings() throws Exception {
|
||||
setupAndRunGenericTest("--type-mappings", "hello=world,key=,foo=bar");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addTypeMapping("hello", "world");
|
||||
times = 1;
|
||||
configurator.addTypeMapping("foo", "bar");
|
||||
times = 1;
|
||||
configurator.addTypeMapping("key", anyString);
|
||||
times = 0;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdditionalProperties() throws Exception {
|
||||
setupAndRunGenericTest("--additional-properties", "hello=world,key=,foo=bar");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addAdditionalProperty("hello", "world");
|
||||
times = 1;
|
||||
configurator.addAdditionalProperty("foo", "bar");
|
||||
times = 1;
|
||||
configurator.addAdditionalProperty("key", anyString);
|
||||
times = 0;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLanguageSpecificPrimitives() throws Exception {
|
||||
setupAndRunGenericTest("--language-specific-primitives", "foo,bar,,hello,world");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addLanguageSpecificPrimitive("foo");
|
||||
times = 1;
|
||||
configurator.addLanguageSpecificPrimitive("bar");
|
||||
times = 1;
|
||||
configurator.addLanguageSpecificPrimitive("hello");
|
||||
times = 1;
|
||||
configurator.addLanguageSpecificPrimitive("world");
|
||||
times = 1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportMappings() throws Exception {
|
||||
setupAndRunGenericTest("--import-mappings", "hello=world,key=,foo=bar");
|
||||
|
||||
new FullVerifications() {{
|
||||
configurator.addImportMapping("hello", "world");
|
||||
times = 1;
|
||||
configurator.addImportMapping("foo", "bar");
|
||||
times = 1;
|
||||
configurator.addImportMapping("key", anyString);
|
||||
times = 0;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokerPackage() throws Exception {
|
||||
final String value = "io.foo.bar.api";
|
||||
setupAndRunGenericTest("--invoker-package", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setInvokerPackage(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupId() throws Exception {
|
||||
final String value = "io.foo.bar.api";
|
||||
setupAndRunGenericTest("--group-id", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setGroupId(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArtifactId() throws Exception {
|
||||
final String value = "awesome-api";
|
||||
setupAndRunGenericTest("--artifact-id", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setArtifactId(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArtifactVersion() throws Exception {
|
||||
final String value = "1.2.3";
|
||||
setupAndRunGenericTest("--artifact-version", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setArtifactVersion(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLibrary() throws Exception {
|
||||
final String value = "library1";
|
||||
setupAndRunGenericTest("--library", value);
|
||||
|
||||
new FullVerifications(){{
|
||||
configurator.setLibrary(value); times=1;
|
||||
}};
|
||||
}
|
||||
|
||||
private void setupAndRunTest(String specFlag, final String spec, String langFlag, final String lang,
|
||||
String outputDirFlag, final String outputDir, boolean configuratorFromFile,
|
||||
final String configFile, String... additionalParameters) {
|
||||
final String[] commonArgs = {"generate", langFlag, lang, outputDirFlag, outputDir, specFlag, spec};
|
||||
|
||||
String[] argsToUse = ArrayUtils.addAll(commonArgs, additionalParameters);
|
||||
|
||||
if (configuratorFromFile) {
|
||||
|
||||
new Expectations(){{
|
||||
CodegenConfigurator.fromFile(configFile);
|
||||
times = 1;
|
||||
result = configurator;
|
||||
}};
|
||||
|
||||
} else {
|
||||
new Expectations() {{
|
||||
CodegenConfigurator.fromFile(anyString);
|
||||
result = null;
|
||||
|
||||
new CodegenConfigurator();
|
||||
times = 1;
|
||||
result = configurator;
|
||||
}};
|
||||
}
|
||||
|
||||
new Expectations() {{
|
||||
|
||||
configurator.toClientOptInput();
|
||||
times = 1;
|
||||
result = clientOptInput;
|
||||
|
||||
new DefaultGenerator();
|
||||
times = 1;
|
||||
result = generator;
|
||||
|
||||
generator.opts(clientOptInput);
|
||||
times = 1;
|
||||
result = generator;
|
||||
|
||||
generator.generate();
|
||||
times = 1;
|
||||
|
||||
}};
|
||||
|
||||
SwaggerCodegen.main(argsToUse);
|
||||
|
||||
new Verifications() {{
|
||||
configurator.setLang(lang);
|
||||
times = 1;
|
||||
configurator.setInputSpec(spec);
|
||||
times = 1;
|
||||
configurator.setOutputDir(outputDir);
|
||||
}};
|
||||
}
|
||||
|
||||
private void setupAndRunGenericTest(String... additionalParameters) {
|
||||
setupAndRunTest("-i", "swagger.yaml", "-l", "java", "-o", "src/main/java", false, null, additionalParameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.swagger.codegen.cmd.utils;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
public class OptionUtilsTest {
|
||||
|
||||
@Test
|
||||
public void splitCommaSeparatedList() throws Exception {
|
||||
doCommaSeparatedListTest("a,b,c", Arrays.asList("a", "b", "c"));
|
||||
doCommaSeparatedListTest("a,,c", Arrays.asList("a", "c"));
|
||||
doCommaSeparatedListTest("", new ArrayList<String>());
|
||||
doCommaSeparatedListTest(null, new ArrayList<String>());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCommaSeparatedTuples() throws Exception {
|
||||
doTupleListTest("a=1,b=2,c=3", Arrays.asList(Pair.of("a", "1"), Pair.of("b", "2"), Pair.of("c", "3")));
|
||||
doTupleListTest("a=1,,c=3", Arrays.asList(Pair.of("a", "1"), Pair.of("c", "3")));
|
||||
doTupleListTest("a=1,xyz,c=3", Arrays.asList(Pair.of("a", "1"), Pair.of("c", "3")));
|
||||
doTupleListTest("a=1,=,c=3", Arrays.asList(Pair.of("a", "1"), Pair.of("c", "3")));
|
||||
doTupleListTest("", new ArrayList<Pair<String, String>>());
|
||||
doTupleListTest(null, new ArrayList<Pair<String, String>>());
|
||||
}
|
||||
|
||||
private void doTupleListTest(String input, List<Pair<String, String>> expectedResults) {
|
||||
final List<Pair<String, String>> result = OptionUtils.parseCommaSeparatedTuples(input);
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), expectedResults.size());
|
||||
for (int i = 0; i < expectedResults.size(); i++) {
|
||||
final Pair<String, String> actualPair = result.get(i);
|
||||
final Pair<String, String> expected = expectedResults.get(i);
|
||||
assertEquals(actualPair, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private void doCommaSeparatedListTest(String csvStr, List<String> expectedResults) {
|
||||
final List<String> result = OptionUtils.splitCommaSeparatedList(csvStr);
|
||||
assertNotNull(result);
|
||||
assertEquals(result.size(), expectedResults.size());
|
||||
for (int i = 0; i < expectedResults.size(); i++) {
|
||||
assertEquals(result.get(i), expectedResults.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<version>2.1.3</version>
|
||||
<version>2.1.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>swagger-codegen-maven-plugin</artifactId>
|
||||
|
||||
@@ -20,6 +20,7 @@ import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.ClientOptInput;
|
||||
import io.swagger.codegen.ClientOpts;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConfigLoader;
|
||||
import io.swagger.codegen.DefaultGenerator;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
@@ -35,6 +36,7 @@ import config.Config;
|
||||
import config.ConfigParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
@@ -111,6 +113,9 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(defaultValue = "true")
|
||||
private boolean addCompileSourceRoot = true;
|
||||
|
||||
@Parameter
|
||||
protected Map<String, String> environmentVariables = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* The project being built.
|
||||
*/
|
||||
@@ -121,9 +126,20 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
public void execute() throws MojoExecutionException {
|
||||
Swagger swagger = new SwaggerParser().read(inputSpec);
|
||||
|
||||
CodegenConfig config = forName(language);
|
||||
CodegenConfig config = CodegenConfigLoader.forName(language);
|
||||
config.setOutputDir(output.getAbsolutePath());
|
||||
|
||||
if (environmentVariables != null) {
|
||||
for(String key : environmentVariables.keySet()) {
|
||||
String value = environmentVariables.get(key);
|
||||
if(value == null) {
|
||||
// don't put null values
|
||||
value = "";
|
||||
}
|
||||
System.setProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (null != templateDirectory) {
|
||||
config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath());
|
||||
}
|
||||
@@ -161,26 +177,19 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
|
||||
ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger);
|
||||
input.setConfig(config);
|
||||
new DefaultGenerator().opts(input).generate();
|
||||
|
||||
try {
|
||||
new DefaultGenerator().opts(input).generate();
|
||||
} catch (Exception e) {
|
||||
// Maven logs exceptions thrown by plugins only if invoked with -e
|
||||
// I find it annoying to jump through hoops to get basic diagnostic information,
|
||||
// so let's log it in any case:
|
||||
getLog().error(e);
|
||||
throw new MojoExecutionException("Code generation failed. See above for the full exception.");
|
||||
}
|
||||
|
||||
if (addCompileSourceRoot) {
|
||||
project.addCompileSourceRoot(output.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private CodegenConfig forName(String name) {
|
||||
ServiceLoader<CodegenConfig> loader = ServiceLoader.load(CodegenConfig.class);
|
||||
for (CodegenConfig config : loader) {
|
||||
if (config.getName().equals(name)) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
// else try to load directly
|
||||
try {
|
||||
return (CodegenConfig) Class.forName(name).newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Can't load config class with name ".concat(name), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<version>2.1.3</version>
|
||||
<version>2.1.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -70,42 +70,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<recompileMode>incremental</recompileMode>
|
||||
<jvmArgs>
|
||||
<jvmArg>-Xmx384m</jvmArg>
|
||||
</jvmArgs>
|
||||
<args>
|
||||
<arg>-target:jvm-1.6</arg>
|
||||
<arg>-deprecation</arg>
|
||||
</args>
|
||||
<launchers>
|
||||
<launcher>
|
||||
<id>run-scalatest</id>
|
||||
<mainClass>org.scalatest.tools.Runner</mainClass>
|
||||
<args>
|
||||
<arg>-p</arg>
|
||||
<arg>${project.build.testOutputDirectory}</arg>
|
||||
</args>
|
||||
<jvmArgs>
|
||||
<jvmArg>-Xmx512m</jvmArg>
|
||||
</jvmArgs>
|
||||
</launcher>
|
||||
</launchers>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.0</version>
|
||||
@@ -140,15 +104,6 @@
|
||||
<version>2.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>${scala-maven-plugin-version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
@@ -156,43 +111,6 @@
|
||||
<properties>
|
||||
<skipTests>true</skipTests>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<scalaVersion>${scala-version}</scalaVersion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/main/scala</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>release-sign-artifacts</id>
|
||||
@@ -238,11 +156,6 @@
|
||||
<excludePackageNames/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>${scala-maven-plugin-version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
@@ -312,6 +225,11 @@
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
@@ -323,15 +241,21 @@
|
||||
<version>${commons-cli-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scalatest</groupId>
|
||||
<artifactId>scalatest_2.11</artifactId>
|
||||
<version>${scala-test-version}</version>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>${testng-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>${scala-version}</version>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>${reflections-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jmockit</groupId>
|
||||
<artifactId>jmockit</artifactId>
|
||||
<version>${jmockit-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.codegen.auth.AuthParser;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.auth.AuthorizationValue;
|
||||
|
||||
@@ -9,8 +10,10 @@ import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
public class ClientOptInput {
|
||||
protected CodegenConfig config;
|
||||
private CodegenConfig config;
|
||||
private ClientOpts opts;
|
||||
private Swagger swagger;
|
||||
private List<AuthorizationValue> auths;
|
||||
@@ -25,42 +28,28 @@ public class ClientOptInput {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientOptInput config(CodegenConfig codegenConfig) {
|
||||
this.setConfig(codegenConfig);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ClientOptInput auth(String urlEncodedAuthString) {
|
||||
this.setAuth(urlEncodedAuthString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getAuth() {
|
||||
if (auths != null) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (AuthorizationValue v : auths) {
|
||||
try {
|
||||
if (b.toString().length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(URLEncoder.encode(v.getKeyName(), "UTF-8"))
|
||||
.append(":")
|
||||
.append(URLEncoder.encode(v.getValue(), "UTF-8"));
|
||||
} catch (Exception e) {
|
||||
// continue
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return AuthParser.reconstruct(auths);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setAuth(String urlEncodedAuthString) {
|
||||
List<AuthorizationValue> auths = new ArrayList<AuthorizationValue>();
|
||||
if (urlEncodedAuthString != null && !"".equals(urlEncodedAuthString)) {
|
||||
String[] parts = urlEncodedAuthString.split(",");
|
||||
for (String part : parts) {
|
||||
String[] kvPair = part.split(":");
|
||||
if (kvPair.length == 2) {
|
||||
auths.add(new AuthorizationValue(URLDecoder.decode(kvPair[0]), URLDecoder.decode(kvPair[1]), "header"));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.auths = auths;
|
||||
this.auths = AuthParser.parse(urlEncodedAuthString);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<AuthorizationValue> getAuthorizationValues() {
|
||||
return auths;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
import config.Config;
|
||||
import config.ConfigParser;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
import org.apache.commons.cli.BasicParser;
|
||||
@@ -9,6 +11,7 @@ import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -41,6 +44,7 @@ public class Codegen extends DefaultGenerator {
|
||||
options.addOption("t", "template-dir", true, "folder containing the template files");
|
||||
options.addOption("d", "debug-info", false, "prints additional info for debugging");
|
||||
options.addOption("a", "auth", true, "adds authorization headers when fetching the swagger definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values");
|
||||
options.addOption("c", "config", true, "location of the configuration file");
|
||||
|
||||
ClientOptInput clientOptInput = new ClientOptInput();
|
||||
ClientOpts clientOpts = new ClientOpts();
|
||||
@@ -84,8 +88,20 @@ public class Codegen extends DefaultGenerator {
|
||||
if (cmd.hasOption("i")) {
|
||||
swagger = new SwaggerParser().read(cmd.getOptionValue("i"), clientOptInput.getAuthorizationValues(), true);
|
||||
}
|
||||
if (cmd.hasOption("c")) {
|
||||
String configFile = cmd.getOptionValue("c");
|
||||
Config genConfig = ConfigParser.read(configFile);
|
||||
config = clientOptInput.getConfig();
|
||||
if (null != genConfig && null != config) {
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
if (genConfig.hasOption(langCliOption.getOpt())) {
|
||||
config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmd.hasOption("t")) {
|
||||
clientOpts.getProperties().put("templateDir", String.valueOf(cmd.getOptionValue("t")));
|
||||
clientOpts.getProperties().put(CodegenConstants.TEMPLATE_DIR, String.valueOf(cmd.getOptionValue("t")));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
usage(options);
|
||||
@@ -145,4 +161,4 @@ public class Codegen extends DefaultGenerator {
|
||||
configString = sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public interface CodegenConfig {
|
||||
|
||||
CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions);
|
||||
|
||||
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger);
|
||||
|
||||
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions);
|
||||
|
||||
List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes);
|
||||
@@ -83,6 +85,10 @@ public interface CodegenConfig {
|
||||
|
||||
Map<String, String> modelTemplateFiles();
|
||||
|
||||
Set<String> languageSpecificPrimitives();
|
||||
|
||||
void preprocessSwagger(Swagger swagger);
|
||||
|
||||
void processSwagger(Swagger swagger);
|
||||
|
||||
String toApiFilename(String name);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import static java.util.ServiceLoader.load;
|
||||
|
||||
public class CodegenConfigLoader {
|
||||
/**
|
||||
* Tries to load config class with SPI first, then with class name directly from classpath
|
||||
*
|
||||
* @param name name of config, or full qualified class name in classpath
|
||||
* @return config class
|
||||
*/
|
||||
public static CodegenConfig forName(String name) {
|
||||
ServiceLoader<CodegenConfig> loader = load(CodegenConfig.class);
|
||||
|
||||
StringBuilder availableConfigs = new StringBuilder();
|
||||
|
||||
for (CodegenConfig config : loader) {
|
||||
if (config.getName().equals(name)) {
|
||||
return config;
|
||||
}
|
||||
|
||||
availableConfigs.append(config.getName()).append("\n");
|
||||
}
|
||||
|
||||
// else try to load directly
|
||||
try {
|
||||
return (CodegenConfig) Class.forName(name).newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Can't load config class with name ".concat(name) + " Available: " + availableConfigs.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
/**
|
||||
* A class for storing constants that are used throughout the project.
|
||||
*/
|
||||
public class CodegenConstants {
|
||||
public static final String API_PACKAGE = "apiPackage";
|
||||
public static final String API_PACKAGE_DESC = "package for generated api classes";
|
||||
|
||||
public static final String MODEL_PACKAGE = "modelPackage";
|
||||
public static final String MODEL_PACKAGE_DESC = "package for generated models";
|
||||
|
||||
public static final String TEMPLATE_DIR = "templateDir";
|
||||
|
||||
|
||||
public static final String INVOKER_PACKAGE = "invokerPackage";
|
||||
public static final String INVOKER_PACKAGE_DESC = "root package for generated code";
|
||||
|
||||
public static final String GROUP_ID = "groupId";
|
||||
public static final String GROUP_ID_DESC = "groupId in generated pom.xml";
|
||||
|
||||
public static final String ARTIFACT_ID = "artifactId";
|
||||
public static final String ARTIFACT_ID_DESC = "artifactId in generated pom.xml";
|
||||
|
||||
public static final String ARTIFACT_VERSION = "artifactVersion";
|
||||
public static final String ARTIFACT_VERSION_DESC = "artifact version in generated pom.xml";
|
||||
|
||||
public static final String SOURCE_FOLDER = "sourceFolder";
|
||||
public static final String SOURCE_FOLDER_DESC = "source folder for generated code";
|
||||
|
||||
public static final String LOCAL_VARIABLE_PREFIX = "localVariablePrefix";
|
||||
public static final String LOCAL_VARIABLE_PREFIX_DESC = "prefix for generated code members and local variables";
|
||||
|
||||
public static final String SERIALIZABLE_MODEL = "serializableModel";
|
||||
public static final String SERIALIZABLE_MODEL_DESC = "boolean - toggle \"implements Serializable\" for generated models";
|
||||
|
||||
public static final String LIBRARY = "library";
|
||||
public static final String LIBRARY_DESC = "library template (sub-template)";
|
||||
|
||||
public static final String SORT_PARAMS_BY_REQUIRED_FLAG = "sortParamsByRequiredFlag";
|
||||
public static final String SORT_PARAMS_BY_REQUIRED_FLAG_DESC = "Sort method arguments to place required parameters before optional parameters. Default: true";
|
||||
|
||||
}
|
||||
@@ -10,9 +10,10 @@ import java.util.Set;
|
||||
public class CodegenModel {
|
||||
public String parent;
|
||||
public String name, classname, description, classVarName, modelJson;
|
||||
public String unescapedDescription;
|
||||
public String defaultValue;
|
||||
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
|
||||
public Set<String> imports = new HashSet<String>();
|
||||
public Boolean hasVars, emptyVars, hasMoreModels, hasEnums;
|
||||
public ExternalDocs externalDocs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import java.util.Set;
|
||||
|
||||
public class CodegenOperation {
|
||||
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
|
||||
public Boolean hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive,
|
||||
public Boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive,
|
||||
returnSimpleType, subresourceOperation, isMapContainer, isListContainer,
|
||||
hasMore = Boolean.TRUE, isMultipart;
|
||||
hasMore = Boolean.TRUE, isMultipart, isResponseBinary = Boolean.FALSE;
|
||||
public String path, operationId, returnType, httpMethod, returnBaseType,
|
||||
returnContainer, summary, notes, baseName, defaultResponse;
|
||||
public List<Map<String, String>> consumes, produces;
|
||||
@@ -29,24 +29,61 @@ public class CodegenOperation {
|
||||
public Set<String> imports = new HashSet<String>();
|
||||
public List<Map<String, String>> examples;
|
||||
public ExternalDocs externalDocs;
|
||||
public Map<String, Object> vendorExtensions;
|
||||
public String nickname; // legacy support
|
||||
|
||||
private boolean nonempty(List<CodegenParameter> params)
|
||||
{
|
||||
/**
|
||||
* Check if there's at least one parameter
|
||||
*
|
||||
* @return true if parameter exists, false otherwise
|
||||
*/
|
||||
private boolean nonempty(List<CodegenParameter> params) {
|
||||
return params != null && params.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there's at least one body parameter
|
||||
*
|
||||
* @return true if body parameter exists, false otherwise
|
||||
*/
|
||||
public boolean getHasBodyParam() {
|
||||
return nonempty(bodyParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there's at least one query parameter
|
||||
*
|
||||
* @return true if query parameter exists, false otherwise
|
||||
*/
|
||||
public boolean getHasQueryParams() {
|
||||
return nonempty(bodyParams);
|
||||
}
|
||||
public boolean getHasHeaderParams() {
|
||||
return nonempty(bodyParams);
|
||||
}
|
||||
public boolean getHasPathParams() {
|
||||
return nonempty(bodyParams);
|
||||
return nonempty(queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there's at least one header parameter
|
||||
*
|
||||
* @return true if header parameter exists, false otherwise
|
||||
*/
|
||||
public boolean getHasHeaderParams() {
|
||||
return nonempty(headerParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there's at least one path parameter
|
||||
*
|
||||
* @return true if path parameter exists, false otherwise
|
||||
*/
|
||||
public boolean getHasPathParams() {
|
||||
return nonempty(pathParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there's at least one form parameter
|
||||
*
|
||||
* @return true if any form parameter exists, false otherwise
|
||||
*/
|
||||
public boolean getHasFormParams() {
|
||||
return nonempty(formParams);
|
||||
}
|
||||
|
||||
// legacy support
|
||||
public String nickname;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@ import java.util.List;
|
||||
|
||||
public class CodegenParameter {
|
||||
public Boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
|
||||
isCookieParam, isBodyParam, isFile, notFile, hasMore, isContainer, secondaryParam;
|
||||
isCookieParam, isBodyParam, isFile, notFile, hasMore, isContainer,
|
||||
secondaryParam, isBinary, isCollectionFormatMulti;
|
||||
public String baseName, paramName, dataType, collectionFormat, description, baseType, defaultValue;
|
||||
public String jsonSchema;
|
||||
public boolean isEnum;
|
||||
public List<String> _enum;
|
||||
public Map<String, Object> allowableValues;
|
||||
public Map<String, Object> vendorExtensions;
|
||||
|
||||
/**
|
||||
* Determines whether this parameter is mandatory. If the parameter is in "path",
|
||||
@@ -32,6 +34,7 @@ public class CodegenParameter {
|
||||
output.paramName = this.paramName;
|
||||
output.dataType = this.dataType;
|
||||
output.collectionFormat = this.collectionFormat;
|
||||
output.isCollectionFormatMulti = this.isCollectionFormatMulti;
|
||||
output.description = this.description;
|
||||
output.baseType = this.baseType;
|
||||
output.isFormParam = this.isFormParam;
|
||||
@@ -50,6 +53,7 @@ public class CodegenParameter {
|
||||
if (this.allowableValues != null) {
|
||||
output.allowableValues = new HashMap<String, Object>(this.allowableValues);
|
||||
}
|
||||
output.vendorExtensions = this.vendorExtensions;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ public class CodegenProperty {
|
||||
public String baseName, complexType, getter, setter, description, datatype, datatypeWithEnum,
|
||||
name, min, max, defaultValue, baseType, containerType;
|
||||
|
||||
public String unescapedDescription;
|
||||
|
||||
/**
|
||||
* maxLength validation for strings, see http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1
|
||||
*/
|
||||
@@ -32,6 +34,7 @@ public class CodegenProperty {
|
||||
public Boolean hasMore = null, required = null, secondaryParam = null;
|
||||
public Boolean isPrimitiveType, isContainer, isNotContainer;
|
||||
public boolean isEnum;
|
||||
public Boolean isReadOnly = false;
|
||||
public List<String> _enum;
|
||||
public Map<String, Object> allowableValues;
|
||||
public CodegenProperty items;
|
||||
|
||||
@@ -15,6 +15,7 @@ public class CodegenResponse {
|
||||
public Boolean primitiveType;
|
||||
public Boolean isMapContainer;
|
||||
public Boolean isListContainer;
|
||||
public Boolean isBinary = Boolean.FALSE;
|
||||
public Object schema;
|
||||
public String jsonSchema;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CodegenSecurity {
|
||||
public String name;
|
||||
@@ -11,5 +12,5 @@ public class CodegenSecurity {
|
||||
public Boolean isKeyInQuery, isKeyInHeader;
|
||||
// Oauth specific
|
||||
public String flow, authorizationUrl, tokenUrl;
|
||||
public Set<String> scopes;
|
||||
public List<Map<String, Object>> scopes;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.swagger.models.parameters.SerializableParameter;
|
||||
import io.swagger.models.properties.AbstractNumericProperty;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.BooleanProperty;
|
||||
import io.swagger.models.properties.ByteArrayProperty;
|
||||
import io.swagger.models.properties.DateProperty;
|
||||
import io.swagger.models.properties.DateTimeProperty;
|
||||
import io.swagger.models.properties.DecimalProperty;
|
||||
@@ -84,22 +85,27 @@ public class DefaultCodegen {
|
||||
protected boolean supportsInheritance = false;
|
||||
protected Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
|
||||
protected String library = null;
|
||||
protected Boolean sortParamsByRequiredFlag = true;
|
||||
|
||||
public List<CliOption> cliOptions() {
|
||||
return cliOptions;
|
||||
}
|
||||
|
||||
public void processOpts() {
|
||||
if (additionalProperties.containsKey("templateDir")) {
|
||||
this.setTemplateDir((String) additionalProperties.get("templateDir"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.TEMPLATE_DIR)) {
|
||||
this.setTemplateDir((String) additionalProperties.get(CodegenConstants.TEMPLATE_DIR));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("modelPackage")) {
|
||||
this.setModelPackage((String) additionalProperties.get("modelPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
|
||||
this.setModelPackage((String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("apiPackage")) {
|
||||
this.setApiPackage((String) additionalProperties.get("apiPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||
this.setApiPackage((String) additionalProperties.get(CodegenConstants.API_PACKAGE));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
|
||||
this.setSortParamsByRequiredFlag(Boolean.valueOf((String)additionalProperties.get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG).toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +124,10 @@ public class DefaultCodegen {
|
||||
return objs;
|
||||
}
|
||||
|
||||
//override with any special handling of the entire swagger spec
|
||||
public void preprocessSwagger(Swagger swagger) {
|
||||
}
|
||||
|
||||
// override with any special handling of the entire swagger spec
|
||||
public void processSwagger(Swagger swagger) {
|
||||
}
|
||||
@@ -125,6 +135,7 @@ public class DefaultCodegen {
|
||||
// override with any special text escaping logic
|
||||
public String escapeText(String input) {
|
||||
if (input != null) {
|
||||
input = input.trim();
|
||||
String output = input.replaceAll("\n", "\\\\n");
|
||||
output = output.replace("\"", "\\\"");
|
||||
return output;
|
||||
@@ -220,6 +231,10 @@ public class DefaultCodegen {
|
||||
this.apiPackage = apiPackage;
|
||||
}
|
||||
|
||||
public void setSortParamsByRequiredFlag(Boolean sortParamsByRequiredFlag) {
|
||||
this.sortParamsByRequiredFlag = sortParamsByRequiredFlag;
|
||||
}
|
||||
|
||||
public String toApiFilename(String name) {
|
||||
return toApiName(name);
|
||||
}
|
||||
@@ -311,6 +326,8 @@ public class DefaultCodegen {
|
||||
typeMapping.put("double", "Double");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("integer", "Integer");
|
||||
typeMapping.put("ByteArray", "byte[]");
|
||||
|
||||
|
||||
instantiationTypes = new HashMap<String, String>();
|
||||
|
||||
@@ -333,8 +350,9 @@ public class DefaultCodegen {
|
||||
importMapping.put("LocalDate", "org.joda.time.*");
|
||||
importMapping.put("LocalTime", "org.joda.time.*");
|
||||
|
||||
cliOptions.add(new CliOption("modelPackage", "package for generated models"));
|
||||
cliOptions.add(new CliOption("apiPackage", "package for generated api classes"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC));
|
||||
}
|
||||
|
||||
|
||||
@@ -391,7 +409,13 @@ public class DefaultCodegen {
|
||||
public String toInstantiationType(Property p) {
|
||||
if (p instanceof MapProperty) {
|
||||
MapProperty ap = (MapProperty) p;
|
||||
String inner = getSwaggerType(ap.getAdditionalProperties());
|
||||
Property additionalProperties2 = ap.getAdditionalProperties();
|
||||
String type = additionalProperties2.getType();
|
||||
if (null == type) {
|
||||
LOGGER.error("No Type defined for Additional Property " + additionalProperties2 + "\n" //
|
||||
+ "\tIn Property: " + p);
|
||||
}
|
||||
String inner = getSwaggerType(additionalProperties2);
|
||||
return instantiationTypes.get("map") + "<String, " + inner + ">";
|
||||
} else if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
@@ -447,6 +471,8 @@ public class DefaultCodegen {
|
||||
String datatype = null;
|
||||
if (p instanceof StringProperty) {
|
||||
datatype = "string";
|
||||
} else if (p instanceof ByteArrayProperty) {
|
||||
datatype = "ByteArray";
|
||||
} else if (p instanceof BooleanProperty) {
|
||||
datatype = "boolean";
|
||||
} else if (p instanceof DateProperty) {
|
||||
@@ -466,10 +492,16 @@ public class DefaultCodegen {
|
||||
} else if (p instanceof DecimalProperty) {
|
||||
datatype = "number";
|
||||
} else if (p instanceof RefProperty) {
|
||||
RefProperty r = (RefProperty) p;
|
||||
datatype = r.get$ref();
|
||||
if (datatype.indexOf("#/definitions/") == 0) {
|
||||
datatype = datatype.substring("#/definitions/".length());
|
||||
try {
|
||||
RefProperty r = (RefProperty) p;
|
||||
datatype = r.get$ref();
|
||||
if (datatype.indexOf("#/definitions/") == 0) {
|
||||
datatype = datatype.substring("#/definitions/".length());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Error obtaining the datatype from RefProperty:" + p + ". Datatype default to Object");
|
||||
datatype = "Object";
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
if (p != null) {
|
||||
@@ -522,6 +554,7 @@ public class DefaultCodegen {
|
||||
m.name = name;
|
||||
}
|
||||
m.description = escapeText(model.getDescription());
|
||||
m.unescapedDescription = model.getDescription();
|
||||
m.classname = toModelName(name);
|
||||
m.classVarName = toVarName(name);
|
||||
m.modelJson = Json.pretty(model);
|
||||
@@ -529,6 +562,7 @@ public class DefaultCodegen {
|
||||
if (model instanceof ArrayModel) {
|
||||
ArrayModel am = (ArrayModel) model;
|
||||
ArrayProperty arrayProperty = new ArrayProperty(am.getItems());
|
||||
m.hasEnums = false; // Otherwise there will be a NullPointerException in JavaClientCodegen.fromModel
|
||||
addParentContainer(m, name, arrayProperty);
|
||||
} else if (model instanceof RefModel) {
|
||||
// TODO
|
||||
@@ -556,7 +590,7 @@ public class DefaultCodegen {
|
||||
}
|
||||
}
|
||||
// interfaces (intermediate models)
|
||||
if (allDefinitions != null) {
|
||||
if (allDefinitions != null && composed.getInterfaces() != null) {
|
||||
for (RefModel _interface : composed.getInterfaces()) {
|
||||
final String interfaceRef = toModelName(_interface.getSimpleRef());
|
||||
final Model interfaceModel = allDefinitions.get(interfaceRef);
|
||||
@@ -617,11 +651,13 @@ public class DefaultCodegen {
|
||||
property.name = toVarName(name);
|
||||
property.baseName = name;
|
||||
property.description = escapeText(p.getDescription());
|
||||
property.unescapedDescription = p.getDescription();
|
||||
property.getter = "get" + getterAndSetterCapitalize(name);
|
||||
property.setter = "set" + getterAndSetterCapitalize(name);
|
||||
property.example = p.getExample();
|
||||
property.defaultValue = toDefaultValue(p);
|
||||
property.jsonSchema = Json.pretty(p);
|
||||
property.isReadOnly = p.getReadOnly();
|
||||
|
||||
String type = getSwaggerType(p);
|
||||
if (p instanceof AbstractNumericProperty) {
|
||||
@@ -660,7 +696,102 @@ public class DefaultCodegen {
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
if(p instanceof IntegerProperty) {
|
||||
IntegerProperty sp = (IntegerProperty) p;
|
||||
if(sp.getEnum() != null) {
|
||||
List<Integer> _enum = sp.getEnum();
|
||||
property._enum = new ArrayList<String>();
|
||||
for(Integer i : _enum) {
|
||||
property._enum.add(i.toString());
|
||||
}
|
||||
property.isEnum = true;
|
||||
|
||||
// legacy support
|
||||
Map<String, Object> allowableValues = new HashMap<String, Object>();
|
||||
allowableValues.put("values", _enum);
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
if(p instanceof LongProperty) {
|
||||
LongProperty sp = (LongProperty) p;
|
||||
if(sp.getEnum() != null) {
|
||||
List<Long> _enum = sp.getEnum();
|
||||
property._enum = new ArrayList<String>();
|
||||
for(Long i : _enum) {
|
||||
property._enum.add(i.toString());
|
||||
}
|
||||
property.isEnum = true;
|
||||
|
||||
// legacy support
|
||||
Map<String, Object> allowableValues = new HashMap<String, Object>();
|
||||
allowableValues.put("values", _enum);
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
if(p instanceof DoubleProperty) {
|
||||
DoubleProperty sp = (DoubleProperty) p;
|
||||
if(sp.getEnum() != null) {
|
||||
List<Double> _enum = sp.getEnum();
|
||||
property._enum = new ArrayList<String>();
|
||||
for(Double i : _enum) {
|
||||
property._enum.add(i.toString());
|
||||
}
|
||||
property.isEnum = true;
|
||||
|
||||
// legacy support
|
||||
Map<String, Object> allowableValues = new HashMap<String, Object>();
|
||||
allowableValues.put("values", _enum);
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
if(p instanceof FloatProperty) {
|
||||
FloatProperty sp = (FloatProperty) p;
|
||||
if(sp.getEnum() != null) {
|
||||
List<Float> _enum = sp.getEnum();
|
||||
property._enum = new ArrayList<String>();
|
||||
for(Float i : _enum) {
|
||||
property._enum.add(i.toString());
|
||||
}
|
||||
property.isEnum = true;
|
||||
|
||||
// legacy support
|
||||
Map<String, Object> allowableValues = new HashMap<String, Object>();
|
||||
allowableValues.put("values", _enum);
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
if(p instanceof DateProperty) {
|
||||
DateProperty sp = (DateProperty) p;
|
||||
if(sp.getEnum() != null) {
|
||||
List<String> _enum = sp.getEnum();
|
||||
property._enum = new ArrayList<String>();
|
||||
for(String i : _enum) {
|
||||
property._enum.add(i.toString());
|
||||
}
|
||||
property.isEnum = true;
|
||||
|
||||
// legacy support
|
||||
Map<String, Object> allowableValues = new HashMap<String, Object>();
|
||||
allowableValues.put("values", _enum);
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
if(p instanceof DateTimeProperty) {
|
||||
DateTimeProperty sp = (DateTimeProperty) p;
|
||||
if(sp.getEnum() != null) {
|
||||
List<String> _enum = sp.getEnum();
|
||||
property._enum = new ArrayList<String>();
|
||||
for(String i : _enum) {
|
||||
property._enum.add(i.toString());
|
||||
}
|
||||
property.isEnum = true;
|
||||
|
||||
// legacy support
|
||||
Map<String, Object> allowableValues = new HashMap<String, Object>();
|
||||
allowableValues.put("values", _enum);
|
||||
property.allowableValues = allowableValues;
|
||||
}
|
||||
}
|
||||
property.datatype = getTypeDeclaration(p);
|
||||
|
||||
// this can cause issues for clients which don't support enums
|
||||
@@ -672,28 +803,29 @@ public class DefaultCodegen {
|
||||
|
||||
property.baseType = getSwaggerType(p);
|
||||
|
||||
if (p instanceof ArrayProperty) {
|
||||
property.isContainer = true;
|
||||
property.containerType = "array";
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
CodegenProperty cp = fromProperty(property.name, ap.getItems());
|
||||
if (cp == null) {
|
||||
LOGGER.warn("skipping invalid property " + Json.pretty(p));
|
||||
} else {
|
||||
property.baseType = getSwaggerType(p);
|
||||
if (!languageSpecificPrimitives.contains(cp.baseType)) {
|
||||
property.complexType = cp.baseType;
|
||||
} else {
|
||||
property.isPrimitiveType = true;
|
||||
}
|
||||
property.items = cp;
|
||||
if (property.items.isEnum) {
|
||||
property.datatypeWithEnum = property.datatypeWithEnum.replace(property.items.baseType,
|
||||
property.items.datatypeWithEnum);
|
||||
property.defaultValue = property.defaultValue.replace(property.items.baseType, property.items.datatypeWithEnum);
|
||||
}
|
||||
}
|
||||
} else if (p instanceof MapProperty) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
property.isContainer = true;
|
||||
property.containerType = "array";
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
CodegenProperty cp = fromProperty(property.name, ap.getItems());
|
||||
if (cp == null) {
|
||||
LOGGER.warn("skipping invalid property " + Json.pretty(p));
|
||||
} else {
|
||||
property.baseType = getSwaggerType(p);
|
||||
if (!languageSpecificPrimitives.contains(cp.baseType)) {
|
||||
property.complexType = cp.baseType;
|
||||
} else {
|
||||
property.isPrimitiveType = true;
|
||||
}
|
||||
property.items = cp;
|
||||
if (property.items.isEnum) {
|
||||
property.datatypeWithEnum = property.datatypeWithEnum.replace(property.items.baseType,
|
||||
property.items.datatypeWithEnum);
|
||||
if(property.defaultValue != null)
|
||||
property.defaultValue = property.defaultValue.replace(property.items.baseType, property.items.datatypeWithEnum);
|
||||
}
|
||||
}
|
||||
} else if (p instanceof MapProperty) {
|
||||
property.isContainer = true;
|
||||
property.containerType = "map";
|
||||
MapProperty ap = (MapProperty) p;
|
||||
@@ -735,10 +867,15 @@ public class DefaultCodegen {
|
||||
}
|
||||
return responses.get(code);
|
||||
}
|
||||
|
||||
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
|
||||
return fromOperation(path, httpMethod, operation, definitions, null);
|
||||
}
|
||||
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
|
||||
CodegenOperation op = CodegenModelFactory.newInstance(CodegenModelType.OPERATION);
|
||||
Set<String> imports = new HashSet<String>();
|
||||
op.vendorExtensions = operation.getVendorExtensions();
|
||||
|
||||
String operationId = operation.getOperationId();
|
||||
if (operationId == null) {
|
||||
@@ -763,7 +900,7 @@ public class DefaultCodegen {
|
||||
}
|
||||
}
|
||||
operationId = builder.toString();
|
||||
LOGGER.warn("generated operationId " + operationId);
|
||||
LOGGER.info("generated operationId " + operationId + "\tfor Path: " + httpMethod + " " + path);
|
||||
}
|
||||
operationId = removeNonNameElementToCamelCase(operationId);
|
||||
op.path = path;
|
||||
@@ -771,15 +908,32 @@ public class DefaultCodegen {
|
||||
op.summary = escapeText(operation.getSummary());
|
||||
op.notes = escapeText(operation.getDescription());
|
||||
op.tags = operation.getTags();
|
||||
op.hasConsumes = false;
|
||||
op.hasProduces = false;
|
||||
|
||||
if (operation.getConsumes() != null && operation.getConsumes().size() > 0) {
|
||||
List<String> consumes = new ArrayList<String>();
|
||||
if (operation.getConsumes() != null) {
|
||||
if (operation.getConsumes().size() > 0) {
|
||||
// use consumes defined in the operation
|
||||
consumes = operation.getConsumes();
|
||||
} else {
|
||||
// empty list, do nothing to override global setting
|
||||
}
|
||||
} else if (swagger != null && swagger.getConsumes() != null && swagger.getConsumes().size() > 0) {
|
||||
// use consumes defined globally
|
||||
consumes = swagger.getConsumes();
|
||||
LOGGER.debug("No consumes defined in operation. Using global consumes (" + swagger.getConsumes() + ") for " + op.operationId);
|
||||
}
|
||||
|
||||
// if "consumes" is defined (per operation or using global definition)
|
||||
if (consumes != null && consumes.size() > 0) {
|
||||
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
|
||||
int count = 0;
|
||||
for (String key : operation.getConsumes()) {
|
||||
for (String key : consumes) {
|
||||
Map<String, String> mediaType = new HashMap<String, String>();
|
||||
mediaType.put("mediaType", key);
|
||||
count += 1;
|
||||
if (count < operation.getConsumes().size()) {
|
||||
if (count < consumes.size()) {
|
||||
mediaType.put("hasMore", "true");
|
||||
} else {
|
||||
mediaType.put("hasMore", null);
|
||||
@@ -790,14 +944,29 @@ public class DefaultCodegen {
|
||||
op.hasConsumes = true;
|
||||
}
|
||||
|
||||
if (operation.getProduces() != null && operation.getProduces().size() > 0) {
|
||||
List<String> produces = new ArrayList<String>();
|
||||
if (operation.getProduces() != null) {
|
||||
if (operation.getProduces().size() > 0) {
|
||||
// use produces defined in the operation
|
||||
produces = operation.getProduces();
|
||||
} else {
|
||||
// empty list, do nothing to override global setting
|
||||
}
|
||||
} else if (swagger != null && swagger.getProduces() != null && swagger.getProduces().size() > 0) {
|
||||
// use produces defined globally
|
||||
produces = swagger.getProduces();
|
||||
LOGGER.debug("No produces defined in operation. Using global produces (" + swagger.getProduces() + ") for " + op.operationId);
|
||||
}
|
||||
|
||||
// if "produces" is defined (per operation or using global definition)
|
||||
if (produces != null && produces.size() > 0) {
|
||||
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
|
||||
int count = 0;
|
||||
for (String key : operation.getProduces()) {
|
||||
for (String key : produces) {
|
||||
Map<String, String> mediaType = new HashMap<String, String>();
|
||||
mediaType.put("mediaType", key);
|
||||
count += 1;
|
||||
if (count < operation.getProduces().size()) {
|
||||
if (count < produces.size()) {
|
||||
mediaType.put("hasMore", "true");
|
||||
} else {
|
||||
mediaType.put("hasMore", null);
|
||||
@@ -822,6 +991,9 @@ public class DefaultCodegen {
|
||||
}
|
||||
r.isDefault = response == methodResponse;
|
||||
op.responses.add(r);
|
||||
if (r.isBinary && r.isDefault){
|
||||
op.isResponseBinary = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
op.responses.get(op.responses.size() - 1).hasMore = false;
|
||||
|
||||
@@ -908,23 +1080,26 @@ public class DefaultCodegen {
|
||||
}
|
||||
}
|
||||
for (String i : imports) {
|
||||
if (!defaultIncludes.contains(i) && !languageSpecificPrimitives.contains(i)) {
|
||||
if (needToImport(i)) {
|
||||
op.imports.add(i);
|
||||
}
|
||||
}
|
||||
op.bodyParam = bodyParam;
|
||||
op.httpMethod = httpMethod.toUpperCase();
|
||||
|
||||
// move "required" parameters in front of "optional" parameters
|
||||
Collections.sort(allParams, new Comparator<CodegenParameter>() {
|
||||
@Override
|
||||
public int compare(CodegenParameter one, CodegenParameter another) {
|
||||
boolean oneRequired = one.required == null ? false : one.required;
|
||||
boolean anotherRequired = another.required == null ? false : another.required;
|
||||
if (oneRequired == anotherRequired) return 0;
|
||||
else if (oneRequired) return -1;
|
||||
else return 1;
|
||||
}
|
||||
});
|
||||
if(sortParamsByRequiredFlag) {
|
||||
Collections.sort(allParams, new Comparator<CodegenParameter>() {
|
||||
@Override
|
||||
public int compare(CodegenParameter one, CodegenParameter another) {
|
||||
boolean oneRequired = one.required == null ? false : one.required;
|
||||
boolean anotherRequired = another.required == null ? false : another.required;
|
||||
if (oneRequired == anotherRequired) return 0;
|
||||
else if (oneRequired) return -1;
|
||||
else return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
op.allParams = addHasMore(allParams);
|
||||
op.bodyParams = addHasMore(bodyParams);
|
||||
op.pathParams = addHasMore(pathParams);
|
||||
@@ -951,7 +1126,7 @@ public class DefaultCodegen {
|
||||
} else {
|
||||
r.code = responseCode;
|
||||
}
|
||||
r.message = response.getDescription();
|
||||
r.message = escapeText(response.getDescription());
|
||||
r.schema = response.getSchema();
|
||||
r.examples = toExamples(response.getExamples());
|
||||
r.jsonSchema = Json.pretty(response);
|
||||
@@ -974,6 +1149,7 @@ public class DefaultCodegen {
|
||||
}
|
||||
}
|
||||
r.dataType = cm.datatype;
|
||||
r.isBinary = cm.datatype.equals("byte[]");
|
||||
if (cm.isContainer != null) {
|
||||
r.simpleType = false;
|
||||
r.containerType = cm.containerType;
|
||||
@@ -1002,6 +1178,10 @@ public class DefaultCodegen {
|
||||
}
|
||||
p.jsonSchema = Json.pretty(param);
|
||||
|
||||
if (System.getProperty("debugParser") != null) {
|
||||
LOGGER.info("working on Parameter " + param);
|
||||
}
|
||||
|
||||
// move the defaultValue for headers, forms and params
|
||||
if (param instanceof QueryParameter) {
|
||||
p.defaultValue = ((QueryParameter) param).getDefaultValue();
|
||||
@@ -1011,11 +1191,17 @@ public class DefaultCodegen {
|
||||
p.defaultValue = ((FormParameter) param).getDefaultValue();
|
||||
}
|
||||
|
||||
p.vendorExtensions = param.getVendorExtensions();
|
||||
|
||||
if (param instanceof SerializableParameter) {
|
||||
SerializableParameter qp = (SerializableParameter) param;
|
||||
Property property = null;
|
||||
String collectionFormat = null;
|
||||
if ("array".equals(qp.getType())) {
|
||||
String type = qp.getType();
|
||||
if (null == type) {
|
||||
LOGGER.warn("Type is NULL for Serializable Parameter: " + param);
|
||||
}
|
||||
if ("array".equals(type)) {
|
||||
Property inner = qp.getItems();
|
||||
if (inner == null) {
|
||||
LOGGER.warn("warning! No inner type supplied for array parameter \"" + qp.getName() + "\", using String");
|
||||
@@ -1027,7 +1213,7 @@ public class DefaultCodegen {
|
||||
p.baseType = pr.datatype;
|
||||
p.isContainer = true;
|
||||
imports.add(pr.baseType);
|
||||
} else if ("object".equals(qp.getType())) {
|
||||
} else if ("object".equals(type)) {
|
||||
Property inner = qp.getItems();
|
||||
if (inner == null) {
|
||||
LOGGER.warn("warning! No inner type supplied for map parameter \"" + qp.getName() + "\", using String");
|
||||
@@ -1040,12 +1226,13 @@ public class DefaultCodegen {
|
||||
imports.add(pr.baseType);
|
||||
} else {
|
||||
Map<PropertyId, Object> args = new HashMap<PropertyId, Object>();
|
||||
String format = qp.getFormat();
|
||||
args.put(PropertyId.ENUM, qp.getEnum());
|
||||
property = PropertyBuilder.build(qp.getType(), qp.getFormat(), args);
|
||||
property = PropertyBuilder.build(type, format, args);
|
||||
}
|
||||
if (property == null) {
|
||||
LOGGER.warn("warning! Property type \"" + qp.getType() + "\" not found for parameter \"" + param.getName() + "\", using String");
|
||||
property = new StringProperty().description("//TODO automatically added by swagger-codegen. Type was " + qp.getType() + " but not supported");
|
||||
LOGGER.warn("warning! Property type \"" + type + "\" not found for parameter \"" + param.getName() + "\", using String");
|
||||
property = new StringProperty().description("//TODO automatically added by swagger-codegen. Type was " + type + " but not supported");
|
||||
}
|
||||
property.setRequired(param.getRequired());
|
||||
CodegenProperty model = fromProperty(qp.getName(), property);
|
||||
@@ -1054,12 +1241,19 @@ public class DefaultCodegen {
|
||||
p._enum = model._enum;
|
||||
p.allowableValues = model.allowableValues;
|
||||
p.collectionFormat = collectionFormat;
|
||||
if(collectionFormat != null && collectionFormat.equals("multi")) {
|
||||
p.isCollectionFormatMulti = true;
|
||||
}
|
||||
p.paramName = toParamName(qp.getName());
|
||||
|
||||
if (model.complexType != null) {
|
||||
imports.add(model.complexType);
|
||||
}
|
||||
} else {
|
||||
if (!(param instanceof BodyParameter)) {
|
||||
LOGGER.error("Cannot use Parameter " + param + " as Body Parameter");
|
||||
}
|
||||
|
||||
BodyParameter bp = (BodyParameter) param;
|
||||
Model model = bp.getSchema();
|
||||
|
||||
@@ -1070,12 +1264,17 @@ public class DefaultCodegen {
|
||||
p.dataType = getTypeDeclaration(cm.classname);
|
||||
imports.add(p.dataType);
|
||||
} else {
|
||||
// TODO: missing format, so this will not always work
|
||||
Property prop = PropertyBuilder.build(impl.getType(), null, null);
|
||||
Property prop = PropertyBuilder.build(impl.getType(), impl.getFormat(), null);
|
||||
prop.setRequired(bp.getRequired());
|
||||
CodegenProperty cp = fromProperty("property", prop);
|
||||
if (cp != null) {
|
||||
p.dataType = cp.datatype;
|
||||
if (p.dataType.equals("byte[]")) {
|
||||
p.isBinary = true;
|
||||
}
|
||||
else {
|
||||
p.isBinary = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (model instanceof ArrayModel) {
|
||||
@@ -1146,7 +1345,25 @@ public class DefaultCodegen {
|
||||
sec.flow = oauth2Definition.getFlow();
|
||||
sec.authorizationUrl = oauth2Definition.getAuthorizationUrl();
|
||||
sec.tokenUrl = oauth2Definition.getTokenUrl();
|
||||
sec.scopes = oauth2Definition.getScopes().keySet();
|
||||
if (oauth2Definition.getScopes() != null) {
|
||||
List<Map<String, Object>> scopes = new ArrayList<Map<String, Object>>();
|
||||
int count = 0, numScopes = oauth2Definition.getScopes().size();
|
||||
for(Map.Entry<String, String> scopeEntry : oauth2Definition.getScopes().entrySet()) {
|
||||
Map<String, Object> scope = new HashMap<String, Object>();
|
||||
scope.put("scope", scopeEntry.getKey());
|
||||
scope.put("description", scopeEntry.getValue());
|
||||
|
||||
count += 1;
|
||||
if (count < numScopes) {
|
||||
scope.put("hasMore", "true");
|
||||
} else {
|
||||
scope.put("hasMore", null);
|
||||
}
|
||||
|
||||
scopes.add(scope);
|
||||
}
|
||||
sec.scopes = scopes;
|
||||
}
|
||||
}
|
||||
|
||||
sec.hasMore = it.hasNext();
|
||||
@@ -1155,6 +1372,12 @@ public class DefaultCodegen {
|
||||
return secs;
|
||||
}
|
||||
|
||||
protected boolean needToImport(String type) {
|
||||
return !defaultIncludes.contains(type)
|
||||
&& !languageSpecificPrimitives.contains(type)
|
||||
&& type.indexOf(".") < 0;
|
||||
}
|
||||
|
||||
protected List<Map<String, Object>> toExamples(Map<String, Object> examples) {
|
||||
if (examples == null) {
|
||||
return null;
|
||||
@@ -1258,7 +1481,7 @@ public class DefaultCodegen {
|
||||
}
|
||||
|
||||
private void addImport(CodegenModel m, String type) {
|
||||
if (type != null && !languageSpecificPrimitives.contains(type) && !defaultIncludes.contains(type)) {
|
||||
if (type != null && needToImport(type)) {
|
||||
m.imports.add(type);
|
||||
}
|
||||
}
|
||||
@@ -1296,6 +1519,8 @@ public class DefaultCodegen {
|
||||
}
|
||||
} else {
|
||||
m.emptyVars = true;
|
||||
m.hasVars = false;
|
||||
m.hasEnums = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1427,4 +1652,42 @@ public class DefaultCodegen {
|
||||
}
|
||||
return new CliOption("library", sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* sanitize name (parameter, property, method, etc)
|
||||
*
|
||||
* @param name string to be sanitize
|
||||
* @return sanitized string
|
||||
*/
|
||||
public String sanitizeName(String name) {
|
||||
// NOTE: performance wise, we should have written with 2 replaceAll to replace desired
|
||||
// character with _ or empty character. Below aims to spell out different cases we've
|
||||
// encountered so far and hopefully make it easier for others to add more special
|
||||
// cases in the future.
|
||||
|
||||
// input[] => input
|
||||
name = name.replaceAll("\\[\\]", "");
|
||||
|
||||
// input[a][b] => input_a_b
|
||||
name = name.replaceAll("\\[", "_");
|
||||
name = name.replaceAll("\\]", "");
|
||||
|
||||
// input(a)(b) => input_a_b
|
||||
name = name.replaceAll("\\(", "_");
|
||||
name = name.replaceAll("\\)", "");
|
||||
|
||||
// input.name => input_name
|
||||
name = name.replaceAll("\\.", "_");
|
||||
|
||||
// input-name => input_name
|
||||
name = name.replaceAll("-", "_");
|
||||
|
||||
// input name and age => input_name_and_age
|
||||
name = name.replaceAll(" ", "_");
|
||||
|
||||
// remove everything else other than word, number and _
|
||||
// $php_variable => php_variable
|
||||
return name.replaceAll("[^a-zA-Z0-9_]", "");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import com.samskivert.mustache.Template;
|
||||
import io.swagger.codegen.languages.CodeGenStatus;
|
||||
import io.swagger.models.ComposedModel;
|
||||
import io.swagger.models.Contact;
|
||||
import io.swagger.models.Info;
|
||||
@@ -13,6 +12,7 @@ import io.swagger.models.License;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.Path;
|
||||
import io.swagger.models.SecurityRequirement;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.auth.OAuth2Definition;
|
||||
import io.swagger.models.auth.SecuritySchemeDefinition;
|
||||
@@ -20,6 +20,8 @@ import io.swagger.models.parameters.Parameter;
|
||||
import io.swagger.util.Json;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -27,24 +29,16 @@ import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
Logger LOGGER = LoggerFactory.getLogger(DefaultGenerator.class);
|
||||
|
||||
protected CodegenConfig config;
|
||||
protected ClientOptInput opts = null;
|
||||
protected Swagger swagger = null;
|
||||
|
||||
public CodeGenStatus status = CodeGenStatus.UNRUN;
|
||||
|
||||
@Override
|
||||
public Generator opts(ClientOptInput opts) {
|
||||
this.opts = opts;
|
||||
|
||||
@@ -55,7 +49,55 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<File> generate() {
|
||||
Boolean generateApis = null;
|
||||
Boolean generateModels = null;
|
||||
Boolean generateSupportingFiles = null;
|
||||
|
||||
Set<String> modelsToGenerate = null;
|
||||
Set<String> apisToGenerate = null;
|
||||
Set<String> supportingFilesToGenerate = null;
|
||||
|
||||
// allows generating only models by specifying a CSV of models to generate, or empty for all
|
||||
if(System.getProperty("models") != null) {
|
||||
String modelNames = System.getProperty("models");
|
||||
generateModels = true;
|
||||
if(!modelNames.isEmpty()) {
|
||||
modelsToGenerate = new HashSet<String>(Arrays.asList(modelNames.split(",")));
|
||||
}
|
||||
}
|
||||
if(System.getProperty("apis") != null) {
|
||||
String apiNames = System.getProperty("apis");
|
||||
generateApis = true;
|
||||
if(!apiNames.isEmpty()) {
|
||||
apisToGenerate = new HashSet<String>(Arrays.asList(apiNames.split(",")));
|
||||
}
|
||||
}
|
||||
if(System.getProperty("supportingFiles") != null) {
|
||||
String supportingFiles = System.getProperty("supportingFiles");
|
||||
generateSupportingFiles = true;
|
||||
if(!supportingFiles.isEmpty()) {
|
||||
supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(",")));
|
||||
}
|
||||
}
|
||||
|
||||
if(generateApis == null && generateModels == null && generateSupportingFiles == null) {
|
||||
// no specifics are set, generate everything
|
||||
generateApis = true; generateModels = true; generateSupportingFiles = true;
|
||||
}
|
||||
else {
|
||||
if(generateApis == null) {
|
||||
generateApis = false;
|
||||
}
|
||||
if(generateModels == null) {
|
||||
generateModels = false;
|
||||
}
|
||||
if(generateSupportingFiles == null) {
|
||||
generateSupportingFiles = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (swagger == null || config == null) {
|
||||
throw new RuntimeException("missing swagger input or config!");
|
||||
}
|
||||
@@ -63,264 +105,319 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
Json.prettyPrint(swagger);
|
||||
}
|
||||
List<File> files = new ArrayList<File>();
|
||||
try {
|
||||
config.processOpts();
|
||||
config.processOpts();
|
||||
config.preprocessSwagger(swagger);
|
||||
|
||||
config.additionalProperties().put("generatedDate", DateTime.now().toString());
|
||||
config.additionalProperties().put("generatorClass", config.getClass().toString());
|
||||
config.additionalProperties().put("generatedDate", DateTime.now().toString());
|
||||
config.additionalProperties().put("generatorClass", config.getClass().toString());
|
||||
|
||||
if (swagger.getInfo() != null) {
|
||||
Info info = swagger.getInfo();
|
||||
if (info.getTitle() != null) {
|
||||
config.additionalProperties().put("appName", info.getTitle());
|
||||
if (swagger.getInfo() != null) {
|
||||
Info info = swagger.getInfo();
|
||||
if (info.getTitle() != null) {
|
||||
config.additionalProperties().put("appName", info.getTitle());
|
||||
}
|
||||
if (info.getVersion() != null) {
|
||||
config.additionalProperties().put("appVersion", info.getVersion());
|
||||
}
|
||||
if (info.getDescription() != null) {
|
||||
config.additionalProperties().put("appDescription",
|
||||
config.escapeText(info.getDescription()));
|
||||
}
|
||||
if (info.getContact() != null) {
|
||||
Contact contact = info.getContact();
|
||||
config.additionalProperties().put("infoUrl", contact.getUrl());
|
||||
if (contact.getEmail() != null) {
|
||||
config.additionalProperties().put("infoEmail", contact.getEmail());
|
||||
}
|
||||
if (info.getVersion() != null) {
|
||||
config.additionalProperties().put("appVersion", info.getVersion());
|
||||
}
|
||||
if (info.getLicense() != null) {
|
||||
License license = info.getLicense();
|
||||
if (license.getName() != null) {
|
||||
config.additionalProperties().put("licenseInfo", license.getName());
|
||||
}
|
||||
if (info.getDescription() != null) {
|
||||
config.additionalProperties().put("appDescription",
|
||||
config.escapeText(info.getDescription()));
|
||||
if (license.getUrl() != null) {
|
||||
config.additionalProperties().put("licenseUrl", license.getUrl());
|
||||
}
|
||||
if (info.getContact() != null) {
|
||||
Contact contact = info.getContact();
|
||||
config.additionalProperties().put("infoUrl", contact.getUrl());
|
||||
if (contact.getEmail() != null) {
|
||||
config.additionalProperties().put("infoEmail", contact.getEmail());
|
||||
}
|
||||
if (info.getVersion() != null) {
|
||||
config.additionalProperties().put("version", info.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder hostBuilder = new StringBuilder();
|
||||
String scheme;
|
||||
if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) {
|
||||
scheme = swagger.getSchemes().get(0).toValue();
|
||||
} else {
|
||||
scheme = "https";
|
||||
}
|
||||
hostBuilder.append(scheme);
|
||||
hostBuilder.append("://");
|
||||
if (swagger.getHost() != null) {
|
||||
hostBuilder.append(swagger.getHost());
|
||||
} else {
|
||||
hostBuilder.append("localhost");
|
||||
}
|
||||
if (swagger.getBasePath() != null) {
|
||||
hostBuilder.append(swagger.getBasePath());
|
||||
}
|
||||
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
|
||||
String basePath = hostBuilder.toString();
|
||||
|
||||
|
||||
// resolve inline models
|
||||
InlineModelResolver inlineModelResolver = new InlineModelResolver();
|
||||
inlineModelResolver.flatten(swagger);
|
||||
|
||||
List<Object> allOperations = new ArrayList<Object>();
|
||||
List<Object> allModels = new ArrayList<Object>();
|
||||
|
||||
// models
|
||||
Map<String, Model> definitions = swagger.getDefinitions();
|
||||
if (definitions != null) {
|
||||
List<String> sortedModelKeys = sortModelsByInheritance(definitions);
|
||||
|
||||
if(generateModels) {
|
||||
if(modelsToGenerate != null && modelsToGenerate.size() > 0) {
|
||||
List<String> updatedKeys = new ArrayList<String>();
|
||||
for(String m : sortedModelKeys) {
|
||||
if(modelsToGenerate.contains(m)) {
|
||||
updatedKeys.add(m);
|
||||
}
|
||||
}
|
||||
sortedModelKeys = updatedKeys;
|
||||
}
|
||||
if (info.getLicense() != null) {
|
||||
License license = info.getLicense();
|
||||
if (license.getName() != null) {
|
||||
config.additionalProperties().put("licenseInfo", license.getName());
|
||||
}
|
||||
if (license.getUrl() != null) {
|
||||
config.additionalProperties().put("licenseUrl", license.getUrl());
|
||||
}
|
||||
}
|
||||
if (info.getVersion() != null) {
|
||||
config.additionalProperties().put("version", info.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder hostBuilder = new StringBuilder();
|
||||
String scheme;
|
||||
if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) {
|
||||
scheme = swagger.getSchemes().get(0).toValue();
|
||||
} else {
|
||||
scheme = "https";
|
||||
}
|
||||
hostBuilder.append(scheme);
|
||||
hostBuilder.append("://");
|
||||
if (swagger.getHost() != null) {
|
||||
hostBuilder.append(swagger.getHost());
|
||||
} else {
|
||||
hostBuilder.append("localhost");
|
||||
}
|
||||
if (swagger.getBasePath() != null) {
|
||||
hostBuilder.append(swagger.getBasePath());
|
||||
}
|
||||
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
|
||||
String basePath = hostBuilder.toString();
|
||||
|
||||
|
||||
List<Object> allOperations = new ArrayList<Object>();
|
||||
List<Object> allModels = new ArrayList<Object>();
|
||||
|
||||
// models
|
||||
Map<String, Model> definitions = swagger.getDefinitions();
|
||||
if (definitions != null) {
|
||||
List<String> sortedModelKeys = sortModelsByInheritance(definitions);
|
||||
|
||||
for (String name : sortedModelKeys) {
|
||||
Model model = definitions.get(name);
|
||||
Map<String, Model> modelMap = new HashMap<String, Model>();
|
||||
modelMap.put(name, model);
|
||||
Map<String, Object> models = processModels(config, modelMap, definitions);
|
||||
models.putAll(config.additionalProperties());
|
||||
|
||||
allModels.add(((List<Object>) models.get("models")).get(0));
|
||||
|
||||
for (String templateName : config.modelTemplateFiles().keySet()) {
|
||||
String suffix = config.modelTemplateFiles().get(templateName);
|
||||
String filename = config.modelFileFolder() + File.separator + config.toModelFilename(name) + suffix;
|
||||
if (!config.shouldOverwrite(filename)) {
|
||||
try {
|
||||
//don't generate models that have an import mapping
|
||||
if(config.importMapping().containsKey(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Model model = definitions.get(name);
|
||||
Map<String, Model> modelMap = new HashMap<String, Model>();
|
||||
modelMap.put(name, model);
|
||||
Map<String, Object> models = processModels(config, modelMap, definitions);
|
||||
models.putAll(config.additionalProperties());
|
||||
|
||||
allModels.add(((List<Object>) models.get("models")).get(0));
|
||||
|
||||
for (String templateName : config.modelTemplateFiles().keySet()) {
|
||||
String suffix = config.modelTemplateFiles().get(templateName);
|
||||
String filename = config.modelFileFolder() + File.separator + config.toModelFilename(name) + suffix;
|
||||
if (!config.shouldOverwrite(filename)) {
|
||||
continue;
|
||||
}
|
||||
String templateFile = getFullTemplateFile(config, templateName);
|
||||
String template = readTemplate(templateFile);
|
||||
Template tmpl = Mustache.compiler()
|
||||
.withLoader(new Mustache.TemplateLoader() {
|
||||
@Override
|
||||
public Reader getTemplate(String name) {
|
||||
return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
|
||||
}
|
||||
})
|
||||
.defaultValue("")
|
||||
.compile(template);
|
||||
writeToFile(filename, tmpl.execute(models));
|
||||
files.add(new File(filename));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not generate model '" + name + "'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (System.getProperty("debugModels") != null) {
|
||||
System.out.println("############ Model info ############");
|
||||
Json.prettyPrint(allModels);
|
||||
}
|
||||
|
||||
// apis
|
||||
Map<String, List<CodegenOperation>> paths = processPaths(swagger.getPaths());
|
||||
if(generateApis) {
|
||||
if(apisToGenerate != null && apisToGenerate.size() > 0) {
|
||||
Map<String, List<CodegenOperation>> updatedPaths = new TreeMap<String, List<CodegenOperation>>();
|
||||
for(String m : paths.keySet()) {
|
||||
if(apisToGenerate.contains(m)) {
|
||||
updatedPaths.put(m, paths.get(m));
|
||||
}
|
||||
}
|
||||
paths = updatedPaths;
|
||||
}
|
||||
for (String tag : paths.keySet()) {
|
||||
try {
|
||||
List<CodegenOperation> ops = paths.get(tag);
|
||||
Map<String, Object> operation = processOperations(config, tag, ops);
|
||||
|
||||
operation.put("basePath", basePath);
|
||||
operation.put("contextPath", contextPath);
|
||||
operation.put("baseName", tag);
|
||||
operation.put("modelPackage", config.modelPackage());
|
||||
operation.putAll(config.additionalProperties());
|
||||
operation.put("classname", config.toApiName(tag));
|
||||
operation.put("classVarName", config.toApiVarName(tag));
|
||||
operation.put("importPath", config.toApiImport(tag));
|
||||
|
||||
processMimeTypes(swagger.getConsumes(), operation, "consumes");
|
||||
processMimeTypes(swagger.getProduces(), operation, "produces");
|
||||
|
||||
allOperations.add(new HashMap<String, Object>(operation));
|
||||
for (int i = 0; i < allOperations.size(); i++) {
|
||||
Map<String, Object> oo = (Map<String, Object>) allOperations.get(i);
|
||||
if (i < (allOperations.size() - 1)) {
|
||||
oo.put("hasMore", "true");
|
||||
}
|
||||
}
|
||||
|
||||
for (String templateName : config.apiTemplateFiles().keySet()) {
|
||||
String filename = config.apiFilename(templateName, tag);
|
||||
if (!config.shouldOverwrite(filename) && new File(filename).exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String templateFile = getFullTemplateFile(config, templateName);
|
||||
String template = readTemplate(templateFile);
|
||||
Template tmpl = Mustache.compiler()
|
||||
.withLoader(new Mustache.TemplateLoader() {
|
||||
@Override
|
||||
public Reader getTemplate(String name) {
|
||||
return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
|
||||
}
|
||||
})
|
||||
.defaultValue("")
|
||||
.compile(template);
|
||||
writeToFile(filename, tmpl.execute(models));
|
||||
|
||||
writeToFile(filename, tmpl.execute(operation));
|
||||
files.add(new File(filename));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not generate api file for '" + tag + "'", e);
|
||||
}
|
||||
}
|
||||
if (System.getProperty("debugModels") != null) {
|
||||
System.out.println("############ Model info ############");
|
||||
Json.prettyPrint(allModels);
|
||||
}
|
||||
}
|
||||
if (System.getProperty("debugOperations") != null) {
|
||||
System.out.println("############ Operation info ############");
|
||||
Json.prettyPrint(allOperations);
|
||||
}
|
||||
|
||||
// apis
|
||||
Map<String, List<CodegenOperation>> paths = processPaths(swagger.getPaths());
|
||||
for (String tag : paths.keySet()) {
|
||||
List<CodegenOperation> ops = paths.get(tag);
|
||||
Map<String, Object> operation = processOperations(config, tag, ops);
|
||||
// supporting files
|
||||
Map<String, Object> bundle = new HashMap<String, Object>();
|
||||
bundle.putAll(config.additionalProperties());
|
||||
bundle.put("apiPackage", config.apiPackage());
|
||||
|
||||
operation.put("basePath", basePath);
|
||||
operation.put("contextPath", contextPath);
|
||||
operation.put("baseName", tag);
|
||||
operation.put("modelPackage", config.modelPackage());
|
||||
operation.putAll(config.additionalProperties());
|
||||
operation.put("classname", config.toApiName(tag));
|
||||
operation.put("classVarName", config.toApiVarName(tag));
|
||||
operation.put("importPath", config.toApiImport(tag));
|
||||
Map<String, Object> apis = new HashMap<String, Object>();
|
||||
apis.put("apis", allOperations);
|
||||
if (swagger.getHost() != null) {
|
||||
bundle.put("host", swagger.getHost());
|
||||
}
|
||||
bundle.put("basePath", basePath);
|
||||
bundle.put("scheme", scheme);
|
||||
bundle.put("contextPath", contextPath);
|
||||
bundle.put("apiInfo", apis);
|
||||
bundle.put("models", allModels);
|
||||
bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
|
||||
bundle.put("modelPackage", config.modelPackage());
|
||||
List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions());
|
||||
if (authMethods != null && !authMethods.isEmpty()) {
|
||||
bundle.put("authMethods", authMethods);
|
||||
bundle.put("hasAuthMethods", true);
|
||||
}
|
||||
if (swagger.getExternalDocs() != null) {
|
||||
bundle.put("externalDocs", swagger.getExternalDocs());
|
||||
}
|
||||
for (int i = 0; i < allModels.size() - 1; i++) {
|
||||
HashMap<String, CodegenModel> cm = (HashMap<String, CodegenModel>) allModels.get(i);
|
||||
CodegenModel m = cm.get("model");
|
||||
m.hasMoreModels = true;
|
||||
}
|
||||
|
||||
processMimeTypes(swagger.getConsumes(), operation, "consumes");
|
||||
processMimeTypes(swagger.getProduces(), operation, "produces");
|
||||
config.postProcessSupportingFileData(bundle);
|
||||
|
||||
allOperations.add(new HashMap<String, Object>(operation));
|
||||
for (int i = 0; i < allOperations.size(); i++) {
|
||||
Map<String, Object> oo = (Map<String, Object>) allOperations.get(i);
|
||||
if (i < (allOperations.size() - 1)) {
|
||||
oo.put("hasMore", "true");
|
||||
if (System.getProperty("debugSupportingFiles") != null) {
|
||||
System.out.println("############ Supporting file info ############");
|
||||
Json.prettyPrint(bundle);
|
||||
}
|
||||
|
||||
if(generateSupportingFiles) {
|
||||
for (SupportingFile support : config.supportingFiles()) {
|
||||
try {
|
||||
String outputFolder = config.outputFolder();
|
||||
if (isNotEmpty(support.folder)) {
|
||||
outputFolder += File.separator + support.folder;
|
||||
}
|
||||
}
|
||||
|
||||
for (String templateName : config.apiTemplateFiles().keySet()) {
|
||||
|
||||
String filename = config.apiFilename(templateName, tag);
|
||||
if (!config.shouldOverwrite(filename) && new File(filename).exists()) {
|
||||
File of = new File(outputFolder);
|
||||
if (!of.isDirectory()) {
|
||||
of.mkdirs();
|
||||
}
|
||||
String outputFilename = outputFolder + File.separator + support.destinationFilename;
|
||||
if (!config.shouldOverwrite(outputFilename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String templateFile = getFullTemplateFile(config, templateName);
|
||||
String template = readTemplate(templateFile);
|
||||
Template tmpl = Mustache.compiler()
|
||||
.withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate(String name) {
|
||||
return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
|
||||
}
|
||||
})
|
||||
.defaultValue("")
|
||||
.compile(template);
|
||||
String templateFile = getFullTemplateFile(config, support.templateFile);
|
||||
|
||||
writeToFile(filename, tmpl.execute(operation));
|
||||
files.add(new File(filename));
|
||||
}
|
||||
}
|
||||
if (System.getProperty("debugOperations") != null) {
|
||||
System.out.println("############ Operation info ############");
|
||||
Json.prettyPrint(allOperations);
|
||||
}
|
||||
|
||||
// supporting files
|
||||
Map<String, Object> bundle = new HashMap<String, Object>();
|
||||
bundle.putAll(config.additionalProperties());
|
||||
bundle.put("apiPackage", config.apiPackage());
|
||||
|
||||
Map<String, Object> apis = new HashMap<String, Object>();
|
||||
apis.put("apis", allOperations);
|
||||
if (swagger.getHost() != null) {
|
||||
bundle.put("host", swagger.getHost());
|
||||
}
|
||||
bundle.put("basePath", basePath);
|
||||
bundle.put("scheme", scheme);
|
||||
bundle.put("contextPath", contextPath);
|
||||
bundle.put("apiInfo", apis);
|
||||
bundle.put("models", allModels);
|
||||
bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
|
||||
bundle.put("modelPackage", config.modelPackage());
|
||||
List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions());
|
||||
if (authMethods != null && !authMethods.isEmpty()) {
|
||||
bundle.put("authMethods", authMethods);
|
||||
bundle.put("hasAuthMethods", true);
|
||||
}
|
||||
if (swagger.getExternalDocs() != null) {
|
||||
bundle.put("externalDocs", swagger.getExternalDocs());
|
||||
}
|
||||
for (int i = 0; i < allModels.size() - 1; i++) {
|
||||
HashMap<String, CodegenModel> cm = (HashMap<String, CodegenModel>) allModels.get(i);
|
||||
CodegenModel m = cm.get("model");
|
||||
m.hasMoreModels = true;
|
||||
}
|
||||
|
||||
config.postProcessSupportingFileData(bundle);
|
||||
|
||||
if (System.getProperty("debugSupportingFiles") != null) {
|
||||
System.out.println("############ Supporting file info ############");
|
||||
Json.prettyPrint(bundle);
|
||||
}
|
||||
|
||||
for (SupportingFile support : config.supportingFiles()) {
|
||||
String outputFolder = config.outputFolder();
|
||||
if (isNotEmpty(support.folder)) {
|
||||
outputFolder += File.separator + support.folder;
|
||||
}
|
||||
File of = new File(outputFolder);
|
||||
if (!of.isDirectory()) {
|
||||
of.mkdirs();
|
||||
}
|
||||
String outputFilename = outputFolder + File.separator + support.destinationFilename;
|
||||
if (!config.shouldOverwrite(outputFilename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String templateFile = getFullTemplateFile(config, support.templateFile);
|
||||
|
||||
if (templateFile.endsWith("mustache")) {
|
||||
String template = readTemplate(templateFile);
|
||||
Template tmpl = Mustache.compiler()
|
||||
.withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate(String name) {
|
||||
return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
|
||||
}
|
||||
})
|
||||
.defaultValue("")
|
||||
.compile(template);
|
||||
|
||||
writeToFile(outputFilename, tmpl.execute(bundle));
|
||||
files.add(new File(outputFilename));
|
||||
} else {
|
||||
InputStream in = null;
|
||||
|
||||
try {
|
||||
in = new FileInputStream(templateFile);
|
||||
} catch (Exception e) {
|
||||
// continue
|
||||
}
|
||||
if (in == null) {
|
||||
in = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(templateFile));
|
||||
}
|
||||
File outputFile = new File(outputFilename);
|
||||
OutputStream out = new FileOutputStream(outputFile, false);
|
||||
if (in != null && out != null) {
|
||||
System.out.println("writing file " + outputFile);
|
||||
IOUtils.copy(in, out);
|
||||
} else {
|
||||
if (in == null) {
|
||||
System.out.println("can't open " + templateFile + " for input");
|
||||
boolean shouldGenerate = true;
|
||||
if(supportingFilesToGenerate != null && supportingFilesToGenerate.size() > 0) {
|
||||
if(supportingFilesToGenerate.contains(support.destinationFilename)) {
|
||||
shouldGenerate = true;
|
||||
}
|
||||
if (out == null) {
|
||||
System.out.println("can't open " + outputFile + " for output");
|
||||
else {
|
||||
shouldGenerate = false;
|
||||
}
|
||||
}
|
||||
if(shouldGenerate) {
|
||||
if (templateFile.endsWith("mustache")) {
|
||||
String template = readTemplate(templateFile);
|
||||
Template tmpl = Mustache.compiler()
|
||||
.withLoader(new Mustache.TemplateLoader() {
|
||||
@Override
|
||||
public Reader getTemplate(String name) {
|
||||
return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
|
||||
}
|
||||
})
|
||||
.defaultValue("")
|
||||
.compile(template);
|
||||
|
||||
files.add(outputFile);
|
||||
writeToFile(outputFilename, tmpl.execute(bundle));
|
||||
files.add(new File(outputFilename));
|
||||
} else {
|
||||
InputStream in = null;
|
||||
|
||||
try {
|
||||
in = new FileInputStream(templateFile);
|
||||
} catch (Exception e) {
|
||||
// continue
|
||||
}
|
||||
if (in == null) {
|
||||
in = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(templateFile));
|
||||
}
|
||||
File outputFile = new File(outputFilename);
|
||||
OutputStream out = new FileOutputStream(outputFile, false);
|
||||
if (in != null && out != null) {
|
||||
System.out.println("writing file " + outputFile);
|
||||
IOUtils.copy(in, out);
|
||||
} else {
|
||||
if (in == null) {
|
||||
System.out.println("can't open " + templateFile + " for input");
|
||||
}
|
||||
if (out == null) {
|
||||
System.out.println("can't open " + outputFile + " for output");
|
||||
}
|
||||
}
|
||||
|
||||
files.add(outputFile);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not generate supporting file '" + support + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
config.processSwagger(swagger);
|
||||
|
||||
status = CodeGenStatus.SUCCESSFUL;
|
||||
} catch (Exception e) {
|
||||
status = CodeGenStatus.FAILED;
|
||||
}
|
||||
|
||||
config.processSwagger(swagger);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
@@ -397,6 +494,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
for (String resourcePath : paths.keySet()) {
|
||||
Path path = paths.get(resourcePath);
|
||||
processOperation(resourcePath, "get", path.getGet(), ops, path);
|
||||
processOperation(resourcePath, "head", path.getHead(), ops, path);
|
||||
processOperation(resourcePath, "put", path.getPut(), ops, path);
|
||||
processOperation(resourcePath, "post", path.getPost(), ops, path);
|
||||
processOperation(resourcePath, "delete", path.getDelete(), ops, path);
|
||||
@@ -416,6 +514,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
|
||||
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations, Path path) {
|
||||
if (operation != null) {
|
||||
if (System.getProperty("debugOperations") != null) {
|
||||
LOGGER.debug("processOperation: resourcePath= " + resourcePath + "\t;" + httpMethod + " " + operation + "\n");
|
||||
}
|
||||
List<String> tags = operation.getTags();
|
||||
if (tags == null) {
|
||||
tags = new ArrayList<String>();
|
||||
@@ -445,44 +546,67 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
|
||||
for (String tag : tags) {
|
||||
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions());
|
||||
co.tags = new ArrayList<String>();
|
||||
co.tags.add(sanitizeTag(tag));
|
||||
config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);
|
||||
CodegenOperation co = null;
|
||||
try {
|
||||
co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions(), swagger);
|
||||
co.tags = new ArrayList<String>();
|
||||
co.tags.add(sanitizeTag(tag));
|
||||
config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);
|
||||
|
||||
List<Map<String, List<String>>> securities = operation.getSecurity();
|
||||
if (securities == null) {
|
||||
continue;
|
||||
}
|
||||
Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>();
|
||||
for (Map<String, List<String>> security : securities) {
|
||||
if (security.size() != 1) {
|
||||
//Not sure what to do
|
||||
List<Map<String, List<String>>> securities = operation.getSecurity();
|
||||
if (securities == null && swagger.getSecurity() != null) {
|
||||
securities = new ArrayList<Map<String, List<String>>>();
|
||||
for (SecurityRequirement sr : swagger.getSecurity()) {
|
||||
securities.add(sr.getRequirements());
|
||||
}
|
||||
}
|
||||
if (securities == null || securities.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String securityName = security.keySet().iterator().next();
|
||||
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
|
||||
if (securityDefinition != null) {
|
||||
if(securityDefinition instanceof OAuth2Definition) {
|
||||
OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
|
||||
OAuth2Definition oauth2Operation = new OAuth2Definition();
|
||||
oauth2Operation.setType(oauth2Definition.getType());
|
||||
oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
|
||||
oauth2Operation.setFlow(oauth2Definition.getFlow());
|
||||
oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
|
||||
for (String scope : security.values().iterator().next()) {
|
||||
if (oauth2Definition.getScopes().containsKey(scope)) {
|
||||
oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
|
||||
}
|
||||
}
|
||||
authMethods.put(securityName, oauth2Operation);
|
||||
} else {
|
||||
authMethods.put(securityName, securityDefinition);
|
||||
}
|
||||
Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>();
|
||||
// NOTE: Use only the first security requirement for now.
|
||||
// See the "security" field of "Swagger Object":
|
||||
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#swagger-object
|
||||
// "there is a logical OR between the security requirements"
|
||||
if (securities.size() > 1) {
|
||||
LOGGER.warn("More than 1 security requirements are found, using only the first one");
|
||||
}
|
||||
Map<String, List<String>> security = securities.get(0);
|
||||
for (String securityName : security.keySet()) {
|
||||
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
|
||||
if (securityDefinition != null) {
|
||||
if(securityDefinition instanceof OAuth2Definition) {
|
||||
OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
|
||||
OAuth2Definition oauth2Operation = new OAuth2Definition();
|
||||
oauth2Operation.setType(oauth2Definition.getType());
|
||||
oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
|
||||
oauth2Operation.setFlow(oauth2Definition.getFlow());
|
||||
oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
|
||||
oauth2Operation.setScopes(new HashMap<String, String>());
|
||||
for (String scope : security.get(securityName)) {
|
||||
if (oauth2Definition.getScopes().containsKey(scope)) {
|
||||
oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
|
||||
}
|
||||
}
|
||||
authMethods.put(securityName, oauth2Operation);
|
||||
} else {
|
||||
authMethods.put(securityName, securityDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!authMethods.isEmpty()) {
|
||||
co.authMethods = config.fromSecurity(authMethods);
|
||||
co.hasAuthMethods = true;
|
||||
}
|
||||
}
|
||||
if (!authMethods.isEmpty()) {
|
||||
co.authMethods = config.fromSecurity(authMethods);
|
||||
catch (Exception ex) {
|
||||
String msg = "Could not process operation:\n" //
|
||||
+ " Tag: " + tag + "\n"//
|
||||
+ " Operation: " + operation.getOperationId() + "\n" //
|
||||
+ " Resource: " + httpMethod + " " + resourcePath + "\n"//
|
||||
+ " Definitions: " + swagger.getDefinitions() + "\n" //
|
||||
+ " Exception: " + ex.getMessage();
|
||||
throw new RuntimeException(msg, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
package io.swagger.codegen;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.operations.Mod;
|
||||
import io.swagger.models.*;
|
||||
import io.swagger.models.parameters.BodyParameter;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
import io.swagger.models.parameters.RefParameter;
|
||||
import io.swagger.models.properties.*;
|
||||
import io.swagger.util.Json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InlineModelResolver {
|
||||
private Swagger swagger = null;
|
||||
private boolean skipMatches = false;
|
||||
|
||||
Map<String, Model> addedModels = new HashMap<String, Model>();
|
||||
Map<String, String> generatedSignature = new HashMap<String, String>();
|
||||
|
||||
public void flatten(Swagger swagger) {
|
||||
this.swagger = swagger;
|
||||
|
||||
if (swagger.getDefinitions() == null) {
|
||||
swagger.setDefinitions(new HashMap<String, Model>());
|
||||
}
|
||||
|
||||
// operations
|
||||
Map<String, Path> paths = swagger.getPaths();
|
||||
Map<String, Model> models = swagger.getDefinitions();
|
||||
|
||||
if (paths != null) {
|
||||
for (String pathname : paths.keySet()) {
|
||||
Path path = paths.get(pathname);
|
||||
|
||||
for (Operation operation : path.getOperations()) {
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
|
||||
if (parameters != null) {
|
||||
for (Parameter parameter : parameters) {
|
||||
if (parameter instanceof BodyParameter) {
|
||||
BodyParameter bp = (BodyParameter) parameter;
|
||||
if (bp.getSchema() != null) {
|
||||
Model model = bp.getSchema();
|
||||
if(model instanceof ModelImpl) {
|
||||
String modelName = uniqueName(bp.getName());
|
||||
ModelImpl obj = (ModelImpl) model;
|
||||
flattenProperties(obj.getProperties(), pathname);
|
||||
|
||||
bp.setSchema(new RefModel(modelName));
|
||||
addGenerated(modelName, model);
|
||||
swagger.addDefinition(modelName, model);
|
||||
}
|
||||
else if (model instanceof ArrayModel) {
|
||||
ArrayModel am = (ArrayModel) model;
|
||||
Property inner = am.getItems();
|
||||
|
||||
if(inner instanceof ObjectProperty) {
|
||||
ObjectProperty op = (ObjectProperty) inner;
|
||||
flattenProperties(op.getProperties(), pathname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Response> responses = operation.getResponses();
|
||||
if (responses != null) {
|
||||
for (String key : responses.keySet()) {
|
||||
Response response = responses.get(key);
|
||||
if (response.getSchema() != null) {
|
||||
Property property = response.getSchema();
|
||||
if (property instanceof ObjectProperty) {
|
||||
String modelName = uniqueName("inline_response_" + key);
|
||||
ObjectProperty op = (ObjectProperty) property;
|
||||
Model model = modelFromProperty(op, modelName);
|
||||
String existing = matchGenerated(model);
|
||||
if (existing != null) {
|
||||
response.setSchema(new RefProperty(existing));
|
||||
} else {
|
||||
response.setSchema(new RefProperty(modelName));
|
||||
addGenerated(modelName, model);
|
||||
swagger.addDefinition(modelName, model);
|
||||
}
|
||||
} else if (property instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) property;
|
||||
if(ap.getItems() instanceof ObjectProperty) {
|
||||
ObjectProperty op = (ObjectProperty) ap.getItems();
|
||||
Map<String, Property> props = op.getProperties();
|
||||
flattenProperties(props, "path");
|
||||
}
|
||||
} else if (property instanceof MapProperty) {
|
||||
MapProperty op = (MapProperty) property;
|
||||
|
||||
Property innerProperty = op.getAdditionalProperties();
|
||||
if(innerProperty instanceof ObjectProperty) {
|
||||
ModelImpl innerModel = new ModelImpl();
|
||||
// TODO: model props
|
||||
innerModel.setTitle(property.getTitle());
|
||||
property.getVendorExtensions();
|
||||
property.getRequired();
|
||||
property.getReadOnly();
|
||||
property.getAccess();
|
||||
innerModel.setDescription(property.getDescription());
|
||||
innerModel.setExample(property.getExample());
|
||||
innerModel.setName(property.getName());
|
||||
innerModel.setXml(property.getXml());
|
||||
|
||||
innerModel.setAdditionalProperties(innerProperty);
|
||||
|
||||
String modelName = uniqueName("inline_response_" + key);
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing != null) {
|
||||
response.setSchema(new RefProperty(existing));
|
||||
} else {
|
||||
response.setSchema(new RefProperty(modelName));
|
||||
addGenerated(modelName, innerModel);
|
||||
swagger.addDefinition(modelName, innerModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// definitions
|
||||
if (models != null) {
|
||||
List<String> modelNames = new ArrayList<String>(models.keySet());
|
||||
for (String modelName : modelNames) {
|
||||
Model model = models.get(modelName);
|
||||
if (model instanceof ModelImpl) {
|
||||
ModelImpl m = (ModelImpl) model;
|
||||
|
||||
Map<String, Property> properties = m.getProperties();
|
||||
flattenProperties(properties, modelName);
|
||||
|
||||
} else if (model instanceof ArrayModel) {
|
||||
ArrayModel m = (ArrayModel) model;
|
||||
Property inner = m.getItems();
|
||||
if (inner instanceof ObjectProperty) {
|
||||
String innerModelName = uniqueName(modelName + "_inner");
|
||||
Model innerModel = modelFromProperty((ObjectProperty) inner, modelName);
|
||||
|
||||
String existing = matchGenerated(innerModel);
|
||||
if (existing == null) {
|
||||
swagger.addDefinition(innerModelName, innerModel);
|
||||
addGenerated(innerModelName, innerModel);
|
||||
m.setItems(new RefProperty(innerModelName));
|
||||
} else {
|
||||
m.setItems(new RefProperty(existing));
|
||||
}
|
||||
}
|
||||
} else if (model instanceof ComposedModel) {
|
||||
ComposedModel m = (ComposedModel) model;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String matchGenerated(Model model) {
|
||||
if (this.skipMatches) {
|
||||
return null;
|
||||
}
|
||||
String json = Json.pretty(model);
|
||||
if (generatedSignature.containsKey(json)) {
|
||||
return generatedSignature.get(json);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addGenerated(String name, Model model) {
|
||||
generatedSignature.put(Json.pretty(model), name);
|
||||
}
|
||||
|
||||
public String uniqueName(String key) {
|
||||
int count = 0;
|
||||
boolean done = false;
|
||||
key = key.replaceAll("[^a-z_\\.A-Z0-9 ]", "");
|
||||
while (!done) {
|
||||
String name = key;
|
||||
if (count > 0) {
|
||||
name = key + "_" + count;
|
||||
}
|
||||
if (swagger.getDefinitions() == null) {
|
||||
return name;
|
||||
} else if (!swagger.getDefinitions().containsKey(name)) {
|
||||
return name;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public void flattenProperties(Map<String, Property> properties, String path) {
|
||||
if (properties == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, Property> propsToUpdate = new HashMap<String, Property>();
|
||||
Map<String, Model> modelsToAdd = new HashMap<String, Model>();
|
||||
for (String key : properties.keySet()) {
|
||||
Property property = properties.get(key);
|
||||
if (property instanceof ObjectProperty && ((ObjectProperty)property).getProperties().size() > 0) {
|
||||
String modelName = uniqueName(path + "_" + key);
|
||||
|
||||
ObjectProperty op = (ObjectProperty) property;
|
||||
Model model = modelFromProperty(op, modelName);
|
||||
|
||||
String existing = matchGenerated(model);
|
||||
|
||||
if (existing != null) {
|
||||
propsToUpdate.put(key, new RefProperty(existing));
|
||||
} else {
|
||||
propsToUpdate.put(key, new RefProperty(modelName));
|
||||
modelsToAdd.put(modelName, model);
|
||||
addGenerated(modelName, model);
|
||||
swagger.addDefinition(modelName, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (propsToUpdate.size() > 0) {
|
||||
for (String key : propsToUpdate.keySet()) {
|
||||
properties.put(key, propsToUpdate.get(key));
|
||||
}
|
||||
}
|
||||
for (String key : modelsToAdd.keySet()) {
|
||||
swagger.addDefinition(key, modelsToAdd.get(key));
|
||||
this.addedModels.put(key, modelsToAdd.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
public Model modelFromProperty(ArrayProperty object, String path) {
|
||||
String access = object.getAccess();
|
||||
String description = object.getDescription();
|
||||
String example = object.getExample();
|
||||
String name = object.getName();
|
||||
Integer position = object.getPosition();
|
||||
Boolean readOnly = object.getReadOnly();
|
||||
Boolean required = object.getRequired();
|
||||
String title = object.getTitle();
|
||||
Map<String, Object> extensions = object.getVendorExtensions();
|
||||
Xml xml = object.getXml();
|
||||
|
||||
// object.getItems()
|
||||
// Map<String, Property> properties = object.getProperties();
|
||||
|
||||
Property inner = object.getItems();
|
||||
if (inner instanceof ObjectProperty) {
|
||||
ArrayModel model = new ArrayModel();
|
||||
model.setDescription(description);
|
||||
model.setExample(example);
|
||||
// model.setName(name);
|
||||
// model.setXml(xml);
|
||||
|
||||
model.setItems(object.getItems());
|
||||
return model;
|
||||
}
|
||||
|
||||
// if(properties != null) {
|
||||
// flattenProperties(properties, path);
|
||||
// model.setProperties(properties);
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Model modelFromProperty(ObjectProperty object, String path) {
|
||||
String access = object.getAccess();
|
||||
String description = object.getDescription();
|
||||
String example = object.getExample();
|
||||
String name = object.getName();
|
||||
Integer position = object.getPosition();
|
||||
Boolean readOnly = object.getReadOnly();
|
||||
Boolean required = object.getRequired();
|
||||
String title = object.getTitle();
|
||||
Map<String, Object> extensions = object.getVendorExtensions();
|
||||
Xml xml = object.getXml();
|
||||
|
||||
Map<String, Property> properties = object.getProperties();
|
||||
|
||||
ModelImpl model = new ModelImpl();
|
||||
model.setDescription(description);
|
||||
model.setExample(example);
|
||||
model.setName(name);
|
||||
model.setXml(xml);
|
||||
|
||||
if (properties != null) {
|
||||
flattenProperties(properties, path);
|
||||
model.setProperties(properties);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public Model modelFromProperty(MapProperty object, String path) {
|
||||
String access = object.getAccess();
|
||||
String description = object.getDescription();
|
||||
String example = object.getExample();
|
||||
String name = object.getName();
|
||||
Integer position = object.getPosition();
|
||||
Boolean readOnly = object.getReadOnly();
|
||||
Boolean required = object.getRequired();
|
||||
String title = object.getTitle();
|
||||
Map<String, Object> extensions = object.getVendorExtensions();
|
||||
Xml xml = object.getXml();
|
||||
|
||||
ArrayModel model = new ArrayModel();
|
||||
model.setDescription(description);
|
||||
model.setExample(example);
|
||||
model.setItems(object.getAdditionalProperties());
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public boolean isSkipMatches() {
|
||||
return skipMatches;
|
||||
}
|
||||
|
||||
public void setSkipMatches(boolean skipMatches) {
|
||||
this.skipMatches = skipMatches;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.swagger.codegen.auth;
|
||||
|
||||
import io.swagger.models.auth.AuthorizationValue;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
public class AuthParser {
|
||||
|
||||
public static List<AuthorizationValue> parse(String urlEncodedAuthStr) {
|
||||
List<AuthorizationValue> auths = new ArrayList<AuthorizationValue>();
|
||||
if (isNotEmpty(urlEncodedAuthStr)) {
|
||||
String[] parts = urlEncodedAuthStr.split(",");
|
||||
for (String part : parts) {
|
||||
String[] kvPair = part.split(":");
|
||||
if (kvPair.length == 2) {
|
||||
auths.add(new AuthorizationValue(URLDecoder.decode(kvPair[0]), URLDecoder.decode(kvPair[1]), "header"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
|
||||
public static String reconstruct(List<AuthorizationValue> authorizationValueList) {
|
||||
if (authorizationValueList != null) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (AuthorizationValue v : authorizationValueList) {
|
||||
try {
|
||||
if (b.toString().length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(URLEncoder.encode(v.getKeyName(), "UTF-8"))
|
||||
.append(":")
|
||||
.append(URLEncoder.encode(v.getValue(), "UTF-8"));
|
||||
} catch (Exception e) {
|
||||
// continue
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
package io.swagger.codegen.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.ClientOptInput;
|
||||
import io.swagger.codegen.ClientOpts;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConfigLoader;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.auth.AuthParser;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.auth.AuthorizationValue;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
import io.swagger.util.Json;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
/**
|
||||
* A class that contains all codegen configuration properties a user would want to manipulate.
|
||||
* An instance could be created by deserializing a JSON file or being populated from CLI or Maven plugin parameters.
|
||||
* It also has a convenience method for creating a ClientOptInput class which is THE object DefaultGenerator.java needs
|
||||
* to generate code.
|
||||
*/
|
||||
public class CodegenConfigurator {
|
||||
|
||||
public static final Logger LOG = LoggerFactory.getLogger(CodegenConfigurator.class);
|
||||
|
||||
private String lang;
|
||||
private String inputSpec;
|
||||
private String outputDir;
|
||||
private boolean verbose = false;
|
||||
private boolean skipOverwrite = false;
|
||||
private String templateDir;
|
||||
private String auth;
|
||||
private String apiPackage;
|
||||
private String modelPackage;
|
||||
private String invokerPackage;
|
||||
private String groupId;
|
||||
private String artifactId;
|
||||
private String artifactVersion;
|
||||
private String library;
|
||||
private Map<String, String> systemProperties = new HashMap<String, String>();
|
||||
private Map<String, String> instantiationTypes = new HashMap<String, String>();
|
||||
private Map<String, String> typeMappings = new HashMap<String, String>();
|
||||
private Map<String, String> additionalProperties = new HashMap<String, String>();
|
||||
private Map<String, String> importMappings = new HashMap<String, String>();
|
||||
private Set<String> languageSpecificPrimitives = new HashSet<String>();
|
||||
|
||||
private final Map<String, String> dynamicProperties = new HashMap<String, String>(); //the map that holds the JsonAnySetter/JsonAnyGetter values
|
||||
|
||||
public CodegenConfigurator() {
|
||||
this.setOutputDir(".");
|
||||
}
|
||||
|
||||
public CodegenConfigurator setLang(String lang) {
|
||||
this.lang = lang;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setInputSpec(String inputSpec) {
|
||||
this.inputSpec = inputSpec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getInputSpec() {
|
||||
return inputSpec;
|
||||
}
|
||||
|
||||
public String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setOutputDir(String outputDir) {
|
||||
this.outputDir = toAbsolutePathStr(outputDir);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getModelPackage() {
|
||||
return modelPackage;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setModelPackage(String modelPackage) {
|
||||
this.modelPackage = modelPackage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSkipOverwrite() {
|
||||
return skipOverwrite;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setSkipOverwrite(boolean skipOverwrite) {
|
||||
this.skipOverwrite = skipOverwrite;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public String getTemplateDir() {
|
||||
return templateDir;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setTemplateDir(String templateDir) {
|
||||
this.templateDir = new File(templateDir).getAbsolutePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAuth() {
|
||||
return auth;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setAuth(String auth) {
|
||||
this.auth = auth;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getApiPackage() {
|
||||
return apiPackage;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setApiPackage(String apiPackage) {
|
||||
this.apiPackage = apiPackage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getInvokerPackage() {
|
||||
return invokerPackage;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setInvokerPackage(String invokerPackage) {
|
||||
this.invokerPackage = invokerPackage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return artifactId;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setArtifactId(String artifactId) {
|
||||
this.artifactId = artifactId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getArtifactVersion() {
|
||||
return artifactVersion;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setArtifactVersion(String artifactVersion) {
|
||||
this.artifactVersion = artifactVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, String> getSystemProperties() {
|
||||
return systemProperties;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setSystemProperties(Map<String, String> systemProperties) {
|
||||
this.systemProperties = systemProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator addSystemProperty(String key, String value) {
|
||||
this.systemProperties.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, String> getInstantiationTypes() {
|
||||
return instantiationTypes;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setInstantiationTypes(Map<String, String> instantiationTypes) {
|
||||
this.instantiationTypes = instantiationTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator addInstantiationType(String key, String value) {
|
||||
this.instantiationTypes.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, String> getTypeMappings() {
|
||||
return typeMappings;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setTypeMappings(Map<String, String> typeMappings) {
|
||||
this.typeMappings = typeMappings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator addTypeMapping(String key, String value) {
|
||||
this.typeMappings.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, String> getAdditionalProperties() {
|
||||
return additionalProperties;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setAdditionalProperties(Map<String, String> additionalProperties) {
|
||||
this.additionalProperties = additionalProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator addAdditionalProperty(String key, String value) {
|
||||
this.additionalProperties.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, String> getImportMappings() {
|
||||
return importMappings;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setImportMappings(Map<String, String> importMappings) {
|
||||
this.importMappings = importMappings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator addImportMapping(String key, String value) {
|
||||
this.importMappings.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<String> getLanguageSpecificPrimitives() {
|
||||
return languageSpecificPrimitives;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setLanguageSpecificPrimitives(Set<String> languageSpecificPrimitives) {
|
||||
this.languageSpecificPrimitives = languageSpecificPrimitives;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodegenConfigurator addLanguageSpecificPrimitive(String value) {
|
||||
this.languageSpecificPrimitives.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLibrary() {
|
||||
return library;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setLibrary(String library) {
|
||||
this.library = library;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientOptInput toClientOptInput() {
|
||||
|
||||
Validate.notEmpty(lang, "language must be specified");
|
||||
Validate.notEmpty(inputSpec, "input spec must be specified");
|
||||
|
||||
setVerboseFlags();
|
||||
setSystemProperties();
|
||||
|
||||
CodegenConfig config = CodegenConfigLoader.forName(lang);
|
||||
|
||||
config.setOutputDir(outputDir);
|
||||
config.setSkipOverwrite(skipOverwrite);
|
||||
|
||||
config.instantiationTypes().putAll(instantiationTypes);
|
||||
config.typeMapping().putAll(typeMappings);
|
||||
config.importMapping().putAll(importMappings);
|
||||
config.languageSpecificPrimitives().addAll(languageSpecificPrimitives);
|
||||
|
||||
checkAndSetAdditionalProperty(apiPackage, CodegenConstants.API_PACKAGE);
|
||||
checkAndSetAdditionalProperty(modelPackage, CodegenConstants.MODEL_PACKAGE);
|
||||
checkAndSetAdditionalProperty(invokerPackage, CodegenConstants.INVOKER_PACKAGE);
|
||||
checkAndSetAdditionalProperty(groupId, CodegenConstants.GROUP_ID);
|
||||
checkAndSetAdditionalProperty(artifactId, CodegenConstants.ARTIFACT_ID);
|
||||
checkAndSetAdditionalProperty(artifactVersion, CodegenConstants.ARTIFACT_VERSION);
|
||||
checkAndSetAdditionalProperty(templateDir, toAbsolutePathStr(templateDir), CodegenConstants.TEMPLATE_DIR);
|
||||
|
||||
handleDynamicProperties(config);
|
||||
|
||||
if (isNotEmpty(library)) {
|
||||
config.setLibrary(library);
|
||||
}
|
||||
|
||||
config.additionalProperties().putAll(additionalProperties);
|
||||
|
||||
ClientOptInput input = new ClientOptInput()
|
||||
.config(config);
|
||||
|
||||
final List<AuthorizationValue> authorizationValues = AuthParser.parse(auth);
|
||||
|
||||
Swagger swagger = new SwaggerParser().read(inputSpec, authorizationValues, true);
|
||||
|
||||
input.opts(new ClientOpts())
|
||||
.swagger(swagger);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public CodegenConfigurator addDynamicProperty(String name, Object value) {
|
||||
dynamicProperties.put(name, value.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, String> getDynamicProperties() {
|
||||
return dynamicProperties;
|
||||
}
|
||||
|
||||
private void handleDynamicProperties(CodegenConfig codegenConfig) {
|
||||
for (CliOption langCliOption : codegenConfig.cliOptions()) {
|
||||
String opt = langCliOption.getOpt();
|
||||
if (dynamicProperties.containsKey(opt)) {
|
||||
codegenConfig.additionalProperties().put(opt, dynamicProperties.get(opt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setVerboseFlags() {
|
||||
if (!verbose) {
|
||||
return;
|
||||
}
|
||||
LOG.info("\nVERBOSE MODE: ON. Additional debug options are injected" +
|
||||
"\n - [debugSwagger] prints the swagger specification as interpreted by the codegen" +
|
||||
"\n - [debugModels] prints models passed to the template engine" +
|
||||
"\n - [debugOperations] prints operations passed to the template engine" +
|
||||
"\n - [debugSupportingFiles] prints additional data passed to the template engine");
|
||||
|
||||
System.setProperty("debugSwagger", "");
|
||||
System.setProperty("debugModels", "");
|
||||
System.setProperty("debugOperations", "");
|
||||
System.setProperty("debugSupportingFiles", "");
|
||||
}
|
||||
|
||||
private void setSystemProperties() {
|
||||
for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
|
||||
System.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static String toAbsolutePathStr(String path) {
|
||||
if (isNotEmpty(path)) {
|
||||
return Paths.get(path).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
private void checkAndSetAdditionalProperty(String property, String propertyKey) {
|
||||
checkAndSetAdditionalProperty(property, property, propertyKey);
|
||||
}
|
||||
|
||||
private void checkAndSetAdditionalProperty(String property, String valueToSet, String propertyKey) {
|
||||
if (isNotEmpty(property)) {
|
||||
additionalProperties.put(propertyKey, valueToSet);
|
||||
}
|
||||
}
|
||||
|
||||
public static CodegenConfigurator fromFile(String configFile) {
|
||||
|
||||
if (isNotEmpty(configFile)) {
|
||||
try {
|
||||
CodegenConfigurator result = Json.mapper().readValue(new File(configFile), CodegenConfigurator.class);
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
LOG.error("Unable to deserialize config file: " + configFile, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -84,12 +84,15 @@ public class XmlExampleGenerator {
|
||||
name = xml.getName();
|
||||
}
|
||||
}
|
||||
for (String pName : model.getProperties().keySet()) {
|
||||
Property p = model.getProperties().get(pName);
|
||||
if (p != null && p.getXml() != null && p.getXml().getAttribute() != null && p.getXml().getAttribute()) {
|
||||
attributes.put(pName, p);
|
||||
} else {
|
||||
elements.put(pName, p);
|
||||
// TODO: map objects will not enter this block
|
||||
if(model.getProperties() != null) {
|
||||
for (String pName : model.getProperties().keySet()) {
|
||||
Property p = model.getProperties().get(pName);
|
||||
if (p != null && p.getXml() != null && p.getXml().getAttribute() != null && p.getXml().getAttribute()) {
|
||||
attributes.put(pName, p);
|
||||
} else {
|
||||
elements.put(pName, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(indent(indent)).append(TAG_START);
|
||||
@@ -128,7 +131,7 @@ public class XmlExampleGenerator {
|
||||
ArrayProperty p = (ArrayProperty) property;
|
||||
Property inner = p.getItems();
|
||||
boolean wrapped = false;
|
||||
if (property.getXml() != null && property.getXml().getWrapped()) {
|
||||
if (property.getXml() != null && property.getXml().getWrapped() != null && property.getXml().getWrapped()) {
|
||||
wrapped = true;
|
||||
}
|
||||
if (wrapped) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.base.CaseFormat;
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import com.samskivert.mustache.Template;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenResponse;
|
||||
@@ -80,10 +81,10 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
|
||||
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
additionalProperties.put("configKey", configKey);
|
||||
additionalProperties.put("configKeyPath", configKeyPath);
|
||||
additionalProperties.put("defaultTimeout", defaultTimeoutInMs);
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -58,11 +59,11 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
|
||||
instantiationTypes.put("array", "ArrayList");
|
||||
instantiationTypes.put("map", "HashMap");
|
||||
|
||||
cliOptions.add(new CliOption("invokerPackage", "root package to use for the generated code"));
|
||||
cliOptions.add(new CliOption("groupId", "groupId for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactId", "artifactId for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactVersion", "artifact version for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, "groupId for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, "artifactId for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "artifact version for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
|
||||
cliOptions.add(new CliOption("useAndroidMavenGradlePlugin", "A flag to toggle android-maven gradle plugin. Default is true."));
|
||||
}
|
||||
|
||||
@@ -187,36 +188,36 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey("invokerPackage")) {
|
||||
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||
} else {
|
||||
//not set, use default to be passed to template
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("groupId")) {
|
||||
this.setGroupId((String) additionalProperties.get("groupId"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.GROUP_ID)) {
|
||||
this.setGroupId((String) additionalProperties.get(CodegenConstants.GROUP_ID));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("artifactId")) {
|
||||
this.setArtifactId((String) additionalProperties.get("artifactId"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_ID)) {
|
||||
this.setArtifactId((String) additionalProperties.get(CodegenConstants.ARTIFACT_ID));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("artifactVersion")) {
|
||||
this.setArtifactVersion((String) additionalProperties.get("artifactVersion"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
|
||||
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("useAndroidMavenGradlePlugin")) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -52,10 +53,10 @@ public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
additionalProperties.put("asyncHttpClient", asyncHttpClient);
|
||||
additionalProperties.put("authScheme", authScheme);
|
||||
additionalProperties.put("authPreemptive", authPreemptive);
|
||||
|
||||
@@ -104,13 +104,13 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
}
|
||||
|
||||
additionalProperties.put("clientPackage", clientPackage);
|
||||
|
||||
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache",
|
||||
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "Configuration.cs"));
|
||||
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "Configuration.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache",
|
||||
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
|
||||
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "ApiClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiException.mustache",
|
||||
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiException.cs"));
|
||||
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "ApiException.cs"));
|
||||
supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll"));
|
||||
supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll"));
|
||||
supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat"));
|
||||
@@ -137,17 +137,17 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar);
|
||||
return outputFolder + File.separator + sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar);
|
||||
return outputFolder + File.separator + sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
@@ -217,7 +217,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||
return getSwaggerType(p) + "<string, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return camelize(operationId);
|
||||
return camelize(sanitizeName(operationId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
public enum CodeGenStatus {
|
||||
UNRUN, SUCCESSFUL, FAILED
|
||||
}
|
||||
@@ -108,11 +108,11 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache",
|
||||
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "Configuration.cs"));
|
||||
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "Configuration.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache",
|
||||
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
|
||||
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "ApiClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiException.mustache",
|
||||
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiException.cs"));
|
||||
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "ApiException.cs"));
|
||||
supportingFiles.add(new SupportingFile("packages.config.mustache", "vendor", "packages.config"));
|
||||
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "compile-mono.sh"));
|
||||
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
|
||||
@@ -142,11 +142,11 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar);
|
||||
return outputFolder + File.separator + sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar);
|
||||
return outputFolder + File.separator + sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected boolean browserClient = true;
|
||||
protected String pubName = "swagger";
|
||||
protected String pubVersion = "1.0.0";
|
||||
protected String pubDescription = "Swagger API client";
|
||||
protected String sourceFolder = "";
|
||||
|
||||
public DartClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/dart";
|
||||
modelTemplateFiles.put("model.mustache", ".dart");
|
||||
apiTemplateFiles.put("api.mustache", ".dart");
|
||||
templateDir = "dart";
|
||||
apiPackage = "lib.api";
|
||||
modelPackage = "lib.model";
|
||||
|
||||
reservedWords = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"abstract", "as", "assert", "async", "async*", "await",
|
||||
"break", "case", "catch", "class", "const", "continue",
|
||||
"default", "deferred", "do", "dynamic", "else", "enum",
|
||||
"export", "external", "extends", "factory", "false", "final",
|
||||
"finally", "for", "get", "if", "implements", "import", "in",
|
||||
"is", "library", "new", "null", "operator", "part", "rethrow",
|
||||
"return", "set", "static", "super", "switch", "sync*", "this",
|
||||
"throw", "true", "try", "typedef", "var", "void", "while",
|
||||
"with", "yield", "yield*" )
|
||||
);
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"String",
|
||||
"bool",
|
||||
"num",
|
||||
"int",
|
||||
"float")
|
||||
);
|
||||
instantiationTypes.put("array", "List");
|
||||
instantiationTypes.put("map", "Map");
|
||||
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("Array", "List");
|
||||
typeMapping.put("array", "List");
|
||||
typeMapping.put("List", "List");
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("string", "String");
|
||||
typeMapping.put("int", "int");
|
||||
typeMapping.put("float", "num");
|
||||
typeMapping.put("long", "int");
|
||||
typeMapping.put("short", "int");
|
||||
typeMapping.put("char", "String");
|
||||
typeMapping.put("double", "num");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("Date", "DateTime");
|
||||
typeMapping.put("date", "DateTime");
|
||||
typeMapping.put("File", "MultipartFile");
|
||||
|
||||
cliOptions.add(new CliOption("browserClient", "Is the client browser based"));
|
||||
cliOptions.add(new CliOption("pubName", "Name in generated pubspec"));
|
||||
cliOptions.add(new CliOption("pubVersion", "Version in generated pubspec"));
|
||||
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "dart";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a Dart client library.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey("browserClient")) {
|
||||
this.setBrowserClient(Boolean.parseBoolean((String) additionalProperties.get("browserClient")));
|
||||
additionalProperties.put("browserClient", browserClient);
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("browserClient", browserClient);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("pubName")) {
|
||||
this.setPubName((String) additionalProperties.get("pubName"));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("pubName", pubName);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("pubVersion")) {
|
||||
this.setPubVersion((String) additionalProperties.get("pubVersion"));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("pubVersion", pubVersion);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("pubDescription")) {
|
||||
this.setPubDescription((String) additionalProperties.get("pubDescription"));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("pubDescription", pubDescription);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
|
||||
}
|
||||
|
||||
final String libFolder = sourceFolder + File.separator + "lib";
|
||||
supportingFiles.add(new SupportingFile("pubspec.mustache", "", "pubspec.yaml"));
|
||||
supportingFiles.add(new SupportingFile("api_client.mustache", libFolder, "api_client.dart"));
|
||||
supportingFiles.add(new SupportingFile("apiException.mustache", libFolder, "api_exception.dart"));
|
||||
supportingFiles.add(new SupportingFile("apilib.mustache", libFolder, "api.dart"));
|
||||
|
||||
final String authFolder = sourceFolder + File.separator + "lib" + File.separator + "auth";
|
||||
supportingFiles.add(new SupportingFile("auth/authentication.mustache", authFolder, "authentication.dart"));
|
||||
supportingFiles.add(new SupportingFile("auth/http_basic_auth.mustache", authFolder, "http_basic_auth.dart"));
|
||||
supportingFiles.add(new SupportingFile("auth/api_key_auth.mustache", authFolder, "api_key_auth.dart"));
|
||||
supportingFiles.add(new SupportingFile("auth/oauth.mustache", authFolder, "oauth.dart"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// camelize (lower first character) the variable name
|
||||
// pet_id => petId
|
||||
name = camelize(name, true);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// should be the same as variable name
|
||||
return toVarName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
}
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return underscore(toModelName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return underscore(toApiName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDefaultValue(Property p) {
|
||||
if (p instanceof MapProperty) {
|
||||
MapProperty ap = (MapProperty) p;
|
||||
String inner = getSwaggerType(ap.getAdditionalProperties());
|
||||
return "{}";
|
||||
} else if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
String inner = getSwaggerType(ap.getItems());
|
||||
return "[]";
|
||||
}
|
||||
|
||||
return super.toDefaultValue(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
type = swaggerType;
|
||||
}
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(operationId)) {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return camelize(operationId, true);
|
||||
}
|
||||
|
||||
public void setBrowserClient(boolean browserClient) {
|
||||
this.browserClient = browserClient;
|
||||
}
|
||||
|
||||
public void setPubName(String pubName) {
|
||||
this.pubName = pubName;
|
||||
}
|
||||
|
||||
public void setPubVersion(String pubVersion) {
|
||||
this.pubVersion = pubVersion;
|
||||
}
|
||||
|
||||
public void setPubDescription(String pubDescription) {
|
||||
this.pubDescription = pubDescription;
|
||||
}
|
||||
|
||||
public void setSourceFolder(String sourceFolder) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
}
|
||||
@@ -2,34 +2,27 @@ package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.properties.AbstractNumericProperty;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.BooleanProperty;
|
||||
import io.swagger.models.properties.DateProperty;
|
||||
import io.swagger.models.properties.DateTimeProperty;
|
||||
import io.swagger.models.properties.DecimalProperty;
|
||||
import io.swagger.models.properties.DoubleProperty;
|
||||
import io.swagger.models.properties.FloatProperty;
|
||||
import io.swagger.models.properties.IntegerProperty;
|
||||
import io.swagger.models.properties.LongProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.properties.PropertyBuilder;
|
||||
import io.swagger.models.properties.RefProperty;
|
||||
import io.swagger.models.properties.StringProperty;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String packageName = "io.swagger";
|
||||
@@ -82,8 +75,8 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
cliOptions.clear();
|
||||
cliOptions.add(new CliOption("packageName", "flash package name (convention: package.name), default: io.swagger"));
|
||||
cliOptions.add(new CliOption("packageVersion", "flash package version, default: 1.0.0"));
|
||||
cliOptions.add(new CliOption("invokerPackage", "root package for generated code"));
|
||||
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code. e.g. src/main/flex"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code. e.g. src/main/flex"));
|
||||
|
||||
}
|
||||
|
||||
@@ -91,15 +84,15 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey("invokerPackage")) {
|
||||
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||
} else {
|
||||
//not set, use default to be passed to template
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("packageName")) {
|
||||
|
||||
@@ -3,19 +3,18 @@ package io.swagger.codegen.languages;
|
||||
import com.google.common.base.Strings;
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenModel;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.ComposedModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.ModelImpl;
|
||||
import io.swagger.models.RefModel;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.LongProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.properties.StringProperty;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -27,16 +26,22 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JavaClientCodegen.class);
|
||||
|
||||
protected String invokerPackage = "io.swagger.client";
|
||||
protected String groupId = "io.swagger";
|
||||
protected String artifactId = "swagger-java-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String sourceFolder = "src/main/java";
|
||||
protected String localVariablePrefix = "";
|
||||
protected boolean fullJavaUtil = false;
|
||||
protected String javaUtilPrefix = "";
|
||||
protected Boolean serializableModel = false;
|
||||
|
||||
|
||||
public JavaClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/java";
|
||||
@@ -66,33 +71,39 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
"Integer",
|
||||
"Long",
|
||||
"Float",
|
||||
"Object")
|
||||
"Object",
|
||||
"byte[]")
|
||||
);
|
||||
instantiationTypes.put("array", "ArrayList");
|
||||
instantiationTypes.put("map", "HashMap");
|
||||
|
||||
cliOptions.add(new CliOption("invokerPackage", "root package for generated code"));
|
||||
cliOptions.add(new CliOption("groupId", "groupId in generated pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml"));
|
||||
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
|
||||
cliOptions.add(new CliOption("localVariablePrefix", "prefix for generated code members and local variables"));
|
||||
|
||||
cliOptions.add(new CliOption("serializableModel", "boolean - toggle \"implements Serializable\" for generated models"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.LOCAL_VARIABLE_PREFIX, CodegenConstants.LOCAL_VARIABLE_PREFIX_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SERIALIZABLE_MODEL, CodegenConstants.SERIALIZABLE_MODEL_DESC));
|
||||
cliOptions.add(new CliOption("fullJavaUtil", "whether to use fully qualified name for classes under java.util (default to false)"));
|
||||
|
||||
supportedLibraries.put("<default>", "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
|
||||
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.6");
|
||||
supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1");
|
||||
supportedLibraries.put("retrofit", "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)");
|
||||
cliOptions.add(buildLibraryCliOption(supportedLibraries));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "java";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a Java client library.";
|
||||
}
|
||||
@@ -100,90 +111,139 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey("invokerPackage")) {
|
||||
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||
} else {
|
||||
//not set, use default to be passed to template
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("groupId")) {
|
||||
this.setGroupId((String) additionalProperties.get("groupId"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.GROUP_ID)) {
|
||||
this.setGroupId((String) additionalProperties.get(CodegenConstants.GROUP_ID));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("artifactId")) {
|
||||
this.setArtifactId((String) additionalProperties.get("artifactId"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_ID)) {
|
||||
this.setArtifactId((String) additionalProperties.get(CodegenConstants.ARTIFACT_ID));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("artifactVersion")) {
|
||||
this.setArtifactVersion((String) additionalProperties.get("artifactVersion"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
|
||||
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
|
||||
} else {
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||
}
|
||||
|
||||
|
||||
if (additionalProperties.containsKey("localVariablePrefix")) {
|
||||
this.setLocalVariablePrefix((String) additionalProperties.get("localVariablePrefix"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.LOCAL_VARIABLE_PREFIX)) {
|
||||
this.setLocalVariablePrefix((String) additionalProperties.get(CodegenConstants.LOCAL_VARIABLE_PREFIX));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("serializableModel")) {
|
||||
this.setSerializableModel(Boolean.valueOf((String)additionalProperties.get("serializableModel").toString()));
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.SERIALIZABLE_MODEL)) {
|
||||
this.setSerializableModel(Boolean.valueOf((String)additionalProperties.get(CodegenConstants.SERIALIZABLE_MODEL).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.LIBRARY)) {
|
||||
this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY));
|
||||
}
|
||||
|
||||
// need to put back serializableModel (boolean) into additionalProperties as value in additionalProperties is string
|
||||
additionalProperties.put("serializableModel", serializableModel);
|
||||
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel);
|
||||
|
||||
if (additionalProperties.containsKey("fullJavaUtil")) {
|
||||
fullJavaUtil = Boolean.valueOf(additionalProperties.get("fullJavaUtil").toString());
|
||||
}
|
||||
if (fullJavaUtil) {
|
||||
javaUtilPrefix = "java.util.";
|
||||
}
|
||||
additionalProperties.put("fullJavaUtil", fullJavaUtil);
|
||||
additionalProperties.put("javaUtilPrefix", javaUtilPrefix);
|
||||
|
||||
if (fullJavaUtil) {
|
||||
typeMapping.put("array", "java.util.List");
|
||||
typeMapping.put("map", "java.util.Map");
|
||||
typeMapping.put("DateTime", "java.util.Date");
|
||||
typeMapping.remove("List");
|
||||
importMapping.remove("Date");
|
||||
importMapping.remove("Map");
|
||||
importMapping.remove("HashMap");
|
||||
importMapping.remove("Array");
|
||||
importMapping.remove("ArrayList");
|
||||
importMapping.remove("List");
|
||||
importMapping.remove("Set");
|
||||
importMapping.remove("DateTime");
|
||||
instantiationTypes.put("array", "java.util.ArrayList");
|
||||
instantiationTypes.put("map", "java.util.HashMap");
|
||||
}
|
||||
|
||||
this.sanitizeConfig();
|
||||
|
||||
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle"));
|
||||
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||
supportingFiles.add(new SupportingFile("gradle.properties.mustache", "", "gradle.properties"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
|
||||
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
|
||||
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
|
||||
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
|
||||
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
|
||||
supportingFiles.add(new SupportingFile("TypeRef.mustache", invokerFolder, "TypeRef.java"));
|
||||
|
||||
final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator);
|
||||
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
|
||||
|
||||
if (!"retrofit".equals(getLibrary())) {
|
||||
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
|
||||
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
|
||||
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
|
||||
}
|
||||
|
||||
// library-specific files
|
||||
if ("okhttp-gson".equals(getLibrary())) {
|
||||
// the "okhttp-gson" library template requires "ApiCallback.mustache" for async call
|
||||
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
|
||||
// "build.sbt" is for development with SBT
|
||||
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
|
||||
} else if ("retrofit".equals(getLibrary())) {
|
||||
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
|
||||
supportingFiles.add(new SupportingFile("CollectionFormats.mustache", invokerFolder, "CollectionFormats.java"));
|
||||
} else {
|
||||
supportingFiles.add(new SupportingFile("TypeRef.mustache", invokerFolder, "TypeRef.java"));
|
||||
}
|
||||
}
|
||||
|
||||
private void sanitizeConfig() {
|
||||
// Sanitize any config options here. We also have to update the additionalProperties because
|
||||
// Sanitize any config options here. We also have to update the additionalProperties because
|
||||
// the whole additionalProperties object is injected into the main object passed to the mustache layer
|
||||
|
||||
|
||||
this.setApiPackage(sanitizePackageName(apiPackage));
|
||||
if (additionalProperties.containsKey("apiPackage")) {
|
||||
this.additionalProperties.put("apiPackage", apiPackage);
|
||||
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||
this.additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
}
|
||||
|
||||
|
||||
this.setModelPackage(sanitizePackageName(modelPackage));
|
||||
if (additionalProperties.containsKey("modelPackage")) {
|
||||
this.additionalProperties.put("modelPackage", modelPackage);
|
||||
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
|
||||
this.additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
}
|
||||
|
||||
|
||||
this.setInvokerPackage(sanitizePackageName(invokerPackage));
|
||||
if (additionalProperties.containsKey("invokerPackage")) {
|
||||
this.additionalProperties.put("invokerPackage", invokerPackage);
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
this.additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
@@ -194,14 +254,15 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
if("_".equals(name)) {
|
||||
name = "_u";
|
||||
@@ -232,6 +293,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
name = sanitizeName(name);
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
@@ -267,10 +330,28 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public String toDefaultValue(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
final ArrayProperty ap = (ArrayProperty) p;
|
||||
return String.format("new ArrayList<%s>()", getTypeDeclaration(ap.getItems()));
|
||||
final String pattern;
|
||||
if (fullJavaUtil) {
|
||||
pattern = "new java.util.ArrayList<%s>()";
|
||||
} else {
|
||||
pattern = "new ArrayList<%s>()";
|
||||
}
|
||||
return String.format(pattern, getTypeDeclaration(ap.getItems()));
|
||||
} else if (p instanceof MapProperty) {
|
||||
final MapProperty ap = (MapProperty) p;
|
||||
return String.format("new HashMap<String, %s>()", getTypeDeclaration(ap.getAdditionalProperties()));
|
||||
final String pattern;
|
||||
if (fullJavaUtil) {
|
||||
pattern = "new java.util.HashMap<String, %s>()";
|
||||
} else {
|
||||
pattern = "new HashMap<String, %s>()";
|
||||
}
|
||||
return String.format(pattern, getTypeDeclaration(ap.getAdditionalProperties()));
|
||||
} else if (p instanceof LongProperty) {
|
||||
LongProperty dp = (LongProperty) p;
|
||||
if (dp.getDefault() != null) {
|
||||
return dp.getDefault().toString()+"l";
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
return super.toDefaultValue(p);
|
||||
}
|
||||
@@ -281,12 +362,15 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return toModelName(type);
|
||||
if (languageSpecificPrimitives.contains(type) || type.indexOf(".") >= 0) {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
type = swaggerType;
|
||||
}
|
||||
if (null == type) {
|
||||
LOGGER.error("No Type defined for Property " + p);
|
||||
}
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@@ -294,7 +378,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public String toOperationId(String operationId) {
|
||||
// throw exception if method name is empty
|
||||
if (StringUtils.isEmpty(operationId)) {
|
||||
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||
throw new RuntimeException("Empty method/operation name (operationId) not allowed");
|
||||
}
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
@@ -302,7 +386,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return camelize(operationId, true);
|
||||
return camelize(sanitizeName(operationId), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -318,6 +402,96 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
Map<String, Object> allowableValues = var.allowableValues;
|
||||
|
||||
// handle ArrayProperty
|
||||
if (var.items != null) {
|
||||
allowableValues = var.items.allowableValues;
|
||||
}
|
||||
|
||||
if (allowableValues == null) {
|
||||
continue;
|
||||
}
|
||||
List<String> values = (List<String>) allowableValues.get("values");
|
||||
if (values == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// put "enumVars" map into `allowableValues", including `name` and `value`
|
||||
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
|
||||
String commonPrefix = findCommonPrefixOfVars(values);
|
||||
int truncateIdx = commonPrefix.length();
|
||||
for (String value : values) {
|
||||
Map<String, String> enumVar = new HashMap<String, String>();
|
||||
String enumName;
|
||||
if (truncateIdx == 0) {
|
||||
enumName = value;
|
||||
} else {
|
||||
enumName = value.substring(truncateIdx);
|
||||
if ("".equals(enumName)) {
|
||||
enumName = value;
|
||||
}
|
||||
}
|
||||
enumVar.put("name", toEnumVarName(enumName));
|
||||
enumVar.put("value", value);
|
||||
enumVars.add(enumVar);
|
||||
}
|
||||
allowableValues.put("enumVars", enumVars);
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
if("retrofit".equals(getLibrary())) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
if (operations != null) {
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation operation : ops) {
|
||||
if (operation.hasConsumes == Boolean.TRUE) {
|
||||
Map<String, String> firstType = operation.consumes.get(0);
|
||||
if (firstType != null) {
|
||||
if ("multipart/form-data".equals(firstType.get("mediaType"))) {
|
||||
operation.isMultipart = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (operation.returnType == null) {
|
||||
operation.returnType = "Void";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
protected boolean needToImport(String type) {
|
||||
return super.needToImport(type) && type.indexOf(".") < 0;
|
||||
}
|
||||
|
||||
private String findCommonPrefixOfVars(List<String> vars) {
|
||||
String prefix = StringUtils.getCommonPrefix(vars.toArray(new String[vars.size()]));
|
||||
// exclude trailing characters that should be part of a valid variable
|
||||
// e.g. ["status-on", "status-off"] => "status-" (not "status-o")
|
||||
return prefix.replaceAll("[a-zA-Z0-9]+\\z", "");
|
||||
}
|
||||
|
||||
private String toEnumVarName(String value) {
|
||||
String var = value.replaceAll("\\W+", "_").toUpperCase();
|
||||
if (var.matches("\\d.*")) {
|
||||
return "_" + var;
|
||||
} else {
|
||||
return var;
|
||||
}
|
||||
}
|
||||
|
||||
private CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
|
||||
// This generator uses inline classes to define enums, which breaks when
|
||||
// dealing with models that have subTypes. To clean this up, we will analyze
|
||||
@@ -333,6 +507,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
List<CodegenProperty> codegenProperties = codegenModel.vars;
|
||||
|
||||
// Iterate over all of the parent model properties
|
||||
boolean removedChildEnum = false;
|
||||
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
|
||||
// Look for enums
|
||||
if (parentModelCodegenPropery.isEnum) {
|
||||
@@ -345,12 +520,21 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
// We found an enum in the child class that is
|
||||
// a duplicate of the one in the parent, so remove it.
|
||||
iterator.remove();
|
||||
removedChildEnum = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
codegenModel.vars = codegenProperties;
|
||||
|
||||
if(removedChildEnum) {
|
||||
// If we removed an entry from this model's vars, we need to ensure hasMore is updated
|
||||
int count = 0, numVars = codegenProperties.size();
|
||||
for(CodegenProperty codegenProperty : codegenProperties) {
|
||||
count += 1;
|
||||
codegenProperty.hasMore = (count < numVars) ? true : null;
|
||||
}
|
||||
codegenModel.vars = codegenProperties;
|
||||
}
|
||||
}
|
||||
|
||||
return codegenModel;
|
||||
@@ -380,6 +564,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
this.localVariablePrefix = localVariablePrefix;
|
||||
}
|
||||
|
||||
|
||||
public Boolean getSerializableModel() {
|
||||
return serializableModel;
|
||||
}
|
||||
@@ -387,7 +572,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public void setSerializableModel(Boolean serializableModel) {
|
||||
this.serializableModel = serializableModel;
|
||||
}
|
||||
|
||||
|
||||
private String sanitizePackageName(String packageName) {
|
||||
packageName = packageName.trim();
|
||||
packageName = packageName.replaceAll("[^a-zA-Z0-9_\\.]", "_");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -21,10 +22,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JavaInflectorServerCodegen extends JavaClientCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "io.swagger.handler";
|
||||
protected String groupId = "io.swagger";
|
||||
protected String artifactId = "swagger-inflector-server";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String title = "Swagger Inflector";
|
||||
|
||||
public JavaInflectorServerCodegen() {
|
||||
@@ -34,14 +31,16 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen implements Cod
|
||||
modelTemplateFiles.put("model.mustache", ".java");
|
||||
apiTemplateFiles.put("api.mustache", ".java");
|
||||
templateDir = "JavaInflector";
|
||||
invokerPackage = "io.swagger.handler";
|
||||
artifactId = "swagger-inflector-server";
|
||||
|
||||
apiPackage = System.getProperty("swagger.codegen.inflector.apipackage", "io.swagger.handler");
|
||||
modelPackage = System.getProperty("swagger.codegen.inflector.modelpackage", "io.swagger.model");
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
additionalProperties.put("title", title);
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenResponse;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenResponse;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -18,16 +16,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "io.swagger.api";
|
||||
protected String groupId = "io.swagger";
|
||||
protected String artifactId = "swagger-jaxrs-server";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String title = "Swagger Server";
|
||||
|
||||
public JaxRSServerCodegen() {
|
||||
super.processOpts();
|
||||
|
||||
sourceFolder = "src/gen/java";
|
||||
invokerPackage = "io.swagger.api";
|
||||
artifactId = "swagger-jaxrs-server";
|
||||
|
||||
outputFolder = System.getProperty("swagger.codegen.jaxrs.genfolder", "generated-code/javaJaxRS");
|
||||
modelTemplateFiles.put("model.mustache", ".java");
|
||||
@@ -39,10 +35,10 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
|
||||
apiPackage = System.getProperty("swagger.codegen.jaxrs.apipackage", "io.swagger.api");
|
||||
modelPackage = System.getProperty("swagger.codegen.jaxrs.modelpackage", "io.swagger.model");
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
additionalProperties.put("title", title);
|
||||
|
||||
|
||||
@@ -165,7 +161,7 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
|
||||
if (name.length() == 0) {
|
||||
return "DefaultApi";
|
||||
}
|
||||
name = name.replaceAll("[^a-zA-Z0-9]+", "_");
|
||||
name = sanitizeName(name);
|
||||
return camelize(name) + "Api";
|
||||
}
|
||||
|
||||
|
||||
@@ -207,11 +207,14 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getOperations(Map<String, Object> objs) {
|
||||
private List<Map<String, Object>> getOperations(Map<String, Object> objs) {
|
||||
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
|
||||
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
|
||||
List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
|
||||
Map<String, Object> api = apis.get(0);
|
||||
return (Map<String, Object>) api.get("operations");
|
||||
for (Map<String, Object> api : apis) {
|
||||
result.add((Map<String, Object>) api.get("operations"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> sortOperationsByPath(List<CodegenOperation> ops) {
|
||||
@@ -221,7 +224,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
opsByPath.put(op.path, op);
|
||||
}
|
||||
|
||||
List<Map<String, Object>> opsByPathList = new ArrayList<Map<String, Object>>();
|
||||
List<Map<String, Object>> opsByPathList = new ArrayList<Map<String, Object>>();
|
||||
for (Entry<String, Collection<CodegenOperation>> entry : opsByPath.asMap().entrySet()) {
|
||||
Map<String, Object> opsByPathEntry = new HashMap<String, Object>();
|
||||
opsByPathList.add(opsByPathEntry);
|
||||
@@ -239,16 +242,13 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||
Map<String, Object> operations = getOperations(objs);
|
||||
|
||||
if (operations != null) {
|
||||
for (Map<String, Object> operations : getOperations(objs)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
|
||||
List<Map<String, Object>> opsByPathList = sortOperationsByPath(ops);
|
||||
operations.put("operationsByPath", opsByPathList);
|
||||
}
|
||||
|
||||
return super.postProcessSupportingFileData(objs);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,10 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String podName = "SwaggerClient";
|
||||
protected String podVersion = "1.0.0";
|
||||
protected String classPrefix = "SWG";
|
||||
protected String authorName = "Swagger";
|
||||
protected String authorEmail = "apiteam@swagger.io";
|
||||
protected String license = "MIT";
|
||||
protected String gitRepoURL = "https://github.com/swagger-api/swagger-codegen";
|
||||
|
||||
public ObjcClientCodegen() {
|
||||
super();
|
||||
@@ -112,6 +116,10 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
cliOptions.add(new CliOption("classPrefix", "prefix for generated classes (convention: Abbreviation of pod name e.g. `HN` for `HackerNews`), default: `SWG`"));
|
||||
cliOptions.add(new CliOption("podName", "cocoapods package name (convention: CameCase), default: `SwaggerClient`"));
|
||||
cliOptions.add(new CliOption("podVersion", "cocoapods package version, default: `1.0.0`"));
|
||||
cliOptions.add(new CliOption("authorName", "Name to use in the podspec file, default: `Swagger`"));
|
||||
cliOptions.add(new CliOption("authorEmail", "Email to use in the podspec file, default: `apiteam@swagger.io`"));
|
||||
cliOptions.add(new CliOption("gitRepoURL", "URL for the git repo where this podspec should point to, default: `https://github.com/swagger-api/swagger-codegen`"));
|
||||
cliOptions.add(new CliOption("license", "License to use in the podspec file, default: `MIT`"));
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
@@ -141,10 +149,30 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
if (additionalProperties.containsKey("classPrefix")) {
|
||||
setClassPrefix((String) additionalProperties.get("classPrefix"));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("authorName")) {
|
||||
setAuthorName((String) additionalProperties.get("authorName"));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("authorEmail")) {
|
||||
setAuthorEmail((String) additionalProperties.get("authorEmail"));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("gitRepoURL")) {
|
||||
setGitRepoURL((String) additionalProperties.get("gitRepoURL"));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("license")) {
|
||||
setLicense((String) additionalProperties.get("license"));
|
||||
}
|
||||
|
||||
additionalProperties.put("podName", podName);
|
||||
additionalProperties.put("podVersion", podVersion);
|
||||
additionalProperties.put("classPrefix", classPrefix);
|
||||
additionalProperties.put("authorName", authorName);
|
||||
additionalProperties.put("authorEmail", authorEmail);
|
||||
additionalProperties.put("gitRepoURL", gitRepoURL);
|
||||
additionalProperties.put("license", license);
|
||||
|
||||
String swaggerFolder = podName;
|
||||
|
||||
@@ -328,9 +356,8 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace non-word characters to `_`
|
||||
// e.g. `created-at` to `created_at`
|
||||
name = name.replaceAll("[^a-zA-Z0-9_]", "_");
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
// if it's all upper case, do noting
|
||||
if (name.matches("^[A-Z_]$")) {
|
||||
@@ -371,7 +398,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return camelize(operationId, true);
|
||||
return camelize(sanitizeName(operationId), true);
|
||||
}
|
||||
|
||||
public void setClassPrefix(String classPrefix) {
|
||||
@@ -385,4 +412,20 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public void setPodVersion(String podVersion) {
|
||||
this.podVersion = podVersion;
|
||||
}
|
||||
|
||||
public void setAuthorEmail(String authorEmail) {
|
||||
this.authorEmail = authorEmail;
|
||||
}
|
||||
|
||||
public void setAuthorName(String authorName) {
|
||||
this.authorName = authorName;
|
||||
}
|
||||
|
||||
public void setGitRepoURL(String gitRepoURL) {
|
||||
this.gitRepoURL = gitRepoURL;
|
||||
}
|
||||
|
||||
public void setLicense(String license) {
|
||||
this.license = license;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -24,6 +25,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String packagePath = "SwaggerClient-php";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String srcBasePath = "lib";
|
||||
protected String variableNamingConvention= "snake_case";
|
||||
|
||||
public PhpClientCodegen() {
|
||||
super();
|
||||
@@ -83,13 +85,14 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
typeMapping.put("list", "array");
|
||||
typeMapping.put("object", "object");
|
||||
typeMapping.put("DateTime", "\\DateTime");
|
||||
|
||||
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all classes. e.g. Yay\\Pets"));
|
||||
|
||||
cliOptions.add(new CliOption("variableNamingConvention", "naming convention of variable name, e.g. camelCase. Default: snake_case"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay\\Pets"));
|
||||
cliOptions.add(new CliOption("packagePath", "The main package name for classes. e.g. GeneratedPetstore"));
|
||||
cliOptions.add(new CliOption("srcBasePath", "The directory under packagePath to serve as source root."));
|
||||
cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets"));
|
||||
cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client"));
|
||||
cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field. e.g. 1.2.3"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "The version to use in the composer package version field. e.g. 1.2.3"));
|
||||
}
|
||||
|
||||
public String getPackagePath() {
|
||||
@@ -153,22 +156,22 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
additionalProperties.put("srcBasePath", srcBasePath);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("invokerPackage")) {
|
||||
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||
} else {
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("modelPackage")) {
|
||||
this.setModelPackage((String) additionalProperties.get("modelPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
|
||||
this.setModelPackage((String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE));
|
||||
} else {
|
||||
additionalProperties.put("modelPackage", modelPackage);
|
||||
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("apiPackage")) {
|
||||
this.setApiPackage((String) additionalProperties.get("apiPackage"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||
this.setApiPackage((String) additionalProperties.get(CodegenConstants.API_PACKAGE));
|
||||
} else {
|
||||
additionalProperties.put("apiPackage", apiPackage);
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("composerProjectName")) {
|
||||
@@ -183,10 +186,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
additionalProperties.put("composerVendorName", composerVendorName);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey("artifactVersion")) {
|
||||
this.setArtifactVersion((String) additionalProperties.get("artifactVersion"));
|
||||
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
|
||||
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
|
||||
} else {
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
}
|
||||
|
||||
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
|
||||
@@ -279,6 +282,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
this.srcBasePath = srcBasePath;
|
||||
}
|
||||
|
||||
public void setParameterNamingConvention(String variableNamingConvention) {
|
||||
this.variableNamingConvention = variableNamingConvention;
|
||||
}
|
||||
|
||||
private void setComposerVendorName(String composerVendorName) {
|
||||
this.composerVendorName = composerVendorName;
|
||||
}
|
||||
@@ -289,9 +296,22 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// return the name in underscore style
|
||||
// PhoneNumber => phone_number
|
||||
name = underscore(name);
|
||||
if (additionalProperties.containsKey("variableNamingConvention")) {
|
||||
this.setParameterNamingConvention((String) additionalProperties.get("variableNamingConvention"));
|
||||
}
|
||||
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
if ("camelCase".equals(variableNamingConvention)) {
|
||||
// return the name in camelCase style
|
||||
// phone_number => phoneNumber
|
||||
name = camelize(name, true);
|
||||
} else { // default to snake case
|
||||
// return the name in underscore style
|
||||
// PhoneNumber => phone_number
|
||||
name = underscore(name);
|
||||
}
|
||||
|
||||
// parameter name starting with number won't compile
|
||||
// need to escape it by appending _ at the beginning
|
||||
@@ -310,6 +330,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// Note: backslash ("\\") is allowed for e.g. "\\DateTime"
|
||||
name = name.replaceAll("[^\\w\\\\]+", "_");
|
||||
|
||||
// model name cannot use reserved keyword
|
||||
if (reservedWords.contains(name)) {
|
||||
escapeReservedWord(name); // e.g. return => _return
|
||||
@@ -325,4 +348,20 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
// should be the same as the model name
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// throw exception if method name is empty
|
||||
if (StringUtils.isEmpty(operationId)) {
|
||||
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||
}
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(operationId)) {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return camelize(sanitizeName(operationId), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
String module = "client";
|
||||
|
||||
public Python3ClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/python3";
|
||||
modelTemplateFiles.put("model.mustache", ".py");
|
||||
apiTemplateFiles.put("api.mustache", ".py");
|
||||
templateDir = "python3";
|
||||
|
||||
apiPackage = module;
|
||||
modelPackage = module + ".models";
|
||||
|
||||
languageSpecificPrimitives.clear();
|
||||
languageSpecificPrimitives.add("int");
|
||||
languageSpecificPrimitives.add("float");
|
||||
//languageSpecificPrimitives.add("long");
|
||||
languageSpecificPrimitives.add("list");
|
||||
languageSpecificPrimitives.add("bool");
|
||||
languageSpecificPrimitives.add("str");
|
||||
languageSpecificPrimitives.add("datetime");
|
||||
languageSpecificPrimitives.add("date");
|
||||
|
||||
typeMapping.clear();
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("long", "int");
|
||||
typeMapping.put("double", "float");
|
||||
typeMapping.put("array", "list");
|
||||
typeMapping.put("map", "map");
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("string", "str");
|
||||
typeMapping.put("date", "date");
|
||||
typeMapping.put("DateTime", "datetime");
|
||||
|
||||
// from https://docs.python.org/release/2.5.4/ref/keywords.html
|
||||
reservedWords = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"and", "del", "from", "not", "while", "as", "elif", "global", "or", "with",
|
||||
"assert", "else", "if", "pass", "yield", "break", "except", "import",
|
||||
"print", "class", "exec", "in", "raise", "continue", "finally", "is",
|
||||
"return", "def", "for", "lambda", "try"));
|
||||
|
||||
//supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("swagger.mustache", module, "swagger.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__.mustache", module, "__init__.py"));
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "python3";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a Python3 client library.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "(String, " + getTypeDeclaration(inner) + ")";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
type = swaggerType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public String toDefaultValue(Property p) {
|
||||
// TODO: Support Python def value
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
|
||||
// if it's all uppper case, convert to lower case
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
name = name.toLowerCase();
|
||||
}
|
||||
|
||||
// camelize (lower first character) the variable name
|
||||
// petId => pet_id
|
||||
name = underscore(name);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// should be the same as variable name
|
||||
return toVarName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
}
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
}
|
||||
|
||||
// underscore the model file name
|
||||
// PhoneNumber.rb => phone_number.rb
|
||||
return underscore(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
|
||||
// e.g. PhoneNumberApi.rb => phone_number_api.rb
|
||||
return underscore(name) + "_api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if (name.length() == 0) {
|
||||
return "DefaultApi";
|
||||
}
|
||||
// e.g. phone_number_api => PhoneNumberApi
|
||||
return camelize(name) + "Api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiVarName(String name) {
|
||||
if (name.length() == 0) {
|
||||
return "default_api";
|
||||
}
|
||||
return underscore(name) + "_api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// throw exception if method name is empty
|
||||
if (StringUtils.isEmpty(operationId)) {
|
||||
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||
}
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(operationId)) {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return underscore(operationId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,6 +41,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
typeMapping.clear();
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("number", "float");
|
||||
typeMapping.put("long", "int");
|
||||
typeMapping.put("double", "float");
|
||||
typeMapping.put("array", "list");
|
||||
@@ -61,7 +62,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
"return", "def", "for", "lambda", "try"));
|
||||
|
||||
cliOptions.clear();
|
||||
cliOptions.add(new CliOption("packageName", "python package name (convension: under_score), default: swagger_client"));
|
||||
cliOptions.add(new CliOption("packageName", "python package name (convention: snake_case), default: swagger_client"));
|
||||
cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0"));
|
||||
}
|
||||
|
||||
@@ -167,8 +168,8 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
// if it's all uppper case, convert to lower case
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
@@ -177,7 +178,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
// underscore the variable name
|
||||
// petId => pet_id
|
||||
name = underscore(dropDots(name));
|
||||
name = underscore(name);
|
||||
|
||||
// remove leading underscore
|
||||
name = name.replaceAll("^_*", "");
|
||||
@@ -198,6 +199,8 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
name = sanitizeName(name);
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
@@ -258,7 +261,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return underscore(operationId);
|
||||
return underscore(sanitizeName(operationId));
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
@@ -272,12 +275,10 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
/**
|
||||
* Generate Python package name from String `packageName`
|
||||
*
|
||||
* (PEP 0008) Python packages should also have short, all-lowercase names,
|
||||
* (PEP 0008) Python packages should also have short, all-lowercase names,
|
||||
* although the use of underscores is discouraged.
|
||||
*/
|
||||
public String generatePackageName(String packageName) {
|
||||
return underscore(packageName.replaceAll("[^\\w]+", ""));
|
||||
return underscore(packageName.replaceAll("[^\\w]+", ""));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "io.swagger.client";
|
||||
protected String groupId = "io.swagger";
|
||||
protected String artifactId = "swagger-java-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String sourceFolder = "src/main/java";
|
||||
|
||||
public RetrofitClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/java";
|
||||
modelTemplateFiles.put("model.mustache", ".java");
|
||||
apiTemplateFiles.put("api.mustache", ".java");
|
||||
templateDir = "retrofit";
|
||||
apiPackage = "io.swagger.client.api";
|
||||
modelPackage = "io.swagger.client.model";
|
||||
|
||||
reservedWords = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"abstract", "continue", "for", "new", "switch", "assert",
|
||||
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
|
||||
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
|
||||
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
|
||||
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
|
||||
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
|
||||
"native", "super", "while")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
supportingFiles.add(new SupportingFile("service.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ServiceGenerator.java"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"String",
|
||||
"boolean",
|
||||
"Boolean",
|
||||
"Double",
|
||||
"Integer",
|
||||
"Long",
|
||||
"Float",
|
||||
"Object")
|
||||
);
|
||||
instantiationTypes.put("array", "ArrayList");
|
||||
instantiationTypes.put("map", "HashMap");
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "retrofit";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a Retrofit client library.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// camelize (lower first character) the variable name
|
||||
// pet_id => petId
|
||||
name = camelize(name, true);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// should be the same as variable name
|
||||
return toVarName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
}
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
// should be the same as the model name
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return toModelName(type);
|
||||
}
|
||||
} else {
|
||||
type = swaggerType;
|
||||
}
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// throw exception if method name is empty
|
||||
if (StringUtils.isEmpty(operationId)) {
|
||||
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||
}
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(operationId)) {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return camelize(operationId, true);
|
||||
}
|
||||
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
if (operations != null) {
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation operation : ops) {
|
||||
if (operation.hasConsumes == Boolean.TRUE) {
|
||||
Map<String, String> firstType = operation.consumes.get(0);
|
||||
if (firstType != null) {
|
||||
if ("multipart/form-data".equals(firstType.get("mediaType"))) {
|
||||
operation.isMultipart = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (operation.returnType == null) {
|
||||
operation.returnType = "Void";
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
}
|
||||
@@ -107,17 +107,14 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
setModelPackage("models");
|
||||
setApiPackage("api");
|
||||
|
||||
supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec"));
|
||||
supportingFiles.add(new SupportingFile("swagger_client.mustache", libFolder, gemName + ".rb"));
|
||||
String baseFolder = libFolder + File.separator + gemName;
|
||||
supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb"));
|
||||
String swaggerFolder = baseFolder + File.separator + "swagger";
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separator + "request.mustache", swaggerFolder, "request.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separator + "response.mustache", swaggerFolder, "response.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separator + "api_error.mustache", swaggerFolder, "api_error.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separator + "version.mustache", swaggerFolder, "version.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separator + "configuration.mustache", swaggerFolder, "configuration.rb"));
|
||||
String modelFolder = baseFolder + File.separator + modelPackage.replace("/", File.separator);
|
||||
supportingFiles.add(new SupportingFile("gemspec.mustache", "", gemName + ".gemspec"));
|
||||
supportingFiles.add(new SupportingFile("gem.mustache", libFolder, gemName + ".rb"));
|
||||
String gemFolder = libFolder + File.separator + gemName;
|
||||
supportingFiles.add(new SupportingFile("api_client.mustache", gemFolder, "api_client.rb"));
|
||||
supportingFiles.add(new SupportingFile("api_error.mustache", gemFolder, "api_error.rb"));
|
||||
supportingFiles.add(new SupportingFile("configuration.mustache", gemFolder, "configuration.rb"));
|
||||
supportingFiles.add(new SupportingFile("version.mustache", gemFolder, "version.rb"));
|
||||
String modelFolder = gemFolder + File.separator + modelPackage.replace("/", File.separator);
|
||||
supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb"));
|
||||
}
|
||||
|
||||
@@ -199,8 +196,8 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
// if it's all uppper case, convert to lower case
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
@@ -227,6 +224,8 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
name = sanitizeName(name);
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (reservedWords.contains(name)) {
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
@@ -279,7 +278,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
}
|
||||
|
||||
return underscore(operationId);
|
||||
return underscore(sanitizeName(operationId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -54,10 +55,10 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
additionalProperties.put("asyncHttpClient", asyncHttpClient);
|
||||
additionalProperties.put("authScheme", authScheme);
|
||||
additionalProperties.put("authPreemptive", authPreemptive);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
@@ -73,10 +74,10 @@ public class ScalatraServerCodegen extends DefaultCodegen implements CodegenConf
|
||||
additionalProperties.put("infoEmail", "apiteam@swagger.io");
|
||||
additionalProperties.put("licenseInfo", "All rights reserved");
|
||||
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("build.sbt", "", "build.sbt"));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -41,10 +42,10 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
"__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
|
||||
// ref: http://php.net/manual/en/language.types.intro.php
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
|
||||
@@ -76,7 +76,7 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
return CodegenType.SERVER;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
||||
@@ -12,15 +12,10 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class SpringMVCServerCodegen extends JavaClientCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "io.swagger.api";
|
||||
protected String groupId = "io.swagger";
|
||||
protected String artifactId = "swagger-spring-mvc-server";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String sourceFolder = "src/main/java";
|
||||
protected String title = "Petstore Server";
|
||||
|
||||
protected String configPackage = "";
|
||||
|
||||
public SpringMVCServerCodegen() {
|
||||
@@ -32,14 +27,15 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
|
||||
apiPackage = "io.swagger.api";
|
||||
modelPackage = "io.swagger.model";
|
||||
configPackage = "io.swagger.configuration";
|
||||
invokerPackage = "io.swagger.api";
|
||||
artifactId = "swagger-spring-mvc-server";
|
||||
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
additionalProperties.put("title", title);
|
||||
additionalProperties.put("apiPackage", apiPackage);
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
additionalProperties.put("configPackage", configPackage);
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
@@ -175,8 +171,28 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if (name.length() == 0) {
|
||||
return "DefaultApi";
|
||||
}
|
||||
name = sanitizeName(name);
|
||||
return camelize(name) + "Api";
|
||||
}
|
||||
|
||||
public void setConfigPackage(String configPackage) {
|
||||
this.configPackage = configPackage;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
// remove the import of "Object" to avoid compilation error
|
||||
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
|
||||
Iterator<Map<String, String>> iterator = imports.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String _import = iterator.next().get("import");
|
||||
if (_import.endsWith(".Object")) iterator.remove();
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
@@ -21,10 +22,10 @@ public class StaticDocCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
apiTemplateFiles.put("operation.mustache", ".html");
|
||||
templateDir = "swagger-static";
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
|
||||
supportingFiles.add(new SupportingFile("main.mustache", "", "main.js"));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenOperation;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
@@ -37,10 +38,10 @@ public class StaticHtmlGenerator extends DefaultCodegen implements CodegenConfig
|
||||
additionalProperties.put("infoEmail", "hello@helloreverb.com");
|
||||
additionalProperties.put("licenseInfo", "All rights reserved");
|
||||
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("index.mustache", "", "index.html"));
|
||||
reservedWords = new HashSet<String>();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.swagger.codegen.*;
|
||||
import io.swagger.models.Swagger;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.Operation;
|
||||
import io.swagger.models.parameters.HeaderParameter;
|
||||
@@ -13,6 +15,7 @@ import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
@@ -234,7 +237,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
List<String> values = (List<String>) codegenProperty.allowableValues.get("values");
|
||||
for (String value : values) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("enum", StringUtils.capitalize(value));
|
||||
map.put("enum", toSwiftyEnumName(value));
|
||||
map.put("raw", value);
|
||||
swiftEnums.add(map);
|
||||
}
|
||||
@@ -248,6 +251,16 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return codegenProperty;
|
||||
}
|
||||
|
||||
public String toSwiftyEnumName(String value) {
|
||||
// Prevent from breaking properly cased identifier
|
||||
if (value.matches("[A-Z][a-z0-9]+[a-zA-Z0-9]*")) {
|
||||
return value;
|
||||
}
|
||||
char[] separators = {'-', '_', ' '};
|
||||
return WordUtils.capitalizeFully(StringUtils.lowerCase(value), separators).replaceAll("[-_ ]", "");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if(name.length() == 0)
|
||||
@@ -256,7 +269,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
|
||||
path = normalizePath(path);
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
|
||||
@@ -266,7 +279,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
}));
|
||||
operation.setParameters(parameters);
|
||||
return super.fromOperation(path, httpMethod, operation, definitions);
|
||||
return super.fromOperation(path, httpMethod, operation, definitions, swagger);
|
||||
}
|
||||
|
||||
private static String normalizePath(String path) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
|
||||
@@ -12,7 +11,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a TypeScript AngurlarJS client library.";
|
||||
return "Generates a TypeScript AngularJS client library.";
|
||||
}
|
||||
|
||||
public TypeScriptAngularClientCodegen() {
|
||||
@@ -25,4 +24,4 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
modelPackage = "API.Client";
|
||||
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@ repositories {
|
||||
dependencies {
|
||||
groovy "org.codehaus.groovy:groovy-all:2.0.5"
|
||||
compile 'org.codehaus.groovy.modules.http-builder:http-builder:0.6'
|
||||
|
||||
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) { gradleVersion = '1.6' }
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.net.URLEncoder;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.DataInputStream;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -48,6 +49,9 @@ public class ApiClient {
|
||||
|
||||
private Map<String, Authentication> authentications;
|
||||
|
||||
private int statusCode;
|
||||
private Map<String, List<String>> responseHeaders;
|
||||
|
||||
private DateFormat dateFormat;
|
||||
|
||||
public ApiClient() {
|
||||
@@ -79,6 +83,20 @@ public class ApiClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status code of the previous request
|
||||
*/
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response headers of the previous request
|
||||
*/
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return responseHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentications (key: authentication name, value: authentication).
|
||||
*/
|
||||
@@ -194,7 +212,7 @@ public class ApiClient {
|
||||
/**
|
||||
* Set the date format used to parse/format date parameters.
|
||||
*/
|
||||
public ApiClient getDateFormat(DateFormat dateFormat) {
|
||||
public ApiClient setDateFormat(DateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
return this;
|
||||
}
|
||||
@@ -367,27 +385,24 @@ public class ApiClient {
|
||||
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return json.deserialize(body, returnType);
|
||||
} else if (returnType.getType().equals(String.class)) {
|
||||
// Expecting string, return the raw response body.
|
||||
return (T) body;
|
||||
} else {
|
||||
throw new ApiException(500, "can not deserialize Content-Type: " + contentType);
|
||||
throw new ApiException(
|
||||
500,
|
||||
"Content type \"" + contentType + "\" is not supported for type: "
|
||||
+ returnType.getType()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke API by sending HTTP request with the given options.
|
||||
*
|
||||
* @param path The sub-path of the HTTP URL
|
||||
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param accept The request's Accept header
|
||||
* @param contentType The request's Content-Type header
|
||||
* @param authNames The authentications to apply
|
||||
* @param returnType The return type into which to deserialize the response
|
||||
* @return The response body in type of string
|
||||
*/
|
||||
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, TypeRef returnType) throws ApiException {
|
||||
private ClientResponse getAPIResponse(String path, String method, List<Pair> queryParams, Object body, byte[] binaryBody, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames) throws ApiException {
|
||||
|
||||
if (body != null && binaryBody != null){
|
||||
throw new ApiException(500, "either body or binaryBody must be null");
|
||||
}
|
||||
|
||||
updateParamsForAuth(authNames, queryParams, headerParams);
|
||||
|
||||
Client client = getClient();
|
||||
@@ -447,7 +462,10 @@ public class ApiClient {
|
||||
if (encodedFormParams != null) {
|
||||
response = builder.type(contentType).post(ClientResponse.class, encodedFormParams);
|
||||
} else if (body == null) {
|
||||
response = builder.post(ClientResponse.class, null);
|
||||
if(binaryBody == null)
|
||||
response = builder.post(ClientResponse.class, null);
|
||||
else
|
||||
response = builder.type(contentType).post(ClientResponse.class, binaryBody);
|
||||
} else if (body instanceof FormDataMultiPart) {
|
||||
response = builder.type(contentType).post(ClientResponse.class, body);
|
||||
} else {
|
||||
@@ -457,7 +475,10 @@ public class ApiClient {
|
||||
if (encodedFormParams != null) {
|
||||
response = builder.type(contentType).put(ClientResponse.class, encodedFormParams);
|
||||
} else if(body == null) {
|
||||
response = builder.put(ClientResponse.class, serialize(body, contentType));
|
||||
if(binaryBody == null)
|
||||
response = builder.put(ClientResponse.class, null);
|
||||
else
|
||||
response = builder.type(contentType).put(ClientResponse.class, binaryBody);
|
||||
} else {
|
||||
response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType));
|
||||
}
|
||||
@@ -465,15 +486,42 @@ public class ApiClient {
|
||||
if (encodedFormParams != null) {
|
||||
response = builder.type(contentType).delete(ClientResponse.class, encodedFormParams);
|
||||
} else if(body == null) {
|
||||
response = builder.delete(ClientResponse.class);
|
||||
if(binaryBody == null)
|
||||
response = builder.delete(ClientResponse.class);
|
||||
else
|
||||
response = builder.type(contentType).delete(ClientResponse.class, binaryBody);
|
||||
} else {
|
||||
response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType));
|
||||
}
|
||||
} else {
|
||||
throw new ApiException(500, "unknown method type " + method);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
if (response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) {
|
||||
/**
|
||||
* Invoke API by sending HTTP request with the given options.
|
||||
*
|
||||
* @param path The sub-path of the HTTP URL
|
||||
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object - if it is not binary, otherwise null
|
||||
* @param binaryBody The request body object - if it is binary, otherwise null
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param accept The request's Accept header
|
||||
* @param contentType The request's Content-Type header
|
||||
* @param authNames The authentications to apply
|
||||
* @return The response body in type of string
|
||||
*/
|
||||
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, byte[] binaryBody, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, TypeRef returnType) throws ApiException {
|
||||
|
||||
ClientResponse response = getAPIResponse(path, method, queryParams, body, binaryBody, headerParams, formParams, accept, contentType, authNames);
|
||||
|
||||
statusCode = response.getStatusInfo().getStatusCode();
|
||||
responseHeaders = response.getHeaders();
|
||||
|
||||
if(response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) {
|
||||
return null;
|
||||
} else if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
|
||||
if (returnType == null)
|
||||
@@ -498,6 +546,58 @@ public class ApiClient {
|
||||
respBody);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Invoke API by sending HTTP request with the given options - return binary result
|
||||
*
|
||||
* @param path The sub-path of the HTTP URL
|
||||
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object - if it is not binary, otherwise null
|
||||
* @param binaryBody The request body object - if it is binary, otherwise null
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param accept The request's Accept header
|
||||
* @param contentType The request's Content-Type header
|
||||
* @param authNames The authentications to apply
|
||||
* @return The response body in type of string
|
||||
*/
|
||||
public byte[] invokeBinaryAPI(String path, String method, List<Pair> queryParams, Object body, byte[] binaryBody, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[]authNames) throws ApiException {
|
||||
|
||||
ClientResponse response = getAPIResponse(path, method, queryParams, body, binaryBody, headerParams, formParams, accept, contentType, authNames);
|
||||
|
||||
if(response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) {
|
||||
return null;
|
||||
}
|
||||
else if(response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
|
||||
if(response.hasEntity()) {
|
||||
DataInputStream stream = new DataInputStream(response.getEntityInputStream());
|
||||
byte[] data = new byte[response.getLength()];
|
||||
try {
|
||||
stream.readFully(data);
|
||||
} catch (IOException ex) {
|
||||
throw new ApiException(500, "Error obtaining binary response data");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
String message = "error";
|
||||
if(response.hasEntity()) {
|
||||
try{
|
||||
message = String.valueOf(response.getEntity(String.class));
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new ApiException(
|
||||
response.getStatusInfo().getStatusCode(),
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update query and header parameters based on authentication settings.
|
||||
|
||||
@@ -12,10 +12,13 @@ public class JSON {
|
||||
|
||||
public JSON() {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
|
||||
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
|
||||
mapper.registerModule(new JodaModule());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the given Java object into JSON string.
|
||||
|
||||
@@ -39,4 +39,13 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given object to string with each line indented by 4 spaces
|
||||
* (except the first line).
|
||||
*/
|
||||
public static String toIndentedString(Object o) {
|
||||
if (o == null) return "null";
|
||||
return o.toString().replace("\n", "\n ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,12 @@ import {{invokerPackage}}.Configuration;
|
||||
import {{invokerPackage}}.Pair;
|
||||
import {{invokerPackage}}.TypeRef;
|
||||
|
||||
import {{modelPackage}}.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.*;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{#operations}}
|
||||
@@ -46,22 +42,22 @@ public class {{classname}} {
|
||||
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
*/
|
||||
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
||||
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{^isBinary}}{{paramName}}{{/isBinary}}{{#isBinary}}null{{/isBinary}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
byte[] {{localVariablePrefix}}postBinaryBody = {{#bodyParam}}{{#isBinary}}{{paramName}}{{/isBinary}}{{^isBinary}}null{{/isBinary}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
{{#allParams}}{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) {
|
||||
throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{nickname}}");
|
||||
}
|
||||
{{/required}}{{/allParams}}
|
||||
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) {
|
||||
throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{nickname}}");
|
||||
}
|
||||
{{/required}}{{/allParams}}
|
||||
// create path and map variables
|
||||
String {{localVariablePrefix}}path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
|
||||
String {{localVariablePrefix}}path = "{{{path}}}".replaceAll("\\{format\\}","json"){{#pathParams}}
|
||||
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
|
||||
|
||||
// query params
|
||||
List<Pair> {{localVariablePrefix}}queryParams = new ArrayList<Pair>();
|
||||
Map<String, String> {{localVariablePrefix}}headerParams = new HashMap<String, String>();
|
||||
Map<String, Object> {{localVariablePrefix}}formParams = new HashMap<String, Object>();
|
||||
{{javaUtilPrefix}}List<Pair> {{localVariablePrefix}}queryParams = new {{javaUtilPrefix}}ArrayList<Pair>();
|
||||
{{javaUtilPrefix}}Map<String, String> {{localVariablePrefix}}headerParams = new {{javaUtilPrefix}}HashMap<String, String>();
|
||||
{{javaUtilPrefix}}Map<String, Object> {{localVariablePrefix}}formParams = new {{javaUtilPrefix}}HashMap<String, Object>();
|
||||
|
||||
{{#queryParams}}
|
||||
{{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
@@ -86,12 +82,23 @@ public class {{classname}} {
|
||||
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
|
||||
|
||||
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
|
||||
{{#isResponseBinary}}
|
||||
byte[] {{localVariablePrefix}}response = null;
|
||||
{{localVariablePrefix}}response = {{localVariablePrefix}}apiClient.invokeBinaryAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams,{{localVariablePrefix}} postBody, {{localVariablePrefix}}postBinaryBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames);
|
||||
return {{localVariablePrefix}}response;
|
||||
{{/isResponseBinary}}
|
||||
|
||||
{{^isResponseBinary}}
|
||||
{{#returnType}}
|
||||
TypeRef {{localVariablePrefix}}returnType = new TypeRef<{{{returnType}}}>() {};
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}postBinaryBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
{{/returnType}}{{^returnType}}
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}postBinaryBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
{{/returnType}}
|
||||
{{/isResponseBinary}}
|
||||
|
||||
|
||||
}
|
||||
{{/operation}}
|
||||
}
|
||||
|
||||
@@ -6,20 +6,45 @@ import java.util.List;
|
||||
{{>generatedAnnotation}}
|
||||
public class ApiException extends Exception {
|
||||
private int code = 0;
|
||||
private String message = null;
|
||||
private Map<String, List<String>> responseHeaders = null;
|
||||
private String responseBody = null;
|
||||
|
||||
public ApiException() {}
|
||||
|
||||
public ApiException(int code, String message) {
|
||||
public ApiException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
public ApiException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody) {
|
||||
super(message, throwable);
|
||||
this.code = code;
|
||||
this.responseHeaders = responseHeaders;
|
||||
this.responseBody = responseBody;
|
||||
}
|
||||
|
||||
public ApiException(String message, int code, Map<String, List<String>> responseHeaders, String responseBody) {
|
||||
this(message, (Throwable) null, code, responseHeaders, responseBody);
|
||||
}
|
||||
|
||||
public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders) {
|
||||
this(message, throwable, code, responseHeaders, null);
|
||||
}
|
||||
|
||||
public ApiException(int code, Map<String, List<String>> responseHeaders, String responseBody) {
|
||||
this((String) null, (Throwable) null, code, responseHeaders, responseBody);
|
||||
}
|
||||
|
||||
public ApiException(int code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this(code, message);
|
||||
this.responseHeaders = responseHeaders;
|
||||
this.responseBody = responseBody;
|
||||
}
|
||||
@@ -28,10 +53,6 @@ public class ApiException extends Exception {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP response headers.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
public enum OAuthFlow {
|
||||
accessCode, implicit, password, application
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
group = '{{groupId}}'
|
||||
version = '{{artifactVersion}}'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.2'
|
||||
classpath 'com.github.dcendents:android-maven-plugin:1.2'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
|
||||
if(hasProperty('target') && target == 'android') {
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def outputFile = output.outputFile
|
||||
if (outputFile != null && outputFile.name.endsWith('.aar')) {
|
||||
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
|
||||
output.outputFile = new File(outputFile.parent, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.libraryVariants.all { variant ->
|
||||
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
|
||||
task.description = "Create jar artifact for ${variant.name}"
|
||||
task.dependsOn variant.javaCompile
|
||||
task.from variant.javaCompile.destinationDir
|
||||
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
|
||||
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
|
||||
artifacts.add('archives', task);
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
pom.artifactId = '{{artifactId}}'
|
||||
}
|
||||
}
|
||||
|
||||
task execute(type:JavaExec) {
|
||||
main = System.getProperty('mainClass')
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.0"
|
||||
jackson_version = "2.4.2"
|
||||
jersey_version = "1.18"
|
||||
jodatime_version = "2.3"
|
||||
junit_version = "4.8.1"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
|
||||
compile "com.sun.jersey:jersey-client:$jersey_version"
|
||||
compile "com.sun.jersey.contribs:jersey-multipart:$jersey_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5"
|
||||
compile "joda-time:joda-time:$jodatime_version"
|
||||
testCompile "junit:junit:$junit_version"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
public enum {{datatypeWithEnum}} {
|
||||
{{#allowableValues}}{{#enumVars}}{{name}}("{{value}}"){{^-last}},
|
||||
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||
|
||||
private String value;
|
||||
|
||||
{{datatypeWithEnum}}(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Uncomment to build for Android
|
||||
#target = android
|
||||
@@ -53,6 +53,9 @@ public class ApiClient {
|
||||
|
||||
private Map<String, Authentication> authentications;
|
||||
|
||||
private int statusCode;
|
||||
private Map<String, List<String>> responseHeaders;
|
||||
|
||||
private DateFormat dateFormat;
|
||||
|
||||
public ApiClient() {
|
||||
@@ -84,6 +87,20 @@ public class ApiClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status code of the previous request
|
||||
*/
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response headers of the previous request
|
||||
*/
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return responseHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentications (key: authentication name, value: authentication).
|
||||
*/
|
||||
@@ -199,7 +216,7 @@ public class ApiClient {
|
||||
/**
|
||||
* Set the date format used to parse/format date parameters.
|
||||
*/
|
||||
public ApiClient getDateFormat(DateFormat dateFormat) {
|
||||
public ApiClient setDateFormat(DateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
return this;
|
||||
}
|
||||
@@ -372,8 +389,15 @@ public class ApiClient {
|
||||
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return json.deserialize(body, returnType);
|
||||
} else if (returnType.getType().equals(String.class)) {
|
||||
// Expecting string, return the raw response body.
|
||||
return (T) body;
|
||||
} else {
|
||||
throw new ApiException(500, "can not deserialize Content-Type: " + contentType);
|
||||
throw new ApiException(
|
||||
500,
|
||||
"Content type \"" + contentType + "\" is not supported for type: "
|
||||
+ returnType.getType()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,7 +436,7 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
Invocation.Builder invocationBuilder = target.request(contentType).accept(accept);
|
||||
Invocation.Builder invocationBuilder = target.request().accept(accept);
|
||||
|
||||
for (String key : headerParams.keySet()) {
|
||||
String value = headerParams.get(key);
|
||||
@@ -484,6 +508,9 @@ public class ApiClient {
|
||||
throw new ApiException(500, "unknown method type " + method);
|
||||
}
|
||||
|
||||
statusCode = response.getStatusInfo().getStatusCode();
|
||||
responseHeaders = buildResponseHeaders(response);
|
||||
|
||||
if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
|
||||
return null;
|
||||
} else if (response.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL)) {
|
||||
@@ -502,23 +529,27 @@ public class ApiClient {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
|
||||
for (String key: response.getHeaders().keySet()) {
|
||||
List<Object> values = response.getHeaders().get(key);
|
||||
List<String> headers = new ArrayList<String>();
|
||||
for (Object o : values) {
|
||||
headers.add(String.valueOf(o));
|
||||
}
|
||||
responseHeaders.put(key, headers);
|
||||
}
|
||||
throw new ApiException(
|
||||
response.getStatus(),
|
||||
message,
|
||||
responseHeaders,
|
||||
buildResponseHeaders(response),
|
||||
respBody);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<String>> buildResponseHeaders(Response response) {
|
||||
Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
|
||||
for (Entry<String, List<Object>> entry: response.getHeaders().entrySet()) {
|
||||
List<Object> values = entry.getValue();
|
||||
List<String> headers = new ArrayList<String>();
|
||||
for (Object o : values) {
|
||||
headers.add(String.valueOf(o));
|
||||
}
|
||||
responseHeaders.put(entry.getKey(), headers);
|
||||
}
|
||||
return responseHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update query and header parameters based on authentication settings.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.ApiClient;
|
||||
import {{invokerPackage}}.Configuration;
|
||||
import {{invokerPackage}}.Pair;
|
||||
import {{invokerPackage}}.TypeRef;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.*;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{#operations}}
|
||||
public class {{classname}} {
|
||||
private ApiClient {{localVariablePrefix}}apiClient;
|
||||
|
||||
public {{classname}}() {
|
||||
this(Configuration.getDefaultApiClient());
|
||||
}
|
||||
|
||||
public {{classname}}(ApiClient apiClient) {
|
||||
this.{{localVariablePrefix}}apiClient = apiClient;
|
||||
}
|
||||
|
||||
public ApiClient getApiClient() {
|
||||
return {{localVariablePrefix}}apiClient;
|
||||
}
|
||||
|
||||
public void setApiClient(ApiClient apiClient) {
|
||||
this.{{localVariablePrefix}}apiClient = apiClient;
|
||||
}
|
||||
|
||||
{{#operation}}
|
||||
/**
|
||||
* {{summary}}
|
||||
* {{notes}}
|
||||
{{#allParams}} * @param {{paramName}} {{description}}
|
||||
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
*/
|
||||
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
||||
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
{{#allParams}}{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) {
|
||||
throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{nickname}}");
|
||||
}
|
||||
{{/required}}{{/allParams}}
|
||||
// create path and map variables
|
||||
String {{localVariablePrefix}}path = "{{{path}}}".replaceAll("\\{format\\}","json"){{#pathParams}}
|
||||
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
|
||||
|
||||
// query params
|
||||
{{javaUtilPrefix}}List<Pair> {{localVariablePrefix}}queryParams = new {{javaUtilPrefix}}ArrayList<Pair>();
|
||||
{{javaUtilPrefix}}Map<String, String> {{localVariablePrefix}}headerParams = new {{javaUtilPrefix}}HashMap<String, String>();
|
||||
{{javaUtilPrefix}}Map<String, Object> {{localVariablePrefix}}formParams = new {{javaUtilPrefix}}HashMap<String, Object>();
|
||||
|
||||
{{#queryParams}}
|
||||
{{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/queryParams}}
|
||||
|
||||
{{#headerParams}}if ({{paramName}} != null)
|
||||
{{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));
|
||||
{{/headerParams}}
|
||||
|
||||
{{#formParams}}if ({{paramName}} != null)
|
||||
{{localVariablePrefix}}formParams.put("{{baseName}}", {{paramName}});
|
||||
{{/formParams}}
|
||||
|
||||
final String[] {{localVariablePrefix}}accepts = {
|
||||
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
|
||||
};
|
||||
final String {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts);
|
||||
|
||||
final String[] {{localVariablePrefix}}contentTypes = {
|
||||
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
|
||||
};
|
||||
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
|
||||
|
||||
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
|
||||
{{#returnType}}
|
||||
TypeRef {{localVariablePrefix}}returnType = new TypeRef<{{{returnType}}}>() {};
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
{{/returnType}}{{^returnType}}
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
{{/returnType}}
|
||||
}
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,107 @@
|
||||
group = '{{groupId}}'
|
||||
version = '{{artifactVersion}}'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.2'
|
||||
classpath 'com.github.dcendents:android-maven-plugin:1.2'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
|
||||
if(hasProperty('target') && target == 'android') {
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def outputFile = output.outputFile
|
||||
if (outputFile != null && outputFile.name.endsWith('.aar')) {
|
||||
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
|
||||
output.outputFile = new File(outputFile.parent, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.libraryVariants.all { variant ->
|
||||
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
|
||||
task.description = "Create jar artifact for ${variant.name}"
|
||||
task.dependsOn variant.javaCompile
|
||||
task.from variant.javaCompile.destinationDir
|
||||
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
|
||||
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
|
||||
artifacts.add('archives', task);
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
pom.artifactId = '{{artifactId}}'
|
||||
}
|
||||
}
|
||||
|
||||
task execute(type:JavaExec) {
|
||||
main = System.getProperty('mainClass')
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
swagger_annotations_version = "1.5.0"
|
||||
jackson_version = "2.4.2"
|
||||
jersey_version = "2.6"
|
||||
jodatime_version = "2.3"
|
||||
junit_version = "4.8.1"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
|
||||
compile "org.glassfish.jersey.core:jersey-client:$jersey_version"
|
||||
compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
|
||||
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5"
|
||||
compile "joda-time:joda-time:$jodatime_version"
|
||||
testCompile "junit:junit:$junit_version"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Callback for asynchronous API call.
|
||||
*
|
||||
* @param <T> The return type
|
||||
*/
|
||||
public interface ApiCallback<T> {
|
||||
/**
|
||||
* This is called when the API call fails.
|
||||
*
|
||||
* @param e The exception causing the failure
|
||||
* @param statusCode Status code of the response if available, otherwise it would be 0
|
||||
* @param responseHeaders Headers of the response if available, otherwise it would be null
|
||||
*/
|
||||
void onFailure(ApiException e, int statusCode, Map<String, List<String>> responseHeaders);
|
||||
|
||||
/**
|
||||
* This is called when the API call succeeded.
|
||||
*
|
||||
* @param result The result deserialized from response
|
||||
* @param statusCode Status code of the response
|
||||
* @param responseHeaders Headers of the response
|
||||
*/
|
||||
void onSuccess(T result, int statusCode, Map<String, List<String>> responseHeaders);
|
||||
}
|
||||
@@ -0,0 +1,960 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.squareup.okhttp.Call;
|
||||
import com.squareup.okhttp.Callback;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.FormEncodingBuilder;
|
||||
import com.squareup.okhttp.MultipartBuilder;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.Headers;
|
||||
import com.squareup.okhttp.internal.http.HttpMethod;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import okio.BufferedSink;
|
||||
import okio.Okio;
|
||||
|
||||
import {{invokerPackage}}.auth.Authentication;
|
||||
import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||
import {{invokerPackage}}.auth.ApiKeyAuth;
|
||||
import {{invokerPackage}}.auth.OAuth;
|
||||
|
||||
public class ApiClient {
|
||||
private String basePath = "{{basePath}}";
|
||||
private boolean lenientOnJson = false;
|
||||
private boolean debugging = false;
|
||||
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
|
||||
private String tempFolderPath = null;
|
||||
|
||||
private Map<String, Authentication> authentications;
|
||||
|
||||
private int statusCode;
|
||||
private Map<String, List<String>> responseHeaders;
|
||||
|
||||
private String dateFormat;
|
||||
private DateFormat dateFormatter;
|
||||
private int dateLength;
|
||||
|
||||
private String datetimeFormat;
|
||||
private DateFormat datetimeFormatter;
|
||||
|
||||
private InputStream sslCaCert;
|
||||
private boolean verifyingSsl;
|
||||
|
||||
private OkHttpClient httpClient;
|
||||
private JSON json;
|
||||
|
||||
public ApiClient() {
|
||||
httpClient = new OkHttpClient();
|
||||
|
||||
verifyingSsl = true;
|
||||
|
||||
json = new JSON(this);
|
||||
|
||||
// Use ISO 8601 format for date and datetime.
|
||||
// See https://en.wikipedia.org/wiki/ISO_8601
|
||||
setDateFormat("yyyy-MM-dd");
|
||||
setDatetimeFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
// Set default User-Agent.
|
||||
setUserAgent("Java-Swagger");
|
||||
|
||||
// Setup authentications (key: authentication name, value: authentication).
|
||||
authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}
|
||||
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
|
||||
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
|
||||
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
}
|
||||
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
public ApiClient setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OkHttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public ApiClient setHttpClient(OkHttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JSON getJSON() {
|
||||
return json;
|
||||
}
|
||||
|
||||
public ApiClient setJSON(JSON json) {
|
||||
this.json = json;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status code of the previous request.
|
||||
* NOTE: Status code of last async response is not recorded here, it is
|
||||
* passed to the callback methods instead.
|
||||
*/
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response headers of the previous request.
|
||||
* NOTE: Headers of last async response is not recorded here, it is passed
|
||||
* to callback methods instead.
|
||||
*/
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return responseHeaders;
|
||||
}
|
||||
|
||||
public boolean isVerifyingSsl() {
|
||||
return verifyingSsl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure whether to verify certificate and hostname when making https requests.
|
||||
* Default to true.
|
||||
* NOTE: Do NOT set to false in production code, otherwise you would face multiple types of cryptographic attacks.
|
||||
*/
|
||||
public ApiClient setVerifyingSsl(boolean verifyingSsl) {
|
||||
this.verifyingSsl = verifyingSsl;
|
||||
applySslSettings();
|
||||
return this;
|
||||
}
|
||||
|
||||
public InputStream getSslCaCert() {
|
||||
return sslCaCert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the CA certificate to be trusted when making https requests.
|
||||
* Use null to reset to default.
|
||||
*/
|
||||
public ApiClient setSslCaCert(InputStream sslCaCert) {
|
||||
this.sslCaCert = sslCaCert;
|
||||
applySslSettings();
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDateFormat() {
|
||||
return dateFormat;
|
||||
}
|
||||
|
||||
public ApiClient setDateFormat(String dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
|
||||
this.dateFormatter = new SimpleDateFormat(dateFormat);
|
||||
// Use UTC as the default time zone.
|
||||
this.dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
this.dateLength = this.dateFormatter.format(new Date()).length();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDatetimeFormat() {
|
||||
return datetimeFormat;
|
||||
}
|
||||
|
||||
public ApiClient setDatetimeFormat(String datetimeFormat) {
|
||||
this.datetimeFormat = datetimeFormat;
|
||||
|
||||
this.datetimeFormatter = new SimpleDateFormat(datetimeFormat);
|
||||
// Note: The datetime formatter uses the system's default time zone.
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given date string into Date object.
|
||||
* The default <code>dateFormat</code> supports these ISO 8601 date formats:
|
||||
* 2015-08-16
|
||||
* 2015-8-16
|
||||
*/
|
||||
public Date parseDate(String str) {
|
||||
if (str == null)
|
||||
return null;
|
||||
try {
|
||||
return dateFormatter.parse(str);
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given date-time string into Date object.
|
||||
* The default <code>datetimeFormat</code> supports these ISO 8601 datetime formats:
|
||||
* 2015-08-16T08:20:05Z
|
||||
* 2015-8-16T8:20:05Z
|
||||
* 2015-08-16T08:20:05+00:00
|
||||
* 2015-08-16T08:20:05+0000
|
||||
* 2015-08-16T08:20:05.376Z
|
||||
* 2015-08-16T08:20:05.376+00:00
|
||||
* 2015-08-16T08:20:05.376+00
|
||||
* Note: The 3-digit milli-seconds is optional. Time zone is required and can be in one of
|
||||
* these formats:
|
||||
* Z (same with +0000)
|
||||
* +08:00 (same with +0800)
|
||||
* -02 (same with -0200)
|
||||
* -0200
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public Date parseDatetime(String str) {
|
||||
if (str == null)
|
||||
return null;
|
||||
|
||||
if ("yyyy-MM-dd'T'HH:mm:ss.SSSZ".equals(datetimeFormat)) {
|
||||
/*
|
||||
* When the default datetime format is used, process the given string
|
||||
* to support various formats defined by ISO 8601.
|
||||
*/
|
||||
// normalize time zone
|
||||
// trailing "Z": 2015-08-16T08:20:05Z => 2015-08-16T08:20:05+0000
|
||||
str = str.replaceAll("[zZ]\\z", "+0000");
|
||||
// remove colon: 2015-08-16T08:20:05+00:00 => 2015-08-16T08:20:05+0000
|
||||
str = str.replaceAll("([+-]\\d{2}):(\\d{2})\\z", "$1$2");
|
||||
// expand time zone: 2015-08-16T08:20:05+00 => 2015-08-16T08:20:05+0000
|
||||
str = str.replaceAll("([+-]\\d{2})\\z", "$100");
|
||||
// add milliseconds when missing
|
||||
// 2015-08-16T08:20:05+0000 => 2015-08-16T08:20:05.000+0000
|
||||
str = str.replaceAll("(:\\d{1,2})([+-]\\d{4})\\z", "$1.000$2");
|
||||
}
|
||||
|
||||
try {
|
||||
return datetimeFormatter.parse(str);
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Date parseDateOrDatetime(String str) {
|
||||
if (str == null)
|
||||
return null;
|
||||
else if (str.length() <= dateLength)
|
||||
return parseDate(str);
|
||||
else
|
||||
return parseDatetime(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given Date object into string.
|
||||
*/
|
||||
public String formatDate(Date date) {
|
||||
return dateFormatter.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given Date object into string.
|
||||
*/
|
||||
public String formatDatetime(Date date) {
|
||||
return datetimeFormatter.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentications (key: authentication name, value: authentication).
|
||||
*/
|
||||
public Map<String, Authentication> getAuthentications() {
|
||||
return authentications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentication for the given name.
|
||||
*
|
||||
* @param authName The authentication name
|
||||
* @return The authentication, null if not found
|
||||
*/
|
||||
public Authentication getAuthentication(String authName) {
|
||||
return authentications.get(authName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set username for the first HTTP basic authentication.
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBasicAuth) {
|
||||
((HttpBasicAuth) auth).setUsername(username);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No HTTP basic authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set password for the first HTTP basic authentication.
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBasicAuth) {
|
||||
((HttpBasicAuth) auth).setPassword(password);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No HTTP basic authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set API key value for the first API key authentication.
|
||||
*/
|
||||
public void setApiKey(String apiKey) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
((ApiKeyAuth) auth).setApiKey(apiKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set API key prefix for the first API key authentication.
|
||||
*/
|
||||
public void setApiKeyPrefix(String apiKeyPrefix) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the User-Agent header's value (by adding to the default header map).
|
||||
*/
|
||||
public ApiClient setUserAgent(String userAgent) {
|
||||
addDefaultHeader("User-Agent", userAgent);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a default header.
|
||||
*
|
||||
* @param key The header's key
|
||||
* @param value The header's value
|
||||
*/
|
||||
public ApiClient addDefaultHeader(String key, String value) {
|
||||
defaultHeaderMap.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
|
||||
*/
|
||||
public boolean isLenientOnJson() {
|
||||
return lenientOnJson;
|
||||
}
|
||||
|
||||
public ApiClient setLenientOnJson(boolean lenient) {
|
||||
this.lenientOnJson = lenient;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that whether debugging is enabled for this API client.
|
||||
*/
|
||||
public boolean isDebugging() {
|
||||
return debugging;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable debugging for this API client.
|
||||
*
|
||||
* @param debugging To enable (true) or disable (false) debugging
|
||||
*/
|
||||
public ApiClient setDebugging(boolean debugging) {
|
||||
this.debugging = debugging;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The path of temporary folder used to store downloaded files from endpoints
|
||||
* with file response. The default value is <code>null</code>, i.e. using
|
||||
* the system's default tempopary folder.
|
||||
*
|
||||
* @see https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File)
|
||||
*/
|
||||
public String getTempFolderPath() {
|
||||
return tempFolderPath;
|
||||
}
|
||||
|
||||
public ApiClient setTempFolderPath(String tempFolderPath) {
|
||||
this.tempFolderPath = tempFolderPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*/
|
||||
public String parameterToString(Object param) {
|
||||
if (param == null) {
|
||||
return "";
|
||||
} else if (param instanceof Date) {
|
||||
return formatDatetime((Date) param);
|
||||
} else if (param instanceof Collection) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (Object o : (Collection)param) {
|
||||
if (b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(String.valueOf(o));
|
||||
}
|
||||
return b.toString();
|
||||
} else {
|
||||
return String.valueOf(param);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Format to {@code Pair} objects.
|
||||
*/
|
||||
public List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
|
||||
List<Pair> params = new ArrayList<Pair>();
|
||||
|
||||
// preconditions
|
||||
if (name == null || name.isEmpty() || value == null) return params;
|
||||
|
||||
Collection valueCollection = null;
|
||||
if (value instanceof Collection) {
|
||||
valueCollection = (Collection) value;
|
||||
} else {
|
||||
params.add(new Pair(name, parameterToString(value)));
|
||||
return params;
|
||||
}
|
||||
|
||||
if (valueCollection.isEmpty()){
|
||||
return params;
|
||||
}
|
||||
|
||||
// get the collection format
|
||||
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
|
||||
|
||||
// create the params based on the collection format
|
||||
if (collectionFormat.equals("multi")) {
|
||||
for (Object item : valueCollection) {
|
||||
params.add(new Pair(name, parameterToString(item)));
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
String delimiter = ",";
|
||||
|
||||
if (collectionFormat.equals("csv")) {
|
||||
delimiter = ",";
|
||||
} else if (collectionFormat.equals("ssv")) {
|
||||
delimiter = " ";
|
||||
} else if (collectionFormat.equals("tsv")) {
|
||||
delimiter = "\t";
|
||||
} else if (collectionFormat.equals("pipes")) {
|
||||
delimiter = "|";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder() ;
|
||||
for (Object item : valueCollection) {
|
||||
sb.append(delimiter);
|
||||
sb.append(parameterToString(item));
|
||||
}
|
||||
|
||||
params.add(new Pair(name, sb.substring(1)));
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the Accept header's value from the given accepts array:
|
||||
* if JSON exists in the given array, use it;
|
||||
* otherwise use all of them (joining into a string)
|
||||
*
|
||||
* @param accepts The accepts array to select from
|
||||
* @return The Accept header to use. If the given array is empty,
|
||||
* null will be returned (not to set the Accept header explicitly).
|
||||
*/
|
||||
public String selectHeaderAccept(String[] accepts) {
|
||||
if (accepts.length == 0) return null;
|
||||
if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json";
|
||||
return StringUtil.join(accepts, ",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the Content-Type header's value from the given array:
|
||||
* if JSON exists in the given array, use it;
|
||||
* otherwise use the first one of the array.
|
||||
*
|
||||
* @param contentTypes The Content-Type array to select from
|
||||
* @return The Content-Type header to use. If the given array is empty,
|
||||
* JSON will be used.
|
||||
*/
|
||||
public String selectHeaderContentType(String[] contentTypes) {
|
||||
if (contentTypes.length == 0) return "application/json";
|
||||
if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json";
|
||||
return contentTypes[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape the given string to be used as URL query value.
|
||||
*/
|
||||
public String escapeString(String str) {
|
||||
try {
|
||||
return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize response body to Java object, according to the Content-Type
|
||||
* response header.
|
||||
*
|
||||
* @param response HTTP response
|
||||
* @param returnType The type of the Java object
|
||||
* @return The deserialized Java object
|
||||
*/
|
||||
public <T> T deserialize(Response response, Type returnType) throws ApiException {
|
||||
if (response == null || returnType == null)
|
||||
return null;
|
||||
|
||||
// Handle file downloading.
|
||||
if (returnType.equals(File.class))
|
||||
return (T) downloadFileFromResponse(response);
|
||||
|
||||
String respBody;
|
||||
try {
|
||||
if (response.body() != null)
|
||||
respBody = response.body().string();
|
||||
else
|
||||
respBody = null;
|
||||
} catch (IOException e) {
|
||||
throw new ApiException(e);
|
||||
}
|
||||
|
||||
if (respBody == null || "".equals(respBody))
|
||||
return null;
|
||||
|
||||
String contentType = response.headers().get("Content-Type");
|
||||
if (contentType == null) {
|
||||
// ensuring a default content type
|
||||
contentType = "application/json";
|
||||
}
|
||||
if (contentType.startsWith("application/json")) {
|
||||
return json.deserialize(respBody, returnType);
|
||||
} else if (returnType.equals(String.class)) {
|
||||
// Expecting string, return the raw response body.
|
||||
return (T) respBody;
|
||||
} else {
|
||||
throw new ApiException(
|
||||
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
|
||||
response.code(),
|
||||
response.headers().toMultimap(),
|
||||
respBody);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the given Java object into request body string, according to the
|
||||
* request Content-Type.
|
||||
*
|
||||
* @param obj The Java object
|
||||
* @param contentType The request Content-Type
|
||||
* @return The serialized string
|
||||
*/
|
||||
public String serialize(Object obj, String contentType) throws ApiException {
|
||||
if (contentType.startsWith("application/json")) {
|
||||
if (obj != null)
|
||||
return json.serialize(obj);
|
||||
else
|
||||
return null;
|
||||
} else {
|
||||
throw new ApiException("Content type \"" + contentType + "\" is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download file from the given response.
|
||||
*/
|
||||
public File downloadFileFromResponse(Response response) throws ApiException {
|
||||
try {
|
||||
File file = prepareDownloadFile(response);
|
||||
BufferedSink sink = Okio.buffer(Okio.sink(file));
|
||||
sink.writeAll(response.body().source());
|
||||
sink.close();
|
||||
return file;
|
||||
} catch (IOException e) {
|
||||
throw new ApiException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public File prepareDownloadFile(Response response) throws IOException {
|
||||
String filename = null;
|
||||
String contentDisposition = response.header("Content-Disposition");
|
||||
if (contentDisposition != null && !"".equals(contentDisposition)) {
|
||||
// Get filename from the Content-Disposition header.
|
||||
Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
|
||||
Matcher matcher = pattern.matcher(contentDisposition);
|
||||
if (matcher.find())
|
||||
filename = matcher.group(1);
|
||||
}
|
||||
|
||||
String prefix = null;
|
||||
String suffix = null;
|
||||
if (filename == null) {
|
||||
prefix = "download-";
|
||||
suffix = "";
|
||||
} else {
|
||||
int pos = filename.lastIndexOf(".");
|
||||
if (pos == -1) {
|
||||
prefix = filename + "-";
|
||||
} else {
|
||||
prefix = filename.substring(0, pos) + "-";
|
||||
suffix = filename.substring(pos);
|
||||
}
|
||||
// File.createTempFile requires the prefix to be at least three characters long
|
||||
if (prefix.length() < 3)
|
||||
prefix = "download-";
|
||||
}
|
||||
|
||||
if (tempFolderPath == null)
|
||||
return File.createTempFile(prefix, suffix);
|
||||
else
|
||||
return File.createTempFile(prefix, suffix, new File(tempFolderPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #execute(Call, Type)
|
||||
*/
|
||||
public <T> T execute(Call call) throws ApiException {
|
||||
return execute(call, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute HTTP call and deserialize the HTTP response body into the given return type.
|
||||
*
|
||||
* @param returnType The return type used to deserialize HTTP response body
|
||||
* @param <T> The return type corresponding to (same with) returnType
|
||||
* @return The Java object deserialized from response body. Returns null if returnType is null.
|
||||
*/
|
||||
public <T> T execute(Call call, Type returnType) throws ApiException {
|
||||
try {
|
||||
Response response = call.execute();
|
||||
this.statusCode = response.code();
|
||||
this.responseHeaders = response.headers().toMultimap();
|
||||
return handleResponse(response, returnType);
|
||||
} catch (IOException e) {
|
||||
throw new ApiException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* #see executeAsync(Call, Type, ApiCallback)
|
||||
*/
|
||||
public <T> void executeAsync(Call call, ApiCallback<T> callback) throws ApiException {
|
||||
executeAsync(call, null, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute HTTP call asynchronously.
|
||||
*
|
||||
* @see #execute(Call, Type)
|
||||
* @param The callback to be executed when the API call finishes
|
||||
*/
|
||||
public <T> void executeAsync(Call call, final Type returnType, final ApiCallback<T> callback) {
|
||||
call.enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Request request, IOException e) {
|
||||
callback.onFailure(new ApiException(e), 0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Response response) throws IOException {
|
||||
T result;
|
||||
try {
|
||||
result = (T) handleResponse(response, returnType);
|
||||
} catch (ApiException e) {
|
||||
callback.onFailure(e, response.code(), response.headers().toMultimap());
|
||||
return;
|
||||
}
|
||||
callback.onSuccess(result, response.code(), response.headers().toMultimap());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public <T> T handleResponse(Response response, Type returnType) throws ApiException {
|
||||
if (response.isSuccessful()) {
|
||||
if (returnType == null || response.code() == 204) {
|
||||
// returning null if the returnType is not defined,
|
||||
// or the status code is 204 (No Content)
|
||||
return null;
|
||||
} else {
|
||||
return deserialize(response, returnType);
|
||||
}
|
||||
} else {
|
||||
String respBody = null;
|
||||
if (response.body() != null) {
|
||||
try {
|
||||
respBody = response.body().string();
|
||||
} catch (IOException e) {
|
||||
throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
|
||||
}
|
||||
}
|
||||
throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build HTTP call with the given options.
|
||||
*
|
||||
* @param path The sub-path of the HTTP URL
|
||||
* @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param authNames The authentications to apply
|
||||
* @return The HTTP call
|
||||
*/
|
||||
public Call buildCall(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames) throws ApiException {
|
||||
updateParamsForAuth(authNames, queryParams, headerParams);
|
||||
|
||||
final String url = buildUrl(path, queryParams);
|
||||
final Request.Builder reqBuilder = new Request.Builder().url(url);
|
||||
processHeaderParams(headerParams, reqBuilder);
|
||||
|
||||
String contentType = (String) headerParams.get("Content-Type");
|
||||
// ensuring a default content type
|
||||
if (contentType == null) contentType = "application/json";
|
||||
|
||||
RequestBody reqBody;
|
||||
if (!HttpMethod.permitsRequestBody(method)) {
|
||||
reqBody = null;
|
||||
} else if ("application/x-www-form-urlencoded".equals(contentType)) {
|
||||
reqBody = buildRequestBodyFormEncoding(formParams);
|
||||
} else if ("multipart/form-data".equals(contentType)) {
|
||||
reqBody = buildRequestBodyMultipart(formParams);
|
||||
} else if (body == null) {
|
||||
if ("DELETE".equals(method)) {
|
||||
// allow calling DELETE without sending a request body
|
||||
reqBody = null;
|
||||
} else {
|
||||
// use an empty request body (for POST, PUT and PATCH)
|
||||
reqBody = RequestBody.create(MediaType.parse(contentType), "");
|
||||
}
|
||||
} else {
|
||||
reqBody = RequestBody.create(MediaType.parse(contentType), serialize(body, contentType));
|
||||
}
|
||||
|
||||
Request request = reqBuilder.method(method, reqBody).build();
|
||||
return httpClient.newCall(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build full URL by concatenating base path, the given sub path and query parameters.
|
||||
*
|
||||
* @param path The sub path
|
||||
* @param queryParams The query parameters
|
||||
* @return The full URL
|
||||
*/
|
||||
public String buildUrl(String path, List<Pair> queryParams) {
|
||||
StringBuilder query = new StringBuilder();
|
||||
if (queryParams != null) {
|
||||
for (Pair param : queryParams) {
|
||||
if (param.getValue() != null) {
|
||||
if (query.toString().length() == 0)
|
||||
query.append("?");
|
||||
else
|
||||
query.append("&");
|
||||
String value = parameterToString(param.getValue());
|
||||
query.append(escapeString(param.getName())).append("=").append(escapeString(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return basePath + path + query.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set header parameters to the request builder, including default headers.
|
||||
*/
|
||||
public void processHeaderParams(Map<String, String> headerParams, Request.Builder reqBuilder) {
|
||||
for (Entry<String, String> param : headerParams.entrySet()) {
|
||||
reqBuilder.header(param.getKey(), parameterToString(param.getValue()));
|
||||
}
|
||||
for (Entry<String, String> header : defaultHeaderMap.entrySet()) {
|
||||
if (!headerParams.containsKey(header.getKey())) {
|
||||
reqBuilder.header(header.getKey(), parameterToString(header.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update query and header parameters based on authentication settings.
|
||||
*
|
||||
* @param authNames The authentications to apply
|
||||
*/
|
||||
public void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
|
||||
for (String authName : authNames) {
|
||||
Authentication auth = authentications.get(authName);
|
||||
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
|
||||
auth.applyToParams(queryParams, headerParams);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a form-encoding request body with the given form parameters.
|
||||
*/
|
||||
public RequestBody buildRequestBodyFormEncoding(Map<String, Object> formParams) {
|
||||
FormEncodingBuilder formBuilder = new FormEncodingBuilder();
|
||||
for (Entry<String, Object> param : formParams.entrySet()) {
|
||||
formBuilder.add(param.getKey(), parameterToString(param.getValue()));
|
||||
}
|
||||
return formBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a multipart (file uploading) request body with the given form parameters,
|
||||
* which could contain text fields and file fields.
|
||||
*/
|
||||
public RequestBody buildRequestBodyMultipart(Map<String, Object> formParams) {
|
||||
MultipartBuilder mpBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
|
||||
for (Entry<String, Object> param : formParams.entrySet()) {
|
||||
if (param.getValue() instanceof File) {
|
||||
File file = (File) param.getValue();
|
||||
Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\"");
|
||||
MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file));
|
||||
mpBuilder.addPart(partHeaders, RequestBody.create(mediaType, file));
|
||||
} else {
|
||||
Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"");
|
||||
mpBuilder.addPart(partHeaders, RequestBody.create(null, parameterToString(param.getValue())));
|
||||
}
|
||||
}
|
||||
return mpBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess Content-Type header from the given file (defaults to "application/octet-stream").
|
||||
*
|
||||
* @param file The given file
|
||||
* @return The Content-Type guessed
|
||||
*/
|
||||
public String guessContentTypeFromFile(File file) {
|
||||
String contentType = URLConnection.guessContentTypeFromName(file.getName());
|
||||
if (contentType == null) {
|
||||
return "application/octet-stream";
|
||||
} else {
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply SSL related settings to httpClient according to the current values of
|
||||
* verifyingSsl and sslCaCert.
|
||||
*/
|
||||
private void applySslSettings() {
|
||||
try {
|
||||
KeyManager[] keyManagers = null;
|
||||
TrustManager[] trustManagers = null;
|
||||
HostnameVerifier hostnameVerifier = null;
|
||||
if (!verifyingSsl) {
|
||||
TrustManager trustAll = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() { return null; }
|
||||
};
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
trustManagers = new TrustManager[]{ trustAll };
|
||||
hostnameVerifier = new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) { return true; }
|
||||
};
|
||||
} else if (sslCaCert != null) {
|
||||
char[] password = null; // Any password will work.
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(sslCaCert);
|
||||
if (certificates.isEmpty()) {
|
||||
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
|
||||
}
|
||||
KeyStore caKeyStore = newEmptyKeyStore(password);
|
||||
int index = 0;
|
||||
for (Certificate certificate : certificates) {
|
||||
String certificateAlias = "ca" + Integer.toString(index++);
|
||||
caKeyStore.setCertificateEntry(certificateAlias, certificate);
|
||||
}
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustManagerFactory.init(caKeyStore);
|
||||
trustManagers = trustManagerFactory.getTrustManagers();
|
||||
}
|
||||
|
||||
if (keyManagers != null || trustManagers != null) {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(keyManagers, trustManagers, new SecureRandom());
|
||||
httpClient.setSslSocketFactory(sslContext.getSocketFactory());
|
||||
} else {
|
||||
httpClient.setSslSocketFactory(null);
|
||||
}
|
||||
httpClient.setHostnameVerifier(hostnameVerifier);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, password);
|
||||
return keyStore;
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Date;
|
||||
|
||||
public class JSON {
|
||||
private ApiClient apiClient;
|
||||
private Gson gson;
|
||||
|
||||
public JSON(ApiClient apiClient) {
|
||||
this.apiClient = apiClient;
|
||||
gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Date.class, new DateAdapter(apiClient))
|
||||
.create();
|
||||
}
|
||||
|
||||
public Gson getGson() {
|
||||
return gson;
|
||||
}
|
||||
|
||||
public void setGson(Gson gson) {
|
||||
this.gson = gson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the given Java object into JSON string.
|
||||
*/
|
||||
public String serialize(Object obj) {
|
||||
return gson.toJson(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize the given JSON string to Java object.
|
||||
*
|
||||
* @param body The JSON string
|
||||
* @param returnType The type to deserialize inot
|
||||
* @return The deserialized Java object
|
||||
*/
|
||||
public <T> T deserialize(String body, Type returnType) {
|
||||
try {
|
||||
if (apiClient.isLenientOnJson()) {
|
||||
JsonReader jsonReader = new JsonReader(new StringReader(body));
|
||||
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
|
||||
jsonReader.setLenient(true);
|
||||
return gson.fromJson(jsonReader, returnType);
|
||||
} else {
|
||||
return gson.fromJson(body, returnType);
|
||||
}
|
||||
} catch (JsonParseException e) {
|
||||
// Fallback processing when failed to parse JSON form response body:
|
||||
// return the response body string directly for the String return type;
|
||||
// parse response body into date or datetime for the Date return type.
|
||||
if (returnType.equals(String.class))
|
||||
return (T) body;
|
||||
else if (returnType.equals(Date.class))
|
||||
return (T) apiClient.parseDateOrDatetime(body);
|
||||
else throw(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
|
||||
private final ApiClient apiClient;
|
||||
|
||||
public DateAdapter(ApiClient apiClient) {
|
||||
super();
|
||||
this.apiClient = apiClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
if (src == null) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
return new JsonPrimitive(apiClient.formatDatetime(src));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date deserialize(JsonElement json, Type date, JsonDeserializationContext context) throws JsonParseException {
|
||||
String str = json.getAsJsonPrimitive().getAsString();
|
||||
try {
|
||||
return apiClient.parseDateOrDatetime(str);
|
||||
} catch (RuntimeException e) {
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.ApiCallback;
|
||||
import {{invokerPackage}}.ApiClient;
|
||||
import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.Configuration;
|
||||
import {{invokerPackage}}.Pair;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import com.squareup.okhttp.Call;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.*;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
{{#operations}}
|
||||
public class {{classname}} {
|
||||
private ApiClient {{localVariablePrefix}}apiClient;
|
||||
|
||||
public {{classname}}() {
|
||||
this(Configuration.getDefaultApiClient());
|
||||
}
|
||||
|
||||
public {{classname}}(ApiClient apiClient) {
|
||||
this.{{localVariablePrefix}}apiClient = apiClient;
|
||||
}
|
||||
|
||||
public ApiClient getApiClient() {
|
||||
return {{localVariablePrefix}}apiClient;
|
||||
}
|
||||
|
||||
public void setApiClient(ApiClient apiClient) {
|
||||
this.{{localVariablePrefix}}apiClient = apiClient;
|
||||
}
|
||||
|
||||
{{#operation}}
|
||||
/* Build call for {{nickname}} */
|
||||
private Call {{nickname}}Call({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
||||
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
|
||||
{{#allParams}}{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) {
|
||||
throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{nickname}}(Async)");
|
||||
}
|
||||
{{/required}}{{/allParams}}
|
||||
|
||||
// create path and map variables
|
||||
String {{localVariablePrefix}}path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
|
||||
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
|
||||
|
||||
{{javaUtilPrefix}}List<Pair> {{localVariablePrefix}}queryParams = new {{javaUtilPrefix}}ArrayList<Pair>();{{#queryParams}}
|
||||
if ({{paramName}} != null)
|
||||
{{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));{{/queryParams}}
|
||||
|
||||
{{javaUtilPrefix}}Map<String, String> {{localVariablePrefix}}headerParams = new {{javaUtilPrefix}}HashMap<String, String>();{{#headerParams}}
|
||||
if ({{paramName}} != null)
|
||||
{{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{/headerParams}}
|
||||
|
||||
{{javaUtilPrefix}}Map<String, Object> {{localVariablePrefix}}formParams = new {{javaUtilPrefix}}HashMap<String, Object>();{{#formParams}}
|
||||
if ({{paramName}} != null)
|
||||
{{localVariablePrefix}}formParams.put("{{baseName}}", {{paramName}});{{/formParams}}
|
||||
|
||||
final String[] {{localVariablePrefix}}accepts = {
|
||||
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
|
||||
};
|
||||
final String {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts);
|
||||
if ({{localVariablePrefix}}accept != null) {{localVariablePrefix}}headerParams.put("Accept", {{localVariablePrefix}}accept);
|
||||
|
||||
final String[] {{localVariablePrefix}}contentTypes = {
|
||||
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
|
||||
};
|
||||
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
|
||||
{{localVariablePrefix}}headerParams.put("Content-Type", {{localVariablePrefix}}contentType);
|
||||
|
||||
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}authNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* {{summary}}
|
||||
* {{notes}}{{#allParams}}
|
||||
* @param {{paramName}} {{description}}{{/allParams}}{{#returnType}}
|
||||
* @return {{{returnType}}}{{/returnType}}
|
||||
*/
|
||||
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
|
||||
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
|
||||
return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}returnType);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
|
||||
}
|
||||
|
||||
/**
|
||||
* {{summary}} (asynchronously)
|
||||
* {{notes}}{{#allParams}}
|
||||
* @param {{paramName}} {{description}}{{/allParams}}
|
||||
* @param callback The callback to be executed when the API call finishes
|
||||
* @return The request call
|
||||
*/
|
||||
public Call {{nickname}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
|
||||
Call {{localVariablePrefix}}call = {{nickname}}Call({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{#returnType}}Type {{localVariablePrefix}}returnType = new TypeToken<{{{returnType}}}>(){}.getType();
|
||||
{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}returnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}}
|
||||
return {{localVariablePrefix}}call;
|
||||
}
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,41 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import {{invokerPackage}}.Pair;
|
||||
|
||||
import com.migcomponents.migbase64.Base64;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class HttpBasicAuth implements Authentication {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
|
||||
String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
|
||||
try {
|
||||
headerParams.put("Authorization", "Basic " + Base64.encodeToString(str.getBytes("UTF-8"), false));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
group = '{{groupId}}'
|
||||
version = '{{artifactVersion}}'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.2'
|
||||
classpath 'com.github.dcendents:android-maven-plugin:1.2'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
|
||||
if(hasProperty('target') && target == 'android') {
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def outputFile = output.outputFile
|
||||
if (outputFile != null && outputFile.name.endsWith('.aar')) {
|
||||
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
|
||||
output.outputFile = new File(outputFile.parent, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.libraryVariants.all { variant ->
|
||||
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
|
||||
task.description = "Create jar artifact for ${variant.name}"
|
||||
task.dependsOn variant.javaCompile
|
||||
task.from variant.javaCompile.destinationDir
|
||||
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
|
||||
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
|
||||
artifacts.add('archives', task);
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
pom.artifactId = '{{artifactId}}'
|
||||
}
|
||||
}
|
||||
|
||||
task execute(type:JavaExec) {
|
||||
main = System.getProperty('mainClass')
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'io.swagger:swagger-annotations:1.5.0'
|
||||
compile 'com.squareup.okhttp:okhttp:2.4.0'
|
||||
compile 'com.google.code.gson:gson:2.3.1'
|
||||
compile 'com.brsanthu:migbase64:2.2'
|
||||
testCompile 'junit:junit:4.8.1'
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
lazy val root = (project in file(".")).
|
||||
settings(
|
||||
organization := "{{groupId}}",
|
||||
name := "{{artifactId}}",
|
||||
version := "{{artifactVersion}}",
|
||||
scalaVersion := "2.11.4",
|
||||
scalacOptions ++= Seq("-feature"),
|
||||
javacOptions in compile ++= Seq("-Xlint:deprecation"),
|
||||
publishArtifact in (Compile, packageDoc) := false,
|
||||
resolvers += Resolver.mavenLocal,
|
||||
libraryDependencies ++= Seq(
|
||||
"io.swagger" % "swagger-annotations" % "1.5.0",
|
||||
"com.squareup.okhttp" % "okhttp" % "2.4.0",
|
||||
"com.google.code.gson" % "gson" % "2.3.1",
|
||||
"com.brsanthu" % "migbase64" % "2.2",
|
||||
"junit" % "junit" % "4.8.1" % "test"
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
public enum {{datatypeWithEnum}} {
|
||||
{{#allowableValues}}{{#enumVars}}@SerializedName("{{value}}")
|
||||
{{name}}("{{value}}"){{^-last}},
|
||||
|
||||
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||
|
||||
private String value;
|
||||
|
||||
{{datatypeWithEnum}}(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.StringUtil;
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
{{#serializableModel}}
|
||||
import java.io.Serializable;{{/serializableModel}}
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
{{#models}}
|
||||
|
||||
{{#model}}{{#description}}
|
||||
/**
|
||||
* {{description}}
|
||||
**/{{/description}}
|
||||
@ApiModel(description = "{{{description}}}")
|
||||
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
|
||||
{{#vars}}{{#isEnum}}
|
||||
|
||||
{{>libraries/okhttp-gson/enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}
|
||||
|
||||
{{>libraries/okhttp-gson/enumClass}}{{/items}}{{/items.isEnum}}
|
||||
@SerializedName("{{baseName}}")
|
||||
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
|
||||
{{/vars}}
|
||||
|
||||
{{#vars}}
|
||||
/**{{#description}}
|
||||
* {{{description}}}{{/description}}{{#minimum}}
|
||||
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
|
||||
* maximum: {{maximum}}{{/maximum}}
|
||||
**/
|
||||
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
|
||||
public {{{datatypeWithEnum}}} {{getter}}() {
|
||||
return {{name}};
|
||||
}
|
||||
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
this.{{name}} = {{name}};
|
||||
}
|
||||
|
||||
{{/vars}}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class {{classname}} {\n");
|
||||
{{#parent}}sb.append(" ").append(StringUtil.toIndentedString(super.toString())).append("\n");{{/parent}}
|
||||
{{#vars}}sb.append(" {{name}}: ").append(StringUtil.toIndentedString({{name}})).append("\n");
|
||||
{{/vars}}sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -112,17 +112,20 @@
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>${swagger-annotations-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson-version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>${retrofit-version}</version>
|
||||
<scope>compile</scope>
|
||||
<groupId>com.brsanthu</groupId>
|
||||
<artifactId>migbase64</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
@@ -135,9 +138,9 @@
|
||||
</dependencies>
|
||||
<properties>
|
||||
<swagger-annotations-version>1.5.0</swagger-annotations-version>
|
||||
<okhttp-version>2.4.0</okhttp-version>
|
||||
<gson-version>2.3.1</gson-version>
|
||||
<retrofit-version>1.9.0</retrofit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
<junit-version>4.8.1</junit-version>
|
||||
</properties>
|
||||
</project>
|
||||
@@ -0,0 +1,315 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
|
||||
import retrofit.RestAdapter;
|
||||
import retrofit.client.OkClient;
|
||||
import retrofit.converter.ConversionException;
|
||||
import retrofit.converter.Converter;
|
||||
import retrofit.converter.GsonConverter;
|
||||
import retrofit.mime.TypedByteArray;
|
||||
import retrofit.mime.TypedInput;
|
||||
import retrofit.mime.TypedOutput;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
|
||||
import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||
import {{invokerPackage}}.auth.ApiKeyAuth;
|
||||
import {{invokerPackage}}.auth.OAuth;
|
||||
import {{invokerPackage}}.auth.OAuthFlow;
|
||||
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
private Map<String, Interceptor> apiAuthorizations;
|
||||
private OkHttpClient okClient;
|
||||
private RestAdapter.Builder adapterBuilder;
|
||||
|
||||
public ApiClient() {
|
||||
apiAuthorizations = new LinkedHashMap<String, Interceptor>();
|
||||
createDefaultAdapter();
|
||||
}
|
||||
|
||||
public ApiClient(String[] authNames) {
|
||||
this();
|
||||
okClient = new OkHttpClient();
|
||||
adapterBuilder.setClient(new OkClient(okClient));
|
||||
for(String authName : authNames) {
|
||||
if (apiAuthorizations.containsKey(authName)) {
|
||||
throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
|
||||
}{{#authMethods}}
|
||||
Interceptor auth;
|
||||
if (authName == "{{name}}") { {{#isBasic}}
|
||||
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
|
||||
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
|
||||
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
|
||||
} else {
|
||||
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
|
||||
}
|
||||
apiAuthorizations.put(authName, auth);{{/authMethods}}
|
||||
}
|
||||
addAuthsToOkClient(okClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic constructor for single auth name
|
||||
* @param authName
|
||||
*/
|
||||
public ApiClient(String authName) {
|
||||
this(new String[]{authName});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single api key
|
||||
* @param authName
|
||||
* @param apiKey
|
||||
*/
|
||||
public ApiClient(String authName, String apiKey) {
|
||||
this(authName);
|
||||
this.setApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single basic auth or password oauth2
|
||||
* @param authName
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String username, String password) {
|
||||
this(authName);
|
||||
this.setCredentials(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for single password oauth2
|
||||
* @param authName
|
||||
* @param clientId
|
||||
* @param secret
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public ApiClient(String authName, String clientId, String secret, String username, String password) {
|
||||
this(authName);
|
||||
this.getTokenEndPoint()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(secret)
|
||||
.setUsername(username)
|
||||
.setPassword(password);
|
||||
}
|
||||
|
||||
public void createDefaultAdapter() {
|
||||
Gson gson = new GsonBuilder()
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
.create();
|
||||
|
||||
adapterBuilder = new RestAdapter
|
||||
.Builder()
|
||||
.setEndpoint("{{basePath}}")
|
||||
.setConverter(new GsonConverterWrapper(gson));
|
||||
}
|
||||
|
||||
public <S> S createService(Class<S> serviceClass) {
|
||||
return adapterBuilder.build().create(serviceClass);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the first api key found
|
||||
* @param apiKey
|
||||
*/
|
||||
private void setApiKey(String apiKey) {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof ApiKeyAuth) {
|
||||
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
|
||||
keyAuth.setApiKey(apiKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the username/password for basic auth or password oauth
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
private void setCredentials(String username, String password) {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof HttpBasicAuth) {
|
||||
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
|
||||
basicAuth.setCredentials(username, password);
|
||||
return;
|
||||
}
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return
|
||||
*/
|
||||
public TokenRequestBuilder getTokenEndPoint() {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getTokenRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @return
|
||||
*/
|
||||
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
return oauth.getAuthenticationRequestBuilder();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
|
||||
* @param accessToken
|
||||
*/
|
||||
public void setAccessToken(String accessToken) {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.setAccessToken(accessToken);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to configure the oauth accessCode/implicit flow parameters
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
* @param redirectURI
|
||||
*/
|
||||
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
if (apiAuthorization instanceof OAuth) {
|
||||
OAuth oauth = (OAuth) apiAuthorization;
|
||||
oauth.getTokenRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setClientSecret(clientSecret)
|
||||
.setRedirectURI(redirectURI);
|
||||
oauth.getAuthenticationRequestBuilder()
|
||||
.setClientId(clientId)
|
||||
.setRedirectURI(redirectURI);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Interceptor> getApiAuthorizations() {
|
||||
return apiAuthorizations;
|
||||
}
|
||||
|
||||
public void setApiAuthorizations(Map<String, Interceptor> apiAuthorizations) {
|
||||
this.apiAuthorizations = apiAuthorizations;
|
||||
}
|
||||
|
||||
public RestAdapter.Builder getAdapterBuilder() {
|
||||
return adapterBuilder;
|
||||
}
|
||||
|
||||
public void setAdapterBuilder(RestAdapter.Builder adapterBuilder) {
|
||||
this.adapterBuilder = adapterBuilder;
|
||||
}
|
||||
|
||||
public OkHttpClient getOkClient() {
|
||||
return okClient;
|
||||
}
|
||||
|
||||
public void addAuthsToOkClient(OkHttpClient okClient) {
|
||||
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
|
||||
okClient.interceptors().add(apiAuthorization);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the okClient given in parameter, adds the auth interceptors and uses it to configure the RestAdapter
|
||||
* @param okClient
|
||||
*/
|
||||
public void configureFromOkclient(OkHttpClient okClient) {
|
||||
OkHttpClient clone = okClient.clone();
|
||||
addAuthsToOkClient(clone);
|
||||
adapterBuilder.setClient(new OkClient(clone));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This wrapper is to take care of this case:
|
||||
* when the deserialization fails due to JsonParseException and the
|
||||
* expected type is String, then just return the body string.
|
||||
*/
|
||||
class GsonConverterWrapper implements Converter {
|
||||
private GsonConverter converter;
|
||||
|
||||
public GsonConverterWrapper(Gson gson) {
|
||||
converter = new GsonConverter(gson);
|
||||
}
|
||||
|
||||
@Override public Object fromBody(TypedInput body, Type type) throws ConversionException {
|
||||
byte[] bodyBytes = readInBytes(body);
|
||||
TypedByteArray newBody = new TypedByteArray(body.mimeType(), bodyBytes);
|
||||
try {
|
||||
return converter.fromBody(newBody, type);
|
||||
} catch (ConversionException e) {
|
||||
if (e.getCause() instanceof JsonParseException && type.equals(String.class)) {
|
||||
return new String(bodyBytes);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public TypedOutput toBody(Object object) {
|
||||
return converter.toBody(object);
|
||||
}
|
||||
|
||||
private byte[] readInBytes(TypedInput body) throws ConversionException {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = body.in();
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[0xFFFF];
|
||||
for (int len; (len = in.read(buffer)) != -1;)
|
||||
os.write(buffer, 0, len);
|
||||
os.flush();
|
||||
return os.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new ConversionException(e);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class CollectionFormats {
|
||||
|
||||
public static class CSVParams {
|
||||
|
||||
protected List<String> params;
|
||||
|
||||
public CSVParams() {
|
||||
}
|
||||
|
||||
public CSVParams(List<String> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public CSVParams(String... params) {
|
||||
this.params = Arrays.asList(params);
|
||||
}
|
||||
|
||||
public List<String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(List<String> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.join(params.toArray(new String[0]), ",");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SSVParams extends CSVParams {
|
||||
|
||||
public SSVParams() {
|
||||
}
|
||||
|
||||
public SSVParams(List<String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
public SSVParams(String... params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.join(params.toArray(new String[0]), " ");
|
||||
}
|
||||
}
|
||||
|
||||
public static class TSVParams extends CSVParams {
|
||||
|
||||
public TSVParams() {
|
||||
}
|
||||
|
||||
public TSVParams(List<String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
public TSVParams(String... params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.join( params.toArray(new String[0]), "\t");
|
||||
}
|
||||
}
|
||||
|
||||
public static class PIPESParams extends CSVParams {
|
||||
|
||||
public PIPESParams() {
|
||||
}
|
||||
|
||||
public PIPESParams(List<String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
public PIPESParams(String... params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.join(params.toArray(new String[0]), "|");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.CollectionFormats.*;
|
||||
|
||||
import retrofit.Callback;
|
||||
import retrofit.http.*;
|
||||
import retrofit.mime.*;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.*;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
{{#operations}}
|
||||
public interface {{classname}} {
|
||||
{{#operation}}
|
||||
/**
|
||||
* {{summary}}
|
||||
* Sync method
|
||||
* {{notes}}
|
||||
{{#allParams}} * @param {{paramName}} {{description}}
|
||||
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
*/
|
||||
{{#formParams}}{{#-first}}
|
||||
{{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
|
||||
@{{httpMethod}}("{{path}}")
|
||||
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}}
|
||||
{{#allParams}}{{>libraries/retrofit/queryParams}}{{>libraries/retrofit/pathParams}}{{>libraries/retrofit/headerParams}}{{>libraries/retrofit/bodyParams}}{{>libraries/retrofit/formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}
|
||||
);{{/hasMore}}{{/allParams}}
|
||||
|
||||
/**
|
||||
* {{summary}}
|
||||
* Async method
|
||||
{{#allParams}} * @param {{paramName}} {{description}}
|
||||
{{/allParams}} * @param cb callback method
|
||||
* @return void
|
||||
*/
|
||||
{{#formParams}}{{#-first}}
|
||||
{{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
|
||||
@{{httpMethod}}("{{path}}")
|
||||
void {{nickname}}(
|
||||
{{#allParams}}{{>libraries/retrofit/queryParams}}{{>libraries/retrofit/pathParams}}{{>libraries/retrofit/headerParams}}{{>libraries/retrofit/bodyParams}}{{>libraries/retrofit/formParams}}, {{/allParams}}Callback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> cb
|
||||
);
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,68 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
public class ApiKeyAuth implements Interceptor {
|
||||
private final String location;
|
||||
private final String paramName;
|
||||
|
||||
private String apiKey;
|
||||
|
||||
public ApiKeyAuth(String location, String paramName) {
|
||||
this.location = location;
|
||||
this.paramName = paramName;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public String getParamName() {
|
||||
return paramName;
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
String paramValue;
|
||||
Request request = chain.request();
|
||||
|
||||
if (location == "query") {
|
||||
String newQuery = request.uri().getQuery();
|
||||
paramValue = paramName + "=" + apiKey;
|
||||
if (newQuery == null) {
|
||||
newQuery = paramValue;
|
||||
} else {
|
||||
newQuery += "&" + paramValue;
|
||||
}
|
||||
|
||||
URI newUri;
|
||||
try {
|
||||
newUri = new URI(request.uri().getScheme(), request.uri().getAuthority(),
|
||||
request.uri().getPath(), newQuery, request.uri().getFragment());
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
request = request.newBuilder().url(newUri.toURL()).build();
|
||||
} else if (location == "header") {
|
||||
request = request.newBuilder()
|
||||
.addHeader(paramName, apiKey)
|
||||
.build();
|
||||
}
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.squareup.okhttp.Credentials;
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
public class HttpBasicAuth implements Interceptor {
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void setCredentials(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
|
||||
// If the request already have an authorization (eg. Basic auth), do nothing
|
||||
if (request.header("Authorization") == null) {
|
||||
String credentials = Credentials.basic(username, password);
|
||||
request = request.newBuilder()
|
||||
.addHeader("Authorization", credentials)
|
||||
.build();
|
||||
}
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.oltu.oauth2.client.OAuthClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
import org.apache.oltu.oauth2.common.message.types.GrantType;
|
||||
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Request.Builder;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
public class OAuth implements Interceptor {
|
||||
|
||||
private volatile String accessToken;
|
||||
private OAuthClient oauthClient;
|
||||
|
||||
private TokenRequestBuilder tokenRequestBuilder;
|
||||
private AuthenticationRequestBuilder authenticationRequestBuilder;
|
||||
|
||||
public OAuth( OkHttpClient client, TokenRequestBuilder requestBuilder ) {
|
||||
this.oauthClient = new OAuthClient(new OAuthOkHttpClient(client));
|
||||
this.tokenRequestBuilder = requestBuilder;
|
||||
}
|
||||
|
||||
public OAuth(TokenRequestBuilder requestBuilder ) {
|
||||
this(new OkHttpClient(), requestBuilder);
|
||||
}
|
||||
|
||||
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
|
||||
this(OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
|
||||
setFlow(flow);
|
||||
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
|
||||
}
|
||||
|
||||
public void setFlow(OAuthFlow flow) {
|
||||
switch(flow) {
|
||||
case accessCode:
|
||||
case implicit:
|
||||
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
|
||||
break;
|
||||
case password:
|
||||
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
|
||||
break;
|
||||
case application:
|
||||
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain)
|
||||
throws IOException {
|
||||
|
||||
Request request = chain.request();
|
||||
|
||||
// If the request already have an authorization (eg. Basic auth), do nothing
|
||||
if (request.header("Authorization") != null) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
// If first time, get the token
|
||||
OAuthClientRequest oAuthRequest;
|
||||
if (getAccessToken() == null) {
|
||||
updateAccessToken(null);
|
||||
}
|
||||
|
||||
// Build the request
|
||||
Builder rb = request.newBuilder();
|
||||
|
||||
String requestAccessToken = new String(getAccessToken());
|
||||
try {
|
||||
oAuthRequest = new OAuthBearerClientRequest(request.urlString())
|
||||
.setAccessToken(requestAccessToken)
|
||||
.buildHeaderMessage();
|
||||
} catch (OAuthSystemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
for ( Map.Entry<String, String> header : oAuthRequest.getHeaders().entrySet() ) {
|
||||
rb.addHeader(header.getKey(), header.getValue());
|
||||
}
|
||||
rb.url( oAuthRequest.getLocationUri());
|
||||
|
||||
//Execute the request
|
||||
Response response = chain.proceed(rb.build());
|
||||
|
||||
// 401 most likely indicates that access token has expired.
|
||||
// Time to refresh and resend the request
|
||||
if ( response.code() == HTTP_UNAUTHORIZED ) {
|
||||
updateAccessToken(requestAccessToken);
|
||||
return intercept( chain );
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
public synchronized void updateAccessToken(String requestAccessToken) throws IOException {
|
||||
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
|
||||
try {
|
||||
OAuthJSONAccessTokenResponse accessTokenResponse;
|
||||
accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage());
|
||||
setAccessToken(accessTokenResponse.getAccessToken());
|
||||
} catch (OAuthSystemException e) {
|
||||
throw new IOException(e);
|
||||
} catch (OAuthProblemException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public synchronized void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public TokenRequestBuilder getTokenRequestBuilder() {
|
||||
return tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
|
||||
this.tokenRequestBuilder = tokenRequestBuilder;
|
||||
}
|
||||
|
||||
public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
|
||||
return authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
|
||||
this.authenticationRequestBuilder = authenticationRequestBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.oltu.oauth2.client.HttpClient;
|
||||
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
|
||||
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
|
||||
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
|
||||
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
|
||||
public class OAuthOkHttpClient implements HttpClient {
|
||||
|
||||
private OkHttpClient client;
|
||||
|
||||
public OAuthOkHttpClient() {
|
||||
this.client = new OkHttpClient();
|
||||
}
|
||||
|
||||
public OAuthOkHttpClient(OkHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
MediaType mediaType = MediaType.parse("application/json");
|
||||
Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
|
||||
|
||||
if(headers != null) {
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("Content-Type")) {
|
||||
mediaType = MediaType.parse(entry.getValue());
|
||||
} else {
|
||||
requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null;
|
||||
requestBuilder.method(requestMethod, body);
|
||||
|
||||
try {
|
||||
Response response = client.newCall(requestBuilder.build()).execute();
|
||||
return OAuthClientResponseFactory.createCustomResponse(
|
||||
response.body().string(),
|
||||
response.body().contentType().toString(),
|
||||
response.code(),
|
||||
responseClass);
|
||||
} catch (IOException e) {
|
||||
throw new OAuthSystemException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
group = '{{groupId}}'
|
||||
version = '{{artifactVersion}}'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.2'
|
||||
classpath 'com.github.dcendents:android-maven-plugin:1.2'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
|
||||
if(hasProperty('target') && target == 'android') {
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
// Rename the aar correctly
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def outputFile = output.outputFile
|
||||
if (outputFile != null && outputFile.name.endsWith('.aar')) {
|
||||
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
|
||||
output.outputFile = new File(outputFile.parent, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.libraryVariants.all { variant ->
|
||||
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
|
||||
task.description = "Create jar artifact for ${variant.name}"
|
||||
task.dependsOn variant.javaCompile
|
||||
task.from variant.javaCompile.destinationDir
|
||||
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
|
||||
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
|
||||
artifacts.add('archives', task);
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
pom.artifactId = '{{artifactId}}'
|
||||
}
|
||||
}
|
||||
|
||||
task execute(type:JavaExec) {
|
||||
main = System.getProperty('mainClass')
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
okhttp_version = "2.3.0"
|
||||
oltu_version = "1.0.0"
|
||||
retrofit_version = "1.9.0"
|
||||
swagger_annotations_version = "1.5.0"
|
||||
junit_version = "4.12"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "com.squareup.okhttp:okhttp:$okhttp_version"
|
||||
compile "com.squareup.retrofit:retrofit:$retrofit_version"
|
||||
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
|
||||
compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"
|
||||
testCompile "junit:junit:$junit_version"
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.StringUtil;
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
{{#serializableModel}}
|
||||
import java.io.Serializable;{{/serializableModel}}
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
{{#models}}
|
||||
|
||||
{{#model}}{{#description}}
|
||||
/**
|
||||
* {{description}}
|
||||
**/{{/description}}
|
||||
@ApiModel(description = "{{{description}}}")
|
||||
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
|
||||
{{#vars}}{{#isEnum}}
|
||||
|
||||
{{>libraries/okhttp-gson/enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}
|
||||
|
||||
{{>libraries/okhttp-gson/enumClass}}{{/items}}{{/items.isEnum}}
|
||||
@SerializedName("{{baseName}}")
|
||||
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
|
||||
{{/vars}}
|
||||
|
||||
{{#vars}}
|
||||
/**{{#description}}
|
||||
* {{{description}}}{{/description}}{{#minimum}}
|
||||
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
|
||||
* maximum: {{maximum}}{{/maximum}}
|
||||
**/
|
||||
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
|
||||
public {{{datatypeWithEnum}}} {{getter}}() {
|
||||
return {{name}};
|
||||
}
|
||||
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
this.{{name}} = {{name}};
|
||||
}
|
||||
|
||||
{{/vars}}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class {{classname}} {\n");
|
||||
{{#parent}}sb.append(" ").append(StringUtil.toIndentedString(super.toString())).append("\n");{{/parent}}
|
||||
{{#vars}}sb.append(" {{name}}: ").append(StringUtil.toIndentedString({{name}})).append("\n");
|
||||
{{/vars}}sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -0,0 +1,147 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>{{groupId}}</groupId>
|
||||
<artifactId>{{artifactId}}</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>{{artifactId}}</name>
|
||||
<version>{{artifactVersion}}</version>
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:swagger-api/swagger-mustache.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:swagger-api/swagger-codegen.git</developerConnection>
|
||||
<url>https://github.com/swagger-api/swagger-codegen</url>
|
||||
</scm>
|
||||
<prerequisites>
|
||||
<maven>2.2.0</maven>
|
||||
</prerequisites>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>loggerPath</name>
|
||||
<value>conf/log4j.properties</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<argLine>-Xms512m -Xmx1500m</argLine>
|
||||
<parallel>methods</parallel>
|
||||
<forkMode>pertest</forkMode>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/lib</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- attach test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add_sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/main/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add_test_sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/test/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>${swagger-annotations-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>${retrofit-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>${oltu-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<swagger-annotations-version>1.5.0</swagger-annotations-version>
|
||||
<retrofit-version>1.9.0</retrofit-version>
|
||||
<okhttp-version>2.4.0</okhttp-version>
|
||||
<oltu-version>1.0.0</oltu-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
</properties>
|
||||
</project>
|
||||
@@ -0,0 +1 @@
|
||||
{{#isQueryParam}}@Query("{{baseName}}") {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}} {{paramName}}{{/isQueryParam}}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user