Compare commits

...

485 Commits

Author SHA1 Message Date
Tony Tam
c00f4ba805 Merge pull request #1437 from swagger-api/release-prepare
updated versions for release
2015-10-25 19:41:11 -07:00
Tony Tam
dd3b253e15 updated versions 2015-10-25 19:31:36 -07:00
Tony Tam
3969a9f294 fix for #925 2015-10-25 17:02:08 -07:00
Tony Tam
78f8eaa687 set to release version 2015-10-25 16:31:40 -07:00
wing328
fe676c83c0 Merge pull request #1412 from Edubits/swift-alamofire-3.0
Swift Alamofire 3.0
2015-10-25 18:28:39 +08:00
wing328
18370b9076 Merge pull request #1402 from lugaru1234/issue960
Fixes #960: Enums have been added to result file
2015-10-25 17:52:37 +08:00
wing328
70d987666e Merge pull request #1436 from tomekc/swift_enum_naming
Swift enum names capitalization follows Swift convention.
2015-10-25 17:46:14 +08:00
Tomek Cejner
6247dd0cde Swift enum names capitalization follows Swift convention. 2015-10-25 00:06:00 +02:00
wing328
ea7ef990b9 Merge pull request #1432 from xhh/ruby-empty-array
Ruby client: include empty arrays in model serialization
2015-10-24 11:45:27 +08:00
Tony Tam
83afaffd92 Merge pull request #1430 from nbruno/java-child-enum-bug
Ensure hasMore is updated when reconciling enum properties from parent
2015-10-23 08:08:30 -07:00
wing328
d2faa63ebc Merge pull request #1431 from wing328/fix_empty_operation_id
Better error message for empty operationId
2015-10-23 18:47:04 +08:00
xhh
dcec2e7b5d Forgot to use _to_hash for non-array value 2015-10-23 18:03:38 +08:00
xhh
940e76f45f Ruby client: include empty arrays in model serialization 2015-10-23 17:08:12 +08:00
wing328
fecbc3c45d Merge pull request #1306 from fdorothy/master
Specifying configuration files from Codegen class
2015-10-23 15:41:00 +08:00
Tony Tam
a6e4203cd5 added property check 2015-10-22 22:39:09 -07:00
wing328
dd34d75f00 better error message for empty operationId 2015-10-23 12:46:44 +08:00
Nick Bruno
1eed1917b9 Ensure hasMore is updated when reconciling enum properties from parent 2015-10-22 22:33:20 -04:00
Tony Tam
91afec43a6 fixed NPE on empty props 2015-10-22 15:43:02 -07:00
Tony Tam
adeff7855c instructions for selective generation 2015-10-22 15:34:20 -07:00
Tony Tam
e289b858a9 Merge pull request #1428 from swagger-api/feature/selective-generation
made selective generation of models
2015-10-22 15:28:58 -07:00
Tony Tam
7170f7fa01 updated supporitng file support 2015-10-22 15:28:49 -07:00
Tony Tam
6253a592d9 added optional support for apis, supoprtingFiles 2015-10-22 14:54:29 -07:00
Tony Tam
9f842a1295 added environment variable support 2015-10-22 14:34:52 -07:00
Tony Tam
723cf9b823 made selective generation of models 2015-10-22 14:03:44 -07:00
Tony Tam
bbb59f93db Merge pull request #1427 from crissdev/patch-1
Update TypeScriptAngularClientCodegen.java
2015-10-22 14:00:27 -07:00
Cristian Trifan
2fcb705826 Update TypeScriptAngularClientCodegen.java
Fix minor typo
2015-10-22 23:19:46 +03:00
wing328
4723f51c63 Merge pull request #1397 from lugaru1234/issue1251
Fixes #1251, #1212: Form parameters has been added to the html template
2015-10-22 16:48:13 +08:00
wing328
485186e6b6 Merge pull request #1418 from ampem/master
[Perl] Ensure parameters to "each" is a hash in TO_JSON and from_hash
2015-10-22 15:14:27 +08:00
Ampem Darko
1ac6842b5a Update mustache template to pass hashes in TO_JSON and from_hash 2015-10-21 16:15:42 +00:00
Ampem Darko
57e3ea3e9c Ensure parameters to "each" is a hash in TO_JSON and from_hash 2015-10-21 13:35:48 +00:00
wing328
0f75b053c8 Merge pull request #1417 from akkie/master
ApiException doesn't use deserialized data
2015-10-21 19:13:18 +08:00
wing328
eee69f1e05 Merge pull request #1416 from xhh/java-do-not-serialize-nulls
[Java] Ignore null fields in model serialization in Java clients
2015-10-21 19:00:09 +08:00
akkie
9b8a633435 ApiException doesn't use deserialized data
This is a fix for #1394. I had not merged the data correctly after the rebase
2015-10-21 12:56:15 +02:00
Tony Tam
dcc47a92b5 added https support 2015-10-20 21:25:51 -07:00
Tony Tam
e9aaa6da36 enabled https 2015-10-20 21:25:35 -07:00
Tony Tam
568a7be994 enabled https 2015-10-20 21:25:21 -07:00
xhh
214e0186e8 Ignore null fields in model serialization
in Java clients.

Closes #1413
2015-10-21 12:05:27 +08:00
Tony Tam
7f5cdba606 rebuilt 2015-10-20 11:42:40 -07:00
Tony Tam
295af57c9a fixed build error 2015-10-20 11:31:21 -07:00
Tony Tam
bade71c6ba merged 2015-10-20 10:59:20 -07:00
Tony Tam
9adb077a7b Merge branch 'feature/inline-models' 2015-10-20 10:57:50 -07:00
Tony Tam
10a9c62e2b merged 2015-10-20 10:57:36 -07:00
Tony Tam
a6bd0773f7 added files 2015-10-20 10:56:18 -07:00
Tony Tam
b2506ab598 rebuilt 2015-10-20 10:32:19 -07:00
Tony Tam
a21f08118e rebuilt 2015-10-20 10:31:42 -07:00
Tony Tam
96380bbc83 rebuilt 2015-10-20 10:31:17 -07:00
Tony Tam
abe4980449 rebuilt 2015-10-20 10:30:19 -07:00
Tony Tam
e3151c57a0 rebuilt 2015-10-20 10:29:48 -07:00
Tony Tam
d2dc333699 rebuilt 2015-10-20 10:29:25 -07:00
Tony Tam
b41a40f9be rebuilt 2015-10-20 10:28:49 -07:00
Tony Tam
2f3a2413c7 rebuilt 2015-10-20 08:49:26 -07:00
Tony Tam
19ea3ecf66 update test for inline body param flattening 2015-10-20 08:48:44 -07:00
Tony Tam
5c29562926 ensure body params are flattened when type ModelImpl 2015-10-20 08:48:26 -07:00
Tony Tam
b827d06077 fix for npe on map models 2015-10-20 08:48:04 -07:00
Tony Tam
539496d735 rebuilt 2015-10-20 07:10:05 -07:00
wing328
6b7059d23f Merge pull request #1394 from akkie/api-exception-json
Deserialize the response body in case of an ApiException
2015-10-20 18:01:09 +08:00
wing328
bff8f96b99 Merge pull request #1404 from tomekc/swift-enhanced
Add default initializer to Swift model classes.
2015-10-20 17:54:41 +08:00
Tony Tam
5e69d929a0 rebuilt 2015-10-19 23:13:27 -07:00
Tony Tam
e1ee7065d5 rebuilt client 2015-10-19 23:12:02 -07:00
Tony Tam
aaf1df1971 more flattening fixes 2015-10-19 23:10:48 -07:00
Tony Tam
555fd54fbb updated swagger-core versions 2015-10-19 22:09:33 -07:00
Tony Tam
905a7746e7 updated test 2015-10-19 21:45:47 -07:00
Tony Tam
eeaf4071f9 updated to not flatten array, map properties in responses unless necessary 2015-10-19 21:35:45 -07:00
Tony Tam
84b7302f12 updated swagger-core version 2015-10-19 21:34:42 -07:00
Robin Eggenkamp
1b0963ebe0 Minimal changes to upgrade to Alamofire 3.0.0 2015-10-19 17:06:41 +02:00
akkie
b054cd3cc6 Deserialize the response body in case of an ApiException
Currently it's not possible to use custom models in the ApiException because the body gets not deserialized to Json and therefore the object deserializer cannot deserialize it to a custom model. This pull request uses the same mechanism as used to deserialize the response body in case of a 2xx status code.
2015-10-19 15:17:29 +02:00
wing328
4ea797d0e8 Merge pull request #1392 from nbruno/add-auth-annotations-jaxrs
Add authorization scope data to CodegenSecurity
2015-10-19 14:15:05 +08:00
Tony Tam
002feb3e7c build error 2015-10-18 21:10:13 -07:00
Tony Tam
89dc4d29ab added map support 2015-10-18 21:05:57 -07:00
Tony Tam
3cf1f1a56a added support for array and model inline types 2015-10-18 20:51:55 -07:00
Nick Bruno
b83db8e535 Merge remote-tracking branch 'upstream/master' into add-auth-annotations-jaxrs 2015-10-18 17:19:44 -04:00
wing328
eb1e0b5034 Merge pull request #1408 from kkrauth/patch-1
Fix syntax issue when no auth methods defined
2015-10-18 16:34:11 +08:00
wing328
d7b4f58994 Merge pull request #1411 from wing328/master
Add support for top-level consumes and produces
2015-10-17 17:41:19 +08:00
wing328
e8fbdaabe3 replace tabs with spaces 2015-10-17 16:44:55 +08:00
wing328
b82333aea4 Add support for top-level consumes and produces
This reverts commit 0b4b5e8839.
2015-10-17 16:30:19 +08:00
Nick Bruno
7bbb883a00 Generate JAXRS and SpringMVC samples to demo Authorization annotations 2015-10-16 21:25:54 -04:00
Nick Bruno
6477a27579 Update SpringMVC template to include Authorization annotations 2015-10-16 21:24:17 -04:00
Tony Tam
ad1626ad2d added yaml sample 2015-10-16 18:22:13 -07:00
Tony Tam
bfa4303e6e added inline model resolver 2015-10-16 18:21:34 -07:00
Tony Tam
9508579eed added inline resolver 2015-10-16 18:21:06 -07:00
Kosta Krauth
9ac980298f Fix syntax issue when no auth methods defined
When no authentication methods are defined, the generated code does not compile due to where the authMethods closing tag is located. Moved the closing tag further down and opening tag further up so that the generated code is correct both when authentication are and aren't present.
2015-10-16 16:45:34 -04:00
wing328
a2fda604f8 Merge pull request #1396 from akkie/disable-ssl-verification
Allow to disable SSL verification
2015-10-16 21:08:31 +08:00
Tomek Cejner
8339e4b092 Add default initializer to Swift model classes. 2015-10-16 14:09:55 +02:00
wing328
90eab19305 Merge pull request #1401 from xhh/ruby-base-url-slashes
Ruby client: remove trailing slashes from base_url
2015-10-16 19:32:13 +08:00
wing328
8a2c34ba7a Merge pull request #1403 from cbornet/retrofit_useless_import
Remove useless import
2015-10-16 19:12:35 +08:00
wing328
8c5991b793 Merge pull request #1372 from cbornet/retrofit_collectionformat
Add colllectionFormat support to retrofit
2015-10-16 18:50:59 +08:00
cbornet
3debd08a32 remove useless import 2015-10-16 12:47:25 +02:00
cbornet
92d1e8a1d9 use StringUtil to format csv 2015-10-16 12:21:45 +02:00
cbornet
71c5160739 add colllectionFormat support to retrofit
Fix #1364
2015-10-16 12:21:45 +02:00
Nadezhda Makarkina
3dd0b04fb9 Enums have been added to result file 2015-10-16 11:53:05 +03:00
Nadezhda Makarkina
04369ddfce Form parameters has been added to the html template 2015-10-16 10:33:56 +03:00
wing328
084e7f7199 Merge pull request #1380 from xhh/java-global-security
Apply global security to operations when necessary
2015-10-16 12:50:41 +08:00
wing328
ab026fdde3 Merge pull request #1393 from gwen15/genfix
REST client code generation bug fix proposal
2015-10-16 12:42:32 +08:00
xhh
e0dfc1b43d Ruby client: remove trailing slashes from base_url
Closes #1399
2015-10-16 12:02:30 +08:00
wing328
d5e2aea723 Merge pull request #1375 from xhh/issue-1308
Remove duplicate fields from sub-classes of the Java codegen
2015-10-16 12:02:25 +08:00
wing328
d2df310290 Merge pull request #1400 from testn/add-library
add library in the additional option
2015-10-16 12:00:28 +08:00
Nat Luengnaruemitchai
7db67aa192 add library in the additional option 2015-10-15 20:44:27 -07:00
xhh
a1fa0b0834 Rebuild Petstore samples 2015-10-16 10:47:00 +08:00
xhh
02a9fe2618 Add more test cases for global security 2015-10-16 10:30:26 +08:00
akkie
97a5a8922f Allow to disable SSL verification
This pull request adds the possibility to disable SSL verification for hosts using a self-signed SSL certificate
2015-10-15 16:07:35 +02:00
gwen15
0802f94d94 Bug fix: some character replacement where done on the local directories
names.

The dot character was replaced by the file separator on the whole paths,
not only on the package name based part.
2015-10-15 12:35:23 +02:00
gwen15
21eb406140 Fix default long value in java client code generation
The generated java code for a Long was "Long id=1;" which is not
compilable by javac because "1" is a primitive integer that cannot be
cast to a Long object. This fix generates now "Long id=1l;".
2015-10-15 12:35:16 +02:00
xhh
84928abd8d Merge branch 'master' into java-global-security 2015-10-15 17:57:27 +08:00
xhh
1c21730607 Log a warning on more than 1 security requirements 2015-10-15 17:56:38 +08:00
xhh
5a76a1b155 Fix tests regarding security 2015-10-15 16:51:43 +08:00
xhh
bc5a610567 Use the first security requirement from the array
According to swagger spec, "there is a logical OR between the security
requirements". The original behavior was to apply the security
requirements as the logic AND and skip security requirements that
include more that 1 security.
2015-10-15 15:17:30 +08:00
wing328
860b551e9b Merge pull request #1376 from xhh/java-util-model-package
[Java] Add a config option to use fully qualified name for java.util classes
2015-10-15 12:12:37 +08:00
wing328
22218cb132 Merge pull request #1378 from xhh/java-invalid-enum-name
[Java] Handle enum names starting with number in Java client
2015-10-15 10:51:03 +08:00
Nick Bruno
300a0dc82c Update retrofit library for changes to OAuth scope handling 2015-10-14 22:50:58 -04:00
wing328
3a66c0c710 Merge pull request #1384 from cbornet/retrofit_test_sample
Add retrofit to CI verified samples
2015-10-15 10:42:40 +08:00
xhh
a94384ca7f Merge branch 'master' into java-util-model-package 2015-10-15 10:38:19 +08:00
xhh
6d50ce6a77 Fix a typo 2015-10-15 10:34:45 +08:00
wing328
583493f5ca Merge pull request #1377 from cbornet/java_gradle_android
Add gradle files with android support to java templates
2015-10-15 10:28:28 +08:00
Nick Bruno
6cc17d8508 Add authorization scope data to CodegenSecurity, demo use in JAXRS 2015-10-14 22:07:43 -04:00
wing328
265b4b5945 Merge pull request #1385 from aersamkull/master
Updates to TypeScript Templates 2
2015-10-15 09:46:46 +08:00
xhh
65e63a8c52 Merge remote-tracking branch 'origin/master' into java-global-security 2015-10-14 20:42:20 +08:00
xhh
e4e77d03f5 Add test cases for global security 2015-10-14 20:40:10 +08:00
wing328
638bbfaf43 Merge pull request #1386 from swagger-api/revert-1370-global_consume
Revert "Add support for top-level consumes and produces"
2015-10-13 23:56:57 +08:00
wing328
0b4b5e8839 Revert "Add support for top-level consumes and produces" 2015-10-13 23:47:42 +08:00
wing328
c7b08bc112 Merge pull request #1373 from estiller/master
Fix bug in handling 204 "No Content" responses from the server in Android & Java generated clients
2015-10-13 22:47:47 +08:00
wing328
f1b0cf839a Merge pull request #1370 from wing328/global_consume
Add support for top-level consumes and produces
2015-10-13 22:35:33 +08:00
aersamkull
988de07c17 Fixes noImplicitAny Error 2015-10-13 13:32:01 +02:00
cbornet
f603efc419 add retrofit to CI verified samples 2015-10-13 12:18:32 +02:00
aersamkull
4e7d893a8e Updates to TypeScript Templates 2015-10-13 12:01:34 +02:00
xhh
1ef51e5ad7 Apply global security to operations when necessary
Closes #1365
2015-10-13 16:22:02 +08:00
xhh
17545e959a Handle enum names starting with number in Java client 2015-10-13 10:32:07 +08:00
cbornet
5ed52b3e1d add gradle files with android support 2015-10-12 16:16:38 +02:00
wing328
6ce09ee779 Update config option 2015-10-12 17:34:07 +08:00
xhh
7b1799f874 Merge branch 'master' into java-util-model-package
Conflicts:
	samples/client/petstore/java/default/src/main/java/io/swagger/client/api/PetApi.java
	samples/client/petstore/java/default/src/main/java/io/swagger/client/api/StoreApi.java
	samples/client/petstore/java/default/src/main/java/io/swagger/client/api/UserApi.java
	samples/client/petstore/java/default/src/main/java/io/swagger/client/model/Order.java
	samples/client/petstore/java/default/src/main/java/io/swagger/client/model/Pet.java
2015-10-12 17:11:43 +08:00
xhh
43b3acf550 Remove duplicate fields from sub-classes of the Java codegen
Closes #1308
2015-10-12 17:07:17 +08:00
wing328
d162d48fa3 Merge pull request #1359 from wing328/better_exception_handling2
Better exception handling
2015-10-12 16:58:01 +08:00
Eran Stiller
e562b0ae34 Fix indentation 2015-10-12 09:52:20 +03:00
Eran Stiller
748460488a Regenerate only the ApiInvoker.java file in the sample 2015-10-12 09:25:24 +03:00
Eran Stiller
1fb2a97497 Revert "Regenerate Android-Java sample"
This reverts commit 15f5eae2a8.
2015-10-12 09:22:36 +03:00
Eran Stiller
15f5eae2a8 Regenerate Android-Java sample 2015-10-12 08:52:52 +03:00
Eran Stiller
6fd54d5285 Fix bug in handling 204 responses 2015-10-12 08:51:00 +03:00
wing328
00517a1ad3 remove unused operation in test json file 2015-10-10 23:27:21 +08:00
wing328
5cd01af350 fix typo in test cases 2015-10-10 23:22:42 +08:00
wing328
9ecb2e92ae restore sample files for objc, php and ruby 2015-10-10 23:13:26 +08:00
wing328
6cc5a32d40 update objc sample 2015-10-10 23:09:41 +08:00
wing328
64fd94262f add globalConsumesAndProduces.json 2015-10-10 22:54:13 +08:00
wing328
5144c54895 add test case for global consumes and produces 2015-10-10 22:47:24 +08:00
wing328
9311dcaccb update codegen to support global consumes and produces 2015-10-10 18:39:54 +08:00
Tony Tam
a5a6ae72c3 Merge pull request #1368 from ducin/badge-maven-central
maven central badge added
2015-10-09 09:38:50 -07:00
Tomasz Ducin
c31ed5a30d maven central badge added 2015-10-09 18:14:27 +02:00
xhh
aa0fbada07 Add a "fullJavaUtil" option to Java clients
to toggle whether to use full qualified name (with full package prefix)
for classes under java.util
2015-10-09 22:10:22 +08:00
xhh
ab34dc5697 Rebuild Java cilents of the Petstore sample 2015-10-09 22:10:21 +08:00
xhh
edf2642e73 Support model name like "List" in Java clients
Support generating model files with name like "List", "Map" and "Date"
by using full qualified names when using them from the java.util
package.
2015-10-09 22:10:21 +08:00
wing328
d95660aca1 Merge pull request #1340 from onnertech/ios-tweaks
[objc] Add casts that avoid method resolution errors for `count`
2015-10-09 16:44:54 +08:00
wing328
297f9e961c Merge pull request #1362 from cristiangarciascmspain/fix-OSX-Pom-TestNG
Add StartAttachListener that fixes #1330
2015-10-09 15:34:15 +08:00
wing328
42b716207f Merge pull request #1360 from wing328/nodejs_server_port
[NodeJS] update index.js to use the var serverPort
2015-10-09 11:32:01 +08:00
wing328
7d69107696 Merge pull request #1356 from arnested/deserialize-httpHeader
Deserialize httpHeader.
2015-10-09 11:31:24 +08:00
wing328
4d2fb1cc9a Merge pull request #1355 from arnested/usage-of-httpHeader-in-exceptions
Use HTTP headers from ApiException in PHP client.
2015-10-09 11:31:15 +08:00
cristiangarciascmspain
503ffd06d0 Add StartAttachListener that fixes #1330 2015-10-08 18:30:13 +02:00
wing328
725df15dd5 update sample for nodejs 2015-10-08 23:57:14 +08:00
wing328
8e9e3a6171 update nodejs to use the var serverport 2015-10-08 23:52:41 +08:00
wing328
6ee42bebe6 add exception handling for #1267 2015-10-08 23:38:09 +08:00
wing328
69a346cb57 remove python3 frmo all-petstore.sh 2015-10-08 23:38:09 +08:00
wing328
d451d4efb8 fix NPE when model's allof with no property 2015-10-08 23:38:09 +08:00
Arne Jørgensen
b7b8b527db Use HTTP headers from ApiException in PHP client.
The `$httpHeader` variable was not set when catching exceptions.

See also #1354.

Regenerated php-petstore sample.
2015-10-08 11:46:36 +02:00
Arne Jørgensen
3bd4502bbf Deserialize httpHeader.
See #1354.

Regenerated php-petstore sample.
2015-10-08 11:25:43 +02:00
Tony Tam
733e19c113 fixed NPE for objc client 2015-10-07 17:11:52 -07:00
wing328
735cae7b49 Merge pull request #1335 from wing328/html_remove_site_css
[HTML] remove site.css from html docs
2015-10-07 16:26:53 +08:00
wing328
3b36bbe97d Update README.mustache 2015-10-06 18:39:44 +08:00
wing328
228e039046 Merge pull request #1333 from wing328/csharp_fix_accept
[C#] better Accept header selection for C# API client
2015-10-06 18:26:02 +08:00
wing328
b27663e1ad Update README.md 2015-10-06 16:14:13 +08:00
wing328
eaddebe220 Update list of generator 2015-10-06 16:13:06 +08:00
wing328
f8485f26d3 Merge pull request #1317 from cbornet/online_options
Add options to online generator
2015-10-06 12:00:51 +08:00
Ches Martin
d9117480f8 [objc] Add casts that avoid method resolution errors
Because the `data` that we're deserializing is of type `id` (essentially
untyped), it's possible to have method resolution clashes without
explicitly casting here once we've parsed a type. I had this issue with
a pagination container model, for instance, which has a field named
`count` that conflicts with the property of the same name on `NSArray`
or `NSDictionary`.
2015-10-06 10:58:48 +07:00
wing328
7b79abef63 update c# sample 2015-10-06 11:33:00 +08:00
wing328
dbd89092f0 add accept header select to async method 2015-10-06 11:30:17 +08:00
wing328
6ed7663466 add remarks to csharp method 2015-10-06 11:28:18 +08:00
wing328
d882e9fe0a remove site.css from html docs 2015-10-05 22:33:25 +08:00
wing328
ea1c2809f7 Merge pull request #1329 from iushankin/issue-1304-part3
Fixed #1304: Migrate tests from the Scala to the plain Java. Part 3
2015-10-05 18:29:36 +08:00
wing328
3c78e29a12 better Accept header for C# 2015-10-05 13:19:58 +08:00
wing328
6cb4473526 Merge pull request #1328 from ducin/docs-toc
readme: Table of Contents
2015-10-05 00:05:32 +08:00
wing328
65a9c78544 Merge pull request #1319 from cbornet/online_version
Add version to swagger.json from pom's version
2015-10-04 23:57:16 +08:00
wing328
69911a1974 Merge pull request #1311 from xhh/java-okhttp-gson-ssl
Add some SSL options to Java okhttp-gson client
2015-10-04 23:02:25 +08:00
wing328
761029241e Merge pull request #1331 from qswinson/csharp_comments
Csharp comments
2015-10-03 10:31:44 +08:00
Quenby Mitchell
1018ca634d generic types need to be escaped for the xmldoc to work for return documentation. List<Foo> should be List{Foo} for the c# compiler to generate the documentation for the generic type. since there is not a spare parameter on the CodegenOperation model to put this correctly formatted documentation, for right now, don't include the return type in the documentation. 2015-10-02 13:11:54 -05:00
Quenby Mitchell
ff0b0c15a8 fix build warnings on CSharp xml comments 2015-10-02 12:14:41 -05:00
wing328
727c32f2a2 Merge pull request #1312 from iushankin/issue-1304
Issue #1304: Migrate tests from the Scala to the plain Java. Part 2
2015-10-02 23:50:37 +08:00
wing328
3c0eab65f3 Merge pull request #1323 from cbornet/fix_scopes_npe
Fix NPE in empty operation oauth scopes
2015-10-02 23:39:25 +08:00
wing328
a72ac99c91 Merge pull request #1316 from cbornet/dynamic_enum
Dynamically fill swagger enum from codegen client names
2015-10-02 23:37:15 +08:00
Ivan Ushankin
4b62a94350 Fixed #1304: Migrate tests from the Scala to the plain Java. Part 3 2015-10-02 16:20:16 +03:00
Tomasz Ducin
12d8f97aee improving ToC 2015-10-01 23:26:24 +02:00
Tomasz Ducin
acaf1b1cd0 added Table of Contents
Initial version of table of contents - showing all headers in the current shape.
2015-10-01 23:14:34 +02:00
cbornet
c1c3439b86 fix some wrong indentations 2015-10-01 17:42:33 +02:00
cbornet
5744bb4053 fix npe in empty operation scopes
Fix #1322
2015-10-01 17:35:07 +02:00
wing328
2711e375cc Merge pull request #1310 from wing328/fix_dynamic_html_parameter_name
[HTML] Fix parameter name in dynamic-html
2015-10-01 20:07:29 +08:00
cbornet
25abc15233 add version to swagger.json from pom's version
Fix #1314
2015-10-01 14:00:19 +02:00
cbornet
984b645ea1 add options to online generator
Fix #1313
2015-10-01 11:09:25 +02:00
wing328
253c46a0d5 Merge pull request #1309 from wing328/fix_springmvc_object
[SpringMVC] fix compilation error by removing import of Object
2015-10-01 10:02:20 +08:00
cbornet
7c431a8e11 dynamically fill swagger enum from codegen client names 2015-10-01 01:12:09 +02:00
Ivan Ushankin
3c98e32765 Issue #1304: Migrate tests from the Scala to the plain Java. Part 2 2015-09-30 17:38:01 +03:00
xhh
f483f934d8 Add some SSL options Java okhttp-gson client
* Add the `verifyingSsl` option to allow skipping verifying SSL
  certificate and host name (default to verify)
* Add `sslCaCert` to allow customizing the CA certificates
2015-09-30 19:48:18 +08:00
wing328
053af7a749 Merge pull request #1305 from iushankin/issue-1304
Fixed #1304: Migrate tests from the Scala to the plain Java. Part 1
2015-09-30 17:57:05 +08:00
wing328
d2d6ff661a fix parameter name in dynamic html 2015-09-30 17:24:11 +08:00
wing328
17bdd73891 fix springmvc by removing import of Object 2015-09-30 16:28:17 +08:00
Tony Tam
d9bfb884da Merge pull request #1307 from warnyul/master
Fix objc model inheritance.
2015-09-29 22:58:43 -07:00
Balázs Varga
19d8766363 Fix model inheritance. 2015-09-29 10:07:51 +02:00
wing328
e270fdcfd9 Merge pull request #1300 from geekerzp/python_client_cert
[Python] Support client certificate file and client key file in TLS/SSL
2015-09-29 14:50:11 +08:00
wing328
a2f47672e7 Merge pull request #1297 from geekerzp/objc_upload_file
[Objc] Add test case in objc client
2015-09-29 14:49:37 +08:00
wing328
90dc0a7bd8 Merge pull request #1302 from geekerzp/ruby_client_cert
[Ruby] Support client ceritficate in ruby client
2015-09-29 14:44:17 +08:00
Fredric Dorothy
2a679f798a Merge https://github.com/fdorothy/swagger-codegen 2015-09-28 11:52:30 -05:00
Fredric Dorothy
dbecb9e562 Added ability to set a configuration file for custom code generators. This should work the same as when you're using one of the built-in generators. 2015-09-28 11:50:08 -05:00
Ivan Ushankin
4db86003f5 Fixed #1304: Migrate tests from the Scala to the plain Java. Part 1 2015-09-28 19:03:02 +03:00
Tony Tam
d5cf2b6cfe made host dynamic for link generation 2015-09-28 08:51:39 -07:00
geekerzp
6a3108a6bf Support client ceritficate in ruby client 2015-09-28 16:31:47 +08:00
wing328
2ea3816e65 Merge pull request #1290 from geekerzp/model_name
[Python, Ruby] Fix issues in python and ruby clients
2015-09-28 08:35:28 +08:00
wing328
baca3027f4 Merge pull request #1298 from geekerzp/ruby_upload_file
[Ruby] Add test case in ruby client
2015-09-27 22:20:20 +08:00
wing328
0e9e2046e7 Merge pull request #1293 from xhh/fix-set-date-format
[Java jersey2]: Fix ApiClient.setDateFormat in Java jersey2 client
2015-09-27 21:48:53 +08:00
wing328
e301020acc Merge pull request #1295 from geekerzp/python_upload_file
[Python] Fix issue in python client
2015-09-27 21:48:29 +08:00
geekerzp
cf1f113852 Support client certificate file and client key file in TLS/SSL in python client 2015-09-26 16:16:59 +08:00
wing328
c26a387d9a Merge pull request #1271 from laurentvdl/master
implement form parameter support using Angular $httpParamSerializer
2015-09-26 09:37:40 +08:00
geekerzp
c70ca9d572 Add test case in ruby client 2015-09-25 17:33:39 +08:00
geekerzp
6bdfb8810c Add test case in objc client 2015-09-25 16:48:19 +08:00
wing328
2a5ab78056 Merge pull request #1296 from xhh/fix-enum-constructor
Fix hard-coded constructor name of enum class in Java okhttp-gson client
2015-09-25 16:34:13 +08:00
xhh
e5a4ef3ba0 Fix hard-coded constructor name of enum class
in Java okhttp-gson client
2015-09-25 15:52:52 +08:00
geekerzp
9b148be57e Fix issue in python client.
If upload only file it will not send file content.
2015-09-25 15:10:32 +08:00
wing328
0380fc5a35 Merge pull request #1274 from geekerzp/objc_log
[Objc] Update objc debug logging
2015-09-25 11:57:28 +08:00
xhh
597282742b Fix ApiClient.setDateFormat in Java jersey2 client 2015-09-24 21:56:50 +08:00
wing328
5e805c2be6 Merge pull request #1284 from acourtneybrown/master
Fixed method name in Java ApiClient mustache template
2015-09-24 16:39:46 +08:00
wing328
b080abeb01 Merge pull request #1280 from xhh/primitive-string-response
[Java] Support primitive string response in Java clients
2015-09-24 16:37:17 +08:00
geekerzp
2943f41cdd Update python and ruby clients.
Use `sanitizeName` to sanitize model name.
2015-09-24 16:29:20 +08:00
geekerzp
84e0df6115 Fixed issue that model name not camelized in python client and ruby client 2015-09-24 16:23:44 +08:00
wing328
a49826e4d7 Merge pull request #1289 from geekerzp/python_log
[Python] Update python log
2015-09-24 16:09:06 +08:00
wing328
b8792b6a71 Merge pull request #1276 from bedag/master
Better diagnostics when something goes wrong
2015-09-24 11:42:48 +08:00
wing328
5ee86b9816 Merge pull request #1264 from xhh/java-enum-improvements
[Java] Improvements on enum var name in Java client
2015-09-24 11:42:11 +08:00
geekerzp
e32272aedb Update log in python client 2015-09-24 10:54:24 +08:00
wing328
ee7f447f77 Merge pull request #1187 from Edubits/swift-2.0
[Swift] Update generated code to Swift 2.0
2015-09-24 10:51:05 +08:00
wing328
a5fb689615 Merge pull request #1260 from wing328/remove_python3_generator
[Python] remove python3 generator
2015-09-24 10:50:47 +08:00
geekerzp
a26cf60a22 Revert "Revert "[Python] Fix issue in python client""
This reverts commit c59e2b88b1.
2015-09-24 10:08:16 +08:00
wing328
ed13d7b1b8 Merge pull request #1288 from swagger-api/revert-1281-python_log
Revert "[Python] Fix issue in python client"
2015-09-24 09:41:18 +08:00
wing328
c59e2b88b1 Revert "[Python] Fix issue in python client" 2015-09-24 09:30:49 +08:00
wing328
e8d40a146c Merge pull request #1281 from geekerzp/python_log
[Python] Fix issue in python client
2015-09-24 09:27:00 +08:00
Adam Brown
4ef69794a3 Fixed method name in Java ApiClient mustache template 2015-09-23 14:16:26 -07:00
geekerzp
30fbdd4d05 Add class prefix to macro DebugLog in objc client 2015-09-23 17:18:07 +08:00
geekerzp
13c079342e Fixed issue #1262 2015-09-23 14:55:46 +08:00
xhh
a284bb7a51 Rebuild Java clients of the Petstore sample 2015-09-23 13:31:28 +08:00
xhh
44bbe301cb Support primitive string response in Java clients 2015-09-23 12:50:38 +08:00
wing328
69f8274287 Merge pull request #1272 from wing328/add_cli_parameter_order
Add CLI option to sort method arguments
2015-09-23 09:47:00 +08:00
wing328
770ea9d12e Merge pull request #1270 from xhh/php-sanitize-model-name
Fix #1145: sanitize model name in PHP client
2015-09-23 09:44:38 +08:00
wing328
d09d8bb495 Merge pull request #1269 from efossier/expose-readonly-to-template
Expose readOnly attribute on model properties to templates
2015-09-23 09:29:49 +08:00
wing328
85f99934c8 Merge pull request #1256 from cbornet/java_retrofit_lib
Set retrofit as a java library
2015-09-23 09:12:07 +08:00
Adrian Moos
66dee928d2 consistent indentation (spaces, not tabs) 2015-09-22 18:08:47 +02:00
Adrian Moos
d4a94fbf52 - DefaultGenerator now communicates failures by throwing exceptions
rather than setting a status flag in a public field
- DefaultGenerator now decorates exceptions to record where a failure
occured (which api, model or operation?)
- CodeGenMojo now propagates this exception to maven to abort the build
2015-09-22 18:01:29 +02:00
geekerzp
844cae75b7 Update debug logging in objc client 2015-09-22 16:32:15 +08:00
wing328
4e4e9e7893 add a CLI option to sort method argument 2015-09-22 15:57:22 +08:00
Laurent Van der Linden
61690d625f change the constructor signature to be backwards compatible
update petstore samples for angular and node
2015-09-22 09:20:52 +02:00
Laurent Van der Linden
1cd8141645 implement form parameter support using Angular $httpParamSerializer 2015-09-22 08:37:49 +02:00
wing328
98ff2d231f Merge pull request #1261 from wing328/typescript-node-fix-param-name
[TypeScript] fix parameter name for typescript-node using baseName
2015-09-22 14:22:07 +08:00
xhh
09add2d871 Fix test failure by allowing backslash in model name 2015-09-22 14:03:27 +08:00
xhh
9cbf2d3707 Fix #1145: sanitize model name in PHP client 2015-09-22 11:33:11 +08:00
geekerzp
0622838947 Fixed issues about logging in objc client 2015-09-22 09:29:48 +08:00
Evan Fossier
a6df340cdc Expose readOnly attribute on model properties to templates, can now use isReadOnly property in model templates 2015-09-21 17:34:23 -07:00
xhh
bcbf9c54c7 Remove unnecessary checking of empty string 2015-09-21 18:14:57 +08:00
xhh
6dcaa890cf Improvements on enum var name in Java client
* Place each enum var in a separate line
* Truncate common prefix when present
2015-09-21 17:29:26 +08:00
wing328
2b06a81a52 remove extra line break in typescript-node sample code 2015-09-20 23:17:04 +08:00
wing328
956624f1a4 remove extra line break for typescript-node 2015-09-20 23:15:02 +08:00
wing328
b1728aed7c update sample for typescript-node 2015-09-20 23:11:46 +08:00
wing328
8733be9ac9 update sample, fix formData basename 2015-09-20 23:06:29 +08:00
wing328
c203854254 fix parameter name for typescript-node using baseName 2015-09-20 22:59:56 +08:00
wing328
3dc3af8d18 remove python3 generator 2015-09-20 22:43:43 +08:00
wing328
cbc2fb237d Merge pull request #1252 from seanbright/model-with-no-props
Fix NPE in JavaClientCodegen when model has no properties of its own
2015-09-20 21:57:05 +08:00
wing328
b7d64d1352 Merge pull request #1254 from GoodTRKR/master
[Obj-C] removed extraneous logs unless logging is specifically enabled in the [SWGConfiguration sharedConfig] instance
2015-09-19 01:04:10 +08:00
cbornet
047b06ac84 remove retrofit codegen from config 2015-09-18 15:03:55 +02:00
cbornet
f29f5d6f13 fix error with formParams in async ops 2015-09-18 14:45:37 +02:00
cbornet
1863aca0fa set retrofit as a java library
Fix #1247
Fix #1248
2015-09-18 14:21:48 +02:00
wing328
cf300c09da Merge pull request #1246 from laurentvdl/patch
Use the baseName when referring to path and query parameters.
2015-09-18 16:46:46 +08:00
wing328
27ab9c2e57 Merge pull request #1238 from DariusMR/master
unicode type forgotten in api_client.mustache for python
2015-09-18 16:44:35 +08:00
Laurent Van der Linden
c83c564a19 Use the baseName when referring to header parameters. 2015-09-18 08:05:13 +02:00
wing328
8978a0a906 Merge pull request #1242 from xhh/options-http-method
[Java okhttp-gson] Support the "OPTIONS"  HTTP method
2015-09-18 10:47:27 +08:00
wing328
6d21422bad Merge pull request #1245 from geekerzp/objc_ssl
[Objc] Enhancements of objc client
2015-09-18 10:45:43 +08:00
Matthew Davis
65cfa735d5 [Obj-C] removed extraneous logs unless logging is specifically enabled in the [SWGConfiguration sharedConfig] instance 2015-09-17 17:39:26 -07:00
Sean Bright
e2ce427fb1 Fix NPE in JavaClientCodegen when model has no properties of its own
A model that inherits from another model and does not add its own properties
causes JavaClientCodegen to crash silently with an NPE.

Fixes #1141
2015-09-17 14:35:07 -04:00
Laurent Van der Linden
781458b0d1 Use the baseName when referring to path and query parameters. 2015-09-17 12:46:20 +02:00
DariusM
65f86dbb0f unicode type forgotten in api_client.mustache for python2, works also with python3 2015-09-17 10:31:40 +02:00
DariusM
cc1c495ea5 unicode type forgotten in api_client.mustache 2015-09-17 10:26:08 +02:00
geekerzp
261ae79528 Remove space from parameterToString in objc client 2015-09-17 15:59:03 +08:00
geekerzp
fb14585adf Add parameterToString method 2015-09-17 15:20:11 +08:00
wing328
27e434d786 Merge pull request #1239 from ePaul/feature/use-baseName-for-jsonproperty
Use the swagger property names in all Java models.
2015-09-17 14:43:21 +08:00
wing328
2a37c48e12 Merge pull request #1243 from process/patch-1
[DOC] fix typo in Python api_client template
2015-09-17 14:42:45 +08:00
Justin Chines
85df7c8ed7 [DOC] fix typo in Python api_client template 2015-09-16 22:09:01 -07:00
wing328
b3ca9cdbe0 Merge pull request #1154 from cbornet/retrofit_oauth
[Retrofit] add authorizations to retrofit client
2015-09-17 11:47:06 +08:00
xhh
477d5c40d9 Rebuild Java okhttp-gson client of Petstore sample 2015-09-17 10:22:53 +08:00
xhh
460c8caa8a Support OPTIONS in Java okhttp-gson client 2015-09-17 10:22:53 +08:00
wing328
53e13aee19 Merge pull request #1234 from geekerzp/python_http_verb
[Python] Enhancements http verbs of python client
2015-09-16 22:32:58 +08:00
wing328
ec05dc4414 Merge pull request #1236 from wing328/springmvc_file_upload
[SpringMVC] Replaced hard-coded fileDetail with {{baseName}}
2015-09-16 18:17:12 +08:00
Paul Ebermann
7eec769654 Use the swagger property names in all Java models.
This changes `@JsonProperty({{name}})` to `@JsonProperty({{baseName}})` in model.mustache for JavaInflector, JavaJaxRS and JavaSpringMVC.
In pull request #535 this was already done for the plain Java files (which get used on client side).

This replaces the sanitized names in the generated code by the original property names from the swagger document.
2015-09-16 11:36:51 +02:00
wing328
f483b8dfa8 Merge pull request #1233 from geekerzp/ruby-apiclient
Fix issue that using temp_folder_path from ApiClient in ruby client
2015-09-15 22:28:54 +08:00
wing328
2ac41ff080 repalced hard-coded fileDetail with {{baseName}} 2015-09-15 22:14:13 +08:00
geekerzp
ade61c0701 Support http body in OPTIONS request in python client 2015-09-15 17:48:59 +08:00
geekerzp
bd63c1d9d9 Support OPTIONS http verb in python client. 2015-09-15 16:40:23 +08:00
geekerzp
5d1e70544c Fix issue that using temp_folder_path from ApiClient
It should use the one from the Configuration object
2015-09-15 15:04:39 +08:00
wing328
349702adf9 Merge pull request #1232 from geekerzp/python_issue
Fix issue in python client
2015-09-15 12:14:49 +08:00
wing328
88410635b3 Merge pull request #1228 from geekerzp/objc_ssl
Objc client ssl verification
2015-09-15 10:14:20 +08:00
geekerzp
0262d3c8d2 Fix issue #1230 2015-09-15 09:57:55 +08:00
wing328
96f4a3ab71 Merge pull request #1226 from xhh/java-okhttp-gson-file-downloading
[Java okhttp-gson] Add support of file downloading
2015-09-14 22:09:48 +08:00
geekerzp
b0063d9e9f Objc client ssl verification 2015-09-14 18:29:49 +08:00
wing328
48bd888483 Merge pull request #1222 from madhukard/master
Java: Support List of Enums in postProcessModels
2015-09-14 01:21:34 +08:00
wing328
1358e33bf6 Merge pull request #1223 from GoodTRKR/master
[Obj-C] Fixed an issue where NSNumber parameters would cause a crash in multipart/form-data upload endpoints
2015-09-14 00:28:43 +08:00
wing328
c8edacb25c Merge pull request #1225 from wing328/fix_getHasXXXParam
Fix getHasXxxParam in CodegenOperation
2015-09-13 22:15:50 +08:00
wing328
47dc4d7642 Merge pull request #1218 from wing328/csharp_fix_map_string
[C#] update map to use String instead of string
2015-09-13 22:15:22 +08:00
xhh
1ecb8a74c1 Allow customizing temp folder for file downloading 2015-09-13 21:02:22 +08:00
xhh
967c574f5b Support file downloading in Java okhttp-gson client 2015-09-13 18:41:53 +08:00
wing328
8bb8a7a79a fix getHasXxxParam 2015-09-12 16:00:10 +08:00
Matthew Davis
1268b0627f added NSNumber catch to pathParams as well 2015-09-11 17:33:36 -07:00
Matthew Davis
761f172c2f forgot an 'else' statement 2015-09-11 17:27:25 -07:00
Matthew Davis
1321d5f9a5 [Obj-C] Fixed an issue where NSNumber parameters would cause a crash in multipart/form-data upload endpoints 2015-09-11 17:23:48 -07:00
Madhukar Devaraju
35f462f571 Java: Support List of Enums in postProcessModels 2015-09-11 14:56:37 -07:00
wing328
f21fa08cd6 update C# ParamterToString to support array of object, add test case 2015-09-11 22:48:38 +08:00
wing328
16afd4ee9b update map to use String instead of string 2015-09-11 18:02:51 +08:00
wing328
46f78f2180 Merge pull request #1215 from xhh/java-last-resp-info
[Java jersey2 okhttp-gson] Fix compilation error, record status code and response headers of last request
2015-09-11 16:05:09 +08:00
xhh
2e402bba97 Rebuild Java clients for the petstore sample 2015-09-11 13:22:37 +08:00
xhh
34f196a144 Java-okhttp-gson: allow access to status code and response headers of last (async) request 2015-09-11 13:22:37 +08:00
xhh
def3f5b3fb Java-jersey2: record status code and response headers of last request 2015-09-11 13:22:37 +08:00
xhh
60e5a34534 Update Java-jersey2 client to skip binary support
Binary parameter/response support was added to the default Java client
codegen which changed the signature of the `invokeAPI` method in
"api.mustache", causing the "jersey2" client fail to compile.
Here an separate version of `api.mustache` is added for "jersey2" client
which does not handle binary support (for now).
2015-09-11 13:22:37 +08:00
wing328
1eed90f34e Merge pull request #1214 from GoodTRKR/master
[Obj-C] Fixed an issue with incorrect references in the ApiClient when using a custom prefix.
2015-09-11 09:30:58 +08:00
wing328
e34063f0f2 Merge pull request #1213 from LeoYReyes/patch-1
[C#] Api.mustache - Remove the parameter in the BasePath getter
2015-09-11 08:41:08 +08:00
Matthew Davis
dbdcf34044 [Obj-C] Fixed an issue with incorrect references in the ApiClient when using a custom prefix. 2015-09-10 15:14:53 -07:00
Leo
43d71ed10c Remove the parameter in the BasePath getter
The parameter in the BasePath getter is not needed.
2015-09-10 12:17:23 -05:00
wing328
b3db24ead6 Merge pull request #1210 from arnested/missing-head-and-options-in-php-client
Add HEAD and OPTIONS support in PHP client.
2015-09-10 22:07:31 +08:00
wing328
d21c6f2b45 Merge pull request #1205 from wing328/SLF4J_warning
update pom.xml to remove warning
2015-09-10 21:52:45 +08:00
Arne Jørgensen
3c3762fd92 Add HEAD and OPTIONS support in PHP client.
The generated PHP client didn't support the HEAD and OPTIONS methods.

Followup on #1156 and #1201.
2015-09-10 14:55:49 +02:00
Robin Eggenkamp
0edbfeff15 Bump Alamofire version to final 2.0.0 2015-09-10 14:24:55 +02:00
Ron
4b539a9d6e Merge pull request #1206 from wing328/fix_sinatra_type
[Sinatra] fix sinatra type (tag)
2015-09-09 15:59:22 +03:00
wing328
71a3218bb3 fix sinatra type (tag) 2015-09-09 20:27:59 +08:00
wing328
d37cf6595a update pom.xml to get rid of the warning 2015-09-09 16:20:17 +08:00
wing328
1bac705876 Merge pull request #1200 from wing328/dart_permission
[Dart] update dart-petstore.sh permission
2015-09-08 22:28:12 +08:00
wing328
3385082e2c Merge pull request #1201 from arnested/missing-head
Fix HEAD path item is missing.
2015-09-08 22:28:03 +08:00
wing328
2b1a63a7de Merge pull request #1150 from ePaul/bugfix/1146-escape-line-breaks-in-response-description
jaxrs: escape line breaks in response description
2015-09-08 21:38:50 +08:00
wing328
93847d8dc7 Merge pull request #1149 from ePaul/feature/1146-do-not-escape-javadocs
jaxrs (and other Java generators): do not escape newlines in generated javadocs.
2015-09-08 21:17:14 +08:00
Arne Jørgensen
3514bf14b3 Fix HEAD path item is missing.
Fixes #1156.
2015-09-08 10:00:17 +02:00
wing328
e215a1c87f update dart permission 2015-09-08 11:38:01 +08:00
wing328
5bcd8fb207 Merge pull request #1199 from xhh/java-okhttp-gson
[Java okhttp-gson, Android] Set source and target compatibility to 1.7 in build.gradle
2015-09-08 11:31:38 +08:00
wing328
a8f7708789 Merge pull request #1198 from yissachar/dart
Add Dart support
2015-09-08 09:18:51 +08:00
wing328
26c0bfef7d Merge pull request #1196 from wing328/typescript_basepath
[TypeScript] Fix base path
2015-09-07 21:57:23 +08:00
wing328
12190e0900 Merge pull request #1172 from xhh/ruby-apiclient
[Ruby] Implement API client structure for Ruby client
2015-09-07 21:56:59 +08:00
wing328
f340a389e9 Merge pull request #1182 from Helmsdown/cli-enhancements-2
Refactor codegen to support an "uber" meta model for user defined values
2015-09-07 21:55:50 +08:00
xhh
8b96cdb7d7 Set source/target compatibility in Android client 2015-09-07 16:35:34 +08:00
xhh
90307cafc6 Merge branch 'master' into java-okhttp-gson 2015-09-07 15:33:18 +08:00
Yissachar Radcliffe
58c5ecf13c Generate auth files to correct location 2015-09-06 19:58:28 -04:00
Yissachar Radcliffe
e72a53448e Add Dart support 2015-09-06 18:35:29 -04:00
wing328
90b89c6189 fix typescript basepath 2015-09-05 16:48:00 +08:00
wing328
ee1febcd95 Merge pull request #1188 from wing328/master
[NodeJS] fixed HTML-escaped description on nodejs json files
2015-09-05 15:44:16 +08:00
russellb337
6c079e95d9 Merge remote-tracking branch 'upstream/master' into cli-enhancements-2 2015-09-04 15:25:10 -07:00
russellb337
d22398eb73 put all values into dynamic properties map 2015-09-04 15:24:36 -07:00
wing328
30228dcca5 Merge pull request #1192 from SparrowJang/master
Python - response is empty object
2015-09-04 22:42:39 +08:00
wing328
2e30a3af27 Merge pull request #1189 from mad102190/feature/objc-response-headers
[Obj-C] Added ability to access HTTP Response headers
2015-09-04 16:42:25 +08:00
wing328
212d240316 Merge pull request #1190 from mad102190/fixes/objc-podspec-generation
[Obj-C][Cocoapods] Added extra CLI options to generate a valid podspec file.
2015-09-04 16:36:17 +08:00
sparrow.jang
ba701be2f2 fixed a empty object for response 2015-09-04 15:20:34 +08:00
SparrowJang
f6d624be2a Merge pull request #2 from swagger-api/master
merge
2015-09-04 14:25:34 +08:00
Matthew Davis
f705e03fc4 changes to podspec.mustache to accept new params 2015-09-03 13:02:24 -07:00
Matthew Davis
75bb59572a added extra CLI options required to generate a valid (lint-able) podspec file. 2015-09-03 12:54:25 -07:00
Matthew Davis
f067b86fa0 re-built sample objc-petstore 2015-09-03 12:31:30 -07:00
Matthew Davis
2822e9ea38 added support for retrieving HTTP response headers in obj-c. Also added a +sharedAPI class method for easy initialization of an API class without passing headers 2015-09-03 12:18:00 -07:00
russellb337
435ce7b9d5 make JsonAnySetter for dynamic properties "builder" style 2015-09-03 10:16:44 -07:00
russellb337
ab6118afe4 update default generator to skip generation of models that have import mappings defined 2015-09-03 08:24:33 -07:00
wing328
8ce06fc898 fix HTML-escaped description on nodejs json files 2015-09-03 22:38:19 +08:00
wing328
9e8e5db7b3 Merge pull request #1180 from ist-ltd/master
Support dots in output folder for C# generator
2015-09-03 22:26:38 +08:00
russellb337
44b5c22cd4 Merge remote-tracking branch 'upstream/master' into cli-enhancements-2 2015-09-02 09:28:58 -07:00
russellb337
6d7557971b switch Generate to use CodegenConfigurator 2015-09-02 09:28:40 -07:00
Cameron
9af16c0d79 Support dots in output folder for C# generator 2015-09-02 13:36:35 +01:00
xhh
027e4c5a20 Set source and target compatibility to 1.7
in build.gradle to make it work with Android
2015-09-02 18:35:58 +08:00
wing328
c56d807a15 Merge pull request #1169 from boazsapir/master
Handle correctly the case of no default response (see comment in #1124)
2015-09-02 18:03:02 +08:00
wing328
7d4ba27e01 Merge pull request #1162 from xhh/java-okhttp-gson
[Java] Add a new library template: okhttp-gson
2015-09-02 16:21:39 +08:00
Tony Tam
c8ed2b0d50 Merge pull request #1175 from swagger-api/feature/issue-1173
formatting, vendor extensions on operations
2015-09-02 00:02:20 -07:00
Tony Tam
1520ec536e formatting, vendor extensions on operations 2015-09-01 23:34:29 -07:00
Tony Tam
e434380eae Merge pull request #1174 from swagger-api/feature/issue-1173
Feature/issue 1173
2015-09-01 23:16:13 -07:00
Tony Tam
5940f46f56 added vendor extensions on parameters per #1173 2015-09-01 23:04:33 -07:00
xhh
7c60e2097f Update API client initialization in Ruby test 2015-09-02 12:00:27 +08:00
xhh
fc7cffbab7 Merge branch 'master' into ruby-apiclient
Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java
2015-09-02 11:46:53 +08:00
Tony Tam
b099d1e7a2 added configuration to superclass for overriding param reordering for #1171 2015-09-01 15:53:58 -07:00
b_sapir
31e8aca357 Handle correctly the case of no default response (see comment in #1124) 2015-09-01 18:26:15 +03:00
wing328
d746894ecb Merge pull request #1168 from xhh/bug-enum-constructor
Fix bug of hard-coded enum name in Java client
2015-09-01 22:56:04 +08:00
xhh
2c64e0893b Fix bug of hard-coded enum name in Java client 2015-09-01 20:06:44 +08:00
xhh
3c79a692aa Use a separate library for base64-encoding in the okhttp-gson template 2015-09-01 19:56:06 +08:00
wing328
72255286b3 Merge pull request #1144 from ePaul/bugfix/1143-add-nullcheck-for-allowedvalues
Add null check to fix issue #1143
2015-09-01 11:54:22 +08:00
xhh
3112e4ad06 Add build files for Gradle and SBT 2015-09-01 11:20:44 +08:00
russellb337
38b1e1aad7 Merge branch 'master' into cli-enhancements-2 2015-08-31 15:20:17 -07:00
wing328
dfb87abe3a Merge pull request #1151 from ePaul/feature/1146-trim-whitespaces-before-escaping
trim strings before escaping
2015-08-31 22:21:38 +08:00
wing328
b96fdb6766 Merge pull request #1164 from ePaul/bugfix/1142-sanitize-api-name-for-spring-mvc
Issue #1142: sanitize api name before camelizing.
2015-08-31 21:46:25 +08:00
wing328
369ceb634d Merge pull request #1163 from ePaul/bugfix/1142-sanitize-file-name-for-models
Issue #1142: sanitize the class name for Java model classes.
2015-08-31 21:44:28 +08:00
Paul Ebermann
92f9b33eb6 Issue #1142: sanitize api name before camelizing.
This builds on #1139 in order to solve another part of #1142:
When the first component of a path contained a dash, the generated class name contained this dash too (for the "language" spring-mvc).
2015-08-31 15:14:54 +02:00
Robin Eggenkamp
5b12379a07 Add missing NSDateFormatter 2015-08-31 15:04:37 +02:00
Robin Eggenkamp
39b4034958 Replace NSError by ErrorType 2015-08-31 15:03:56 +02:00
Robin Eggenkamp
28030cba19 Merge branch 'master' into swift-2.0
Conflicts:
	modules/swagger-codegen/src/main/resources/swift/APIs.mustache
	modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache
	modules/swagger-codegen/src/main/resources/swift/Cartfile.mustache
	modules/swagger-codegen/src/main/resources/swift/Models.mustache
	modules/swagger-codegen/src/main/resources/swift/Podspec.mustache
	modules/swagger-codegen/src/main/resources/swift/api.mustache
2015-08-31 14:41:41 +02:00
Paul Ebermann
e0679c0b14 Issue #1142: sanitize the class name for Java model classes.
This builds on #1139, calling the new sanitizeName() method before camelizing it when generating model names.
2015-08-31 14:13:48 +02:00
xhh
2fd8b8ff16 Update help text of config options in README 2015-08-31 20:10:29 +08:00
xhh
e35be1bd40 Generate Java petstore sample for okhttp-gson 2015-08-31 19:59:17 +08:00
wing328
39ac64d24a Merge pull request #1161 from wing328/upgrade_JMockit
Upgrade JMockit to 1.19
2015-08-31 18:55:38 +08:00
wing328
b846fa5c3e update JMockit to 1.19 2015-08-31 18:44:01 +08:00
xhh
3c84847adb Add a new library template to Java client: okhttp-gson
which uses OkHttp as HTTP library and Gson as JSON processing library
2015-08-31 18:42:09 +08:00
wing328
2b48ec072c Merge pull request #1153 from wing328/csharp_fix_encode
[C#] Fix UrlEncode in API client
2015-08-31 12:42:48 +08:00
wing328
8114c416b9 Merge pull request #1139 from wing328/sanitize_name
Add function to sanitize name (1)
2015-08-30 22:46:58 +08:00
wing328
adee62da7d Merge pull request #1138 from Helmsdown/cli-enhancements
Expose more configuration items in the CLI
2015-08-30 22:46:25 +08:00
cbornet
a207251b29 minor changes
removed gson version in pom and added a space between the parameters
2015-08-29 18:41:16 +02:00
cbornet
265de9654b add authorizations to retrofit client
added basic auth, api key and oauth support to the service generator using okhttp interceptors

Fix #962
2015-08-29 18:14:33 +02:00
wing328
177436e69c fix decode with encode 2015-08-29 22:43:22 +08:00
wing328
1331484a0f fix urlencode in apiclient 2015-08-29 22:39:44 +08:00
geekerzp
4477009ef8 Handle special characters in parameter names in ruby client 2015-08-29 16:19:43 +08:00
Paul Ebermann
930c5191e0 Issue #1146: trim string before escaping
This removes leading and trailing whitespace before escaping strings. This gets rid of annoying `\n` in some string literals (e.g. in annotations).
2015-08-28 19:56:37 +02:00
russellb337
5f811f3ba7 merge from upstream/master 2015-08-28 10:47:08 -07:00
Paul Ebermann
74bffbaadb Issue #1146: fix indentation in the generated API file. 2015-08-28 19:41:32 +02:00
Paul Ebermann
cdd104d3fb Issue #1146: escape the response description.
This prevents line breaks in string literals, which are not allowed in Java.
2015-08-28 19:39:01 +02:00
Paul Ebermann
be84f03d14 Issue #1146: do not escape newlines in generated javadocs.
For this, we add a property `unescapedDescription` to CodegenModel + CodegenProperty, and use them for the Javadoc generation, while the annotation uses the escaped `description`.
2015-08-28 18:40:14 +02:00
wing328
28579cee03 Merge pull request #1135 from restlet/fix/nodejs_server_swagger_invalid_json
[Node.js] fix invalid JSON being generated in swagger.json
2015-08-28 18:31:39 +08:00
Paul Ebermann
32ffab4519 fix issue #1143: add another null check.
The problem was trying to iterate over a null list.
2015-08-28 11:39:45 +02:00
wing328
e3c6cc3220 Merge pull request #1121 from Edubits/prevent-NPE
Fix possible NullPointerException
2015-08-28 16:05:20 +08:00
wing328
84346c0ba6 Merge pull request #1122 from F481/master
added some useful log/output messages and exception handling
2015-08-28 15:53:35 +08:00
russellb337
acbf3d3cc5 comment twak 2015-08-27 15:59:10 -07:00
russellb337
5c74146879 a few tweaks 2015-08-27 15:56:58 -07:00
russellb337
a59c128f90 curse you github desktop client for not refreshing when i want you to 2015-08-27 15:40:56 -07:00
russellb337
810bf58c3a first draft of CodegenConfigurator 2015-08-27 15:40:33 -07:00
russellb337
724683fab0 Merge branch 'master' into cli-enhancements 2015-08-27 10:18:55 -07:00
russellb337
074ba1ea54 undo some of the debugging changes I made 2015-08-27 09:11:49 -07:00
wing328
9e5de7da5e Merge pull request #1132 from geekerzp/python-configuration
[Python] Add option `verify_ssl` to switch SSL/TLS verification
2015-08-27 17:01:29 +08:00
wing328
50f6067831 add a case to handle space in name 2015-08-27 16:47:41 +08:00
wing328
9453967815 add function to sanitize name 2015-08-27 16:14:07 +08:00
F481
fc4fce3731 write processOperation debug output only if the debugOperations property is set 2015-08-27 08:06:24 +02:00
russellb337
d31013d977 remove reflections from parent pom 2015-08-26 18:50:29 -07:00
russellb337
ccf0cc8375 whoops, didn't mean to upgrade the minor version 2015-08-26 18:35:22 -07:00
russellb337
99ed012fc6 trying a new version of jetty 2015-08-26 18:31:29 -07:00
russellb337
8ba4a6d7ad downgrade reflections version
I’m guessing
2015-08-26 18:25:23 -07:00
russellb337
60fddcf378 adding back imports that somewhere got deleted during reformatting 2015-08-26 17:55:02 -07:00
russellb337
cf5982d2c4 remove class comment 2015-08-26 17:51:19 -07:00
russellb337
1378976d37 merging upstream changes 2015-08-26 17:40:49 -07:00
russellb337
e5811ebdc7 expose more generate options in the cli 2015-08-26 17:38:51 -07:00
Hugo Wood
d434b7c440 fix invalid JSON being generated in swagger.json of Node.js server 2015-08-26 17:34:53 +02:00
wing328
8de9e23814 Merge pull request #1131 from wing328/csharp_fix_compilebat
[C#] fix invokerPackage with packageName in compile.mustache
2015-08-26 17:30:07 +08:00
wing328
b35a7b696e Merge pull request #1127 from ivanmartinvalle/master
Add status code and response headers of the last request to java and c#
2015-08-26 17:27:34 +08:00
wing328
587028efd1 Merge pull request #1129 from geekerzp/objc-test
[Objc] Add test cases for sanitizeForSerialization method in objc client
2015-08-26 17:02:55 +08:00
wing328
af8d61cc02 Merge pull request #1130 from geekerzp/python-test
[Python] Add test cases for sanitize_for_serialization method in python client
2015-08-26 16:46:42 +08:00
wing328
1996aa9244 Merge pull request #1126 from xhh/java-enum-refactor
[Java] Support special characters in enum values
2015-08-26 16:41:56 +08:00
wing328
f79f8895c5 Merge pull request #1125 from wing328/php_param_name
[PHP] add camelCase support for variable naming
2015-08-26 09:49:08 +08:00
geekerzp
b3d28f07f1 Add option verify_ssl to switch SSL/TLS verification. 2015-08-25 17:58:14 +08:00
wing328
570a595ffb fix invokerPackage with packageName in compile.mustache 2015-08-25 15:35:22 +08:00
geekerzp
568b7a4fcd Add test cases for sanitize_for_serialization method in python client. 2015-08-25 15:04:46 +08:00
geekerzp
1b2f491b0e Add tese case for sanitizing array of models in objc client. 2015-08-25 11:16:19 +08:00
geekerzp
eb21963fa5 Update test case testSanitizeForSerialization in objc client. 2015-08-25 10:51:03 +08:00
geekerzp
ab5483cd04 Add test cases for sanitizeForSerialization method in objc client. 2015-08-25 09:54:30 +08:00
Tony Tam
392e5172b5 changed default behavior for inflector to have unimplemented handlers 2015-08-24 17:26:26 -07:00
ivanmartinvalle
52dc7e210c Add status code and response headers of the last request to java and csharp templates per #990 2015-08-24 18:35:06 -05:00
Tony Tam
15e336b90a Merge pull request #1123 from wing328/python_typo
[Python] better wording for documentation
2015-08-24 07:18:42 -07:00
Tony Tam
698ed970dc Merge pull request #1124 from boazsapir/binary
support binary input and output
2015-08-24 07:16:29 -07:00
wing328
a43d2163a0 add camelCase support for php variable naming 2015-08-24 21:53:28 +08:00
b_sapir
564dffa7e8 Merge remote-tracking branch 'origin/binary' into binary
Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java
	modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache
	modules/swagger-codegen/src/main/resources/Java/api.mustache
2015-08-24 16:15:18 +03:00
wing328
68f61d9a37 use snake_case instead of under_score 2015-08-24 21:11:52 +08:00
wing328
a7c08e680c update python samples 2015-08-24 21:08:21 +08:00
wing328
2251a2f892 fix typo, update documentation for python lib 2015-08-24 21:08:21 +08:00
b_sapir
b0c776bbea Support binary input and output - fix some merge problems 2015-08-24 15:59:58 +03:00
F481
3d89399b58 fixed syntax error 2015-08-24 14:28:13 +02:00
F481
0261121d78 added some useful log/output messages and exception handling 2015-08-24 14:04:50 +02:00
b_sapir
c177cf75d2 Support binary input and output (for body parameters or responses with type "string" and format "binary". Implemented for Java. 2015-08-24 15:04:10 +03:00
b_sapir
d4b4fe4b47 Support binary input and output (for body parameters or responses with type "string" and format "binary". Implemented for Java. 2015-08-24 14:33:15 +03:00
Robin Eggenkamp
e956495665 [Swift] Update to new Swift 2.0 syntax and Xcode 7
Note: configs with responseAs: “PromiseKit” won’t work yet
2015-08-24 12:27:33 +02:00
xhh
8408a97aef Java: Support special characters in enum values
and use upper case for enum names

Conflicts:
	samples/client/petstore/java/default/src/main/java/io/swagger/client/JSON.java
	samples/client/petstore/java/default/src/main/java/io/swagger/client/model/Order.java
	samples/client/petstore/java/default/src/main/java/io/swagger/client/model/Pet.java
2015-08-24 18:21:16 +08:00
Robin Eggenkamp
b3afbe73b9 [Swift] Add missing checks for usePromiseKit 2015-08-24 12:20:34 +02:00
Robin Eggenkamp
85aabbe810 Fix possible NullPointerException
getWrapped() returns a Boolean which can be null
2015-08-24 12:09:14 +02:00
Ron
3f8dbf416d Update README.md 2015-08-24 11:20:51 +03:00
Ron
0e0bfde3a8 Update README.md 2015-08-24 11:20:30 +03:00
Tony Tam
29a2eedc1e java8 tag fixes 2015-08-24 01:04:33 -07:00
Tony Tam
0d5c066605 fixed scalatest version 2015-08-24 01:04:28 -07:00
Tony Tam
6820179903 fixed scalatest version 2015-08-24 01:04:24 -07:00
Tony Tam
617fa43a89 updated development version 2015-08-24 00:52:35 -07:00
Tony Tam
dd67287d63 updated development version 2015-08-24 00:51:18 -07:00
geekerzp
6d58d44542 Merge branch 'ruby-api-client' into ruby-apiclient 2015-08-20 11:34:07 +08:00
xhh
0e2e7838ae Merge branch 'bug-fix-ruby-file-upload' into ruby-api-client
Conflicts:
	modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache
	samples/client/petstore/ruby/lib/petstore/swagger/request.rb
2015-08-20 11:24:33 +08:00
xhh
2e3f94c2a5 Add file used in test: hello.txt 2015-08-20 11:18:05 +08:00
xhh
e02a9f1797 Merge branch 'develop_2.0' into ruby-api-client 2015-08-20 11:10:25 +08:00
xhh
0d399d3f6a Add spec for file uploading 2015-08-20 11:07:20 +08:00
xhh
030e45982c Add back support of file uploading to Ruby client 2015-08-20 10:45:40 +08:00
geekerzp
7be6e971fa Update api client of ruby client.
Update ApiClient#build_request, change `@verify_ssl`, `@ssl_ca_cert`, `@debugging`
to `Configuration.verify_ssl`, `Configuration.ssl_ca_cert`, `Configuration.debugging`.
2015-08-18 20:21:56 +08:00
geekerzp
828f8694c8 Fix typo in ruby client 2015-08-18 16:13:32 +08:00
geekerzp
31d948fc16 Update readme of ruby client 2015-08-18 14:35:54 +08:00
geekerzp
a481db7486 Add configuration object in ruby client 2015-08-18 14:27:09 +08:00
xhh
7af5db3565 Rebuild Ruby petstore sample 2015-07-27 16:37:26 +08:00
xhh
47c8597d36 Ruby: move request/response logic to api_client 2015-07-27 16:34:51 +08:00
xhh
5bfae7b78c Ruby: use a default ApiClient when not provided 2015-07-27 10:32:51 +08:00
xhh
a75b05b952 Update tests with latest code 2015-07-22 16:02:18 +08:00
xhh
609d915541 Rebuild Ruby petstore sample 2015-07-22 15:39:48 +08:00
xhh
948cdb3a75 Done with API client structure for Ruby client 2015-07-22 15:37:29 +08:00
xhh
4ecc757bea More on API client structure for Ruby client 2015-07-21 17:07:41 +08:00
xhh
3de42afed3 Implement API client structure for Ruby client 2015-07-21 11:37:46 +08:00
649 changed files with 27496 additions and 12781 deletions

5
.gitignore vendored
View File

@@ -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

View File

@@ -1,12 +1,45 @@
# Swagger Code Generator
[![Build Status](https://travis-ci.org/swagger-api/swagger-codegen.png)](https://travis-ci.org/swagger-api/swagger-codegen)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.swagger/swagger-codegen-project/badge.svg?style=plastic)](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
```

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,4 @@
{
"library": "okhttp-gson",
"artifactId": "swagger-petstore-okhttp-gson"
}

View File

@@ -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

View File

@@ -0,0 +1,4 @@
{
"library": "retrofit",
"artifactId": "swagger-petstore-retrofit"
}

31
bin/java-petstore-retrofit.sh Executable file
View 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

View File

@@ -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>

View File

@@ -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());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>

View File

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

View File

@@ -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>

View File

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

View File

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

View File

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

View File

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

View File

@@ -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";
}

View File

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

View File

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

View File

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

View File

@@ -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;

View File

@@ -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;

View File

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

View File

@@ -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_]", "");
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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) {

View File

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

View File

@@ -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")) {

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
package io.swagger.codegen.languages;
public enum CodeGenStatus {
UNRUN, SUCCESSFUL, FAILED
}

View File

@@ -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

View File

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

View File

@@ -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")) {

View File

@@ -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_\\.]", "_");

View File

@@ -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>(

View File

@@ -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";
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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]+", ""));
}
}

View File

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

View File

@@ -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

View File

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

View File

@@ -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"));

View File

@@ -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>(

View File

@@ -76,7 +76,7 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi
}
public CodegenType getTag() {
return CodegenType.CLIENT;
return CodegenType.SERVER;
}
public String getName() {

View File

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

View File

@@ -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"));

View File

@@ -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>();

View File

@@ -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) {

View File

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

View File

@@ -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' }

View File

@@ -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.

View File

@@ -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.

View File

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

View File

@@ -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}}
}

View File

@@ -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.
*/

View File

@@ -0,0 +1,5 @@
package {{invokerPackage}}.auth;
public enum OAuthFlow {
accessCode, implicit, password, application
}

View File

@@ -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"
}

View File

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

View File

@@ -0,0 +1,2 @@
# Uncomment to build for Android
#target = android

View File

@@ -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.
*

View File

@@ -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}}

View File

@@ -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"
}

View File

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

View File

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

View File

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

View File

@@ -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}}

View File

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

View File

@@ -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'
}

View File

@@ -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"
)
)

View File

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

View File

@@ -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}}

View File

@@ -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>

View File

@@ -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) {
}
}
}
}
}

View File

@@ -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]), "|");
}
}
}

View File

@@ -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}}

View File

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

View File

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

View File

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

View File

@@ -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
}
}

View File

@@ -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"
}

View File

@@ -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}}

View File

@@ -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>

View File

@@ -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