Compare commits

..

609 Commits

Author SHA1 Message Date
Tony Tam
6aa66897aa updated readme 2015-08-24 00:44:03 -07:00
Tony Tam
9b0ddd3a7f Merge branch 'develop_2.0' 2015-08-24 00:39:03 -07:00
Tony Tam
ee05366d0b updated README for release 2015-08-24 00:37:23 -07:00
Tony Tam
d048a68438 added sample 2015-08-24 00:33:26 -07:00
Tony Tam
9cc7615b71 rebuilt, updated versions 2015-08-24 00:32:58 -07:00
Tony Tam
dfb9d26c75 Merge branch 'wing328-fix_java_serialize' into develop_2.0 2015-08-24 00:03:31 -07:00
Tony Tam
715c0af41f merged & rebuilt 2015-08-24 00:03:20 -07:00
Tony Tam
65829e5b6e merged & rebuilt 2015-08-24 00:03:08 -07:00
Tony Tam
a3c7e22d55 Merge pull request #1116 from swagger-api/issue-1115
fixes for jaxrs codegen
2015-08-23 23:56:14 -07:00
Tony Tam
d8ceb8c648 enabled samples 2015-08-23 23:47:01 -07:00
Tony Tam
87f1ef4dc2 re-ordered 2015-08-23 23:46:54 -07:00
Tony Tam
7c2310a13f updated to jersey 1.18.1, fixes for #1115 2015-08-23 23:34:35 -07:00
Tony Tam
6dcb8da2d8 altered to return inner type only 2015-08-23 23:33:55 -07:00
Tony Tam
a83f01ad60 made string safe 2015-08-23 23:33:27 -07:00
Tony Tam
6c1f7243bf rebuilt 2015-08-23 23:29:53 -07:00
wing328
164ed99812 fix serializableModel (boolean) 2015-08-24 11:50:21 +08:00
Tony Tam
355cc88e0d Merge pull request #1113 from swagger-api/issue-1112
moved file
2015-08-23 19:04:14 -07:00
Tony Tam
35ed412d1e moved file 2015-08-23 18:58:46 -07:00
Tony Tam
a5190266b6 Merge pull request #1111 from swagger-api/revert-1029-jaxrs-server-codegen-improvements
Revert "fixed generated code to go to target/generated-sources, added…
2015-08-23 18:53:05 -07:00
Tony Tam
d51fe80138 Revert "fixed generated code to go to target/generated-sources, added maven-c…" 2015-08-23 18:28:42 -07:00
Tony Tam
ec9cdca7cb Merge pull request #1109 from swagger-api/rebase-issue-838
update files as rebase from #838
2015-08-23 17:38:34 -07:00
Tony Tam
8a9f43b142 Merge pull request #910 from swagger-api/maven-plugin-configuration-improvements
Maven plugin configuration improvements
2015-08-23 17:33:55 -07:00
Tony Tam
0fc5702e4d Merge pull request #1029 from swagger-api/jaxrs-server-codegen-improvements
fixed generated code to go to target/generated-sources, added maven-c…
2015-08-23 17:32:29 -07:00
Tony Tam
3390fae15b Merge branch 'tiffanyperumpail-develop_2.0' into develop_2.0 2015-08-23 17:25:24 -07:00
Tony Tam
e19b883c89 Merge branch 'develop_2.0' of ssh://github.com/tiffanyperumpail/swagger-codegen into tiffanyperumpail-develop_2.0 2015-08-23 17:24:27 -07:00
Tony Tam
9531e1ae59 Merge branch 'Rogercf-support-to-array-of-enums' into develop_2.0 2015-08-23 17:22:44 -07:00
Tony Tam
3d38c41b0e resolved merge issue 2015-08-23 17:22:34 -07:00
Tony Tam
718e1ff68a Merge branch 'TobiasPfeifer-develop_2.0' into develop_2.0 2015-08-23 14:23:33 -07:00
Tony Tam
a6a9d743be added template 2015-08-23 14:23:20 -07:00
Tony Tam
414de00894 fixed return type, rebuilt 2015-08-23 14:23:00 -07:00
Tony Tam
cc7366787f Merge branch 'develop_2.0' of ssh://github.com/TobiasPfeifer/swagger-codegen into TobiasPfeifer-develop_2.0 2015-08-23 11:20:02 -07:00
Tony Tam
3486eecdfc Merge branch 'xhh-library-template-jersey2' into develop_2.0 2015-08-23 11:10:12 -07:00
Tony Tam
66e6d4fb8a rebuilt client 2015-08-23 11:10:04 -07:00
Tony Tam
f7dc066dec merged 2015-08-23 11:09:47 -07:00
Tony Tam
3160913433 update files as rebase from #838 2015-08-23 11:05:19 -07:00
Ole Lensmar
e253fdea33 Merge branches 'develop_2.0' and 'jaxrs-server-codegen-improvements' of https://github.com/swagger-api/swagger-codegen into jaxrs-server-codegen-improvements
Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java
2015-08-23 10:26:07 -04:00
Ole Lensmar
ac49d0dcdc post-merge fixes 2015-08-23 09:37:28 -04:00
Ole Lensmar
b956d47a9d Merge branches 'develop_2.0' and 'maven-plugin-configuration-improvements' of https://github.com/swagger-api/swagger-codegen into maven-plugin-configuration-improvements
Conflicts:
	modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java
2015-08-23 09:37:08 -04:00
wing328
f662699fd0 Merge pull request #1107 from wing328/php_fix_datetime
[PHP] Fixed deserialization for datetime object
2015-08-23 17:11:55 +08:00
wing328
1c1571cc3a Merge pull request #1106 from geekerzp/python-query
[Python] Fix issue that missing query parameters in python client.
2015-08-23 17:11:19 +08:00
wing328
e13374e1df Merge pull request #1105 from who/serializable_java_models
[Java] Adding an option so java models can implement Serializable
2015-08-23 17:10:57 +08:00
wing328
f2df26f6e6 fix deserializing datetime, add test case 2015-08-22 23:09:12 +08:00
xhh
569082743f Remove the unused LibraryHelp command 2015-08-22 22:05:43 +08:00
xhh
595c01c537 Merge branch 'develop_2.0' into library-template-jersey2
Conflicts:
	modules/swagger-codegen/src/main/resources/Java/JsonUtil.mustache
2015-08-22 21:53:04 +08:00
geekerzp
dc423cc11d Fix issue that Mssing query parameters in python client. 2015-08-22 17:46:13 +08:00
Andrew B
4f25a0e6c5 adding an option so java models can implement Serializable 2015-08-21 18:36:03 -07:00
Tony Tam
0af29cc5cf Merge pull request #1104 from swagger-api/issue-1103
added check, fix for #1103
2015-08-21 15:22:22 -07:00
Tony Tam
44b4af0374 added check, fix for #1103 2015-08-21 15:02:56 -07:00
Tony Tam
b68beefa69 Merge pull request #1101 from swagger-api/issue-1099
optional files are never written
2015-08-21 09:35:11 -07:00
Tony Tam
07162811a7 fix for #1099, added file check 2015-08-21 08:56:22 -07:00
wing328
4023460f2e Merge pull request #1096 from geekerzp/objc-param-to-str
[Objc] Sanitize request parameters in objc client
2015-08-21 22:22:17 +08:00
wing328
83bea6a0c5 Merge pull request #1095 from who/fix_issue_1089
[Java] Sanitize configurable package names (fixes #1089)
2015-08-21 22:15:53 +08:00
wing328
d03f680c64 Merge pull request #1090 from geekerzp/python-keyword
[Python] Change reserved word handling in python client.
2015-08-21 21:51:32 +08:00
geekerzp
4189d0765b Update api body template of objc client 2015-08-21 11:40:59 +08:00
geekerzp
6218ad139f Fix issue that it will throw error if not pass optional form param in objc client. 2015-08-21 11:20:29 +08:00
geekerzp
b7cd38d38b Update objc client.
Sanitize request parameters (path, query, header, form, body).
2015-08-21 09:42:31 +08:00
Andrew B
2b61305582 Fixing issue #1089 2015-08-20 14:16:10 -07:00
wing328
2057d0e144 Merge pull request #1068 from Helmsdown/add-generated-annotation
Add @Generated annotation to all generated Java templates
2015-08-20 17:45:17 +08:00
xhh
af2ec4cf85 Merge branch 'develop_2.0' into library-template-jersey2
Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java
	modules/swagger-codegen/src/main/resources/Java/api.mustache
2015-08-20 17:36:42 +08:00
wing328
9a239ad2a4 Merge pull request #1076 from DavidBiesack/static-html
improve static html; add template guards for collections.
2015-08-20 17:31:03 +08:00
wing328
a610fb5ac3 Merge pull request #1051 from who/develop_2.0
[Java] Fixing subClassed types so that they can use enums
2015-08-20 17:14:17 +08:00
Andrew B
fb4c62cc28 Fixing merge conflict in pom.xml 2015-08-19 23:08:49 -07:00
geekerzp
894d571ea5 Change reserved word handling in python client.
* First, remove the beginning underscores.
* Then, append underscore if the var is reserved word or number.
2015-08-19 18:05:47 +08:00
wing328
dc1992ad45 Merge pull request #1081 from wing328/php_var_name_number
[PHP, Perl, Silex] fixed variable names starting with number, made LOGGER protected
2015-08-19 14:56:13 +08:00
wing328
c62fca8c54 Merge pull request #1079 from wing328/add_flash_generator
[Flash] Add back Flash generator
2015-08-18 20:04:53 +08:00
wing328
5d52952ebd Merge pull request #1077 from geekerzp/objc-apiclient
[Objc] Change the ApiClient  initialization of objc client
2015-08-18 09:39:48 +08:00
wing328
c1fbf6bb1c Merge branch 'php_var_name_number' of https://github.com/wing328/swagger-codegen into php_var_name_number 2015-08-17 14:40:12 +08:00
wing328
10cd672529 fix variable name starting with number, make LOGGER protected 2015-08-17 14:39:29 +08:00
wing328
52918d325e Merge pull request #1082 from wing328/fix_pom_swagger_parser
update swagger-parser-version to 1.0.10 (removed snapshot)
2015-08-17 14:38:11 +08:00
wing328
8cff8fc55a update swagger-parser-version to 1.0.10 (removed snapshot) 2015-08-17 14:27:33 +08:00
wing328
90d5ce228a Merge pull request #1067 from Helmsdown/path-level-params
Codegen should honor path level parameters
2015-08-17 14:13:22 +08:00
wing328
d4ff25f0b3 fix variable name starting with number, make LOGGER protected 2015-08-17 10:43:03 +08:00
wing328
4163f07911 Merge pull request #1069 from geekerzp/python-httplib
[Python] Fix issues in python client
2015-08-16 15:03:16 +08:00
wing328
560fd5718d Merge pull request #1074 from wing328/php_improve1
[PHP] minor improvements
2015-08-16 14:59:43 +08:00
wing328
97580a8c45 Merge pull request #1070 from wing328/objc_readme_update
[Objc] minor wording change for readme based on feedback from developers
2015-08-16 14:59:27 +08:00
wing328
aee72d97c3 Merge pull request #1080 from wing328/update_pomxml
Update swagger-core-version to 1.5.4-SNAPSHOT
2015-08-16 00:22:54 +08:00
wing328
49ad008d7c update pom.xml 2015-08-16 00:14:24 +08:00
wing328
7a2c0a076a update readme, change default value, update pom 2015-08-16 00:03:19 +08:00
wing328
365f4bc0c0 beta release of flash generator 2015-08-15 23:56:01 +08:00
wing328
3478e053e1 add back flash generator 2015-08-15 18:12:14 +08:00
geekerzp
75536868f2 Add default api client in configuration class in objc client 2015-08-14 17:54:41 +08:00
geekerzp
84e8ef489c Update pom.xml 2015-08-14 11:55:22 +08:00
wing328
cffba0299a update core to 1.5.4 2015-08-14 11:19:04 +08:00
geekerzp
a6c07a8364 Change api client pool pattern to singleton pattern in objc client 2015-08-14 09:47:02 +08:00
David Biesack
b14edffc79 improve static html; add template guards for collections. Update -core dependency 2015-08-13 13:46:32 -04:00
wing328
b971aa7433 add example to config option, replace localhost with basePath 2015-08-13 23:27:59 +08:00
wing328
bb4311b7a2 minor wording change for objc readme based on feedback from developers 2015-08-12 20:53:15 +08:00
geekerzp
1c0eb60c71 Fix issues in python client 2015-08-12 11:19:29 +08:00
russellb337
a0eeb90a97 fixing bug 2015-08-11 12:50:19 -07:00
russellb337
38fccbd73d add @Generated to all Java class templates 2015-08-11 12:42:18 -07:00
russellb337
6fbb8ab1e0 add @Generated annotation to all Java class templates 2015-08-11 12:42:06 -07:00
russellb337
6044f0586e removing unnecessary getTypeDeclaration implementation in JaxRSServerCodegen 2015-08-11 09:19:22 -07:00
wing328
84ff5cfc87 Merge pull request #1064 from RMarinaro/develop_2.0
fix for #1061 java
2015-08-11 21:33:08 +08:00
wing328
96be2b196b Merge pull request #1037 from restlet/fix/nodejs_server_swagger
Fix swagger.json supporting file for the node.js server (fixes #652)
2015-08-11 21:28:06 +08:00
Hugo Wood
d93b404b23 Fix swagger.json supporting file for the node.js server (fixes #652) 2015-08-11 14:37:00 +02:00
wing328
be63776162 Merge pull request #1063 from geekerzp/objc-deserialize-bool
[Objc] Fix deserialize bool value issue
2015-08-11 10:18:52 +08:00
russellb337
ae4b4979a7 add defensive null check 2015-08-10 13:58:02 -07:00
russellb337
0a8fb1e532 codegen should honor path level parameters 2015-08-10 13:50:52 -07:00
wing328
e78844cb54 Merge pull request #1043 from marcospri/develop_2.0
Support for nested lists/maps for the python client
2015-08-10 18:30:02 +08:00
Ryan Marinaro
2eb0c8cea6 added a fix for #1061. The only problematic spot was the api.mustache file, although if more parameterized templates were to evolve in the other mustache files we could definitely add {{localVariablePrefix}} to those. For now I didn't want to add any extra noise to the template files which didn't need the prefixes. 2015-08-08 10:19:31 -04:00
geekerzp
2aaad03ab6 Fix the issue of bool deserialization in objc client 2015-08-08 15:13:13 +08:00
xhh
cb181e3480 Merge branch 'develop_2.0' into library-template-jersey2 2015-08-08 11:18:17 +08:00
xhh
b686b53259 Support overriding API/model templates with library template 2015-08-08 11:14:06 +08:00
wing328
f27eb7e0de Merge pull request #1058 from xhh/str-response-offset
Fix bug with truncated lone string responses for Android/Scala clients
2015-08-08 11:10:02 +08:00
wing328
36b7fb20b2 Merge pull request #1059 from geekerzp/objc-auth
[Objc] Fix issue about authentication
2015-08-08 09:37:47 +08:00
Ron
f2ef21e756 Merge pull request #1062 from swagger-api/dependencies-version-update
Update pom.xml
2015-08-07 17:32:28 -04:00
Ron
e57f1de21f Update pom.xml 2015-08-07 17:10:35 -04:00
xhh
a41361c959 Change the "--library" option into a config option 2015-08-07 22:16:32 +08:00
xhh
167e95bb3a Merge branch 'develop_2.0' into library-template-jersey2
Conflicts:
	modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache
2015-08-07 21:18:27 +08:00
geekerzp
732a9eb64d Fix issue in Configuration-body.mustache in objc client 2015-08-07 18:31:07 +08:00
xhh
c7f595fc91 Fix bug with truncated lone string responses for Android/Scala clients 2015-08-07 10:40:42 +08:00
Tony Tam
29e8a8f573 Merge pull request #1057 from who/fix_1056
Fixing a bug with truncated lone string responses
2015-08-06 17:38:54 -07:00
Andrew B
d5b959d8cd Fixing a bug with truncated lone string responses 2015-08-06 16:54:24 -07:00
Andrew B
7a92f53b55 Adding some tests for PR 1051 2015-08-06 15:22:18 -07:00
tiffanyperumpail
4ac8a93022 Change swagger-parser-version to 1.0.9-SNAPSHOT 2015-08-06 11:29:59 -07:00
Marcos Prieto
cad2f961bd Undo unicode on sanitize method. Keep the PR on point 2015-08-06 10:21:56 +02:00
tiffanyperumpail
5328c00e8f Simplified enum by changing CodeGenStatus to an enum instead of a wrapper. Updated version of swagger-parser to 1.0.9. 2015-08-05 16:53:39 -07:00
tiffanyperumpail
1b31a01b76 Added CodeGenStatus class with Status enum 2015-08-05 16:18:24 -07:00
Andrew B
c67a6582fc Bumping the version of swagger-parser to 1.0.9 2015-08-05 15:58:54 -07:00
Andrew B
dc76887820 Fixing subClassed types so that they can use enums 2015-08-05 15:50:34 -07:00
xhh
4321339d4f Java petstore sample: move to "default" sub-folder, add jersey2 2015-08-05 17:28:45 +08:00
xhh
07f10a8abc Add command to display all library templates supported
for a specific language
2015-08-05 16:37:08 +08:00
xhh
4ba521a5c0 Add jersey2 library template for Java client 2015-08-05 15:37:26 +08:00
xhh
d88ec847ae Remave unused imports 2015-08-05 09:43:15 +08:00
xhh
7c16dfcf13 Rebuild Java petstore sample 2015-08-04 18:36:03 +08:00
xhh
aff21e5e6b Add a "library" option to generate with sub-template 2015-08-04 18:32:54 +08:00
Marcos Prieto
befacc41bd Support for nested dict/list
Checking for `startwith` instead of just `in` to correctly categorize
nested structures.
2015-08-04 11:51:38 +02:00
Marcos Prieto
edebbcb802 Support for unicode headers, ie support for urlib3.util.make_headers 2015-08-04 11:51:25 +02:00
xhh
bfb4629ab7 Java client: decouple JSON handling 2015-08-04 15:47:55 +08:00
Tony Tam
1007534575 fix for #1042, removed empty / when basePath is null 2015-08-03 16:47:51 -07:00
Rogercf
97d24a7119 Update DefaultCodegen.java
Fixed indentation
2015-08-03 19:50:29 -03:00
Rogercf
13038d2a12 Update DefaultCodegen.java
Replaced hardcoded "String" with property.items.baseType
2015-08-03 19:46:10 -03:00
Rogercf
c5dc070685 Update model.mustache
Fixed generating array of enums properties in the java template
2015-08-03 19:21:54 -03:00
Rogercf
a30b66beb1 Update DefaultCodegen.java
Setting the "items" field when the type is array and updating some values if the array is an array of enums
2015-08-03 19:20:51 -03:00
Rogercf
aff766b785 Update CodegenProperty.java
Added a "items" field to keep track of the inner type to be accessed in the mustache templates
2015-08-03 19:19:10 -03:00
xhh
112a7ec8c1 Java client: move form params handling to ApiClient 2015-08-03 18:33:42 +08:00
wing328
55be0330e3 Merge pull request #1039 from geekerzp/python-desciption
[Python] Fix issue in python client
2015-08-03 10:48:56 +08:00
wing328
fe83d18a09 Merge pull request #1026 from geekerzp/objc-deserializtion
[Objc] Fix deserialize nested map error
2015-07-31 16:17:11 +08:00
wing328
a6f8f9e4ff Merge pull request #1017 from herveDarritchon/develop_2.0
Defect (Issue #905) : Add code to be able to override the configPackage …
2015-07-31 16:05:17 +08:00
geekerzp
79c988616c Fix issue #1038 2015-07-31 16:01:45 +08:00
wing328
dc62f688d9 Merge pull request #1015 from tandrup/conditional-copy-from-parent
Conditional copy properties from parent
2015-07-31 15:56:48 +08:00
wing328
db10bd764b Merge pull request #1036 from wing328/csharp_add_back_dll
[C#] add back RestSharp and Newtonsoft.Json DLL
2015-07-31 15:56:21 +08:00
wing328
92208b4ec2 Merge pull request #987 from xhh/retrofit-form-field-naming
Retrofit: fix form field naming by using baseName
2015-07-31 09:09:09 +08:00
xhh
0ef4702aa8 Merge branch 'develop_2.0' into retrofit-form-field-naming
Conflicts:
	samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java
2015-07-30 16:40:43 +08:00
wing328
cc358cf9ce Merge pull request #1032 from xhh/retrofit-string-resp
Retrofit template: return body string directly when failed to parse response body as JSON
2015-07-30 15:58:05 +08:00
xhh
a1e6908b65 Merge branch 'develop_2.0' into retrofit-string-resp 2015-07-30 15:02:02 +08:00
xhh
2d4c07a474 Fix typo 2015-07-30 15:01:51 +08:00
wing328
05f00013f1 add back csharp dll, update sample 2015-07-30 10:19:46 +08:00
wing328
bc528ef928 Merge pull request #1027 from adamholdenyall/patch-3
Catch all exceptions on Deserialize
2015-07-30 10:06:32 +08:00
Tony Tam
318a239976 Merge pull request #1031 from Toilal/pom-issues
Fix issues in POM configuration
2015-07-29 07:35:05 -07:00
Toilal
189962208e Update scala maven plugin and fix issues in POM configuration 2015-07-29 15:15:12 +02:00
wing328
bd28271b0b Merge pull request #1019 from geekerzp/python-refactor
[Python] Enhancements of python client
2015-07-29 17:39:58 +08:00
xhh
14b808a910 Retrofit template: return body string directly
when failed to parse response body as JSON, fixing unit test for
UserApi#loginUser
2015-07-29 17:10:49 +08:00
wing328
d345f8fae3 Merge pull request #967 from moander/feature/docker
Docker build script and Dockerfile
2015-07-29 15:36:08 +08:00
Ole Lensmar
26336356cf added generated samples for jaxrs and inflector 2015-07-28 14:56:23 -07:00
Ole Lensmar
9c3fad3040 fixed generated code to go to target/generated-sources, added maven-codegen-plugin to generated jaxrs project together with initial swagger definition, fixed overwrite flag to kick in only if file exists, fixed initial readme 2015-07-28 14:40:43 -07:00
moander
d396a0a0e4 Friendly error message when project is not built 2015-07-28 22:48:18 +02:00
Tony Tam
dc7c2a4bab updated name 2015-07-28 13:35:33 -07:00
Tony Tam
0b85ad464a Merge pull request #1028 from swagger-api/inflector-template
added template for the inflector
2015-07-28 10:31:40 -07:00
Ole Lensmar
c5d02fe98e added template for the inflector 2015-07-28 10:19:36 -07:00
adamholdenyall
a81e5096f5 Catch all exceptions on Deserialize
If you look at the source of NewtonSoft.Json, you'll see that DeserializeObject never throws an IOException. All exceptions should be caught in this method, just like Serialize.
2015-07-28 09:53:10 -05:00
wing328
52971e6aa9 Merge pull request #1018 from wing328/fix_empty_operationid
[All] Better exception handling for empty operationId (method name)
2015-07-28 17:39:19 +08:00
geekerzp
b2e0d83f2e Update objc client.
* Fix issue that list of primitive types deserialization.
* Add test cases for list of primitive types deserialization and nested list deserialization.
2015-07-28 17:21:10 +08:00
geekerzp
2be3414357 Update python client.
Add test case for nested list deserialization.
2015-07-28 15:23:44 +08:00
geekerzp
ea901bf1ce Update python client.
Add test case for nested dict deserialization.
2015-07-28 14:34:50 +08:00
geekerzp
8bd282acd6 Change parameter name key to identifier of
Configuration#get_api_key_with_prefix in python client.
2015-07-28 11:25:19 +08:00
geekerzp
b51ef77401 Remove #!/usr/bin/env python from python client 2015-07-28 11:25:19 +08:00
geekerzp
3265ec0f72 Refactor python client. 2015-07-28 11:25:19 +08:00
wing328
732e645042 Merge pull request #1022 from SparrowJang/develop_2.0
fixed a error rule for parsing `)`
2015-07-28 11:15:28 +08:00
geekerzp
cc45ff17cb Fix deserialize nested map error in objc client 2015-07-28 10:51:20 +08:00
wing328
b843b55339 Merge pull request #1001 from who/csharp_dotnet2_template
C# .Net 2.0 generator and template
2015-07-28 09:32:03 +08:00
Sparrow.jang
75711f954b fixed a bug for parsing ) error 2015-07-27 18:50:32 +08:00
SparrowJang
d0b5af31a5 Merge pull request #1 from swagger-api/develop_2.0
Develop 2.0
2015-07-27 18:47:40 +08:00
wing328
c01c06b198 Merge pull request #1004 from mhardorf/conf-file-maven-plugin
Add support for specifying configuration file in maven plugin
2015-07-27 18:30:09 +08:00
Mads Mætzke Tandrup
586f4c14e1 Merge remote-tracking branch 'upstream/develop_2.0' into conditional-copy-from-parent
# Conflicts:
#	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java
2015-07-27 11:30:47 +02:00
wing328
fe0e43f963 Merge pull request #1012 from tandrup/combine-ts-node
Combine TypeScript Node output and beautify Angular output
2015-07-27 17:24:34 +08:00
wing328
47abfe7079 Merge pull request #1014 from 2rs2ts/module-generation-readme-path-fix
Fix path in instructions for making your own codegen modules
2015-07-27 17:12:13 +08:00
Mads Mætzke Tandrup
d0a3def441 Adding npm run clean command to clean the sample dir 2015-07-27 11:02:38 +02:00
Mads Mætzke Tandrup
64f2e85608 Update TypeScript angular sample 2015-07-27 10:20:55 +02:00
Mads Mætzke Tandrup
09ccf12a3b Update Typescript node samples 2015-07-27 10:19:12 +02:00
Mads Mætzke Tandrup
fde5c60cb0 Support authentication from swagger in TypeScript Node 2015-07-27 10:18:38 +02:00
Mads Mætzke Tandrup
b18cc5e0de Include header parameters 2015-07-27 10:13:36 +02:00
wing328
6d8dea5dfc better exception handling for empty method name 2015-07-27 12:07:35 +08:00
wing328
a8f580032f fix empty operationId in java codegen 2015-07-27 11:39:37 +08:00
wing328
d0baa48fcd fix empty operationId 2015-07-27 11:21:51 +08:00
wing328
31200acc1a Merge pull request #998 from geekerzp/objc-date
[Objc] Enhancements of objective-c client
2015-07-27 10:41:42 +08:00
geekerzp
3b9b3e82f9 Update comments in objc client 2015-07-27 10:29:27 +08:00
wing328
783a4c0572 Merge pull request #1016 from ngs/swift-podspec-version
[Swift] Add version to Podspec template
2015-07-27 08:33:44 +08:00
wing328
9ce824d720 Merge pull request #1007 from ngs/swift-alamofire-1.3.0
[Swift] Support file upload with Alamofire 1.3.0
2015-07-27 08:29:34 +08:00
Mads Mætzke Tandrup
dee828622a Test file upload in sample client 2015-07-26 14:26:01 +02:00
Hervé Darritchon
5c0ae7babe Defect (PR #905) : Add code to be able to override the configPackage in the spring mvc template. 2015-07-26 12:11:29 +02:00
Mads Mætzke Tandrup
02da80e837 Update sample with small test script 2015-07-26 08:22:32 +02:00
Mads Mætzke Tandrup
e41a475335 Update typescript node sample 2015-07-25 22:05:43 +02:00
Mads Mætzke Tandrup
fea8e680df Fix TypeScript node file upload 2015-07-25 22:05:29 +02:00
Mads Mætzke Tandrup
b0f6b49595 Fix TypeScript Map type 2015-07-25 22:02:06 +02:00
Atsushi Nagase
b56da43953 [Swift] Add version to Podspec template 2015-07-26 03:19:33 +09:00
Atsushi Nagase
979a704310 [Swift] Update Alamofire to 1.3 in Podspec 2015-07-26 03:01:11 +09:00
Atsushi Nagase
5dcdadb751 [Swift] tweak conditions
336bb87b53 (commitcomment-12318006)
2015-07-26 02:59:43 +09:00
Atsushi Nagase
f98974190e [Swift] Support file upload with Alamofire 1.3.0
refs:

- https://github.com/Alamofire/Alamofire/milestones/1.3.0
- https://github.com/Alamofire/Alamofire/pull/539
2015-07-26 02:59:43 +09:00
wing328
6719a6cc74 Merge pull request #1013 from SparrowJang/develop_2.0
added a utf8 declaration to fix #1011 issue
2015-07-25 23:15:04 +08:00
Mads Mætzke Tandrup
3f9b2a9678 Adding build system for typescript AngularJS sample 2015-07-25 14:11:10 +02:00
Mads Mætzke Tandrup
bbf0ce8c80 Adding README for sample 2015-07-25 13:57:45 +02:00
Mads Mætzke Tandrup
9fc8c770d3 Adding build system for poetaster typescript node sample 2015-07-25 13:55:30 +02:00
wing328
8f2c99f0af Merge pull request #1005 from mhardorf/sort-by-inheritance
Sort model objects by inheritance
2015-07-25 18:18:29 +08:00
Mads Mætzke Tandrup
81f5cc47e7 Rename property to be more language specific 2015-07-25 12:03:17 +02:00
wing328
db37c02ebd Merge pull request #1010 from onovy/develop_2.0
[Python] Allow to set cookie in python(3) API constructor.
2015-07-25 17:03:11 +08:00
wing328
fc71b23464 Merge pull request #1006 from ngs/podspec
[Swift] Add podspec template
2015-07-25 16:46:13 +08:00
Mads Mætzke Tandrup
e924cec595 Conditional copy properties from parent.
Pull request #946 broke the TypeScript generation with inheritance where a superclass defined an enum. This makes it up to each language to decide the behavior appropriate for the language.
2015-07-25 07:45:08 +02:00
Andrew Garrett
90f152da75 Fix path in instructions for making your own codegen modules 2015-07-24 11:44:30 -07:00
Sparrow.jang
713ae4a957 added a utf8 declaration to fix #1011 issue 2015-07-24 22:40:24 +08:00
Ondrej Novy
50736458d0 Allow to set cookie in python(3) API constructor. 2015-07-24 11:48:43 +02:00
Mads Mætzke Tandrup
34b341874c Include api and model package in angular 2015-07-24 11:05:36 +02:00
Mads Mætzke Tandrup
7a1f3dbf9e Fix angular output to go to one dir to make it build 2015-07-24 10:23:07 +02:00
Mads Mætzke Tandrup
3723a9ba2d Updating typescript samples 2015-07-24 10:22:41 +02:00
Mads Mætzke Tandrup
bc8eae838c Beautify typescript angular output 2015-07-24 10:14:42 +02:00
Mads Mætzke Tandrup
88ed496b44 Extract abstract class for TypeScript generators 2015-07-24 10:03:02 +02:00
Mads Mætzke Tandrup
646da19c7d Combine TypeScript node output in one file and add missing require statements 2015-07-24 09:48:49 +02:00
Atsushi Nagase
80b5363202 [Swift] add cliOptions for podspec
```
podSource
    Source information used for Podspec

podVersion
    Version used for Podspec

podAuthors
    Authors used for Podspec

podSocialMediaURL
    Social Media URL used for Podspec

podDocsetURL
    Docset URL used for Podspec

podLicense
    License used for Podspec

podHomepage
    Homepage used for Podspec

podSummary
    Summary used for Podspec

podDescription
    Description used for Podspec

podScreenshots
    Screenshots used for Podspec

podDocumentationURL
    Documentation URL used for Podspec
```
2015-07-24 16:27:28 +09:00
Atsushi Nagase
071fc2ded6 [Swift] Add podspec template 2015-07-23 22:22:45 +09:00
Martin Hardorf
992b0c7e5e Sort model objects by inheritance 2015-07-23 13:11:53 +02:00
Martin Hardorf
037f59d0df Add support for specifying configuration file in maven plugin 2015-07-23 13:10:59 +02:00
geekerzp
5a235c642a Update comments of objc client 2015-07-23 18:03:19 +08:00
geekerzp
08ea05f7a1 Update objc client.
* Add comments in SWGConfiguration.h
* Change `Date` to `date` in ObjcClientCodegen.java
* Update comments in model body template
2015-07-23 16:03:38 +08:00
Andrew B
e301d9d00e Adding sample generator and output 2015-07-22 11:31:29 -07:00
Andrew B
8a399ee1cb Renaming the C# .net 2.0 to be more generic 2015-07-22 11:13:13 -07:00
Andrew B
4e5b9e4af3 Renaming the C# .net 2.0 to be more generic 2015-07-22 11:13:08 -07:00
geekerzp
37c79525f7 Update model body template in objc client.
* Add some comments.
2015-07-22 18:31:50 +08:00
geekerzp
f9ad16e7aa Update objc client.
* Add test cases for deserialization.
* Pretty print model infomation.
2015-07-22 17:45:31 +08:00
wing328
cde8d7ba4c Merge pull request #984 from geekerzp/python-enum
[Python] Support enum for model property
2015-07-22 16:48:34 +08:00
geekerzp
bd6fa6a2e4 Update PetApiTests#test_find_pet_by_tags test case of python client 2015-07-22 15:50:40 +08:00
geekerzp
b9287cf417 Add to_str method in python client and add test cases. 2015-07-22 11:00:51 +08:00
Andrew B
df93ca80f7 Fixing an issue that was causing incorrect JSON key names 2015-07-21 15:49:37 -07:00
Andrew B
0247f0774d Updating the mono compile script to target .net 2 2015-07-21 11:12:17 -07:00
wing328
37dbd6e4cd Merge pull request #992 from who/develop_2.0
[C#] Fixing a mono compilation error
2015-07-21 21:43:06 +08:00
wing328
34db9814d8 Merge pull request #994 from wing328/fix_swagger_parser_version
Fix compilation error with a newer swagger parser
2015-07-21 17:39:24 +08:00
wing328
cf7082c2e6 fix swagger parser version to use 1.0.9-SNAPSHOT 2015-07-21 16:54:14 +08:00
wing328
6b4f810fec Merge pull request #981 from Edubits/develop_2.0
[Swift] Support use in Framework
2015-07-21 16:35:36 +08:00
Tony Tam
f7a07f72b8 added resolve option for #903 2015-07-20 23:31:49 -07:00
Andrew B
a6012ecf41 Initial commit of the Unity3D C# .net 2.0 generator 2015-07-20 23:26:59 -07:00
Andrew B
0b7b57bf4d [C#] Fixing a mono compilation error 2015-07-20 21:22:49 -07:00
wing328
498a400d4e Merge pull request #988 from wing328/csharp_update_unit_test
[C#] Updated unit test and minor change to conform style guide
2015-07-21 12:08:15 +08:00
wing328
405e5a7a35 Merge pull request #946 from xhh/model-all-of
Copy properties from parent models defined with allOf
2015-07-21 11:41:24 +08:00
wing328
f1304022b0 Merge pull request #852 from tomtit/issue837
Fixed #837: Generation of default values for complex arrays and maps has been improved.
2015-07-21 11:28:43 +08:00
wing328
fc7f2a92d0 Merge pull request #878 from lugaru1234/issue798
Fixed #798: original jar generation has been fixed.
2015-07-20 21:50:51 +08:00
wing328
27113cf326 Merge pull request #859 from lugaru1234/issue831
Fixed #831: skipOverwrite flag has been added
2015-07-20 21:14:33 +08:00
wing328
7179c15158 Merge pull request #966 from wing328/nodejs_fix_summary
[NodeJS] Add back summary and description to the endpoint definition
2015-07-20 11:12:15 +08:00
wing328
ba72e7344a remove nuget pacakges 2015-07-20 10:48:20 +08:00
wing328
596bde2ef6 remove leading space for path variable, update unit test 2015-07-20 10:43:08 +08:00
wing328
a863e538a8 Merge pull request #943 from psmay/develop_2.0-RestSharp-path-params
[C#] Use RestSharp's mechanism for path parameters in URL templates
2015-07-20 10:16:01 +08:00
xhh
a134b5ca76 Retrofit: fix form field naming by using baseName 2015-07-20 10:12:36 +08:00
Peter S. May
1f7664f81e Fixed case typo in previous edit. 2015-07-18 19:38:20 -04:00
geekerzp
68820e5a80 Update comments of api template of python client 2015-07-18 15:54:00 +08:00
geekerzp
195c71da37 Update comments of python client 2015-07-18 15:35:12 +08:00
geekerzp
ddfa713f55 Update wording of comment in api template of python client 2015-07-18 15:22:39 +08:00
geekerzp
c9889c5baf Update api template of python client 2015-07-18 15:03:55 +08:00
geekerzp
60d6cd744a Format python client using pep8 2015-07-18 14:30:19 +08:00
Peter S. May
1072c9d017 Merge remote-tracking branch 'upstream/develop_2.0' into develop_2.0-RestSharp-path-params
Conflicts:
	modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache
	modules/swagger-codegen/src/main/resources/csharp/api.mustache
2015-07-17 21:45:54 -04:00
Peter S. May
4bc4a8aed1 WIP pre-adding new sources for ApiClient and api 2015-07-17 21:09:05 -04:00
Robin Eggenkamp
0ad7005547 [Swift] Add support for basic form data 2015-07-16 17:56:20 +02:00
geekerzp
3993ef3dc8 Update python codegen.
Remove leading underscore.
2015-07-16 18:58:23 +08:00
geekerzp
8746f1544b Merge branch 'develop_2.0' into python-enum 2015-07-16 17:27:17 +08:00
geekerzp
f0e09ae33a Add enum support for model property of python client 2015-07-16 17:24:42 +08:00
wing328
e879268043 Merge pull request #941 from geekerzp/develop_2.0_python_async
[Python] Support asynchronous request in python client
2015-07-16 10:47:02 +08:00
geekerzp
33561fa159 Support date type in python client 2015-07-16 10:11:27 +08:00
Robin Eggenkamp
78760907a5 [Swift] Support use in a Framework
To support use in a Framework set access level of relevant classes,
methods and members to public
2015-07-15 18:22:36 +02:00
Robin Eggenkamp
30eb1f1075 Fix bug in api name placeholder 2015-07-15 18:20:05 +02:00
wing328
5c9afbafb2 Merge pull request #918 from geekerzp/develop_2.0_objc_issue
[Objc] Enhancements and Issue fix
2015-07-15 18:20:40 +08:00
geekerzp
0092d8a63b Update unit tests of objc client 2015-07-15 18:11:04 +08:00
wing328
3c6f07cbe3 Merge pull request #975 from wing328/sinatra_fix_tag
[Sinatra] Fixed outdated tag in mustache template
2015-07-15 17:50:25 +08:00
geekerzp
95cb5f73a3 Remove SWGFile from objc client 2015-07-15 17:10:24 +08:00
geekerzp
02f6c805af Update integration test of objc client 2015-07-15 17:10:24 +08:00
geekerzp
13d74f01a2 Add logging in objc client 2015-07-15 17:10:24 +08:00
geekerzp
8877be82f0 Update api-body.mustache of objc client 2015-07-15 17:10:24 +08:00
geekerzp
a25d3f2543 Update README file of objc client 2015-07-15 17:10:23 +08:00
geekerzp
3f017af464 Update objc client.
Replace SWGFile with NSURL.
2015-07-15 17:10:23 +08:00
geekerzp
0e56d0d1c6 Support file downloading in Objc codegen. 2015-07-15 17:10:23 +08:00
geekerzp
f48a7f20e6 Update config-help of objc cli 2015-07-15 17:10:23 +08:00
geekerzp
9a15ced211 Supoort customize classPrefix in objc client. 2015-07-15 17:10:23 +08:00
geekerzp
e244d20152 Remove lib files. 2015-07-15 17:10:23 +08:00
geekerzp
412b6b3839 Update objc client.
* Package objc client using cocoapods.
* Support cli options.
2015-07-15 17:08:45 +08:00
geekerzp
0a652a3d13 Fix issue#896 https://github.com/swagger-api/swagger-codegen/issues/896 2015-07-15 17:08:44 +08:00
geekerzp
4d302683f3 Update logging of python client 2015-07-15 15:58:45 +08:00
geekerzp
517717958d Update doc string of RESTClientObject#agent method of python client 2015-07-15 15:27:15 +08:00
geekerzp
b42ead3c0f Replace urllib3.util.url.parse_url with urllib3.util.parse_url 2015-07-15 15:27:14 +08:00
geekerzp
8a3c64aa41 Add logging and debug report for python client. 2015-07-15 15:27:14 +08:00
geekerzp
d97b0984cb Update ApiClient of python client.
Add docstring for method call_api.
2015-07-15 15:25:32 +08:00
geekerzp
0e8cf70dc4 Fix typo 2015-07-15 15:25:32 +08:00
geekerzp
88e5860d9b support asynchronous request in python client 2015-07-15 15:25:31 +08:00
wing328
157b07e552 Merge pull request #912 from gabrielar/develop_2.0-pull-requests/add-pathPrefix-key-to-operations
Add a `pathPrefix` key to the `operations` key
2015-07-15 10:26:13 +08:00
wing328
1f097ee1a1 Merge pull request #977 from who/develop_2.0
[PHP] Support for customizing namespace and Composer fields
2015-07-15 10:06:26 +08:00
wing328
7a5fd24785 Merge pull request #979 from xhh/auth-methods-fix
Fix NullPointerException for authMethods
2015-07-15 09:50:53 +08:00
wing328
59258be3dd Merge pull request #978 from tkQubo/fix/swift_bug
[Swift] Fix a bug
2015-07-15 09:42:39 +08:00
xhh
e5bdb3a0c1 Fix NullPointerException for authMethods 2015-07-15 09:21:09 +08:00
wing328
dd35c672f0 Merge pull request #935 from geekerzp/python-file-response
[Python] Support file downloading for Python API client
2015-07-14 17:45:11 +08:00
geekerzp
18ea21087f Update README file of python client 2015-07-14 17:34:38 +08:00
geekerzp
746a55be73 Update README file of python client 2015-07-14 17:15:24 +08:00
wing328
7242a664e3 Merge pull request #923 from xhh/ruby-debug
[Ruby] Some improvements & cleaning-up on Ruby API client
2015-07-14 16:34:41 +08:00
geekerzp
9f76acbbd7 Update README file of python client 2015-07-14 15:42:01 +08:00
geekerzp
af67353022 Update integration test of python client 2015-07-14 15:38:23 +08:00
kubo_takaichi
ecf4082d68 Fix bug in api name placeholder and api url 2015-07-14 13:41:28 +09:00
wing328
5821e41185 Merge pull request #927 from wing328/csharp_file_response
[C# ] Add file response
2015-07-14 12:34:51 +08:00
xhh
822e640e0a Merge branch 'develop_2.0' into ruby-debug
Conflicts:
	modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache
	modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache
	samples/client/petstore/ruby/lib/petstore/swagger/request.rb
	samples/client/petstore/ruby/lib/swagger_client.rb
	samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb
2015-07-14 12:33:17 +08:00
geekerzp
30925b7800 Update pom.xml of python client 2015-07-14 10:28:36 +08:00
geekerzp
bb570d7efa Update integration-test of python client 2015-07-14 09:43:59 +08:00
geekerzp
c88c85a317 Enhancements intergration-test of python client 2015-07-14 09:39:19 +08:00
geekerzp
23dfac0194 Update deserialization of python client.
Return None if deserialize data is None.
2015-07-14 09:39:19 +08:00
geekerzp
b99f006861 Update Python client.
Throw ApiException if fail to parse string to datetime.
2015-07-14 09:39:19 +08:00
geekerzp
80d1deb2dd Update unit tests of Python client.
Add more test cases for deserialization.
2015-07-14 09:39:19 +08:00
geekerzp
2912ee8ae1 Update deserialize response of Python client. 2015-07-14 09:39:18 +08:00
geekerzp
6df6c079ee Support file downloading in Python codegen. 2015-07-14 09:39:18 +08:00
Andrew B
f4226474e2 Updating command-line parameter description for artifactVersion 2015-07-13 15:02:14 -07:00
Andrew B
b70a0bf0c6 Fixing an issue with errant namespace in the sample petstore 2015-07-13 14:56:33 -07:00
Andrew B
7dca394eca Support for customizing Composer package and namespaces 2015-07-13 14:46:56 -07:00
wing328
80303b524d Merge pull request #884 from xhh/params-order
Make sure "required" parameters are placed in front of "optional" parameters
2015-07-13 17:51:22 +08:00
wing328
6e7c70f247 fix sinatra outdated tag, use version tag 2015-07-13 17:43:18 +08:00
xhh
715c56afcc Rebuild petstore PHP sample with updated order on params 2015-07-13 16:51:19 +08:00
xhh
aad05c4dee Merge branch 'develop_2.0' into params-order
Conflicts:
	samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php
	samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php
	samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php
2015-07-13 16:48:19 +08:00
wing328
3f9d1607b6 Merge pull request #926 from wing328/php_support_file_response
[PHP] support "file" response
2015-07-13 15:51:20 +08:00
wing328
879c1b921c update php petstore sample 2015-07-13 15:31:20 +08:00
xhh
fb0b7d622f Merge branch 'develop_2.0' into params-order
Conflicts:
	modules/swagger-codegen/src/main/resources/php/api.mustache
2015-07-13 15:30:06 +08:00
wing328
f154e407d2 update coding style based on CodeSniffer 2015-07-13 15:26:12 +08:00
wing328
44705b566d add default version for package 2015-07-13 15:24:12 +08:00
wing328
71a22141bf add enum support for model property 2015-07-13 15:24:11 +08:00
wing328
38149173ff revert petstore json, fixed test case 2015-07-13 15:21:39 +08:00
wing328
2258a4632d fix test.php, fix default configuration 2015-07-13 15:21:39 +08:00
wing328
259b31ccd4 temporary folder setting 2015-07-13 15:21:38 +08:00
wing328
7f31da734d add file response for php, update test case 2015-07-13 15:09:09 +08:00
wing328
fcd0b31d7d add file response for php 2015-07-13 15:09:09 +08:00
wing328
4c2df94ec7 Merge pull request #953 from bletail/develop_2.0
Python/Python3 datetime and date type fixed
2015-07-13 15:05:13 +08:00
wing328
38760d2aa1 Merge pull request #915 from xhh/ruby-file-response
[Ruby] Support file downloading for Ruby API client
2015-07-13 14:50:40 +08:00
wing328
f6174051cb Merge pull request #931 from cbornet/oauth_support
generate oauth2 fields in the data for the templates
2015-07-13 14:39:14 +08:00
wing328
68915eeb8f Merge pull request #968 from mhardorf/develop_2.0
Cleaned up TypeScript code generator
2015-07-13 12:16:11 +08:00
wing328
1434691927 Merge pull request #916 from wing328/fix_optional
[Perl, Python AsyncScala] Fix optional tag in the template
2015-07-13 11:53:58 +08:00
wing328
b46efd839d Merge pull request #914 from webjunkie/patch-1
Optional is used in PHP template although not available
2015-07-13 11:52:55 +08:00
wing328
c7f8f0171b Merge pull request #919 from wing328/fix_java_android_path_issue
[Java, Android] Fix path variable name
2015-07-13 11:51:45 +08:00
wing328
045a3b44c1 Merge pull request #901 from tkQubo/feature/swift_develop_2.0
[Swift] Some fixes for SwiftGenerator for develop 2.0
2015-07-13 11:51:07 +08:00
wing328
6c85fc285a Merge pull request #959 from dilipkrish/develop_2.0
Updated the swagger-codegen sample for generating the service side stubs
2015-07-13 10:14:05 +08:00
Dilip Krishnan
7cc9581f04 Updated the mustache template to remove the spurious import
Also regenerated the spring-mvc server sample
2015-07-12 20:56:36 -05:00
Dilip Krishnan
9283249963 Updated the swagger-codegen sample for generating the service side stubs
for spring mvc using springfox implementation
2015-07-12 20:56:31 -05:00
Tony Tam
461f556289 Merge pull request #893 from sudohippie/develop_2.0-fork
Android & Java template modifications to check collectionFormat when creating query parameters
2015-07-09 10:11:54 -07:00
Martin Hardorf
e3d3641b96 Removed unused import 2015-07-09 14:57:40 +02:00
Martin Hardorf
7e8f8e85d7 Changed default name of the modelPackage 2015-07-09 14:55:15 +02:00
Martin Hardorf
abc7100a17 Removed unused code from the api classes 2015-07-09 14:54:36 +02:00
Morten Andersen
661b9d6315 Docker generate example 2015-07-09 12:58:33 +02:00
moander
a21c2be877 Set executable flag 2015-07-09 10:39:35 +00:00
moander
5c29cbf33d Build and run script for docker 2015-07-09 12:33:43 +02:00
Martin Hardorf
d3bc347e31 Changed base path to use contextPath 2015-07-09 10:34:39 +02:00
wing328
1f35f58841 add back summary and description to nodejs swagger.json 2015-07-09 14:05:08 +08:00
xhh
a51d71e728 Fix syntax error when there are no authMethods 2015-07-09 10:48:16 +08:00
wing328
b8c06505f6 use fully qualified name for Task 2015-07-09 10:21:55 +08:00
moander
80731633b4 Created a Dockerfile 2015-07-09 01:22:06 +02:00
Tobias Pfeifer
4c16366f45 fix SpringMVCServerCodegen for maps as in JavaClientCodegen 2015-07-08 15:45:38 +02:00
Martin Hardorf
4133cae2bc Fixed mustache to handle non-required parameters 2015-07-08 11:19:25 +02:00
Martin Hardorf
f6a1af2831 Changed maps to any and DateTime to Date 2015-07-08 11:17:06 +02:00
xhh
a24fee00cb Support primitive response in Ruby client 2015-07-08 16:46:31 +08:00
xhh
f42f329ace Parse "date" as Date in Ruby client 2015-07-08 13:10:28 +08:00
xhh
6fd2ccabee Merge branch 'develop_2.0' into ruby-debug 2015-07-08 12:38:21 +08:00
DariusM
20c7932df4 Python /python3 datetime and date fixed 2015-07-07 13:00:28 +02:00
wing328
e49fe7a12f better style for model, add <value> to all properties 2015-07-07 16:25:33 +08:00
wing328
b1b0e28f59 update c# style 2015-07-06 23:06:28 +08:00
Tony Tam
dfd8d5ef64 updated to latest release version 2015-07-06 04:55:12 -07:00
wing328
94768d44b5 better type comparision 2015-07-06 13:55:33 +08:00
wing328
3b1999af4b update csharp sample 2015-07-06 11:24:59 +08:00
wing328
7e4a82bcfb add readme 2015-07-06 11:18:05 +08:00
wing328
f823c0e26a update newtonsoft json 2015-07-06 11:03:36 +08:00
xhh
bf32777b67 Fix NullPointerException in tests, improve usage to addVars 2015-07-03 18:07:34 +08:00
wing328
987a61640b fix file upload issue. add error handling for status code 0 2015-07-03 17:39:27 +08:00
xhh
66d16cfeaf Validate parameter against allowed values (enum) 2015-07-03 16:46:23 +08:00
xhh
0bf4163389 Copy properties of intermediate (interface) models 2015-07-03 15:08:37 +08:00
xhh
b61a400d91 Copy properties of parent model to model with allOf
Also fix #936
2015-07-03 15:08:37 +08:00
wing328
55827fe516 fix model import for csharp 2015-07-03 14:20:54 +08:00
wing328
5c888ad039 better method comment 2015-07-03 13:55:51 +08:00
wing328
d7d6ba957e fix comment and use 4-space indentation 2015-07-03 11:45:31 +08:00
wing328
57b54d8ad7 update code style for apiclient, configuration and apiexception 2015-07-03 10:36:21 +08:00
Peter S. May
4b896c759c [C#] Use RestSharp's mechanism for path parameters in URL templates
Previously, a simple find-and-replace had been used to substitute path parameters into the path. Among other omissions, this resulted in special characters such as `/` being left unescaped.

The RestSharp request object, as it turns out, expects a path template in the same format as provided by Swagger (with param names in braces), to be filled in using `AddParameter()`. In this edit, the code now uses this mechanism. The form parameter values are now passed to `CallApi*()` as a `Dictionary<String, String>`, where they are added to the request before submission. Since this was already how query and form parameters (etc.) were implemented, the resulting code is more consistent with itself than before.
2015-07-02 15:33:30 -04:00
Ole Lensmar
aba755d3de Merge pull request #940 from xhh/jax-rs-classname
Sanitize API class name in Jax RS server codegen
2015-07-02 11:38:10 +02:00
xhh
fe35675168 Allow numbers for classname
and remove spaces
2015-07-02 17:15:53 +08:00
xhh
d825b96720 Sanitize API class name in Jax RS server codegen 2015-07-02 12:00:18 +08:00
wing328
422da698f6 import model only if it has import for c# 2015-07-02 11:18:41 +08:00
wing328
488e604207 use stream for file 2015-07-01 21:37:48 +08:00
xhh
846d282ba0 Add helper methods for last response 2015-07-01 18:48:31 +08:00
xhh
6f1dd5ce35 Store last response in a thread-safe way 2015-07-01 17:37:16 +08:00
xhh
108b2241c0 Validate model property against allowed values (enum)
when present with attribute setters
2015-07-01 17:18:29 +08:00
wing328
4d6dbf7d92 show return in doc only if it has a return 2015-07-01 15:16:28 +08:00
Nadezhda Makarkina
eca827613d Fixed #831: skipOverwrite flag has been added 2015-06-30 17:58:35 +03:00
wing328
2e76b56f30 revert file to String, add test case for upload file 2015-06-30 17:50:22 +08:00
wing328
f290de95dd update parameter name to camelize lower 2015-06-29 23:14:00 +08:00
wing328
59987a54a9 fix deserialization of string and other primitive 2015-06-29 22:16:38 +08:00
cbornet
2d59c5d190 generate oauth2 fields in the data for the templates
Fixes #347
2015-06-29 13:39:39 +02:00
wing328
9726ada8d1 fix return type and tempfolder 2015-06-29 15:30:34 +08:00
wing328
76ece5a4eb add file response support for c# (passed test cases) 2015-06-29 12:17:49 +08:00
kubo_takaichi
91af76cf41 Use CLI option 2015-06-27 23:24:49 +09:00
kubo_takaichi
65af735d6c Merge commit '4143e286374bdd384c39a68df1f8f3a3eb58e6a4' into feature/swift_develop_2.0 2015-06-27 21:19:32 +09:00
wing328
30bc58f6ff Merge branch 'fix_optional' of https://github.com/wing328/swagger-codegen into fix_optional 2015-06-26 23:57:06 +08:00
wing328
3eca940e7d fix perl and asyncscala optional tab 2015-06-26 23:56:20 +08:00
wing328
38d62d768a fix optional for python, python3 2015-06-26 23:56:20 +08:00
xhh
1de6952279 Support customizing default headers via config option
for example:

    config.default_headers['X-MY-HEADER'] = 'my-header-value'
2015-06-26 19:09:20 +08:00
xhh
54d6a7e19c Merge branch 'develop_2.0' into ruby-file-response 2015-06-26 17:44:37 +08:00
xhh
fafddbf040 Fix naming in specs 2015-06-26 17:16:38 +08:00
xhh
d8b0cb739f Add config file for bin/ruby-petstore.sh
to rename swagger_client to petstore
2015-06-26 17:15:14 +08:00
xhh
2d3d35cfd7 Rebuild Ruby petstore client 2015-06-26 16:37:58 +08:00
xhh
8c10e4f2b0 Remove unused code 2015-06-26 16:06:32 +08:00
xhh
0ac1ef266f Avoid more monkey-patching 2015-06-26 16:04:18 +08:00
xhh
327128dbba Fix "date" type deserialization 2015-06-26 15:57:46 +08:00
xhh
16e80c65d7 Avoiding monkey-patching in Ruby API client 2015-06-26 15:56:59 +08:00
xhh
40c9f05536 Merge branch 'develop_2.0' into ruby-debug 2015-06-26 10:38:58 +08:00
wing328
091e76703c update sample 2015-06-26 10:35:50 +08:00
wing328
6a24b328e3 fix variable name in path 2015-06-26 10:30:12 +08:00
Tony Tam
4143e28637 Merge branch 'wing328-csharp_add_cli_support' into develop_2.0 2015-06-25 11:55:41 -07:00
Tony Tam
31efefe0b9 Merge branch 'csharp_add_cli_support' of ssh://github.com/wing328/swagger-codegen into wing328-csharp_add_cli_support 2015-06-25 11:54:30 -07:00
Tony Tam
e60bd564cb Merge pull request #864 from geekerzp/python-cli-option
[Python] Enabling cli config options for python generator
2015-06-25 11:53:29 -07:00
Tony Tam
69b75bb1af Merge pull request #885 from mhardorf/develop_2.0
Added support for TypeScript generation for AngularJS and Node.js
2015-06-25 11:53:21 -07:00
Tony Tam
1fb796f14d Merge pull request #891 from who/develop_2.0
Replacing getClientResponseStatus() with getStatusInfo()
2015-06-25 11:53:10 -07:00
Tony Tam
e996498a24 Merge pull request #913 from xhh/scala-warnings
[Scala] Fix warnings and upgrade jersey for Scala client
2015-06-25 11:52:57 -07:00
Tony Tam
c3d1367e7c Merge pull request #894 from wing328/csharp_add_nunit
[C#] Add NUnit test
2015-06-25 11:52:19 -07:00
Tony Tam
69eae7d35b merged 2015-06-25 10:23:05 -07:00
Tony Tam
162d1d1f98 merged 2015-06-25 10:21:38 -07:00
Tony Tam
07d5365c5c merged from #902, rebuilt client 2015-06-25 10:17:28 -07:00
Tony Tam
f1239aba6c Merge pull request #908 from wing328/fix_php_file_sep
[PHP] Fix regular expression in toPackagePath
2015-06-25 10:10:30 -07:00
Tony Tam
37620518e7 Merge pull request #892 from wing328/add_sinatra
[Ruby] Add back Sinatra tempates
2015-06-25 10:10:22 -07:00
William Cheng
9d739a44cd update python test case 2015-06-25 21:47:00 +08:00
wing328
18ac6e8aae fix perl and asyncscala optional tab 2015-06-25 23:10:25 +08:00
wing328
8cce7ac053 fix optional for python, python3 2015-06-25 22:40:14 +08:00
xhh
e6e1db2064 Support looser format when detecting filename 2015-06-25 16:26:04 +08:00
xhh
ceafbcc97f Add config option for file downloading folder. Log about file downloading 2015-06-25 16:07:02 +08:00
xhh
f3a0f464f7 Support file downloading in Ruby generator 2015-06-25 15:35:48 +08:00
Raghav Sidhanti
1af23fb751 Unit tests for Android and Java parameterToPairs method 2015-06-24 11:55:03 -07:00
Raghav Sidhanti
ea76f34de5 Merge branch 'develop_2.0' of https://github.com/swagger-api/swagger-codegen into develop_2.0-fork 2015-06-24 11:25:32 -07:00
Julian Bez
8ce3823698 Change to not required 2015-06-24 16:34:32 +02:00
Julian Bez
644231b915 Change optional to required 2015-06-24 16:32:49 +02:00
xhh
621e3e7b1a Add comments for some configuration options 2015-06-24 15:57:01 +08:00
wing328
6aac24398a update model to support inheritance (#879) 2015-06-24 14:34:05 +08:00
xhh
545fb52b7d Merge branch 'develop_2.0' into ruby-debug 2015-06-24 14:10:47 +08:00
Ole Lensmar
8e6c0f96fb updated documentation and removed java-specific parameters from general configuration 2015-06-24 07:31:10 +02:00
Gabriel Radu
1b1f860c82 Add a pathPrefix key to the operations key 2015-06-24 03:28:38 +01:00
Ole Lensmar
50dd196d42 fixed code formatting and imports 2015-06-24 00:12:50 +02:00
Ole Lensmar
ce6ec20fef added config parameters for all default parameters and a configOptions map for language specific parameters 2015-06-24 00:11:13 +02:00
Ole Lensmar
11e56f5c9c Merge pull request #898 from garethjevans/develop_2.0
Contributed maven plugin to the swagger-codegen project
2015-06-23 23:20:49 +02:00
nmonterroso
efd5b806be updating php generated samples and updating tests 2015-06-23 09:27:52 -07:00
nmonterroso
1b4c71c280 re-adding Configuration->deleteDefaultHeader 2015-06-23 09:27:34 -07:00
wing328
d83036ccdf fix regular expression 2015-06-23 22:36:57 +08:00
wing328
d18426c69a fix reg expression 2015-06-23 22:30:43 +08:00
wing328
351833a923 test fix 2015-06-23 21:52:00 +08:00
wing328
2979d93829 use replace instead of replaceAll 2015-06-23 21:47:10 +08:00
Martin Hardorf
2fce2e4109 Removed wrong hasMore from Angular TypeScript mustache 2015-06-23 15:37:07 +02:00
xhh
13d350be2e Fix warnings and upgrade jersey for Scala client
* Upgrade jersey to latest version (from 1.7 to 1.19)
* Replace getClientResponseStatus() with getStatusInfo()
* Fix the following maven warnings and model import warnings

    [WARNING] 'build.plugins.plugin.version' for org.codehaus.mojo:build-helper-maven-plugin is missing. @ line 72, column 15
    [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!

    [WARNING]  Expected all dependencies to require Scala version: 2.10.4
    [WARNING]  com.fasterxml.jackson.module:jackson-module-scala_2.10:2.4.2 requires scala version: 2.10.4
    [WARNING]  org.scala-lang:scala-reflect:2.10.4 requires scala version: 2.10.4
    [WARNING]  io.swagger:swagger-scala-client:1.0.0 requires scala version: 2.10.4
    [WARNING]  org.scalatest:scalatest_2.10:2.1.3 requires scala version: 2.10.3
    [WARNING] Multiple versions of scala libraries detected!

   [WARNING] /Users/xhh/projects/swagger-codegen/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Pet.scala:3: warning: imported `Category' is permanently hidden by definition of object Category in package model
2015-06-23 21:23:48 +08:00
wing328
550493ba84 fix php separator 2015-06-23 21:20:12 +08:00
Martin Hardorf
c45af23946 Fixed headerParams and paramName 2015-06-23 12:05:43 +02:00
xhh
19ee56592e Allow customizing SSL CA certificate
by adding a `ssl_ca_cert` configuration option
2015-06-23 17:23:22 +08:00
kubo_takaichi
aec4af1b88 Replace slash with File.separator 2015-06-23 16:10:21 +09:00
xhh
46869df631 Make HTTP response accessible by storing the last response
so that users are able to retrieve, for example, rate-limit headers
from the response
2015-06-23 15:02:40 +08:00
nmonterroso
c91a1b963b change serializer to be instanced, rather than static methods 2015-06-22 21:33:44 -07:00
nmonterroso
2fced0f634 Revert "Updates to csharp model template to support inheritance"
This reverts commit 5f1df9e093.
2015-06-22 21:12:13 -07:00
nmonterroso
60b0ffeb0e don't prepend the invokerPackage - an artifact from an earlier implementation 2015-06-22 21:06:22 -07:00
nmonterroso
6623e120cd renaming to Configuration 2015-06-22 20:53:59 -07:00
nmonterroso
46ec934a9c java7 doesn't have replace, but put operates as such, so switch to that 2015-06-22 20:49:12 -07:00
nmonterroso
5a9e9550ca fixing php-doc 2015-06-22 20:43:00 -07:00
nmonterroso
8e0142338e removing unused imports 2015-06-22 20:36:57 -07:00
nmonterroso
61e368ce87 Merge remote-tracking branch 'swagger/develop_2.0' into php-upgrades 2015-06-22 20:29:09 -07:00
nmonterroso
c93b0dd3b8 make srcBasePath configureable 2015-06-22 20:24:19 -07:00
kubo_takaichi
79e31a5761 Add a workaround against void forcibly being converted to string 2015-06-23 12:20:00 +09:00
kubo_takaichi
fa3a9a9d61 Change class package 2015-06-23 12:20:00 +09:00
kubo_takaichi
febaa340e3 Treat object as String (temporary measure) 2015-06-23 12:20:00 +09:00
kubo_takaichi
bcab55e3ef Tighten parameter requirement 2015-06-23 12:20:00 +09:00
kubo_takaichi
24465d2df4 Change model naming 2015-06-23 12:20:00 +09:00
kubo_takaichi
8540ac71c8 Update swift code generation script 2015-06-23 12:20:00 +09:00
kubo_takaichi
9e47042122 Update models 2015-06-23 12:20:00 +09:00
kubo_takaichi
e0109afc60 Fix typo 2015-06-23 12:20:00 +09:00
kubo_takaichi
ff88f7175d Update models 2015-06-23 12:20:00 +09:00
kubo_takaichi
c9a9b0ad2b Refine authMethods description 2015-06-23 12:20:00 +09:00
kubo_takaichi
db01ec801f Add suppressRequired functionality 2015-06-23 12:20:00 +09:00
kubo_takaichi
495e528eec Add generated code 2015-06-23 12:20:00 +09:00
kubo_takaichi
a7c91d610f Add error response body to NSError 2015-06-23 12:20:00 +09:00
kubo_takaichi
d08acf7298 Add a dateTime formatter candidate 2015-06-23 12:20:00 +09:00
kubo_takaichi
7be35bb02e Change method name to avoid name collision 2015-06-23 12:20:00 +09:00
Raghav sidhanti
b4d6fd3ba3 Returning when query param value is null. 2015-06-22 20:16:35 -07:00
nmonterroso
d5d1483656 properly account for custom and non-custom settings for modelPackage and apiPackage 2015-06-22 20:14:54 -07:00
Tony Tam
02c41ac574 fix for #900, invalid param name for java client 2015-06-22 20:00:28 -07:00
nmonterroso
3a6f431f62 make packagePath configureable, and remove unused code 2015-06-22 19:34:03 -07:00
nmonterroso
4fe979a8c0 code compiles and *should* work, but need to re-organize for separate client/api-specific class namespaces 2015-06-22 19:26:26 -07:00
xhh
3b6a3b4a38 Add logging for API call entry and result 2015-06-23 10:12:20 +08:00
nmonterroso
da14c9e692 changing to invokerPackage 2015-06-22 19:09:32 -07:00
nmonterroso
b8b003bc83 Merge remote-tracking branch 'swagger/develop_2.0' into php-upgrades
Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java
	modules/swagger-codegen/src/main/resources/php/ApiClient.mustache
	modules/swagger-codegen/src/main/resources/php/ApiException.mustache
	modules/swagger-codegen/src/main/resources/php/api.mustache
	modules/swagger-codegen/src/main/resources/php/autoload.mustache
	modules/swagger-codegen/src/main/resources/php/configuration.mustache
	modules/swagger-codegen/src/main/resources/php/model.mustache
	modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala
2015-06-22 19:09:13 -07:00
xhh
229ea93627 Add debugging switch to Ruby generator 2015-06-23 10:06:01 +08:00
xhh
24296eacea Merge branch 'develop_2.0' into params-order
Conflicts:
	samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb
2015-06-23 10:02:18 +08:00
Raghav Sidhanti
6958db3d3d Refactored Pairs to use List instead of Set. 2015-06-22 17:14:18 -07:00
Raghav Sidhanti
32b50e7c8e Refactored parameterToPairs 2015-06-22 17:02:00 -07:00
Tony Tam
b803895750 Merge pull request #865 from ammmze/feature/php-namespace-and-doc
Improve PHP namespace support
2015-06-22 16:53:57 -07:00
Tony Tam
d1153dfeb4 Merge pull request #866 from geekerzp/develop_2.0_objc_deserialize_map
[Objc] bug fix for map response
2015-06-22 16:53:28 -07:00
Tony Tam
385fab225e Merge pull request #871 from xhh/ruby-object-type
[Ruby] Support deserialization of "object" type in Ruby generator
2015-06-22 16:53:21 -07:00
Tony Tam
89a5abb217 Merge pull request #870 from wing328/perl_cli_support
[Perl] Add CLI config options and code enhancement
2015-06-22 16:53:12 -07:00
Raghav Sidhanti
79a5614be9 Invalid strings will be passed as blank query param. 2015-06-22 15:55:29 -07:00
Raghav Sidhanti
a1b56c9b83 Renamed QueryParam to Pair class in Android templates. 2015-06-22 15:28:29 -07:00
Raghav Sidhanti
ecddfb7ccf Renamed QueryParam to Pair class in Java templates. 2015-06-22 15:16:45 -07:00
nmonterroso
bd5eb7ace3 update tests 2015-06-22 12:30:52 -07:00
nmonterroso
8e15bd6a85 call setHost on config 2015-06-22 12:13:39 -07:00
nmonterroso
5ef50f9f4b rename ApiConfiguration to ApiClientConfiguration 2015-06-22 12:07:48 -07:00
nmonterroso
a6331244e1 move all configuration to ApiConfiguration 2015-06-22 12:05:22 -07:00
nmonterroso
01d7776fc1 don't create a new response object, and keep the old string value in the exception and have the object as ApiException->responseObject 2015-06-22 11:47:23 -07:00
nmonterroso
109b7eeaec adding static setters/getters for models since members are no public 2015-06-22 11:19:01 -07:00
nmonterroso
5de99bafa7 fixing package output 2015-06-22 11:18:36 -07:00
Gareth Evans
a664abcf51 Contributed maven plugin to the swagger-codegen project 2015-06-22 19:17:29 +01:00
nmonterroso
6f11092a57 call setHost using API baspath when no apiclient is provided 2015-06-22 10:35:57 -07:00
nmonterroso
e598384d97 move authentication to the API level, so that supporting classes aren't api-specific 2015-06-22 10:31:38 -07:00
nmonterroso
53bddae904 separate serialization responsibility to ObjectSerializer class 2015-06-22 09:47:28 -07:00
nmonterroso
1519912a1a cleaning up some php doc 2015-06-22 09:26:45 -07:00
nmonterroso
b3a3bdd2e0 add fully-qualified class names to deserialize params 2015-06-22 09:18:41 -07:00
nmonterroso
04be474f56 moving $host back to ApiClient and making ApiClient setters fluent 2015-06-22 08:36:49 -07:00
nmonterroso
99e963709b renaming configuration 2015-06-22 08:30:08 -07:00
nmonterroso
b9ca19168a remove static fields in Configuration and make variable case more consistent 2015-06-22 08:28:22 -07:00
geekerzp
acf09da578 Fix typo in python codegen 2015-06-22 16:35:15 +08:00
wing328
1d59937150 add nunit test for csharp 2015-06-22 11:53:44 +08:00
nmonterroso
caa1b7f411 generate model imports for support files, and use them as imports 2015-06-19 15:20:29 -07:00
Raghav Sidhanti
7a9a41fe01 Java and Android template changes to accommodate query params defined by the collection-format. 2015-06-19 14:06:25 -07:00
nmonterroso
acdc5328fe deserialize thrown exceptions 2015-06-19 11:24:56 -07:00
nmonterroso
3252dd0d18 check for null array in constructor 2015-06-19 10:32:38 -07:00
nmonterroso
5c409884b9 make setters fluent 2015-06-19 10:31:05 -07:00
nmonterroso
f9f58596b8 account for return type where the response type is in a list container, and properly import models into operations 2015-06-18 16:51:24 -07:00
nmonterroso
bb11322919 use proper namespaces, getters/setters, and phpdocs 2015-06-18 15:41:12 -07:00
nmonterroso
4495774fd5 proper autoloader and move generated files to PSR-4 compliant locations 2015-06-18 15:08:45 -07:00
Andrew B
1aeb50feef Replacing getClientResponseStatus() with getStatusInfo() 2015-06-18 14:41:17 -07:00
Branden Cash
b74050dd7b Change to use the autoload.php and change the namespacing 2015-06-18 11:45:08 -07:00
Branden Cash
2ac7384abf Fix tests 2015-06-18 11:43:54 -07:00
Branden Cash
eed45a41a3 Fixed the missing closing doc chars and updated sample 2015-06-18 11:43:54 -07:00
Branden Cash
69c2f6f945 Add phpdoc for the api.apiClient 2015-06-18 11:43:54 -07:00
Branden Cash
5119299e8a Remove unused code 2015-06-18 11:43:54 -07:00
Branden Cash
719a0b732e Update sample client 2015-06-18 11:43:48 -07:00
Branden Cash
8ed690cad0 Better namespace support, so that your not limited to only having a single vendor space, you can have \Vendor\Package\Model as a namespace. Also updates with proper phpdoc comments so that IDE code hinting can function properly. 2015-06-18 11:41:14 -07:00
William Cheng
f957471509 update silex sample code location 2015-06-19 02:37:08 +08:00
William Cheng
0b0325b8af update readme, fix swaggering name 2015-06-19 02:32:50 +08:00
William Cheng
d178d5e7d8 add sinatra template 2015-06-19 02:11:08 +08:00
nmonterroso
4ef34680cd renaming to ApiClient.mustache 2015-06-18 10:30:53 -07:00
wing328
6ab7be4058 add package version 2015-06-18 22:20:52 +08:00
wing328
df72188bc0 add cli support to csharp 2015-06-18 22:06:59 +08:00
geekerzp
8d18aee2f2 Update test case test_deserialize_to_dict of python client 2015-06-18 22:02:54 +08:00
Martin Hardorf
449ba4f644 Fixed required parameters for APIs in TypeScript 2015-06-18 12:42:04 +02:00
geekerzp
194c8ff71d Update config-help message of python client 2015-06-18 10:43:25 +08:00
geekerzp
62f4c252f2 Update python codegen.
* Update config-help message.
* Do not sanitize packageName to underscore format.
2015-06-18 10:43:24 +08:00
geekerzp
5d19ef6146 Generate the python into python/ folder directly 2015-06-18 10:43:24 +08:00
geekerzp
a32335dfbc Enable cli config options for python generator 2015-06-18 10:43:24 +08:00
geekerzp
6b6480a026 Updated xcode project of objc client 2015-06-18 10:38:19 +08:00
geekerzp
a4df33d040 Add comments for SWGJSONResponseSerializer#responseObjectForResponse
method of objective-c client.
2015-06-18 10:03:51 +08:00
geekerzp
8b15416be5 Add SWGJSONResponseSerializer for objective-c client.
If the response data is valid json, return the deserialized json.
If the response data is invalid json, return the string of response data.
2015-06-18 10:03:51 +08:00
geekerzp
bc92465bf7 Update Objective-C method description (doc comments) style 2015-06-18 10:03:51 +08:00
geekerzp
a6bdc35d59 Support pure object response for objc client 2015-06-18 10:03:51 +08:00
geekerzp
c50c8b724d Support map response for objc client.
completed.
2015-06-18 10:03:50 +08:00
geekerzp
0da3e58fff Support map response for objc client.
not completed
2015-06-18 10:03:12 +08:00
xhh
edcb71ad22 Merge branch 'develop_2.0' into params-order
Conflicts:
	bin/all-petstore.sh
2015-06-18 09:59:13 +08:00
xhh
d6d707543d Merge branch 'develop_2.0' into ruby-object-type
Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java
2015-06-18 09:56:58 +08:00
William Cheng
8858e7d7e3 update perl sample 2015-06-18 02:44:40 +08:00
William Cheng
64b46c2e15 update indentation, remove export 2015-06-18 02:40:15 +08:00
wing328
82baa7ce4b update help text 2015-06-18 10:57:10 +08:00
wing328
d7315b56dc removed non-perl update 2015-06-18 10:57:10 +08:00
wing328
10e07eaf74 add support for cli (perl) 2015-06-18 10:57:09 +08:00
Martin Hardorf
e7d4a438dd Added tests for TypeScript Angular and Node.js 2015-06-17 17:58:52 +02:00
Martin Hardorf
9e8631b75f Added shell scripts for sample generation of TypeScript 2015-06-17 17:56:37 +02:00
Tony Tam
e39ec927a2 Merge pull request #879 from shoatman/master
Updates to csharp model template to support inheritance
2015-06-17 08:30:07 -07:00
Tony Tam
6ad3a717fe Merge pull request #882 from wing328/php_add_silex
[PHP] add Silex server-side codegen
2015-06-17 08:29:48 -07:00
Tony Tam
f66b5cf65b Merge pull request #867 from wing328/fix_jar_path
[Bug fix] Fix path inside JAR for non-template files
2015-06-17 08:28:30 -07:00
Tony Tam
d8c337185f Merge pull request #857 from wing328/php_warning
[PHP] Remove PHP5.3 warning
2015-06-17 08:27:47 -07:00
Tony Tam
5ade64b3e1 Merge pull request #856 from wing328/csharp_upgrade_restsharp
[C#] upgrade restsharp to 105.1.0
2015-06-17 08:27:10 -07:00
Tony Tam
e65a079f0e Merge pull request #855 from geekerzp/develop_2.0_python_deserialize_map
[Python] bug fix for map response
2015-06-17 08:26:58 -07:00
Tony Tam
378ffffdc7 Merge pull request #854 from geekerzp/develop_2.0_objc_pro_rename
[Objc] Change xcode project name in objc sample code
2015-06-17 08:26:42 -07:00
Tony Tam
dd356b54c0 Merge pull request #853 from wing328/perl_support_map3
[Perl] update deserialization to support Map and List
2015-06-17 08:25:45 -07:00
Tony Tam
f56388845c Merge pull request #850 from xhh/ruby-cli-option2
[Ruby] Enabling cli config options for ruby generator
2015-06-17 08:25:34 -07:00
William Cheng
436db1f8e7 add __toString and update php sample 2015-06-17 19:00:29 +08:00
Martin Hardorf
ba4b88ef86 Fixed TypeScript mustache 2015-06-17 12:22:15 +02:00
xhh
b39d44db03 Add missing petstore scripts to bin/all-petstore.sh 2015-06-17 16:16:44 +08:00
xhh
9c4e5ed596 Rebuild Petstare sample for Java, Android, PHP, etc. 2015-06-17 16:15:37 +08:00
wing328
ce40da0f71 add php silex server side codegen 2015-06-17 16:01:24 +08:00
xhh
7f4586a47f Fix comment regarding required parameter in PHP generator 2015-06-17 16:00:59 +08:00
xhh
24a2de7389 Sort parameters to move required ones in front of optional ones 2015-06-17 16:00:16 +08:00
Shane Oatman
5f1df9e093 Updates to csharp model template to support inheritance 2015-06-16 12:12:17 -07:00
xhh
5435777c65 Merge remote-tracking branch 'origin/develop_2.0' into ruby-object-type 2015-06-16 18:42:18 +08:00
xhh
7c355030f4 Add to_s method for models 2015-06-16 18:41:51 +08:00
Nadezhda Makarkina
7b5b874fdc Fixed #798: original jar generation has been fixed. 2015-06-16 11:58:22 +03:00
Martin Hardorf
f87bb12ebb Added support for TypeScript generation for AngularJS and Node.js 2015-06-16 10:44:05 +02:00
xhh
d2d5cf0d57 Add convention notes to Ruby CLI options 2015-06-16 12:17:11 +08:00
xhh
6348f67b18 Merge remote-tracking branch 'origin/develop_2.0' into ruby-cli-option2 2015-06-16 12:07:15 +08:00
Ron
eaf5a371ff Merge pull request #863 from wing328/fix_typo
Fixed a minor typo with the command example
2015-06-15 13:20:05 +03:00
Ron
dee0948e3e Update README.md 2015-06-15 13:19:56 +03:00
xhh
a59d4ba346 Add test case for finding nonexistent pet 2015-06-15 16:51:38 +08:00
xhh
ec8e5179cb Remove unused comments 2015-06-15 16:46:30 +08:00
xhh
9d5928551b Unify ClientError and ServerError into ApiError
in Ruby generator
2015-06-15 16:38:08 +08:00
wing328
456e17430b Merge branch 'php_warning' of https://github.com/wing328/swagger-codegen into php_warning 2015-06-15 15:51:12 +08:00
wing328
839f0971f0 rename php ApiClient 2015-06-15 15:50:40 +08:00
xhh
e9c1dd7842 Regard bare "object" type as Object, add comments
The handling of base "object" type (without definions of
"additionalProperties") is similar to Java generator now.
2015-06-15 12:49:17 +08:00
wing328
24b110be9d show writing file for non-template file 2015-06-14 01:27:47 +08:00
wing328
7a560865a0 fix jar path in windows 2015-06-14 00:59:40 +08:00
geekerzp
718a9a79ed Update test case test_deserialize_to_object of python client. 2015-06-13 19:05:15 +08:00
geekerzp
ff9623fb5c Support pure object response for python client. 2015-06-13 18:58:27 +08:00
xhh
80616b4c2b Add test cases for StoreApi#get_inventory 2015-06-12 23:03:17 +08:00
xhh
36f0ed6d0c Add test cases for Response#deserialize 2015-06-12 22:44:52 +08:00
xhh
4c8c6c3880 Rebuild Ruby Petstore sample 2015-06-12 20:18:50 +08:00
xhh
e38fc2c3da Deserialize response for "object" type in Ruby client 2015-06-12 20:15:48 +08:00
wing328
2fdae91cbc fix a typo in readme 2015-06-12 16:12:54 +08:00
William Cheng
7aab1eaffb update test.php to put exception test at last 2015-06-10 23:53:56 +08:00
wing328
a0c55693dc add test case for loginUser, separate test cases into different files 2015-06-10 21:59:48 +08:00
wing328
9aca2868b9 change static method to instance method, update test case to remove php warning 2015-06-10 21:18:48 +08:00
wing328
4982784d7c upgrade restsharp to 105.1.0 2015-06-10 15:57:07 +08:00
geekerzp
e2d441e862 support map type response for python client 2015-06-10 11:55:12 +08:00
wing328
303dbe7730 fix array,map for perl, add test case 2015-06-10 10:53:21 +08:00
geekerzp
d7b10a17c1 Renamed objc client from PetstoreClient to SwaggerClient 2015-06-10 10:53:16 +08:00
Alexey Nechaev
3f194d3288 Fixed #837: Generation of default values for complex arrays and maps has been improved. 2015-06-09 19:34:09 +03:00
fehguy
672fcd5a14 updated dev version 2015-06-09 01:36:52 -07:00
fehguy
3768932ba2 updated dev version 2015-06-09 01:36:48 -07:00
xhh
1315e2d72c Add new line to make code more readable 2015-06-09 15:47:37 +08:00
xhh
44780e6e1b Merge branch 'develop_2.0' into ruby-cli-option2
Conflicts:
	modules/swagger-codegen/src/main/resources/ruby/swagger/version.mustache
2015-06-09 15:44:50 +08:00
xhh
d2a82d56aa Enable CLI options for Ruby generator 2015-06-09 10:16:52 +08:00
797 changed files with 61568 additions and 22312 deletions

47
.dockerignore Normal file
View File

@@ -0,0 +1,47 @@
*.iml
out/
*.ipr
*.iws
classpath.txt
version.properties
.project
.classpath
lib/*
build/*
generated-files/*
generated-sources/*
generated-code/*
*.swp
*.swo
/target
/generated-files
/nbactions.xml
*.pyc
__pycache__
samples/server-generator/scalatra/output
samples/server-generator/node/output/node_modules
samples/server-generator/scalatra/target
samples/server-generator/scalatra/output/.history
samples/client/petstore/qt5cpp/PetStore/moc_*
samples/client/petstore/qt5cpp/PetStore/*.o
samples/client/petstore/objc/PetstoreClient.xcworkspace/xcuserdata
samples/client/petstore/qt5cpp/build-*
samples/client/petstore/qt5cpp/PetStore/PetStore
samples/client/petstore/qt5cpp/PetStore/Makefile
samples/client/petstore/java/hello.txt
samples/client/petstore/android-java/hello.txt
samples/client/petstore/objc/Build
samples/client/petstore/objc/Pods
samples/server/petstore/nodejs/node_modules
target
.idea
.lib
atlassian-ide-plugin.xml
.DS_Store
samples/client/petstore/php/SwaggerClient-php/composer.lock
samples/client/petstore/php/SwaggerClient-php/vendor/
samples/client/petstore/silex/SwaggerServer/composer.lock
samples/client/petstore/silex/SwaggerServer/venodr/

13
.gitignore vendored
View File

@@ -9,6 +9,7 @@ version.properties
lib/*
build/*
generated-files/*
generated-sources/*
generated-code/*
*.swp
*.swo
@@ -30,8 +31,10 @@ samples/client/petstore/qt5cpp/PetStore/PetStore
samples/client/petstore/qt5cpp/PetStore/Makefile
samples/client/petstore/java/hello.txt
samples/client/petstore/android-java/hello.txt
samples/client/petstore/objc/Build
samples/client/petstore/objc/Pods
samples/client/petstore/objc/SwaggerClientTests/Build
samples/client/petstore/objc/SwaggerClientTests/Pods
samples/client/petstore/objc/SwaggerClientTests/SwaggerClient.xcworkspace
samples/client/petstore/objc/SwaggerClientTests/Podfile.lock
samples/server/petstore/nodejs/node_modules
target
.idea
@@ -41,3 +44,9 @@ atlassian-ide-plugin.xml
samples/client/petstore/php/SwaggerClient-php/composer.lock
samples/client/petstore/php/SwaggerClient-php/vendor/
samples/client/petstore/silex/SwaggerServer/composer.lock
samples/client/petstore/silex/SwaggerServer/venodr/
samples/client/petstore/python/.projectile
samples/client/petstore/python/.venv/

View File

@@ -1,5 +1,5 @@
sudo: false
language: java
script: mvn verify
script: mvn verify -Psamples
jdk:
- oraclejdk7

13
Dockerfile Normal file
View File

@@ -0,0 +1,13 @@
FROM maven:3.3-jdk-7
WORKDIR /src
VOLUME /src
VOLUME /root/.m2/repository
ADD . /opt/swagger-codegen
RUN cd /opt/swagger-codegen && mvn package
ENTRYPOINT ["java", "-jar", "/opt/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"]
CMD ["help"]

View File

@@ -7,15 +7,34 @@ This is the swagger codegen project, which allows generation of client libraries
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.
## Build and run using docker
```
git clone https://github.com/swagger-api/swagger-codegen
cd swagger-codegen
./run-in-docker.sh mvn package
```
Build a nodejs server stub:
```
./run-in-docker.sh generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l nodejs \
-o samples/server/petstore/nodejs
```
## Compatibility
The Swagger Specification has undergone 3 revisions since initial creation in 2010. The swagger-codegen project has the following compatibilies with the swagger specification:
Swagger Codegen Version | Release Date | Swagger Spec compatibility | Notes
----------------------- | ------------ | -------------------------- | -----
2.1.0 | 2015-06-09 | 1.0, 1.1, 1.2, 2.0 | [master](https://github.com/swagger-api/swagger-codegen)
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)
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.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)
### Prerequisites
@@ -73,6 +92,7 @@ SYNOPSIS
[(-o <output directory> | --output <output directory>)]
[(-t <template directory> | --template-dir <template directory>)]
[(-v | --verbose)]
[(-s | --skip-overwrite)]
OPTIONS
-a <authorization>, --auth <authorization>
@@ -105,7 +125,11 @@ OPTIONS
-v, --verbose
verbose mode
```
-s , --skip-overwrite
specifies if the existing files should be overwritten during
the generation
```
You can then compile and run the client, as well as unit tests against it:
@@ -161,11 +185,16 @@ There are different aspects of customizing the code generator beyond just creati
```
$ ls -1 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/
AbstractTypeScriptClientCodegen.java
AkkaScalaClientCodegen.java
AndroidClientCodegen.java
AsyncScalaClientCodegen.java
CSharpClientCodegen.java
CodeGenStatus.java
CsharpDotNet2ClientCodegen.java
FlashClientCodegen.java
JavaClientCodegen.java
JavaInflectorServerCodegen.java
JaxRSServerCodegen.java
NodeJSServerCodegen.java
ObjcClientCodegen.java
@@ -178,13 +207,17 @@ RetrofitClientCodegen.java
RubyClientCodegen.java
ScalaClientCodegen.java
ScalatraServerCodegen.java
SilexServerCodegen.java
SinatraServerCodegen.java
SpringMVCServerCodegen.java
StaticDocCodegen.java
StaticHtmlGenerator.java
SwaggerGenerator.java
SwaggerYamlGenerator.java
SwiftGenerator.java
SwiftCodegen.java
TizenClientCodegen.java
TypeScriptAngularClientCodegen.java
TypeScriptNodeClientCodegen.java
```
Each of these files creates reasonable defaults so you can get running quickly. But if you want to configure package names, prefixes, model folders, etc. you can use a json config file to pass the values.
@@ -199,7 +232,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
Supported config options can be different per language. Running `config-help -l {lang}` will show available options.
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jarr config-help -l java
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar config-help -l java
```
Output
@@ -226,6 +259,11 @@ CONFIG OPTIONS
sourceFolder
source folder for generated code
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
```
Your config file for java can look like

View File

@@ -18,19 +18,29 @@ if [ ! -d "${APP_DIR}" ]; then
fi
cd $APP_DIR
./bin/akka-scala-petstore.sh
./bin/android-java-petstore.sh
./bin/csharp-petstore.sh
./bin/dynamic-html.sh
./bin/html-petstore.sh
./bin/jaxrs-petstore-server.sh
./bin/java-petstore.sh
./bin/qt5-petstore.sh
./bin/java-petstore-jersey2.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/objc-petstore.sh
./bin/scala-async-petstore.sh
./bin/scala-petstore.sh
./bin/scalatra-petstore-server.sh
./bin/silex-petstore-server.sh
./bin/spring-mvc-petstore-server.sh
./bin/swift-petstore.sh
./bin/tizen-petstore.sh
./bin/typescript-angular-petstore.sh
./bin/typescript-node-petstore.sh

31
bin/csharp-dotnet2-petstore.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 CsharpDotNet2 -o samples/client/petstore/csharp-dotnet2/SwaggerClientTest/Lib/SwaggerClient"
java $JAVA_OPTS -jar $executable $ags

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 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l csharp -o samples/client/petstore/csharp"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l csharp -o samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient"
java $JAVA_OPTS -jar $executable $ags

31
bin/flash-petstore.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 -t modules/swagger-codegen/src/main/resources/flash -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l flash -o samples/client/petstore/flash"
java $JAVA_OPTS -jar $executable $ags

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 -t modules/swagger-codegen/src/main/resources/JavaInflector -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l inflector -o samples/server/petstore/java-inflector"
java $JAVA_OPTS -jar $executable $ags

View File

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

31
bin/java-petstore-jersey2.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-jersey2.json -o samples/client/petstore/java/jersey2"
java $JAVA_OPTS -jar $executable $ags

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 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l java -o samples/client/petstore/java"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l java -o samples/client/petstore/java/default"
java $JAVA_OPTS -jar $executable $ags

5
bin/ruby-petstore.json Normal file
View File

@@ -0,0 +1,5 @@
{
"gemName": "petstore",
"moduleName": "Petstore",
"gemVersion": "1.0.0"
}

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/ruby -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -o samples/client/petstore/ruby"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/ruby -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -c bin/ruby-petstore.json -o samples/client/petstore/ruby"
java $JAVA_OPTS -jar $executable $ags

31
bin/silex-petstore-server.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 -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/server/petstore/silex"
java $JAVA_OPTS -jar $executable $ags

31
bin/sinatra-petstore-server.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 -t modules/swagger-codegen/src/main/resources/sinatra -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l sinatra -o samples/server/petstore/sinatra"
java $JAVA_OPTS -jar $executable $ags

4
bin/swift-petstore.json Normal file
View File

@@ -0,0 +1,4 @@
{
"projectName": "PetstoreClient",
"responseAs": "PromiseKit"
}

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/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -c ./bin/swift-petstore.json -o samples/client/petstore/swift"
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags
java $JAVA_OPTS -jar $executable $ags

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 typescript-angular -o samples/client/petstore/typescript-angular"
java $JAVA_OPTS -jar $executable $ags

31
bin/typescript-node-petstore.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 typescript-node -o samples/client/petstore/typescript-node"
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.2</version>
<version>2.1.3</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -41,7 +41,7 @@
<version>2.3</version>
<executions>
<execution>
<id>reduced-pom</id>
<id>process-resources</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
@@ -52,15 +52,6 @@
<dependencyReducedPomLocation>
${java.io.tmpdir}/dependency-reduced-pom.xml
</dependencyReducedPomLocation>
</configuration>
</execution>
<execution>
<id>process-resources</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
@@ -99,6 +90,13 @@
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -45,7 +45,7 @@ public class ConfigHelp implements Runnable {
System.out.println("CONFIG OPTIONS");
for (CliOption langCliOption : config.cliOptions()) {
System.out.println("\t" + langCliOption.getOpt());
System.out.println("\t " + langCliOption.getDescription());
System.out.println("\t " + langCliOption.getDescription().replaceAll("\n", "\n\t "));
System.out.println();
}
}

View File

@@ -66,6 +66,10 @@ public class Generate implements Runnable {
"Supported options can be different for each language. Run config-help -l {lang} command for language specific config options.")
private String configFile;
@Option(name = {"-s", "--skip-overwrite"}, title = "skip overwrite", description = "specifies if the existing files should be " +
"overwritten during the generation.")
private boolean skipOverwrite;
/**
* Tries to load config class with SPI first, then with class name directly from classpath
*
@@ -111,13 +115,19 @@ public class Generate implements Runnable {
Config genConfig = ConfigParser.read(configFile);
if (null != genConfig) {
for (CliOption langCliOption : config.cliOptions()) {
if (genConfig.hasOption(langCliOption.getOpt())) {
config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt()));
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));
}
}
}
}
}
config.setSkipOverwrite(skipOverwrite);
input.setConfig(config);
Swagger swagger = new SwaggerParser().read(spec, input.getAuthorizationValues(), true);

View File

@@ -0,0 +1,73 @@
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,977 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server Petstore server. You can find out more about Swagger at <a href=\"http://swagger.io\">http://swagger.io</a> or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters",
"version": "1.0.0",
"title": "Swagger Petstore",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"email": "apiteam@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"host": "petstore.swagger.io",
"basePath": "/v2",
"schemes": [
"http"
],
"paths": {
"/pet": {
"post": {
"tags": [
"pet"
],
"summary": "Add a new pet to the store",
"description": "",
"operationId": "addPet",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": false,
"schema": {
"$ref": "#/definitions/Pet"
}
}
],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
},
"put": {
"tags": [
"pet"
],
"summary": "Update an existing pet",
"description": "",
"operationId": "updatePet",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": false,
"schema": {
"$ref": "#/definitions/Pet"
}
}
],
"responses": {
"405": {
"description": "Validation exception"
},
"404": {
"description": "Pet not found"
},
"400": {
"description": "Invalid ID supplied"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet/findByStatus": {
"get": {
"tags": [
"pet"
],
"summary": "Finds Pets by status",
"description": "Multiple status values can be provided with comma seperated strings",
"operationId": "findPetsByStatus",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "status",
"in": "query",
"description": "Status values that need to be considered for filter",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi",
"default": "available"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
},
"400": {
"description": "Invalid status value"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet/findByTags": {
"get": {
"tags": [
"pet"
],
"summary": "Finds Pets by tags",
"description": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
"operationId": "findPetsByTags",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "tags",
"in": "query",
"description": "Tags to filter by",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
},
"400": {
"description": "Invalid tag value"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet/{petId}": {
"get": {
"tags": [
"pet"
],
"summary": "Find pet by ID",
"description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions",
"operationId": "getPetById",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"404": {
"description": "Pet not found"
},
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Pet"
}
},
"400": {
"description": "Invalid ID supplied"
}
},
"security": [
{
"api_key": []
},
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
},
"post": {
"tags": [
"pet"
],
"summary": "Updates a pet in the store with form data",
"description": "",
"operationId": "updatePetWithForm",
"consumes": [
"application/x-www-form-urlencoded"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be updated",
"required": true,
"type": "string"
},
{
"name": "name",
"in": "formData",
"description": "Updated name of the pet",
"required": false,
"type": "string"
},
{
"name": "status",
"in": "formData",
"description": "Updated status of the pet",
"required": false,
"type": "string"
}
],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
},
"delete": {
"tags": [
"pet"
],
"summary": "Deletes a pet",
"description": "",
"operationId": "deletePet",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "api_key",
"in": "header",
"description": "",
"required": false,
"type": "string"
},
{
"name": "petId",
"in": "path",
"description": "Pet id to delete",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"400": {
"description": "Invalid pet value"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet/{petId}/uploadImage": {
"post": {
"tags": [
"pet"
],
"summary": "uploads an image",
"description": "",
"operationId": "uploadFile",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet to update",
"required": true,
"type": "integer",
"format": "int64"
},
{
"name": "additionalMetadata",
"in": "formData",
"description": "Additional data to pass to server",
"required": false,
"type": "string"
},
{
"name": "file",
"in": "formData",
"description": "file to upload",
"required": false,
"type": "file"
}
],
"responses": {
"default": {
"description": "successful operation"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/store/inventory": {
"get": {
"tags": [
"store"
],
"summary": "Returns pet inventories by status",
"description": "Returns a map of status codes to quantities",
"operationId": "getInventory",
"produces": [
"application/json",
"application/xml"
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "object",
"additionalProperties": {
"type": "integer",
"format": "int32"
}
}
}
},
"security": [
{
"api_key": []
}
]
}
},
"/store/order": {
"post": {
"tags": [
"store"
],
"summary": "Place an order for a pet",
"description": "",
"operationId": "placeOrder",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "order placed for purchasing the pet",
"required": false,
"schema": {
"$ref": "#/definitions/Order"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Order"
}
},
"400": {
"description": "Invalid Order"
}
}
}
},
"/store/order/{orderId}": {
"get": {
"tags": [
"store"
],
"summary": "Find purchase order by ID",
"description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
"operationId": "getOrderById",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "orderId",
"in": "path",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "string"
}
],
"responses": {
"404": {
"description": "Order not found"
},
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Order"
}
},
"400": {
"description": "Invalid ID supplied"
}
}
},
"delete": {
"tags": [
"store"
],
"summary": "Delete purchase order by ID",
"description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
"operationId": "deleteOrder",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "orderId",
"in": "path",
"description": "ID of the order that needs to be deleted",
"required": true,
"type": "string"
}
],
"responses": {
"404": {
"description": "Order not found"
},
"400": {
"description": "Invalid ID supplied"
}
}
}
},
"/user": {
"post": {
"tags": [
"user"
],
"summary": "Create user",
"description": "This can only be done by the logged in user.",
"operationId": "createUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Created user object",
"required": false,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/createWithArray": {
"post": {
"tags": [
"user"
],
"summary": "Creates list of users with given input array",
"description": "",
"operationId": "createUsersWithArrayInput",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "List of user object",
"required": false,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/createWithList": {
"post": {
"tags": [
"user"
],
"summary": "Creates list of users with given input array",
"description": "",
"operationId": "createUsersWithListInput",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "List of user object",
"required": false,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/login": {
"get": {
"tags": [
"user"
],
"summary": "Logs user into the system",
"description": "",
"operationId": "loginUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "username",
"in": "query",
"description": "The user name for login",
"required": false,
"type": "string"
},
{
"name": "password",
"in": "query",
"description": "The password for login in clear text",
"required": false,
"type": "string"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid username/password supplied"
}
}
}
},
"/user/logout": {
"get": {
"tags": [
"user"
],
"summary": "Logs out current logged in user session",
"description": "",
"operationId": "logoutUser",
"produces": [
"application/json",
"application/xml"
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/{username}": {
"get": {
"tags": [
"user"
],
"summary": "Get user by user name",
"description": "",
"operationId": "getUserByName",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "username",
"in": "path",
"description": "The name that needs to be fetched. Use user1 for testing. ",
"required": true,
"type": "string"
}
],
"responses": {
"404": {
"description": "User not found"
},
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/User"
},
"examples": {
"application/json": {
"id": 1,
"username": "johnp",
"firstName": "John",
"lastName": "Public",
"email": "johnp@swagger.io",
"password": "-secret-",
"phone": "0123456789",
"userStatus": 0
}
}
},
"400": {
"description": "Invalid username supplied"
}
}
},
"put": {
"tags": [
"user"
],
"summary": "Updated user",
"description": "This can only be done by the logged in user.",
"operationId": "updateUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "username",
"in": "path",
"description": "name that need to be deleted",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "Updated user object",
"required": false,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"404": {
"description": "User not found"
},
"400": {
"description": "Invalid user supplied"
}
}
},
"delete": {
"tags": [
"user"
],
"summary": "Delete user",
"description": "This can only be done by the logged in user.",
"operationId": "deleteUser",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "username",
"in": "path",
"description": "The name that needs to be deleted",
"required": true,
"type": "string"
}
],
"responses": {
"404": {
"description": "User not found"
},
"400": {
"description": "Invalid username supplied"
}
}
}
}
},
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"name": "api_key",
"in": "header"
},
"petstore_auth": {
"type": "oauth2",
"authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog",
"flow": "implicit",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
}
},
"definitions": {
"User": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"username": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "integer",
"format": "int32",
"description": "User Status"
}
},
"xml": {
"name": "User"
}
},
"Category": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"xml": {
"name": "Category"
}
},
"Pet": {
"required": [
"name",
"photoUrls"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"category": {
"$ref": "#/definitions/Category"
},
"name": {
"type": "string",
"example": "doggie"
},
"photoUrls": {
"type": "array",
"xml": {
"name": "photoUrl",
"wrapped": true
},
"items": {
"type": "string"
}
},
"tags": {
"type": "array",
"xml": {
"name": "tag",
"wrapped": true
},
"items": {
"$ref": "#/definitions/Tag"
}
},
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
},
"xml": {
"name": "Pet"
}
},
"Tag": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"xml": {
"name": "Tag"
}
},
"Order": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"petId": {
"type": "integer",
"format": "int64"
},
"quantity": {
"type": "integer",
"format": "int32"
},
"shipDate": {
"type": "string",
"format": "date-time"
},
"status": {
"type": "string",
"description": "Order Status",
"enum": [
"placed",
"approved",
"delivered"
]
},
"complete": {
"type": "boolean"
}
},
"xml": {
"name": "Order"
}
}
}
}

View File

@@ -0,0 +1,55 @@
swagger-codegen-maven-plugin
============================
A Maven plugin to support the [swagger](http://swagger.io) code generation project
Usage
============================
Add to your `build->plugins` section (default phase is `generate-sources` phase)
```xml
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>src/main/resources/api.yaml</inputSpec>
<language>java</language>
<configOptions>
<sourceFolder>src/gen/java/main</sourceFolder>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
```
Followed by:
```
mvn clean compile
```
### General Configuration parameters
- `inputSpec` - swagger spec file path
- `language` - target generation language
- `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`)
- `templateDirectory` - directory with mustache templates
- `addCompileSourceRoot` - add the output directory to the project as a source root (`true` by default)
- `modelPackage` - the package to use for generated model objects/classes
- `apiPackage` - the package to use for generated api objects/classes
- `invokerPackage` - the package to use for the generated invoker objects
- `configOptions` - a map of language-specific parameters (see below)
### Java-specific parameters (under configOptions)
- `sourceFolder` - the folder to use for generated sources under the output folder
- `groupId` - groupId in generated pom.xml
- `artifactId` - artifactId in generated pom.xml
- `artifactVersion` - artifact version in generated pom.xml

View File

@@ -0,0 +1,87 @@
<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>
<parent>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-project</artifactId>
<version>2.1.3</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<name>swagger-codegen (maven-plugin)</name>
<packaging>maven-plugin</packaging>
<description>maven plugin to build modules from swagger codegen</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.4</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -0,0 +1,16 @@
package io.swagger.codegen.plugin;
/**
* User: lanwen
* Date: 24.03.15
* Time: 14:47
*/
public final class AdditionalParams {
public static final String TEMPLATE_DIR_PARAM = "templateDir";
public static final String MODEL_PACKAGE_PARAM = "modelPackage";
public static final String API_PACKAGE_PARAM = "apiPackage";
public static final String INVOKER_PACKAGE_PARAM = "invokerPackage";
private AdditionalParams() {
}
}

View File

@@ -0,0 +1,186 @@
package io.swagger.codegen.plugin;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import io.swagger.codegen.CliOption;
import io.swagger.codegen.ClientOptInput;
import io.swagger.codegen.ClientOpts;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.DefaultGenerator;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import config.Config;
import config.ConfigParser;
import java.io.File;
import java.util.Map;
import java.util.ServiceLoader;
import static io.swagger.codegen.plugin.AdditionalParams.API_PACKAGE_PARAM;
import static io.swagger.codegen.plugin.AdditionalParams.INVOKER_PACKAGE_PARAM;
import static io.swagger.codegen.plugin.AdditionalParams.MODEL_PACKAGE_PARAM;
import static io.swagger.codegen.plugin.AdditionalParams.TEMPLATE_DIR_PARAM;
/**
* Goal which generates client/server code from a swagger json/yaml definition.
*/
@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class CodeGenMojo extends AbstractMojo {
/**
* Location of the output directory.
*/
@Parameter(name = "output",
property = "swagger.codegen.maven.plugin.output",
defaultValue = "${project.build.directory}/generated-sources/swagger")
private File output;
/**
* Location of the swagger spec, as URL or file.
*/
@Parameter(name = "inputSpec", required = true)
private String inputSpec;
/**
* Folder containing the template files.
*/
@Parameter(name = "templateDirectory")
private File templateDirectory;
/**
* The package to use for generated model objects/classes
*/
@Parameter(name = "modelPackage")
private String modelPackage;
/**
* The package to use for generated api objects/classes
*/
@Parameter(name = "apiPackage")
private String apiPackage;
/**
* The package to use for the generated invoker objects
*/
@Parameter(name = "invokerPackage")
private String invokerPackage;
/**
* Client language to generate.
*/
@Parameter(name = "language", required = true)
private String language;
/**
* Path to separate json configuration file.
*/
@Parameter(name = "configurationFile", required = false)
private String configurationFile;
/**
* A map of language-specific parameters as passed with the -c option to the command line
*/
@Parameter(name = "configOptions")
private Map configOptions;
/**
* Add the output directory to the project as a source root, so that the
* generated java types are compiled and included in the project artifact.
*/
@Parameter(defaultValue = "true")
private boolean addCompileSourceRoot = true;
/**
* The project being built.
*/
@Parameter(readonly = true, required = true, defaultValue = "${project}")
private MavenProject project;
@Override
public void execute() throws MojoExecutionException {
Swagger swagger = new SwaggerParser().read(inputSpec);
CodegenConfig config = forName(language);
config.setOutputDir(output.getAbsolutePath());
if (null != templateDirectory) {
config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath());
}
if (null != modelPackage) {
config.additionalProperties().put(MODEL_PACKAGE_PARAM, modelPackage);
}
if (null != apiPackage) {
config.additionalProperties().put(API_PACKAGE_PARAM, apiPackage);
}
if (null != invokerPackage) {
config.additionalProperties().put(INVOKER_PACKAGE_PARAM, invokerPackage);
}
if (configOptions != null) {
for (CliOption langCliOption : config.cliOptions()) {
if (configOptions.containsKey(langCliOption.getOpt())) {
config.additionalProperties().put(langCliOption.getOpt(),
configOptions.get(langCliOption.getOpt()));
}
}
}
if (null != configurationFile) {
Config genConfig = ConfigParser.read(configurationFile);
if (null != genConfig) {
for (CliOption langCliOption : config.cliOptions()) {
if (genConfig.hasOption(langCliOption.getOpt())) {
config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt()));
}
}
} else {
throw new RuntimeException("Unable to read configuration file");
}
}
ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger);
input.setConfig(config);
new DefaultGenerator().opts(input).generate();
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.2</version>
<version>2.1.3</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -83,9 +83,7 @@
</execution>
</executions>
<configuration>
<configuration>
<recompileMode>incremental</recompileMode>
</configuration>
<recompileMode>incremental</recompileMode>
<jvmArgs>
<jvmArg>-Xmx384m</jvmArg>
</jvmArgs>
@@ -149,14 +147,6 @@
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin-version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<configuration>
<releaseProfiles>release</releaseProfiles>
<goals>sign</goals>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
@@ -180,7 +170,7 @@
</execution>
</executions>
<configuration>
<scala-version>${scala-version}</scala-version>
<scalaVersion>${scala-version}</scalaVersion>
</configuration>
</plugin>
<plugin>

View File

@@ -60,10 +60,31 @@ public abstract class AbstractGenerator {
throw new RuntimeException("can't load template " + name);
}
private String getCPResourcePath(String name) {
/**
* Get the template file path with template dir prepended, and use the
* library template if exists.
*/
public String getFullTemplateFile(CodegenConfig config, String templateFile) {
String library = config.getLibrary();
if (library != null && !"".equals(library)) {
String libTemplateFile = config.templateDir() + File.separator +
"libraries" + File.separator + library + File.separator +
templateFile;
if (templateExists(libTemplateFile)) {
return libTemplateFile;
}
}
return config.templateDir() + File.separator + templateFile;
}
public boolean templateExists(String name) {
return this.getClass().getClassLoader().getResource(getCPResourcePath(name)) != null;
}
public String getCPResourcePath(String name) {
if (!"/".equals(File.separator)) {
return name.replaceAll(Pattern.quote(File.separator), "/");
}
return name;
}
}
}

View File

@@ -65,6 +65,8 @@ public interface CodegenConfig {
CodegenModel fromModel(String name, Model model);
CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions);
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions);
List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes);
@@ -102,4 +104,17 @@ public interface CodegenConfig {
String apiFilename(String templateName, String tag);
boolean shouldOverwrite(String filename);
boolean isSkipOverwrite();
void setSkipOverwrite(boolean skipOverwrite);
Map<String, String> supportedLibraries();
void setLibrary(String library);
/**
* Library template (sub-template).
*/
String getLibrary();
}

View File

@@ -30,6 +30,23 @@ public class CodegenOperation {
public List<Map<String, String>> examples;
public ExternalDocs externalDocs;
private boolean nonempty(List<CodegenParameter> params)
{
return params != null && params.size() > 0;
}
public boolean getHasBodyParam() {
return nonempty(bodyParams);
}
public boolean getHasQueryParams() {
return nonempty(bodyParams);
}
public boolean getHasHeaderParams() {
return nonempty(bodyParams);
}
public boolean getHasPathParams() {
return nonempty(bodyParams);
}
// legacy support
public String nickname;
}

View File

@@ -1,10 +1,18 @@
package io.swagger.codegen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
public class CodegenParameter {
public Boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
isCookieParam, isBodyParam, isFile, notFile, hasMore, isContainer, secondaryParam;
public String baseName, paramName, dataType, collectionFormat, description, baseType, defaultValue;
public String jsonSchema;
public boolean isEnum;
public List<String> _enum;
public Map<String, Object> allowableValues;
/**
* Determines whether this parameter is mandatory. If the parameter is in "path",
@@ -35,6 +43,13 @@ public class CodegenParameter {
output.required = this.required;
output.jsonSchema = this.jsonSchema;
output.defaultValue = this.defaultValue;
output.isEnum = this.isEnum;
if (this._enum != null) {
output._enum = new ArrayList<String>(this._enum);
}
if (this.allowableValues != null) {
output.allowableValues = new HashMap<String, Object>(this.allowableValues);
}
return output;
}

View File

@@ -34,4 +34,107 @@ public class CodegenProperty {
public boolean isEnum;
public List<String> _enum;
public Map<String, Object> allowableValues;
public CodegenProperty items;
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CodegenProperty other = (CodegenProperty) obj;
if ((this.baseName == null) ? (other.baseName != null) : !this.baseName.equals(other.baseName)) {
return false;
}
if ((this.complexType == null) ? (other.complexType != null) : !this.complexType.equals(other.complexType)) {
return false;
}
if ((this.getter == null) ? (other.getter != null) : !this.getter.equals(other.getter)) {
return false;
}
if ((this.setter == null) ? (other.setter != null) : !this.setter.equals(other.setter)) {
return false;
}
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
return false;
}
if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) {
return false;
}
if ((this.datatypeWithEnum == null) ? (other.datatypeWithEnum != null) : !this.datatypeWithEnum.equals(other.datatypeWithEnum)) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if ((this.min == null) ? (other.min != null) : !this.min.equals(other.min)) {
return false;
}
if ((this.max == null) ? (other.max != null) : !this.max.equals(other.max)) {
return false;
}
if ((this.defaultValue == null) ? (other.defaultValue != null) : !this.defaultValue.equals(other.defaultValue)) {
return false;
}
if ((this.baseType == null) ? (other.baseType != null) : !this.baseType.equals(other.baseType)) {
return false;
}
if ((this.containerType == null) ? (other.containerType != null) : !this.containerType.equals(other.containerType)) {
return false;
}
if (this.maxLength != other.maxLength && (this.maxLength == null || !this.maxLength.equals(other.maxLength))) {
return false;
}
if (this.minLength != other.minLength && (this.minLength == null || !this.minLength.equals(other.minLength))) {
return false;
}
if ((this.pattern == null) ? (other.pattern != null) : !this.pattern.equals(other.pattern)) {
return false;
}
if ((this.example == null) ? (other.example != null) : !this.example.equals(other.example)) {
return false;
}
if ((this.jsonSchema == null) ? (other.jsonSchema != null) : !this.jsonSchema.equals(other.jsonSchema)) {
return false;
}
if (this.minimum != other.minimum && (this.minimum == null || !this.minimum.equals(other.minimum))) {
return false;
}
if (this.maximum != other.maximum && (this.maximum == null || !this.maximum.equals(other.maximum))) {
return false;
}
if (this.exclusiveMinimum != other.exclusiveMinimum && (this.exclusiveMinimum == null || !this.exclusiveMinimum.equals(other.exclusiveMinimum))) {
return false;
}
if (this.exclusiveMaximum != other.exclusiveMaximum && (this.exclusiveMaximum == null || !this.exclusiveMaximum.equals(other.exclusiveMaximum))) {
return false;
}
if (this.required != other.required && (this.required == null || !this.required.equals(other.required))) {
return false;
}
if (this.secondaryParam != other.secondaryParam && (this.secondaryParam == null || !this.secondaryParam.equals(other.secondaryParam))) {
return false;
}
if (this.isPrimitiveType != other.isPrimitiveType && (this.isPrimitiveType == null || !this.isPrimitiveType.equals(other.isPrimitiveType))) {
return false;
}
if (this.isContainer != other.isContainer && (this.isContainer == null || !this.isContainer.equals(other.isContainer))) {
return false;
}
if (this.isNotContainer != other.isNotContainer && (this.isNotContainer == null || !this.isNotContainer.equals(other.isNotContainer))) {
return false;
}
if (this.isEnum != other.isEnum) {
return false;
}
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
return false;
}
if (this.allowableValues != other.allowableValues && (this.allowableValues == null || !this.allowableValues.equals(other.allowableValues))) {
return false;
}
return true;
}
}

View File

@@ -1,5 +1,7 @@
package io.swagger.codegen;
import java.util.Set;
public class CodegenSecurity {
public String name;
public String type;
@@ -7,4 +9,7 @@ public class CodegenSecurity {
// ApiKey specific
public String keyParamName;
public Boolean isKeyInQuery, isKeyInHeader;
// Oauth specific
public String flow, authorizationUrl, tokenUrl;
public Set<String> scopes;
}

View File

@@ -14,6 +14,7 @@ import io.swagger.models.Swagger;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.BasicAuthDefinition;
import io.swagger.models.auth.In;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.CookieParameter;
@@ -36,6 +37,7 @@ 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.PropertyBuilder.PropertyId;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json;
@@ -49,9 +51,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -60,7 +64,7 @@ import java.util.regex.Pattern;
public class DefaultCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected String outputFolder = "";
protected Set<String> defaultIncludes = new HashSet<String>();
@@ -76,6 +80,10 @@ public class DefaultCodegen {
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite;
protected boolean supportsInheritance = false;
protected Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
protected String library = null;
public List<CliOption> cliOptions() {
return cliOptions;
@@ -225,6 +233,11 @@ public class DefaultCodegen {
}
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");
}
return operationId;
}
@@ -422,14 +435,6 @@ public class DefaultCodegen {
return dp.getDefault().toString();
}
return "null";
} else if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "new HashMap<String, " + inner + ">() ";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "new ArrayList<" + inner + ">() ";
} else {
return "null";
}
@@ -506,6 +511,10 @@ public class DefaultCodegen {
}
public CodegenModel fromModel(String name, Model model) {
return fromModel(name, model, null);
}
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
if (reservedWords.contains(name)) {
m.name = escapeReservedWord(name);
@@ -525,12 +534,59 @@ public class DefaultCodegen {
// TODO
} else if (model instanceof ComposedModel) {
final ComposedModel composed = (ComposedModel) model;
Map<String, Property> properties = new HashMap<String, Property>();
List<String> required = new ArrayList<String>();
// parent model
final RefModel parent = (RefModel) composed.getParent();
final String parentModel = toModelName(parent.getSimpleRef());
m.parent = parentModel;
addImport(m, parentModel);
final ModelImpl child = (ModelImpl) composed.getChild();
addVars(m, child.getProperties(), child.getRequired());
if (parent != null) {
final String parentRef = toModelName(parent.getSimpleRef());
m.parent = parentRef;
addImport(m, parentRef);
if (!supportsInheritance && allDefinitions != null) {
final Model parentModel = allDefinitions.get(parentRef);
if (parentModel instanceof ModelImpl) {
final ModelImpl _parent = (ModelImpl) parentModel;
if (_parent.getProperties() != null) {
properties.putAll(_parent.getProperties());
}
if (_parent.getRequired() != null) {
required.addAll(_parent.getRequired());
}
}
}
}
// interfaces (intermediate models)
if (allDefinitions != null) {
for (RefModel _interface : composed.getInterfaces()) {
final String interfaceRef = toModelName(_interface.getSimpleRef());
final Model interfaceModel = allDefinitions.get(interfaceRef);
if (interfaceModel instanceof ModelImpl) {
final ModelImpl _interfaceModel = (ModelImpl) interfaceModel;
if (_interfaceModel.getProperties() != null) {
properties.putAll(_interfaceModel.getProperties());
}
if (_interfaceModel.getRequired() != null) {
required.addAll(_interfaceModel.getRequired());
}
}
}
}
// child model (properties owned by the model itself)
Model child = composed.getChild();
if (child != null && child instanceof RefModel && allDefinitions != null) {
final String childRef = ((RefModel) child).getSimpleRef();
child = allDefinitions.get(childRef);
}
if (child != null && child instanceof ModelImpl) {
final ModelImpl _child = (ModelImpl) child;
if (_child.getProperties() != null) {
properties.putAll(_child.getProperties());
}
if (_child.getRequired() != null) {
required.addAll(_child.getRequired());
}
}
addVars(m, properties, required);
} else {
ModelImpl impl = (ModelImpl) model;
if (impl.getAdditionalProperties() != null) {
@@ -553,7 +609,7 @@ public class DefaultCodegen {
public CodegenProperty fromProperty(String name, Property p) {
if (p == null) {
LOGGER.error("unexpected missing property for name " + null);
LOGGER.error("unexpected missing property for name " + name);
return null;
}
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
@@ -583,7 +639,9 @@ public class DefaultCodegen {
if (np.getMaximum() != null) {
allowableValues.put("max", np.getMaximum());
}
property.allowableValues = allowableValues;
if(allowableValues.size() > 0) {
property.allowableValues = allowableValues;
}
}
if (p instanceof StringProperty) {
@@ -614,22 +672,28 @@ public class DefaultCodegen {
property.baseType = getSwaggerType(p);
if (p instanceof ArrayProperty) {
property.isContainer = true;
property.containerType = "array";
ArrayProperty ap = (ArrayProperty) p;
CodegenProperty cp = fromProperty("inner", 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;
}
}
} 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);
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;
@@ -850,6 +914,17 @@ public class DefaultCodegen {
}
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;
}
});
op.allParams = addHasMore(allParams);
op.bodyParams = addHasMore(bodyParams);
op.pathParams = addHasMore(pathParams);
@@ -964,7 +1039,9 @@ public class DefaultCodegen {
p.baseType = pr.datatype;
imports.add(pr.baseType);
} else {
property = PropertyBuilder.build(qp.getType(), qp.getFormat(), null);
Map<PropertyId, Object> args = new HashMap<PropertyId, Object>();
args.put(PropertyId.ENUM, qp.getEnum());
property = PropertyBuilder.build(qp.getType(), qp.getFormat(), args);
}
if (property == null) {
LOGGER.warn("warning! Property type \"" + qp.getType() + "\" not found for parameter \"" + param.getName() + "\", using String");
@@ -972,8 +1049,11 @@ public class DefaultCodegen {
}
property.setRequired(param.getRequired());
CodegenProperty model = fromProperty(qp.getName(), property);
p.collectionFormat = collectionFormat;
p.dataType = model.datatype;
p.isEnum = model.isEnum;
p._enum = model._enum;
p.allowableValues = model.allowableValues;
p.collectionFormat = collectionFormat;
p.paramName = toParamName(qp.getName());
if (model.complexType != null) {
@@ -1056,10 +1136,17 @@ public class DefaultCodegen {
sec.keyParamName = apiKeyDefinition.getName();
sec.isKeyInHeader = apiKeyDefinition.getIn() == In.HEADER;
sec.isKeyInQuery = !sec.isKeyInHeader;
} else if(schemeDefinition instanceof BasicAuthDefinition) {
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isOAuth = false;
sec.isBasic = true;
} else {
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = false;
sec.isBasic = schemeDefinition instanceof BasicAuthDefinition;
sec.isOAuth = !sec.isBasic;
final OAuth2Definition oauth2Definition = (OAuth2Definition) schemeDefinition;
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false;
sec.isOAuth = true;
sec.flow = oauth2Definition.getFlow();
sec.authorizationUrl = oauth2Definition.getAuthorizationUrl();
sec.tokenUrl = oauth2Definition.getTokenUrl();
sec.scopes = oauth2Definition.getScopes().keySet();
}
sec.hasMore = it.hasNext();
@@ -1146,7 +1233,9 @@ public class DefaultCodegen {
if (mappedType != null) {
addImport(m, mappedType);
}
} /**
}
/**
* Underscore the given word.
*
* @param word The word
@@ -1208,10 +1297,9 @@ public class DefaultCodegen {
} else {
m.emptyVars = true;
}
} public static String camelize(String word) {
return camelize(word, false);
}
/**
* Remove characters not suitable for variable or method name from the input and camelize it
*
@@ -1231,7 +1319,13 @@ public class DefaultCodegen {
name = name.substring(0, 1).toLowerCase() + name.substring(1);
}
return name;
} public static String camelize(String word, boolean lowercaseFirstLetter) {
}
public static String camelize(String word) {
return camelize(word, false);
}
public static String camelize(String word, boolean lowercaseFirstLetter) {
// Replace all slashes with dots (package separator)
Pattern p = Pattern.compile("\\/(.?)");
Matcher m = p.matcher(word);
@@ -1294,6 +1388,43 @@ public class DefaultCodegen {
}
public boolean shouldOverwrite(String filename) {
return true;
return !(skipOverwrite && new File(filename).exists());
}
public boolean isSkipOverwrite() {
return skipOverwrite;
}
public void setSkipOverwrite(boolean skipOverwrite) {
this.skipOverwrite = skipOverwrite;
}
/**
* All library templates supported.
* (key: library name, value: library description)
*/
public Map<String, String> supportedLibraries() {
return supportedLibraries;
}
public void setLibrary(String library) {
if (library != null && !supportedLibraries.containsKey(library))
throw new RuntimeException("unknown library: " + library);
this.library = library;
}
/**
* Library template (sub-template).
*/
public String getLibrary() {
return library;
}
protected CliOption buildLibraryCliOption(Map<String, String> supportedLibraries) {
StringBuilder sb = new StringBuilder("library template (sub-template) to use:");
for (String lib : supportedLibraries.keySet()) {
sb.append("\n").append(lib).append(" - ").append(supportedLibraries.get(lib));
}
return new CliOption("library", sb.toString());
}
}

View File

@@ -1,7 +1,12 @@
package io.swagger.codegen;
import static org.apache.commons.lang3.StringUtils.capitalize;
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;
import io.swagger.models.License;
@@ -9,9 +14,12 @@ import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.util.Json;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import java.io.File;
import java.io.FileInputStream;
@@ -20,6 +28,8 @@ 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;
@@ -28,14 +38,13 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
public class DefaultGenerator extends AbstractGenerator implements Generator {
protected CodegenConfig config;
protected ClientOptInput opts = null;
protected Swagger swagger = null;
public CodeGenStatus status = CodeGenStatus.UNRUN;
public Generator opts(ClientOptInput opts) {
this.opts = opts;
@@ -56,6 +65,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
List<File> files = new ArrayList<File>();
try {
config.processOpts();
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) {
@@ -105,10 +118,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
if (swagger.getBasePath() != null) {
hostBuilder.append(swagger.getBasePath());
} else {
hostBuilder.append("/");
}
String contextPath = swagger.getBasePath() == null ? "/" : swagger.getBasePath();
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
String basePath = hostBuilder.toString();
@@ -118,11 +129,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
// models
Map<String, Model> definitions = swagger.getDefinitions();
if (definitions != null) {
for (String name : definitions.keySet()) {
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);
Map<String, Object> models = processModels(config, modelMap, definitions);
models.putAll(config.additionalProperties());
allModels.add(((List<Object>) models.get("models")).get(0));
@@ -130,7 +143,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
for (String templateName : config.modelTemplateFiles().keySet()) {
String suffix = config.modelTemplateFiles().get(templateName);
String filename = config.modelFileFolder() + File.separator + config.toModelFilename(name) + suffix;
String template = readTemplate(config.templateDir() + File.separator + templateName);
if (!config.shouldOverwrite(filename)) {
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
public Reader getTemplate(String name) {
@@ -178,11 +195,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
for (String templateName : config.apiTemplateFiles().keySet()) {
String filename = config.apiFilename(templateName, tag);
if (new File(filename).exists() && !config.shouldOverwrite(filename)) {
if (!config.shouldOverwrite(filename) && new File(filename).exists()) {
continue;
}
String template = readTemplate(config.templateDir() + File.separator + templateName);
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
public Reader getTemplate(String name) {
@@ -218,7 +236,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
bundle.put("models", allModels);
bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
bundle.put("modelPackage", config.modelPackage());
bundle.put("authMethods", config.fromSecurity(swagger.getSecurityDefinitions()));
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());
}
@@ -245,9 +267,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
of.mkdirs();
}
String outputFilename = outputFolder + File.separator + support.destinationFilename;
if (!config.shouldOverwrite(outputFilename)) {
continue;
}
if (support.templateFile.endsWith("mustache")) {
String template = readTemplate(config.templateDir() + File.separator + support.templateFile);
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) {
@@ -263,20 +290,21 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
InputStream in = null;
try {
in = new FileInputStream(config.templateDir() + File.separator + support.templateFile);
in = new FileInputStream(templateFile);
} catch (Exception e) {
// continue
}
if (in == null) {
in = this.getClass().getClassLoader().getResourceAsStream(config.templateDir() + File.separator + support.templateFile);
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 " + config.templateDir() + File.separator + support.templateFile + " for input");
System.out.println("can't open " + templateFile + " for input");
}
if (out == null) {
System.out.println("can't open " + outputFile + " for output");
@@ -288,8 +316,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
config.processSwagger(swagger);
status = CodeGenStatus.SUCCESSFUL;
} catch (Exception e) {
e.printStackTrace();
status = CodeGenStatus.FAILED;
}
return files;
}
@@ -315,17 +345,63 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
private List<String> sortModelsByInheritance(final Map<String, Model> definitions) {
List<String> sortedModelKeys = new ArrayList<String>(definitions.keySet());
Comparator<String> cmp = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
Model model1 = definitions.get(o1);
Model model2 = definitions.get(o2);
int model1InheritanceDepth = getInheritanceDepth(model1);
int model2InheritanceDepth = getInheritanceDepth(model2);
if (model1InheritanceDepth == model2InheritanceDepth) {
return 0;
} else if (model1InheritanceDepth > model2InheritanceDepth) {
return 1;
} else {
return -1;
}
}
private int getInheritanceDepth(Model model) {
int inheritanceDepth = 0;
Model parent = getParent(model);
while (parent != null) {
inheritanceDepth++;
parent = getParent(parent);
}
return inheritanceDepth;
}
private Model getParent(Model model) {
if (model instanceof ComposedModel) {
return definitions.get(((ComposedModel) model).getParent().getReference());
}
return null;
}
};
Collections.sort(sortedModelKeys, cmp);
return sortedModelKeys;
}
public Map<String, List<CodegenOperation>> processPaths(Map<String, Path> paths) {
Map<String, List<CodegenOperation>> ops = new HashMap<String, List<CodegenOperation>>();
for (String resourcePath : paths.keySet()) {
Path path = paths.get(resourcePath);
processOperation(resourcePath, "get", path.getGet(), ops);
processOperation(resourcePath, "put", path.getPut(), ops);
processOperation(resourcePath, "post", path.getPost(), ops);
processOperation(resourcePath, "delete", path.getDelete(), ops);
processOperation(resourcePath, "patch", path.getPatch(), ops);
processOperation(resourcePath, "options", path.getOptions(), ops);
processOperation(resourcePath, "get", path.getGet(), ops, path);
processOperation(resourcePath, "put", path.getPut(), ops, path);
processOperation(resourcePath, "post", path.getPost(), ops, path);
processOperation(resourcePath, "delete", path.getDelete(), ops, path);
processOperation(resourcePath, "patch", path.getPatch(), ops, path);
processOperation(resourcePath, "options", path.getOptions(), ops, path);
}
return ops;
}
@@ -338,14 +414,35 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return map.get(name);
}
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations, Path path) {
if (operation != null) {
List<String> tags = operation.getTags();
if (tags == null) {
tags = new ArrayList<String>();
tags.add("default");
}
/*
build up a set of parameter "ids" defined at the operation level
per the swagger 2.0 spec "A unique parameter is defined by a combination of a name and location"
i'm assuming "location" == "in"
*/
Set<String> operationParameters = new HashSet<String>();
if (operation.getParameters() != null) {
for (Parameter parameter : operation.getParameters()) {
operationParameters.add(generateParameterId(parameter));
}
}
//need to propagate path level down to the operation
if(path.getParameters() != null) {
for (Parameter parameter : path.getParameters()) {
//skip propagation if a parameter with the same name is already defined at the operation level
if (!operationParameters.contains(generateParameterId(parameter))) {
operation.addParameter(parameter);
}
}
}
for (String tag : tags) {
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions());
@@ -366,7 +463,22 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
String securityName = security.keySet().iterator().next();
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
if (securityDefinition != null) {
authMethods.put(securityName, securityDefinition);
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);
}
}
}
if (!authMethods.isEmpty()) {
@@ -376,6 +488,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
private String generateParameterId(Parameter parameter) {
return parameter.getName() + ":" + parameter.getIn();
}
protected String sanitizeTag(String tag) {
// remove spaces and make strong case
String[] parts = tag.split(" ");
@@ -392,6 +508,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Map<String, Object> operations = new HashMap<String, Object>();
Map<String, Object> objs = new HashMap<String, Object>();
objs.put("classname", config.toApiName(tag));
objs.put("pathPrefix", config.toApiVarName(tag));
// check for operationId uniqueness
Set<String> opIds = new HashSet<String>();
@@ -429,6 +546,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
operations.put("imports", imports);
// add a flag to indicate whether there's any {{import}}
if (imports.size() > 0) {
operations.put("hasImport", true);
}
config.postProcessOperations(operations);
if (objs.size() > 0) {
List<CodegenOperation> os = (List<CodegenOperation>) objs.get("operation");
@@ -441,14 +564,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return operations;
}
public Map<String, Object> processModels(CodegenConfig config, Map<String, Model> definitions) {
public Map<String, Object> processModels(CodegenConfig config, Map<String, Model> definitions, Map<String, Model> allDefinitions) {
Map<String, Object> objs = new HashMap<String, Object>();
objs.put("package", config.modelPackage());
List<Object> models = new ArrayList<Object>();
Set<String> allImports = new LinkedHashSet<String>();
for (String key : definitions.keySet()) {
Model mm = definitions.get(key);
CodegenModel cm = config.fromModel(key, mm);
CodegenModel cm = config.fromModel(key, mm, allDefinitions);
Map<String, Object> mo = new HashMap<String, Object>();
mo.put("model", cm);
mo.put("importPath", config.toModelImport(key));

View File

@@ -0,0 +1,144 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import java.util.*;
import java.io.File;
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public AbstractTypeScriptClientCodegen() {
super();
supportsInheritance = true;
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "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", "const", "super", "while"));
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object"));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("DateTime", "Date");
}
@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 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 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 "{ [key: string]: "+ getTypeDeclaration(inner) + "; }";
} else if (p instanceof FileProperty) {
return "any";
}
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;
}
}

View File

@@ -251,6 +251,11 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
@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");
}
return super.toOperationId(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, operationId));
}
@@ -396,4 +401,4 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
}
}
}
}

View File

@@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
@@ -168,6 +170,11 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
@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");
@@ -232,6 +239,8 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
supportingFiles.add(new SupportingFile("apiException.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
supportingFiles.add(new SupportingFile("Pair.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Pair.java"));
}
public Boolean getUseAndroidMavenGradlePlugin() {

View File

@@ -21,6 +21,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
@@ -204,4 +206,4 @@ public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenCo
return "null";
}
}
}
}

View File

@@ -7,22 +7,24 @@ 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.codegen.CliOption;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "IO.Swagger.Client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-csharp-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/csharp";
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client";
protected String sourceFolder = "src" + File.separator + "main" + File.separator + "csharp";
public CSharpClientCodegen() {
super();
outputFolder = "generated-code/csharp";
outputFolder = "generated-code" + File.separator + "csharp";
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
templateDir = "csharp";
@@ -34,20 +36,10 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while")
);
additionalProperties.put("invokerPackage", invokerPackage);
supportingFiles.add(new SupportingFile("Configuration.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(sourceFolder + File.separator + invokerPackage).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"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"string",
"bool?",
"double?",
@@ -64,6 +56,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"Integer",
"Long",
"Float",
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
@@ -79,12 +72,50 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("number", "double?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "string"); // path to file
typeMapping.put("file", "Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger"));
cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packageVersion")) {
packageVersion = (String) additionalProperties.get("packageVersion");
} else {
additionalProperties.put("packageVersion", packageVersion);
}
if (additionalProperties.containsKey("packageName")) {
packageName = (String) additionalProperties.get("packageName");
apiPackage = packageName + ".Api";
modelPackage = packageName + ".Model";
clientPackage = packageName + ".Client";
} else {
additionalProperties.put("packageName", packageName);
}
additionalProperties.put("clientPackage", clientPackage);
supportingFiles.add(new SupportingFile("Configuration.mustache",
(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"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(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"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
public CodegenType getTag() {
@@ -106,11 +137,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String apiFileFolder() {
return (outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/')).replace('.', File.separatorChar);
return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar);
}
public String modelFileFolder() {
return (outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/')).replace('.', File.separatorChar);
return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar);
}
@Override
@@ -137,8 +168,24 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(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) 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
@@ -192,6 +239,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@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");

View File

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

View File

@@ -0,0 +1,255 @@
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 io.swagger.codegen.CliOption;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client";
protected String sourceFolder = "src" + File.separator + "main" + File.separator + "CsharpDotNet2";
public CsharpDotNet2ClientCodegen() {
super();
outputFolder = "generated-code" + File.separator + "CsharpDotNet2";
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
templateDir = "CsharpDotNet2";
apiPackage = "IO.Swagger.Api";
modelPackage = "IO.Swagger.Model";
reservedWords = new HashSet<String>(
Arrays.asList(
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while")
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"string",
"bool?",
"double?",
"int?",
"long?",
"float?",
"byte[]",
"List",
"Dictionary",
"DateTime?",
"String",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
instantiationTypes.put("map", "Dictionary");
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
typeMapping.put("long", "long?");
typeMapping.put("double", "double?");
typeMapping.put("number", "double?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger"));
cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packageVersion")) {
packageVersion = (String) additionalProperties.get("packageVersion");
} else {
additionalProperties.put("packageVersion", packageVersion);
}
if (additionalProperties.containsKey("packageName")) {
packageName = (String) additionalProperties.get("packageName");
apiPackage = packageName + ".Api";
modelPackage = packageName + ".Model";
clientPackage = packageName + ".Client";
} else {
additionalProperties.put("packageName", packageName);
}
if (additionalProperties.containsKey("clientPackage")) {
this.setClientPackage((String) additionalProperties.get("clientPackage"));
} else {
additionalProperties.put("clientPackage", clientPackage);
}
supportingFiles.add(new SupportingFile("Configuration.mustache",
(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"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(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"));
}
public void setClientPackage(String clientPackage) {
this.clientPackage = clientPackage;
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "CsharpDotNet2";
}
public String getHelp() {
return "Generates a C# .Net 2.0 client library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
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);
}
@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 the variable name
// pet_id => PetId
name = camelize(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) {
// 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) 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 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.toLowerCase())) {
type = typeMapping.get(swaggerType.toLowerCase());
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);
}
}

View File

@@ -0,0 +1,367 @@
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 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 java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import org.apache.commons.lang.StringUtils;
public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = "io.swagger";
protected String packageVersion = null;
protected String invokerPackage = "io.swagger";
protected String sourceFolder = "src/main/flex";
public FlashClientCodegen() {
super();
modelPackage = "io.swagger.client.model";
apiPackage = "io.swagger.client.api";
outputFolder = "generated-code" + File.separatorChar + "flash";
modelTemplateFiles.put("model.mustache", ".as");
modelTemplateFiles.put("modelList.mustache", "List.as");
apiTemplateFiles.put("api.mustache", ".as");
templateDir = "flash";
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("Number");
languageSpecificPrimitives.add("Boolean");
languageSpecificPrimitives.add("String");
languageSpecificPrimitives.add("Date");
languageSpecificPrimitives.add("Array");
languageSpecificPrimitives.add("Dictionary");
typeMapping.clear();
typeMapping.put("integer", "Number");
typeMapping.put("float", "Number");
typeMapping.put("long", "Number");
typeMapping.put("double", "Number");
typeMapping.put("array", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("boolean", "Boolean");
typeMapping.put("string", "String");
typeMapping.put("date", "Date");
typeMapping.put("DateTime", "Date");
typeMapping.put("object", "Object");
typeMapping.put("file", "File");
importMapping = new HashMap<String, String>();
importMapping.put("File", "flash.filesystem.File");
// from
reservedWords = new HashSet<String>(
Arrays.asList(
"add", "for", "lt", "tellTarget", "and", "function", "ne", "this", "break", "ge", "new", "typeof", "continue", "gt", "not", "var", "delete", "if", "on", "void", "do", "ifFrameLoaded", "onClipEvent", "while", "else", "in", "or", "with", "eq", "le", "return"));
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"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("invokerPackage")) {
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
} else {
//not set, use default to be passed to template
additionalProperties.put("invokerPackage", invokerPackage);
}
if (additionalProperties.containsKey("sourceFolder")) {
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
}
if (additionalProperties.containsKey("packageName")) {
setPackageName((String) additionalProperties.get("packageName"));
apiPackage = packageName + ".client.api";
modelPackage = packageName + ".client.model";
}
else {
setPackageName("io.swagger");
}
if (additionalProperties.containsKey("packageVersion")) {
setPackageVersion((String) additionalProperties.get("packageVersion"));
}
else {
setPackageVersion("1.0.0");
}
additionalProperties.put("packageName", packageName);
additionalProperties.put("packageVersion", packageVersion);
//modelPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "model";
//apiPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "api";
final String invokerFolder = (sourceFolder + File.separator + invokerPackage + File.separator + "swagger" + File.separator).replace(".", File.separator).replace('.', File.separatorChar);
supportingFiles.add(new SupportingFile("ApiInvoker.as", invokerFolder + "common", "ApiInvoker.as"));
supportingFiles.add(new SupportingFile("ApiUrlHelper.as", invokerFolder + "common", "ApiUrlHelper.as"));
supportingFiles.add(new SupportingFile("ApiUserCredentials.as", invokerFolder + "common", "ApiUserCredentials.as"));
supportingFiles.add(new SupportingFile("ListWrapper.as", invokerFolder + "common", "ListWrapper.as"));
supportingFiles.add(new SupportingFile("SwaggerApi.as", invokerFolder + "common", "SwaggerApi.as"));
supportingFiles.add(new SupportingFile("XMLWriter.as", invokerFolder + "common", "XMLWriter.as"));
supportingFiles.add(new SupportingFile("ApiError.as", invokerFolder + "exception", "ApiErrors.as"));
supportingFiles.add(new SupportingFile("ApiErrorCodes.as", invokerFolder + "exception", "ApiErrorCodes.as"));
supportingFiles.add(new SupportingFile("ApiClientEvent.as", invokerFolder + "event", "ApiClientEvent.as"));
supportingFiles.add(new SupportingFile("Response.as", invokerFolder + "event", "Response.as"));
supportingFiles.add(new SupportingFile("build.properties", sourceFolder, "build.properties"));
supportingFiles.add(new SupportingFile("build.xml", sourceFolder, "build.xml"));
supportingFiles.add(new SupportingFile("AirExecutorApp-app.xml", sourceFolder + File.separatorChar + "bin", "AirExecutorApp-app.xml"));
supportingFiles.add(new SupportingFile("ASAXB-0.1.1.swc", sourceFolder + File.separatorChar + "lib", "ASAXB-0.1.1.swc"));
supportingFiles.add(new SupportingFile("as3corelib.swc", sourceFolder + File.separatorChar + "lib", "as3corelib.swc"));
supportingFiles.add(new SupportingFile("flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc"));
supportingFiles.add(new SupportingFile("flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
supportingFiles.add(new SupportingFile("flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
supportingFiles.add(new SupportingFile("flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc"));
}
private static String dropDots(String str) {
return str.replaceAll("\\.", "_");
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "flash";
}
public String getHelp() {
return "Generates a Flash client library.";
}
@Override
public String escapeReservedWord(String name) {
return name + "_";
}
@Override
public String apiFileFolder() {
return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
}
public String modelFileFolder() {
return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p);
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p);
}
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 = toModelName(swaggerType);
}
return type;
}
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
return "null";
} else if (p instanceof BooleanProperty) {
return "false";
} else if (p instanceof DateProperty) {
return "null";
} else if (p instanceof DateTimeProperty) {
return "null";
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0.0";
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0.0";
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0";
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0";
} else if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "new Dictionary()";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "new Array()";
} else {
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();
}
// underscore the variable name
// petId => pet_id
name = camelize(dropDots(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) {
// 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 => phone_number
return camelize(dropDots(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 camelize(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 "DefaultApi";
}
return camelize(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);
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
}

View File

@@ -1,17 +1,32 @@
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.CodegenModel;
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.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
@@ -19,7 +34,9 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/java";
protected String localVariablePrefix = "";
protected Boolean serializableModel = false;
public JavaClientCodegen() {
super();
outputFolder = "generated-code/java";
@@ -59,6 +76,13 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
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"));
supportedLibraries.put("<default>", "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.6");
cliOptions.add(buildLibraryCliOption(supportedLibraries));
}
public CodegenType getTag() {
@@ -76,7 +100,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("invokerPackage")) {
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
} else {
@@ -109,13 +133,29 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
}
if (additionalProperties.containsKey("localVariablePrefix")) {
this.setLocalVariablePrefix((String) additionalProperties.get("localVariablePrefix"));
}
if (additionalProperties.containsKey("serializableModel")) {
this.setSerializableModel(Boolean.valueOf((String)additionalProperties.get("serializableModel").toString()));
}
// need to put back serializableModel (boolean) into additionalProperties as value in additionalProperties is string
additionalProperties.put("serializableModel", serializableModel);
this.sanitizeConfig();
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
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("JsonUtil.mustache", invokerFolder, "JsonUtil.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"));
@@ -124,7 +164,26 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
}
private void sanitizeConfig() {
// 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);
}
this.setModelPackage(sanitizePackageName(modelPackage));
if (additionalProperties.containsKey("modelPackage")) {
this.additionalProperties.put("modelPackage", modelPackage);
}
this.setInvokerPackage(sanitizePackageName(invokerPackage));
if (additionalProperties.containsKey("invokerPackage")) {
this.additionalProperties.put("invokerPackage", invokerPackage);
}
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
@@ -144,6 +203,10 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
if("_".equals(name)) {
name = "_u";
}
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
@@ -200,6 +263,18 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return super.getTypeDeclaration(p);
}
@Override
public String toDefaultValue(Property p) {
if (p instanceof ArrayProperty) {
final ArrayProperty ap = (ArrayProperty) p;
return String.format("new ArrayList<%s>()", getTypeDeclaration(ap.getItems()));
} else if (p instanceof MapProperty) {
final MapProperty ap = (MapProperty) p;
return String.format("new HashMap<String, %s>()", getTypeDeclaration(ap.getAdditionalProperties()));
}
return super.toDefaultValue(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
@@ -217,6 +292,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");
@@ -225,6 +305,57 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(operationId, true);
}
@Override
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null && codegenModel.hasEnums) {
final Model parentModel = allDefinitions.get(toModelName(codegenModel.parent));
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
}
return codegenModel;
}
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
// the parent and child models, look for enums that match, and remove
// them from the child models and leave them in the parent.
// Because the child models extend the parents, the enums will be available via the parent.
// Only bother with reconciliation if the parent model has enums.
if (parentCodegenModel.hasEnums) {
// Get the properties for the parent and child models
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
List<CodegenProperty> codegenProperties = codegenModel.vars;
// Iterate over all of the parent model properties
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
// Look for enums
if (parentModelCodegenPropery.isEnum) {
// Now that we have found an enum in the parent class,
// and search the child class for the same enum.
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
while (iterator.hasNext()) {
CodegenProperty codegenProperty = iterator.next();
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
// We found an enum in the child class that is
// a duplicate of the one in the parent, so remove it.
iterator.remove();
}
}
}
}
codegenModel.vars = codegenProperties;
}
return codegenModel;
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
@@ -244,4 +375,26 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
public void setLocalVariablePrefix(String localVariablePrefix) {
this.localVariablePrefix = localVariablePrefix;
}
public Boolean getSerializableModel() {
return serializableModel;
}
public void setSerializableModel(Boolean serializableModel) {
this.serializableModel = serializableModel;
}
private String sanitizePackageName(String packageName) {
packageName = packageName.trim();
packageName = packageName.replaceAll("[^a-zA-Z0-9_\\.]", "_");
if(Strings.isNullOrEmpty(packageName)) {
return "invalidPackageName";
}
return packageName;
}
}

View File

@@ -0,0 +1,188 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
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() {
super();
sourceFolder = "src/main/java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
templateDir = "JavaInflector";
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("title", title);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float")
);
}
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "inflector";
}
public String getHelp() {
return "Generates a Java Inflector Server application.";
}
@Override
public void processOpts() {
super.processOpts();
supportingFiles.clear();
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("web.mustache", "src/main/webapp/WEB-INF", "web.xml"));
supportingFiles.add(new SupportingFile("inflector.mustache", "", "inflector.yaml"));
}
@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 getTypeDeclaration(inner);
}
return super.getTypeDeclaration(p);
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
}
int pos = basePath.indexOf("/");
if (pos > 0) {
basePath = basePath.substring(0, pos);
}
if (basePath == "") {
basePath = "default";
} else {
if (co.path.startsWith("/" + basePath)) {
co.path = co.path.substring(("/" + basePath).length());
}
co.subresourceOperation = !co.path.isEmpty();
}
List<CodegenOperation> opList = operations.get(basePath);
if (opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(basePath, opList);
}
opList.add(co);
co.baseName = basePath;
}
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.returnType == null) {
operation.returnType = "Void";
} else if (operation.returnType.startsWith("List")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("List<".length(), end);
operation.returnContainer = "List";
}
} else if (operation.returnType.startsWith("Map")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Map<".length(), end);
operation.returnContainer = "Map";
}
} else if (operation.returnType.startsWith("Set")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Set<".length(), end);
operation.returnContainer = "Set";
}
}
}
}
return objs;
}
@Override
public void processSwagger(Swagger swagger) {
super.processSwagger(swagger);
try {
File file = new File( outputFolder + "/src/main/swagger/swagger.json" );
file.getParentFile().mkdirs();
FileWriter swaggerFile = new FileWriter(file);
swaggerFile.write( Json.pretty( swagger ));
swaggerFile.flush();
swaggerFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultController";
}
name = name.replaceAll("[^a-zA-Z0-9]+", "_");
return camelize(name)+ "Controller";
}
public boolean shouldOverwrite(String filename) {
return super.shouldOverwrite(filename);
}
}

View File

@@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenResponse;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
@@ -89,21 +90,6 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
}
@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 getTypeDeclaration(inner);
}
return super.getTypeDeclaration(p);
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath;
@@ -137,27 +123,35 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
List<CodegenResponse> responses = operation.responses;
if (responses != null) {
for (CodegenResponse resp : responses) {
if ("0".equals(resp.code)) {
resp.code = "200";
}
}
}
if (operation.returnType == null) {
operation.returnType = "Void";
} else if (operation.returnType.startsWith("List")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("List<".length(), end);
operation.returnType = rt.substring("List<".length(), end).trim();
operation.returnContainer = "List";
}
} else if (operation.returnType.startsWith("Map")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Map<".length(), end);
operation.returnType = rt.substring("Map<".length(), end).split(",")[1].trim();
operation.returnContainer = "Map";
}
} else if (operation.returnType.startsWith("Set")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Set<".length(), end);
operation.returnType = rt.substring("Set<".length(), end).trim();
operation.returnContainer = "Set";
}
}
@@ -166,6 +160,15 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
return objs;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
name = name.replaceAll("[^a-zA-Z0-9]+", "_");
return camelize(name) + "Api";
}
@Override
public String apiFilename(String templateName, String tag) {
@@ -200,7 +203,6 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
}
public boolean shouldOverwrite(String filename) {
return !filename.endsWith("ServiceImpl.java") && !filename.endsWith("ServiceFactory.java");
return super.shouldOverwrite(filename) && !filename.endsWith("ServiceImpl.java") && !filename.endsWith("ServiceFactory.java");
}
}
}

View File

@@ -9,11 +9,19 @@ import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0";
@@ -197,4 +205,50 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
}
return objs;
}
@SuppressWarnings("unchecked")
private Map<String, Object> getOperations(Map<String, Object> objs) {
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");
}
private List<Map<String, Object>> sortOperationsByPath(List<CodegenOperation> ops) {
Multimap<String, CodegenOperation> opsByPath = ArrayListMultimap.create();
for (CodegenOperation op : ops) {
opsByPath.put(op.path, op);
}
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);
opsByPathEntry.put("path", entry.getKey());
opsByPathEntry.put("operation", entry.getValue());
List<CodegenOperation> operationsForThisPath = Lists.newArrayList(entry.getValue());
operationsForThisPath.get(operationsForThisPath.size() - 1).hasMore = null;
if (opsByPathList.size() < opsByPath.asMap().size()) {
opsByPathEntry.put("hasMore", "true");
}
}
return opsByPathList;
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Map<String, Object> operations = getOperations(objs);
if (operations != null) {
@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

@@ -16,45 +16,64 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
protected Set<String> foundationClasses = new HashSet<String>();
protected String sourceFolder = "client";
protected String podName = "SwaggerClient";
protected String podVersion = "1.0.0";
protected String classPrefix = "SWG";
protected String projectName = "swaggerClient";
public ObjcClientCodegen() {
super();
outputFolder = "generated-code" + File.separator + "objc";
modelTemplateFiles.put("model-header.mustache", ".h");
modelTemplateFiles.put("model-body.mustache", ".m");
apiTemplateFiles.put("api-header.mustache", ".h");
apiTemplateFiles.put("api-body.mustache", ".m");
templateDir = "objc";
modelPackage = "";
defaultIncludes = new HashSet<String>(
Arrays.asList(
"bool",
"BOOL",
"int",
"NSString",
"NSObject",
"NSArray",
"NSNumber",
"NSDate",
"NSDictionary",
"NSMutableArray",
"NSMutableDictionary")
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"NSNumber",
"NSString",
"NSObject",
"NSDate",
"bool",
"BOOL")
);
defaultIncludes.clear();
defaultIncludes.add("bool");
defaultIncludes.add("BOOL");
defaultIncludes.add("int");
defaultIncludes.add("NSURL");
defaultIncludes.add("NSString");
defaultIncludes.add("NSObject");
defaultIncludes.add("NSArray");
defaultIncludes.add("NSNumber");
defaultIncludes.add("NSDate");
defaultIncludes.add("NSDictionary");
defaultIncludes.add("NSMutableArray");
defaultIncludes.add("NSMutableDictionary");
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("NSNumber");
languageSpecificPrimitives.add("NSString");
languageSpecificPrimitives.add("NSObject");
languageSpecificPrimitives.add("NSDate");
languageSpecificPrimitives.add("NSURL");
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("BOOL");
typeMapping.clear();
typeMapping.put("enum", "NSString");
typeMapping.put("date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "NSNumber");
typeMapping.put("string", "NSString");
typeMapping.put("integer", "NSNumber");
typeMapping.put("int", "NSNumber");
typeMapping.put("float", "NSNumber");
typeMapping.put("long", "NSNumber");
typeMapping.put("double", "NSNumber");
typeMapping.put("array", "NSArray");
typeMapping.put("map", "NSDictionary");
typeMapping.put("number", "NSNumber");
typeMapping.put("List", "NSArray");
typeMapping.put("object", "NSObject");
typeMapping.put("file", "NSURL");
// ref: http://www.tutorialspoint.com/objective_c/objective_c_basic_syntax.htm
reservedWords = new HashSet<String>(
@@ -70,26 +89,10 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
"double", "protocol", "interface", "implementation",
"NSObject", "NSInteger", "NSNumber", "CGFloat",
"property", "nonatomic", "retain", "strong",
"weak", "unsafe_unretained", "readwrite", "readonly"
"weak", "unsafe_unretained", "readwrite", "readonly",
"description"
));
typeMapping = new HashMap<String, String>();
typeMapping.put("enum", "NSString");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "BOOL");
typeMapping.put("string", "NSString");
typeMapping.put("integer", "NSNumber");
typeMapping.put("int", "NSNumber");
typeMapping.put("float", "NSNumber");
typeMapping.put("long", "NSNumber");
typeMapping.put("double", "NSNumber");
typeMapping.put("array", "NSArray");
typeMapping.put("map", "NSDictionary");
typeMapping.put("number", "NSNumber");
typeMapping.put("List", "NSArray");
typeMapping.put("object", "NSObject");
importMapping = new HashMap<String, String>();
foundationClasses = new HashSet<String>(
@@ -98,15 +101,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
"NSObject",
"NSString",
"NSDate",
"NSURL",
"NSDictionary")
);
instantiationTypes.put("array", "NSMutableArray");
instantiationTypes.put("map", "NSMutableDictionary");
cliOptions.add(new CliOption("classPrefix", "prefix for generated classes"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
cliOptions.add(new CliOption("projectName", "name of the Xcode project in generated Podfile"));
cliOptions.clear();
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`"));
}
public CodegenType getTag() {
@@ -125,33 +130,43 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("sourceFolder")) {
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
if (additionalProperties.containsKey("podName")) {
setPodName((String) additionalProperties.get("podName"));
}
if (additionalProperties.containsKey("podVersion")) {
setPodVersion((String) additionalProperties.get("podVersion"));
}
if (additionalProperties.containsKey("classPrefix")) {
this.setClassPrefix((String) additionalProperties.get("classPrefix"));
setClassPrefix((String) additionalProperties.get("classPrefix"));
}
if (additionalProperties.containsKey("projectName")) {
this.setProjectName((String) additionalProperties.get("projectName"));
} else {
additionalProperties.put("projectName", projectName);
}
additionalProperties.put("podName", podName);
additionalProperties.put("podVersion", podVersion);
additionalProperties.put("classPrefix", classPrefix);
supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h"));
supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m"));
supportingFiles.add(new SupportingFile("SWGQueryParamCollection.h", sourceFolder, "SWGQueryParamCollection.h"));
supportingFiles.add(new SupportingFile("SWGQueryParamCollection.m", sourceFolder, "SWGQueryParamCollection.m"));
supportingFiles.add(new SupportingFile("SWGApiClient.h", sourceFolder, "SWGApiClient.h"));
supportingFiles.add(new SupportingFile("SWGApiClient.m", sourceFolder, "SWGApiClient.m"));
supportingFiles.add(new SupportingFile("SWGFile.h", sourceFolder, "SWGFile.h"));
supportingFiles.add(new SupportingFile("SWGFile.m", sourceFolder, "SWGFile.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", sourceFolder, "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", sourceFolder, "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("SWGConfiguration-body.mustache", sourceFolder, "SWGConfiguration.m"));
supportingFiles.add(new SupportingFile("SWGConfiguration-header.mustache", sourceFolder, "SWGConfiguration.h"));
supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile"));
String swaggerFolder = podName;
modelPackage = swaggerFolder;
apiPackage = swaggerFolder;
supportingFiles.add(new SupportingFile("Object-header.mustache", swaggerFolder, classPrefix + "Object.h"));
supportingFiles.add(new SupportingFile("Object-body.mustache", swaggerFolder, classPrefix + "Object.m"));
supportingFiles.add(new SupportingFile("QueryParamCollection-header.mustache", swaggerFolder, classPrefix + "QueryParamCollection.h"));
supportingFiles.add(new SupportingFile("QueryParamCollection-body.mustache", swaggerFolder, classPrefix + "QueryParamCollection.m"));
supportingFiles.add(new SupportingFile("ApiClient-header.mustache", swaggerFolder, classPrefix + "ApiClient.h"));
supportingFiles.add(new SupportingFile("ApiClient-body.mustache", swaggerFolder, classPrefix + "ApiClient.m"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-header.mustache", swaggerFolder, classPrefix + "JSONResponseSerializer.h"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-body.mustache", swaggerFolder, classPrefix + "JSONResponseSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-body.mustache", swaggerFolder, classPrefix + "JSONRequestSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-header.mustache", swaggerFolder, classPrefix + "JSONRequestSerializer.h"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", swaggerFolder, "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", swaggerFolder, "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("Configuration-body.mustache", swaggerFolder, classPrefix + "Configuration.m"));
supportingFiles.add(new SupportingFile("Configuration-header.mustache", swaggerFolder, classPrefix + "Configuration.h"));
supportingFiles.add(new SupportingFile("podspec.mustache", "", podName + ".podspec"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
@Override
@@ -200,21 +215,32 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
Property inner = ap.getItems();
String innerType = getSwaggerType(inner);
// In this codition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray*'
if (languageSpecificPrimitives.contains(innerType)) {
return getSwaggerType(p) + "*";
}
// In this codition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
String innerTypeDeclaration = getTypeDeclaration(inner);
if (innerTypeDeclaration.endsWith("*")) {
innerTypeDeclaration = innerTypeDeclaration.substring(0, innerTypeDeclaration.length() - 1);
}
return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*";
// In this codition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray* /* NSString */'
if (languageSpecificPrimitives.contains(innerType)) {
return getSwaggerType(p) + "*" + " /* " + innerTypeDeclaration + " */";
}
// In this codition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
else {
return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*";
}
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
String innerTypeDeclaration = getTypeDeclaration(inner);
if (innerTypeDeclaration.endsWith("*")) {
innerTypeDeclaration = innerTypeDeclaration.substring(0, innerTypeDeclaration.length() - 1);
}
return getSwaggerType(p) + "* /* NSString, " + innerTypeDeclaration + " */";
} else {
String swaggerType = getSwaggerType(p);
@@ -273,11 +299,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toModelImport(String name) {
if ("".equals(modelPackage())) {
return name;
} else {
return modelPackage() + "." + name;
}
return name;
}
@Override
@@ -287,12 +309,12 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder;
return outputFolder + File.separatorChar + apiPackage();
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder;
return outputFolder + File.separatorChar + modelPackage();
}
@Override
@@ -339,6 +361,11 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");
@@ -347,15 +374,15 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(operationId, true);
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
public void setClassPrefix(String classPrefix) {
this.classPrefix = classPrefix;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
public void setPodName(String podName) {
this.podName = podName;
}
public void setPodVersion(String podVersion) {
this.podVersion = podVersion;
}
}

View File

@@ -7,16 +7,17 @@ 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.codegen.CliOption;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "SwaggerClient";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-client";
protected String artifactVersion = "1.0.0";
protected String moduleName = "SwaggerClient";
protected String moduleVersion = "1.0.0";
public PerlClientCodegen() {
super();
@@ -26,8 +27,6 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
apiTemplateFiles.put("api.mustache", ".pm");
templateDir = "perl";
typeMapping.clear();
languageSpecificPrimitives.clear();
reservedWords = new HashSet<String>(
Arrays.asList(
@@ -44,11 +43,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
)
);
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
additionalProperties.put("artifactVersion", artifactVersion);
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("double");
languageSpecificPrimitives.add("string");
@@ -58,6 +53,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
languageSpecificPrimitives.add("HASH");
languageSpecificPrimitives.add("object");
typeMapping.clear();
typeMapping.put("integer", "int");
typeMapping.put("long", "int");
typeMapping.put("float", "double");
@@ -71,9 +67,31 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("map", "HASH");
typeMapping.put("object", "object");
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "Object/BaseObject.pm"));
cliOptions.clear();
cliOptions.add(new CliOption("moduleName", "perl module name (convention: CamelCase), default: SwaggerClient"));
cliOptions.add(new CliOption("moduleVersion", "perl module version, default: 1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("moduleVersion")) {
moduleVersion = (String) additionalProperties.get("moduleVersion");
} else {
additionalProperties.put("moduleVersion", moduleVersion);
}
if (additionalProperties.containsKey("moduleName")) {
moduleName = (String) additionalProperties.get("moduleName");
} else {
additionalProperties.put("moduleName", moduleName);
}
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm"));
}
public CodegenType getTag() {
@@ -95,11 +113,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return (outputFolder + "/lib/WWW/" + invokerPackage + apiPackage()).replace('/', File.separatorChar);
return (outputFolder + "/lib/WWW/" + moduleName + apiPackage()).replace('/', File.separatorChar);
}
public String modelFileFolder() {
return (outputFolder + "/lib/WWW/" + invokerPackage + modelPackage()).replace('/', File.separatorChar);
return (outputFolder + "/lib/WWW/" + moduleName + modelPackage()).replace('/', File.separatorChar);
}
@Override
@@ -141,15 +159,17 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toVarName(String name) {
// 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
if (name.matches("^[0-9]")) {
if (name.matches("^\\d.*")) {
name = "_" + name;
}
// return the name in underscore style
// PhoneNumber => phone_number
return underscore(name);
return name;
}
@Override
@@ -196,6 +216,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");

View File

@@ -1,5 +1,6 @@
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;
@@ -7,45 +8,42 @@ 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.RefProperty;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import org.apache.commons.lang3.StringUtils;
public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-client";
protected String invokerPackage = "Swagger\\Client";
protected String composerVendorName = "swagger";
protected String composerProjectName = "swagger-client";
protected String packagePath = "SwaggerClient-php";
protected String artifactVersion = "1.0.0";
protected String srcBasePath = "lib";
public PhpClientCodegen() {
super();
invokerPackage = camelize("SwaggerClient");
String packagePath = invokerPackage + "-php";
modelPackage = packagePath + "/lib/models";
apiPackage = packagePath + "/lib";
outputFolder = "generated-code/php";
outputFolder = "generated-code" + File.separator + "php";
modelTemplateFiles.put("model.mustache", ".php");
apiTemplateFiles.put("api.mustache", ".php");
templateDir = "php";
apiPackage = invokerPackage + "\\Api";
modelPackage = invokerPackage + "\\Model";
reservedWords = new HashSet<String>(
Arrays.asList(
"__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);
// ref: http://php.net/manual/en/language.types.intro.php
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"bool",
"boolean",
"int",
"integer",
@@ -55,12 +53,19 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
"object",
"DateTime",
"mixed",
"number")
"number",
"void",
"byte")
);
instantiationTypes.put("array", "array");
instantiationTypes.put("map", "map");
// provide primitives to mustache template
String primitives = "'" + StringUtils.join(languageSpecificPrimitives, "', '") + "'";
additionalProperties.put("primitives", primitives);
// ref: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types
typeMapping = new HashMap<String, String>();
typeMapping.put("integer", "int");
@@ -69,20 +74,55 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("double", "double");
typeMapping.put("string", "string");
typeMapping.put("byte", "int");
typeMapping.put("boolean", "boolean");
typeMapping.put("date", "DateTime");
typeMapping.put("datetime", "DateTime");
typeMapping.put("file", "string");
typeMapping.put("boolean", "bool");
typeMapping.put("date", "\\DateTime");
typeMapping.put("datetime", "\\DateTime");
typeMapping.put("file", "\\SplFileObject");
typeMapping.put("map", "map");
typeMapping.put("array", "array");
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("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"));
}
supportingFiles.add(new SupportingFile("composer.mustache", packagePath.replace('/', File.separatorChar), "composer.json"));
supportingFiles.add(new SupportingFile("configuration.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "Configuration.php"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "ApiClient.php"));
supportingFiles.add(new SupportingFile("ApiException.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "ApiException.php"));
supportingFiles.add(new SupportingFile("require.mustache", packagePath.replace('/', File.separatorChar), invokerPackage + ".php"));
public String getPackagePath() {
return packagePath;
}
public String toPackagePath(String packageName, String basePath) {
packageName = packageName.replace(invokerPackage, "");
if (basePath != null && basePath.length() > 0) {
basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar;
}
String regFirstPathSeparator;
if ("/".equals(File.separator)) { // for mac, linux
regFirstPathSeparator = "^/";
} else { // for windows
regFirstPathSeparator = "^\\\\";
}
String regLastPathSeparator;
if ("/".equals(File.separator)) { // for mac, linux
regLastPathSeparator = "/$";
} else { // for windows
regLastPathSeparator = "\\\\$";
}
return (getPackagePath() + File.separatorChar + basePath
// Replace period, backslash, forward slash with file separator in package name
+ packageName.replaceAll("[\\.\\\\/]", File.separator)
// Trim prefix file separators from package path
.replaceAll(regFirstPathSeparator, ""))
// Trim trailing file separators from the overall path
.replaceAll(regLastPathSeparator+ "$", "");
}
public CodegenType getTag() {
@@ -97,6 +137,68 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
return "Generates a PHP client library.";
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packagePath")) {
this.setPackagePath((String) additionalProperties.get("packagePath"));
} else {
additionalProperties.put("packagePath", packagePath);
}
if (additionalProperties.containsKey("srcBasePath")) {
this.setSrcBasePath((String) additionalProperties.get("srcBasePath"));
} else {
additionalProperties.put("srcBasePath", srcBasePath);
}
if (additionalProperties.containsKey("invokerPackage")) {
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
} else {
additionalProperties.put("invokerPackage", invokerPackage);
}
if (additionalProperties.containsKey("modelPackage")) {
this.setModelPackage((String) additionalProperties.get("modelPackage"));
} else {
additionalProperties.put("modelPackage", modelPackage);
}
if (additionalProperties.containsKey("apiPackage")) {
this.setApiPackage((String) additionalProperties.get("apiPackage"));
} else {
additionalProperties.put("apiPackage", apiPackage);
}
if (additionalProperties.containsKey("composerProjectName")) {
this.setComposerProjectName((String) additionalProperties.get("composerProjectName"));
} else {
additionalProperties.put("composerProjectName", composerProjectName);
}
if (additionalProperties.containsKey("composerVendorName")) {
this.setComposerVendorName((String) additionalProperties.get("composerVendorName"));
} else {
additionalProperties.put("composerVendorName", composerVendorName);
}
if (additionalProperties.containsKey("artifactVersion")) {
this.setArtifactVersion((String) additionalProperties.get("artifactVersion"));
} else {
additionalProperties.put("artifactVersion", artifactVersion);
}
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, srcBasePath), "Configuration.php"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClient.php"));
supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiException.php"));
supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php"));
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
@@ -104,11 +206,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar);
return (outputFolder + "/" + toPackagePath(apiPackage(), srcBasePath));
}
public String modelFileFolder() {
return (outputFolder + "/" + modelPackage()).replace('/', File.separatorChar);
return (outputFolder + "/" + toPackagePath(modelPackage(), srcBasePath));
}
@Override
@@ -116,15 +218,27 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
return getTypeDeclaration(inner) + "[]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]";
} else if (p instanceof RefProperty) {
String type = super.getTypeDeclaration(p);
return (!languageSpecificPrimitives.contains(type))
? "\\" + modelPackage + "\\" + type : type;
}
return super.getTypeDeclaration(p);
}
@Override
public String getTypeDeclaration(String name) {
if (!languageSpecificPrimitives.contains(name)) {
return "\\" + modelPackage + "\\" + name;
}
return super.getTypeDeclaration(name);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
@@ -149,18 +263,43 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
return "null";
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setArtifactVersion(String artifactVersion) {
this.artifactVersion = artifactVersion;
}
public void setPackagePath(String packagePath) {
this.packagePath = packagePath;
}
public void setSrcBasePath(String srcBasePath) {
this.srcBasePath = srcBasePath;
}
private void setComposerVendorName(String composerVendorName) {
this.composerVendorName = composerVendorName;
}
public void setComposerProjectName(String composerProjectName) {
this.composerProjectName = composerProjectName;
}
@Override
public String toVarName(String name) {
// 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
if (name.matches("^[0-9]")) {
if (name.matches("^\\d.*")) {
name = "_" + name;
}
// return the name in underscore style
// PhoneNumber => phone_number
return underscore(name);
return name;
}
@Override
@@ -186,5 +325,4 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
// should be the same as the model name
return toModelName(name);
}
}

View File

@@ -12,6 +12,8 @@ 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";
@@ -33,6 +35,7 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
languageSpecificPrimitives.add("date");
typeMapping.clear();
typeMapping.put("integer", "int");
@@ -43,7 +46,8 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
typeMapping.put("map", "map");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "str");
typeMapping.put("date", "datetime");
typeMapping.put("date", "date");
typeMapping.put("DateTime", "datetime");
// from https://docs.python.org/release/2.5.4/ref/keywords.html
reservedWords = new HashSet<String>(
@@ -199,6 +203,11 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
@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");

View File

@@ -1,5 +1,6 @@
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;
@@ -12,26 +13,22 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String module = "SwaggerPetstore";
protected String invokerPackage;
protected String eggPackage;
protected String packageName = null;
protected String packageVersion = null;
public PythonClientCodegen() {
super();
eggPackage = module + "-python";
invokerPackage = eggPackage + File.separatorChar + module;
modelPackage = "models";
apiPackage = "api";
outputFolder = "generated-code" + File.separatorChar + "python";
modelTemplateFiles.put("model.mustache", ".py");
apiTemplateFiles.put("api.mustache", ".py");
templateDir = "python";
apiPackage = invokerPackage + File.separatorChar + "apis";
modelPackage = invokerPackage + File.separatorChar + "models";
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("float");
@@ -39,6 +36,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
languageSpecificPrimitives.add("date");
typeMapping.clear();
typeMapping.put("integer", "int");
@@ -46,10 +44,13 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("long", "int");
typeMapping.put("double", "float");
typeMapping.put("array", "list");
typeMapping.put("map", "map");
typeMapping.put("map", "dict");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "str");
typeMapping.put("date", "datetime");
typeMapping.put("date", "date");
typeMapping.put("DateTime", "datetime");
typeMapping.put("object", "object");
typeMapping.put("file", "file");
// from https://docs.python.org/release/2.5.4/ref/keywords.html
reservedWords = new HashSet<String>(
@@ -59,14 +60,43 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
"print", "class", "exec", "in", "raise", "continue", "finally", "is",
"return", "def", "for", "lambda", "try"));
additionalProperties.put("module", module);
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "python package name (convension: under_score), default: swagger_client"));
cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0"));
}
supportingFiles.add(new SupportingFile("README.mustache", eggPackage, "README.md"));
supportingFiles.add(new SupportingFile("setup.mustache", eggPackage, "setup.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", invokerPackage, "api_client.py"));
supportingFiles.add(new SupportingFile("rest.mustache", invokerPackage, "rest.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", invokerPackage, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", invokerPackage, "__init__.py"));
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packageName")) {
setPackageName((String) additionalProperties.get("packageName"));
}
else {
setPackageName("swagger_client");
}
if (additionalProperties.containsKey("packageVersion")) {
setPackageVersion((String) additionalProperties.get("packageVersion"));
}
else {
setPackageVersion("1.0.0");
}
additionalProperties.put("packageName", packageName);
additionalProperties.put("packageVersion", packageVersion);
String swaggerFolder = packageName;
modelPackage = swaggerFolder + File.separatorChar + "models";
apiPackage = swaggerFolder + File.separatorChar + "apis";
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFolder, "api_client.py"));
supportingFiles.add(new SupportingFile("rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFolder, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFolder, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py"));
}
@@ -111,7 +141,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "(String, " + getTypeDeclaration(inner) + ")";
return getSwaggerType(p) + "(str, " + getTypeDeclaration(inner) + ")";
}
return super.getTypeDeclaration(p);
}
@@ -132,8 +162,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
public String toDefaultValue(Property p) {
// TODO: Support Python def value
return "null";
return "None";
}
@Override
@@ -150,6 +179,9 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
// petId => pet_id
name = underscore(dropDots(name));
// remove leading underscore
name = name.replaceAll("^_*", "");
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
@@ -216,6 +248,11 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
@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");
@@ -224,4 +261,23 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
return underscore(operationId);
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
/**
* Generate Python package name from String `packageName`
*
* (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]+", ""));
}
}

View File

@@ -15,6 +15,8 @@ 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";
@@ -171,6 +173,11 @@ public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConf
@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");

View File

@@ -1,5 +1,6 @@
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;
@@ -12,17 +13,19 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = "swagger_client";
protected String gemName = null;
protected String moduleName = null;
protected String gemVersion = "1.0.0";
protected String libFolder = "lib";
public RubyClientCodegen() {
super();
moduleName = generateModuleName();
modelPackage = gemName + "/models";
apiPackage = gemName + "/api";
outputFolder = "generated-code" + File.separatorChar + "ruby";
modelPackage = "models";
apiPackage = "api";
outputFolder = "generated-code" + File.separator + "ruby";
modelTemplateFiles.put("model.mustache", ".rb");
apiTemplateFiles.put("api.mustache", ".rb");
templateDir = "ruby";
@@ -39,33 +42,82 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
"if", "not", "return", "undef", "yield")
);
additionalProperties.put("gemName", gemName);
additionalProperties.put("moduleName", moduleName);
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("array");
languageSpecificPrimitives.add("map");
languageSpecificPrimitives.add("string");
languageSpecificPrimitives.add("DateTime");
typeMapping.put("long", "int");
typeMapping.put("integer", "int");
typeMapping.put("Array", "array");
typeMapping.put("String", "string");
typeMapping.put("List", "array");
typeMapping.put("map", "map");
typeMapping.put("string", "String");
typeMapping.put("char", "String");
typeMapping.put("int", "Integer");
typeMapping.put("integer", "Integer");
typeMapping.put("long", "Integer");
typeMapping.put("short", "Integer");
typeMapping.put("float", "Float");
typeMapping.put("double", "Float");
typeMapping.put("number", "Float");
typeMapping.put("date", "Date");
typeMapping.put("DateTime", "DateTime");
typeMapping.put("boolean", "BOOLEAN");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Hash");
typeMapping.put("object", "Object");
typeMapping.put("file", "File");
// remove modelPackage and apiPackage added by default
cliOptions.clear();
cliOptions.add(new CliOption("gemName", "gem name (convention: underscore_case), default: swagger_client"));
cliOptions.add(new CliOption("moduleName", "top module name (convention: CamelCase, usually corresponding to gem name), default: SwaggerClient"));
cliOptions.add(new CliOption("gemVersion", "gem version, default: 1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("gemName")) {
setGemName((String) additionalProperties.get("gemName"));
}
if (additionalProperties.containsKey("moduleName")) {
setModuleName((String) additionalProperties.get("moduleName"));
}
if (gemName == null && moduleName == null) {
setGemName("swagger_client");
setModuleName(generateModuleName(gemName));
} else if (gemName == null) {
setGemName(generateGemName(moduleName));
} else if (moduleName == null) {
setModuleName(generateModuleName(gemName));
}
additionalProperties.put("gemName", gemName);
additionalProperties.put("moduleName", moduleName);
if (additionalProperties.containsKey("gemVersion")) {
setGemVersion((String) additionalProperties.get("gemVersion"));
} else {
// not set, pass the default value to template
additionalProperties.put("gemVersion", gemVersion);
}
// use constant model/api package (folder path)
setModelPackage("models");
setApiPackage("api");
String baseFolder = "lib" + File.separatorChar + gemName;
String swaggerFolder = baseFolder + File.separatorChar + "swagger";
String modelFolder = baseFolder + File.separatorChar + "models";
supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec"));
supportingFiles.add(new SupportingFile("swagger_client.mustache", "lib", gemName + ".rb"));
supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb"));
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"));
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "request.mustache", swaggerFolder, "request.rb"));
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "response.mustache", swaggerFolder, "response.rb"));
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "version.mustache", swaggerFolder, "version.rb"));
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "configuration.mustache", swaggerFolder, "configuration.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("base_object.mustache", modelFolder, "base_object.rb"));
}
@@ -84,10 +136,17 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
/**
* Generate Ruby module name from the gem name, e.g. use "SwaggerClient" for "swagger_client".
*/
public String generateModuleName() {
public String generateModuleName(String gemName) {
return camelize(gemName.replaceAll("[^\\w]+", "_"));
}
/**
* Generate Ruby gem name from the module name, e.g. use "swagger_client" for "SwaggerClient".
*/
public String generateGemName(String moduleName) {
return underscore(moduleName.replaceAll("[^\\w]+", ""));
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
@@ -95,11 +154,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return outputFolder + File.separatorChar + "lib" + File.separatorChar + gemName + File.separatorChar + "api";
return outputFolder + File.separator + libFolder + File.separator + gemName + File.separator + apiPackage.replace("/", File.separator);
}
public String modelFileFolder() {
return outputFolder + File.separatorChar + "lib" + File.separatorChar + gemName + File.separatorChar + "models";
return outputFolder + File.separator + libFolder + File.separator + gemName + File.separator + modelPackage.replace("/", File.separator);
}
@Override
@@ -107,11 +166,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
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 getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}
@@ -210,6 +269,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");
@@ -220,12 +284,23 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toModelImport(String name) {
return modelPackage() + "/" + toModelFilename(name);
return gemName + "/" + modelPackage() + "/" + toModelFilename(name);
}
@Override
public String toApiImport(String name) {
return apiPackage() + "/" + toApiFilename(name);
return gemName + "/" + apiPackage() + "/" + toApiFilename(name);
}
public void setGemName(String gemName) {
this.gemName = gemName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public void setGemVersion(String gemVersion) {
this.gemVersion = gemVersion;
}
}

View File

@@ -20,6 +20,11 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
@@ -206,6 +211,11 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
@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");
@@ -214,4 +224,17 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
return camelize(operationId, true);
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// remove model imports to avoid warnings for importing class in the same package in Scala
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
final String prefix = modelPackage() + ".";
Iterator<Map<String, String>> iterator = imports.iterator();
while (iterator.hasNext()) {
String _import = iterator.next().get("import");
if (_import.startsWith(prefix)) iterator.remove();
}
return objs;
}
}

View File

@@ -0,0 +1,194 @@
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.HashMap;
import java.util.HashSet;
public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage;
protected String groupId = "io.swagger";
protected String artifactId = "swagger-server";
protected String artifactVersion = "1.0.0";
public SilexServerCodegen() {
super();
invokerPackage = camelize("SwaggerServer");
String packagePath = "SwaggerServer";
modelPackage = packagePath + "/lib/models";
apiPackage = packagePath + "/lib";
outputFolder = "generated-code/silex";
// no model, api files
modelTemplateFiles.clear();
apiTemplateFiles.clear();
templateDir = "silex";
reservedWords = new HashSet<String>(
Arrays.asList(
"__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);
// ref: http://php.net/manual/en/language.types.intro.php
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"boolean",
"int",
"integer",
"double",
"float",
"string",
"object",
"DateTime",
"mixed",
"number")
);
instantiationTypes.put("array", "array");
instantiationTypes.put("map", "map");
// ref: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types
typeMapping = new HashMap<String, String>();
typeMapping.put("integer", "int");
typeMapping.put("long", "int");
typeMapping.put("float", "float");
typeMapping.put("double", "double");
typeMapping.put("string", "string");
typeMapping.put("byte", "int");
typeMapping.put("boolean", "boolean");
typeMapping.put("date", "DateTime");
typeMapping.put("datetime", "DateTime");
typeMapping.put("file", "string");
typeMapping.put("map", "map");
typeMapping.put("array", "array");
typeMapping.put("list", "array");
typeMapping.put("object", "object");
supportingFiles.add(new SupportingFile("README.mustache", packagePath.replace('/', File.separatorChar), "README.md"));
supportingFiles.add(new SupportingFile("composer.json", packagePath.replace('/', File.separatorChar), "composer.json"));
supportingFiles.add(new SupportingFile("index.mustache", packagePath.replace('/', File.separatorChar), "index.php"));
supportingFiles.add(new SupportingFile(".htaccess", packagePath.replace('/', File.separatorChar), ".htaccess"));
}
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "silex-PHP";
}
public String getHelp() {
return "Generates a Silex server 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 if (instantiationTypes.containsKey(type)) {
return type;
}
} else {
type = swaggerType;
}
if (type == null) {
return null;
}
return toModelName(type);
}
public String toDefaultValue(Property p) {
return "null";
}
@Override
public String toVarName(String name) {
// 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
if (name.matches("^\\d.*")) {
name = "_" + 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
if (reservedWords.contains(name)) {
escapeReservedWord(name); // e.g. return => _return
}
// 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);
}
}

View File

@@ -0,0 +1,217 @@
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 org.apache.commons.lang.StringUtils;
public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = null;
protected String moduleName = null;
protected String gemVersion = "1.0.0";
protected String libFolder = "lib";
public SinatraServerCodegen() {
super();
apiPackage = "lib";
outputFolder = "generated-code" + File.separator + "sinatra";
// no model
modelTemplateFiles.clear();
apiTemplateFiles.put("api.mustache", ".rb");
templateDir = "sinatra";
typeMapping.clear();
languageSpecificPrimitives.clear();
reservedWords = new HashSet<String>(
Arrays.asList(
"__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__",
"begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN",
"break", "do", "false", "next", "rescue", "then", "when", "END", "case",
"else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif",
"if", "not", "return", "undef", "yield")
);
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("array");
languageSpecificPrimitives.add("map");
languageSpecificPrimitives.add("string");
languageSpecificPrimitives.add("DateTime");
typeMapping.put("long", "int");
typeMapping.put("integer", "int");
typeMapping.put("Array", "array");
typeMapping.put("String", "string");
typeMapping.put("List", "array");
typeMapping.put("map", "map");
// remove modelPackage and apiPackage added by default
cliOptions.clear();
}
@Override
public void processOpts() {
super.processOpts();
// use constant model/api package (folder path)
//setModelPackage("models");
setApiPackage("api");
supportingFiles.add(new SupportingFile("my_app.mustache", "", "my_app.rb"));
supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "swaggering.rb"));
supportingFiles.add(new SupportingFile("config.ru", "", "config.ru"));
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "sinatra";
}
public String getHelp() {
return "Generates a Sinatra server library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + apiPackage.replace("/", File.separator);
}
@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;
}
if (type == null) {
return null;
}
return type;
}
public String toDefaultValue(Property p) {
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 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 underscore(operationId);
}
}

View File

@@ -1,9 +1,6 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.*;
import io.swagger.models.Operation;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
@@ -27,7 +24,7 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
protected String configPackage = "";
public SpringMVCServerCodegen() {
super.processOpts();
super();
outputFolder = "generated-code/javaSpringMVC";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
@@ -55,6 +52,9 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
"Long",
"Float")
);
cliOptions.add(new CliOption("configPackage", "configuration package for generated code"));
}
public CodegenType getTag() {
@@ -73,6 +73,10 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("configPackage")) {
this.setConfigPackage((String) additionalProperties.get("configPackage"));
}
supportingFiles.clear();
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
@@ -98,21 +102,6 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
}
@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 getTypeDeclaration(inner);
}
return super.getTypeDeclaration(p);
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath;
@@ -146,27 +135,38 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
List<CodegenResponse> responses = operation.responses;
if (responses != null) {
for (CodegenResponse resp : responses) {
if ("0".equals(resp.code)) {
resp.code = "200";
}
}
}
System.out.println(operation.operationId);
io.swagger.util.Json.prettyPrint(operation);
if (operation.returnType == null) {
operation.returnType = "Void";
} else if (operation.returnType.startsWith("List")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("List<".length(), end);
operation.returnType = rt.substring("List<".length(), end).trim();
operation.returnContainer = "List";
}
} else if (operation.returnType.startsWith("Map")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Map<".length(), end);
operation.returnType = rt.substring("Map<".length(), end).split(",")[1].trim();
operation.returnContainer = "Map";
}
} else if (operation.returnType.startsWith("Set")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Set<".length(), end);
operation.returnType = rt.substring("Set<".length(), end).trim();
operation.returnContainer = "Set";
}
}
@@ -174,5 +174,9 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
}
return objs;
}
public void setConfigPackage(String configPackage) {
this.configPackage = configPackage;
}
}

View File

@@ -0,0 +1,298 @@
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.Model;
import io.swagger.models.Operation;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
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 javax.annotation.Nullable;
import java.util.*;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
protected static final String LIBRARY_PROMISE_KIT = "PromiseKit";
protected static final String[] RESPONSE_LIBRARIES = { LIBRARY_PROMISE_KIT };
protected String projectName = "SwaggerClient";
protected boolean unwrapRequired = false;
protected String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "Swaggers";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "swift";
}
public String getHelp() {
return "Generates a swift client library.";
}
public SwiftCodegen() {
super();
outputFolder = "generated-code" + File.separator + "swift";
modelTemplateFiles.put("model.mustache", ".swift");
apiTemplateFiles.put("api.mustache", ".swift");
templateDir = "swift";
apiPackage = File.separator + "APIs";
modelPackage = File.separator + "Models";
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"Int",
"Float",
"Double",
"Bool",
"Void",
"String",
"Character")
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"NSDate",
"Array",
"Dictionary",
"Set",
"Any",
"Empty",
"AnyObject")
);
reservedWords = new HashSet<String>(
Arrays.asList(
"class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue",
"false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else",
"self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if",
"true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol",
"switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional",
"struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol",
"required", "right", "set", "Type", "unowned", "weak")
);
typeMapping = new HashMap<String, String>();
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("date", "NSDate");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "Bool");
typeMapping.put("string", "String");
typeMapping.put("char", "Character");
typeMapping.put("short", "Int");
typeMapping.put("int", "Int");
typeMapping.put("long", "Int");
typeMapping.put("integer", "Int");
typeMapping.put("Integer", "Int");
typeMapping.put("float", "Float");
typeMapping.put("number", "Double");
typeMapping.put("double", "Double");
typeMapping.put("object", "String");
typeMapping.put("file", "NSURL");
importMapping = new HashMap<String, String>();
cliOptions.add(new CliOption("projectName", "Project name in Xcode"));
cliOptions.add(new CliOption("responseAs", "Optionally use libraries to manage response. Currently " +
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " +
"(which would crash the app if api returns null as opposed to required option specified in json schema"));
cliOptions.add(new CliOption("podSource", "Source information used for Podspec"));
cliOptions.add(new CliOption("podVersion", "Version used for Podspec"));
cliOptions.add(new CliOption("podAuthors", "Authors used for Podspec"));
cliOptions.add(new CliOption("podSocialMediaURL", "Social Media URL used for Podspec"));
cliOptions.add(new CliOption("podDocsetURL", "Docset URL used for Podspec"));
cliOptions.add(new CliOption("podLicense", "License used for Podspec"));
cliOptions.add(new CliOption("podHomepage", "Homepage used for Podspec"));
cliOptions.add(new CliOption("podSummary", "Summary used for Podspec"));
cliOptions.add(new CliOption("podDescription", "Description used for Podspec"));
cliOptions.add(new CliOption("podScreenshots", "Screenshots used for Podspec"));
cliOptions.add(new CliOption("podDocumentationURL", "Documentation URL used for Podspec"));
}
@Override
public void processOpts() {
super.processOpts();
// Setup project name
if (additionalProperties.containsKey("projectName")) {
projectName = (String) additionalProperties.get("projectName");
} else {
additionalProperties.put("projectName", projectName);
}
sourceFolder = projectName + File.separator + sourceFolder;
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
if (additionalProperties.containsKey("unwrapRequired")) {
unwrapRequired = Boolean.parseBoolean(String.valueOf(additionalProperties.get("unwrapRequired")));
}
additionalProperties.put("unwrapRequired", unwrapRequired);
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
if (additionalProperties.containsKey("responseAs")) {
Object responseAsObject = additionalProperties.get("responseAs");
if (responseAsObject instanceof String) {
responseAs = ((String)responseAsObject).split(",");
} else {
responseAs = (String[]) responseAsObject;
}
}
additionalProperties.put("responseAs", responseAs);
if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) {
additionalProperties.put("usePromiseKit", true);
}
supportingFiles.add(new SupportingFile("Podspec.mustache", "", projectName + ".podspec"));
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder,
"AlamofireImplementations.swift"));
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
}
@Override
public String escapeReservedWord(String name) {
return "Swagger" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar);
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + apiPackage().replace('.', File.separatorChar);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return "[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 toDefaultValue(Property p) {
// nil
return null;
}
@Override
public String toInstantiationType(Property p) {
if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "[String:" + inner + "]";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "[" + inner + "]";
}
return null;
}
@Override
public CodegenProperty fromProperty(String name, Property p) {
CodegenProperty codegenProperty = super.fromProperty(name, p);
if (codegenProperty.isEnum) {
List<Map<String, String>> swiftEnums = new ArrayList<Map<String, String>>();
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("raw", value);
swiftEnums.add(map);
}
codegenProperty.allowableValues.put("values", swiftEnums);
codegenProperty.datatypeWithEnum =
StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length());
if (reservedWords.contains(codegenProperty.datatypeWithEnum)) {
codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum);
}
}
return codegenProperty;
}
@Override
public String toApiName(String name) {
if(name.length() == 0)
return "DefaultAPI";
return initialCaps(name) + "API";
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
path = normalizePath(path);
List<Parameter> parameters = operation.getParameters();
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
return super.fromOperation(path, httpMethod, operation, definitions);
}
private static String normalizePath(String path) {
StringBuilder builder = new StringBuilder();
int cursor = 0;
Matcher matcher = PATH_PARAM_PATTERN.matcher(path);
boolean found = matcher.find();
while (found) {
String stringBeforeMatch = path.substring(cursor, matcher.start());
builder.append(stringBeforeMatch);
String group = matcher.group().substring(1, matcher.group().length() - 1);
group = camelize(group, true);
builder
.append("{")
.append(group)
.append("}");
cursor = matcher.end();
found = matcher.find();
}
String stringAfterMatch = path.substring(cursor);
builder.append(stringAfterMatch);
return builder.toString();
}
}

View File

@@ -1,265 +0,0 @@
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.CodegenConfig;
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.Model;
import io.swagger.models.Operation;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SwiftGenerator extends DefaultCodegen implements CodegenConfig {
private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
protected String sourceFolder = "Classes/Swaggers";
public SwiftGenerator() {
super();
outputFolder = "generated-code/swift";
modelTemplateFiles.put("model.mustache", ".swift");
apiTemplateFiles.put("api.mustache", ".swift");
templateDir = "swift";
apiPackage = "/APIs";
modelPackage = "/Models";
// Inject application name
String appName = System.getProperty("appName");
if (appName == null) {
appName = "SwaggerClient";
}
additionalProperties.put("projectName", appName);
// Inject base url override
String basePathOverride = System.getProperty("basePathOverride");
if (basePathOverride != null) {
additionalProperties.put("basePathOverride", basePathOverride);
}
sourceFolder = appName + "/" + sourceFolder;
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift"));
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"Int",
"Float",
"Double",
"Bool",
"Void",
"String",
"Character")
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"NSDate",
"Array",
"Dictionary",
"Set",
"Any",
"Empty",
"AnyObject")
);
reservedWords = new HashSet<String>(
Arrays.asList(
"class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue",
"false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else",
"self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if",
"true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol",
"switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional",
"struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol",
"required", "right", "set", "Type", "unowned", "weak")
);
typeMapping = new HashMap<String, String>();
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("date", "NSDate");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "Bool");
typeMapping.put("string", "String");
typeMapping.put("char", "Character");
typeMapping.put("short", "Int");
typeMapping.put("int", "Int");
typeMapping.put("long", "Int");
typeMapping.put("integer", "Int");
typeMapping.put("Integer", "Int");
typeMapping.put("float", "Float");
typeMapping.put("number", "Double");
typeMapping.put("double", "Double");
typeMapping.put("object", "AnyObject");
typeMapping.put("file", "NSData");
importMapping = new HashMap<String, String>();
}
private static String normalizePath(String path) {
StringBuilder builder = new StringBuilder();
int cursor = 0;
Matcher matcher = PATH_PARAM_PATTERN.matcher(path);
boolean found = matcher.find();
while (found) {
String stringBeforeMatch = path.substring(cursor, matcher.start());
builder.append(stringBeforeMatch);
String group = matcher.group().substring(1, matcher.group().length() - 1);
group = camelize(group, true);
builder
.append("{")
.append(group)
.append("}");
cursor = matcher.end();
found = matcher.find();
}
String stringAfterMatch = path.substring(cursor);
builder.append(stringAfterMatch);
return builder.toString();
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "swift";
}
public String getHelp() {
return "Generates a swift client library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar);
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return "[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 toDefaultValue(Property p) {
// nil
return null;
}
@Override
public String toInstantiationType(Property p) {
if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "[String:" + inner + "]";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "[" + inner + "]";
}
return null;
}
@Override
public CodegenProperty fromProperty(String name, Property p) {
CodegenProperty codegenProperty = super.fromProperty(name, p);
if (codegenProperty.isEnum) {
List<Map<String, String>> swiftEnums = new ArrayList<Map<String, String>>();
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("raw", value);
swiftEnums.add(map);
}
codegenProperty.allowableValues.put("values", swiftEnums);
codegenProperty.datatypeWithEnum =
StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length());
}
return codegenProperty;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultAPI";
}
return initialCaps(name) + "API";
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
path = normalizePath(path);
List<Parameter> parameters = operation.getParameters();
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
return super.fromOperation(path, httpMethod, operation, definitions);
}
}

View File

@@ -25,6 +25,8 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig {
protected static String PREFIX = "Sami";
protected Set<String> foundationClasses = new HashSet<String>();
@@ -265,6 +267,11 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
@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");

View File

@@ -0,0 +1,28 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.SupportingFile;
import java.io.File;
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
@Override
public String getName() {
return "typescript-angular";
}
public String getHelp() {
return "Generates a TypeScript AngurlarJS client library.";
}
public TypeScriptAngularClientCodegen() {
super();
outputFolder = "generated-code/typescript-angular";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-Angular";
apiPackage = "API.Client";
modelPackage = "API.Client";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
}
}

View File

@@ -0,0 +1,24 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.SupportingFile;
public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen {
@Override
public String getName() {
return "typescript-node";
}
@Override
public String getHelp() {
return "Generates a TypeScript nodejs client library.";
}
public TypeScriptNodeClientCodegen() {
super();
outputFolder = "generated-code/typescript-node";
templateDir = "TypeScript-node";
supportingFiles.add(new SupportingFile("api.mustache", null, "api.ts"));
}
}

View File

@@ -0,0 +1,291 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
using System.Linq;
using System.Net;
using System.Text;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Extensions;
namespace {{packageName}}.Client
{
/// <summary>
/// API client is mainly responible for making the HTTP call to the API backend.
/// </summary>
public class ApiClient
{
private readonly Dictionary<String, String> _defaultHeaderMap = new Dictionary<String, String>();
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" /> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiClient(String basePath="{{basePath}}")
{
BasePath = basePath;
RestClient = new RestClient(BasePath);
}
/// <summary>
/// Gets or sets the base path.
/// </summary>
/// <value>The base path</value>
public string BasePath { get; set; }
/// <summary>
/// Gets or sets the RestClient.
/// </summary>
/// <value>An instance of the RestClient</value>
public RestClient RestClient { get; set; }
/// <summary>
/// Gets the default header.
/// </summary>
public Dictionary<String, String> DefaultHeader
{
get { return _defaultHeaderMap; }
}
/// <summary>
/// Makes the HTTP request (Sync).
/// </summary>
/// <param name="path">URL path.</param>
/// <param name="method">HTTP method.</param>
/// <param name="queryParams">Query parameters.</param>
/// <param name="postBody">HTTP body (POST request).</param>
/// <param name="headerParams">Header parameters.</param>
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="authSettings">Authentication settings.</param>
/// <returns>Object</returns>
public Object CallApi(String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, String[] authSettings)
{
var request = new RestRequest(path, method);
UpdateParamsForAuth(queryParams, headerParams, authSettings);
// add default header, if any
foreach(var defaultHeader in _defaultHeaderMap)
request.AddHeader(defaultHeader.Key, defaultHeader.Value);
// add header parameter, if any
foreach(var param in headerParams)
request.AddHeader(param.Key, param.Value);
// add query parameter, if any
foreach(var param in queryParams)
request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost);
// add form parameter, if any
foreach(var param in formParams)
request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost);
// add file parameter, if any
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
if (postBody != null) // http body (model) parameter
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
return (Object)RestClient.Execute(request);
}
/// <summary>
/// Add default header.
/// </summary>
/// <param name="key">Header field name.</param>
/// <param name="value">Header field value.</param>
/// <returns></returns>
public void AddDefaultHeader(string key, string value)
{
_defaultHeaderMap.Add(key, value);
}
/// <summary>
/// Escape string (url-encoded).
/// </summary>
/// <param name="str">String to be escaped.</param>
/// <returns>Escaped string.</returns>
public string EscapeString(string str)
{
return RestSharp.Contrib.HttpUtility.UrlEncode(str);
}
/// <summary>
/// Create FileParameter based on Stream.
/// </summary>
/// <param name="name">Parameter name.</param>
/// <param name="stream">Input stream.</param>
/// <returns>FileParameter.</returns>
public FileParameter ParameterToFile(string name, Stream stream)
{
if (stream is FileStream)
return FileParameter.Create(name, stream.ReadAsBytes(), Path.GetFileName(((FileStream)stream).Name));
else
return FileParameter.Create(name, stream.ReadAsBytes(), "no_file_name_provided");
}
/// <summary>
/// If parameter is DateTime, output in ISO8601 format.
/// If parameter is a list of string, join the list with ",".
/// Otherwise just return the string.
/// </summary>
/// <param name="obj">The parameter (header, path, query, form).</param>
/// <returns>Formatted string.</returns>
public string ParameterToString(object obj)
{
if (obj is DateTime)
return ((DateTime)obj).ToString ("u");
else if (obj is List<string>)
return String.Join(",", (obj as List<string>).ToArray());
else
return Convert.ToString (obj);
}
/// <summary>
/// Deserialize the JSON string into a proper object.
/// </summary>
/// <param name="content">HTTP body (e.g. string, JSON).</param>
/// <param name="type">Object type.</param>
/// <returns>Object representation of the JSON string.</returns>
public object Deserialize(string content, Type type, IList<Parameter> headers=null)
{
if (type == typeof(Object)) // return an object
{
return content;
}
if (type == typeof(Stream))
{
var filePath = String.IsNullOrEmpty(Configuration.TempFolderPath)
? Path.GetTempPath()
: Configuration.TempFolderPath;
var fileName = filePath + Guid.NewGuid();
if (headers != null)
{
var regex = new Regex(@"Content-Disposition:.*filename=['""]?([^'""\s]+)['""]?$");
var match = regex.Match(headers.ToString());
if (match.Success)
fileName = filePath + match.Value.Replace("\"", "").Replace("'", "");
}
File.WriteAllText(fileName, content);
return new FileStream(fileName, FileMode.Open);
}
if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object
{
return DateTime.Parse(content, null, System.Globalization.DateTimeStyles.RoundtripKind);
}
if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type
{
return ConvertType(content, type);
}
// at this point, it must be a model (json)
try
{
return JsonConvert.DeserializeObject(content, type);
}
catch (IOException e)
{
throw new ApiException(500, e.Message);
}
}
/// <summary>
/// Serialize an object into JSON string.
/// </summary>
/// <param name="obj">Object.</param>
/// <returns>JSON string.</returns>
public string Serialize(object obj)
{
try
{
return obj != null ? JsonConvert.SerializeObject(obj) : null;
}
catch (Exception e)
{
throw new ApiException(500, e.Message);
}
}
/// <summary>
/// Get the API key with prefix.
/// </summary>
/// <param name="apiKeyIdentifier">API key identifier (authentication scheme).</param>
/// <returns>API key with prefix.</returns>
public string GetApiKeyWithPrefix (string apiKeyIdentifier)
{
var apiKeyValue = "";
Configuration.ApiKey.TryGetValue (apiKeyIdentifier, out apiKeyValue);
var apiKeyPrefix = "";
if (Configuration.ApiKeyPrefix.TryGetValue (apiKeyIdentifier, out apiKeyPrefix))
return apiKeyPrefix + " " + apiKeyValue;
else
return apiKeyValue;
}
/// <summary>
/// Update parameters based on authentication.
/// </summary>
/// <param name="queryParams">Query parameters.</param>
/// <param name="headerParams">Header parameters.</param>
/// <param name="authSettings">Authentication settings.</param>
public void UpdateParamsForAuth(Dictionary<String, String> queryParams, Dictionary<String, String> headerParams, string[] authSettings)
{
if (authSettings == null || authSettings.Length == 0)
return;
foreach (string auth in authSettings)
{
// determine which one to use
switch(auth)
{
{{#authMethods}}
case "{{name}}":
{{#isApiKey}}{{#isKeyInHeader}}headerParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInHeader}}{{#isKeyInQuery}}queryParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}headerParams["Authorization"] = "Basic " + Base64Encode(Configuration.Username + ":" + Configuration.Password);{{/isBasic}}
{{#isOAuth}}//TODO support oauth{{/isOAuth}}
break;
{{/authMethods}}
default:
//TODO show warning about security definition not found
break;
}
}
}
/// <summary>
/// Encode string in base64 format.
/// </summary>
/// <param name="text">String to be encoded.</param>
/// <returns>Encoded string.</returns>
public static string Base64Encode(string text)
{
var textByte = System.Text.Encoding.UTF8.GetBytes(text);
return System.Convert.ToBase64String(textByte);
}
/// <summary>
/// Dynamically cast the object into target type.
/// Ref: http://stackoverflow.com/questions/4925718/c-dynamic-runtime-cast
/// </summary>
/// <param name="source">Object to be casted</param>
/// <param name="dest">Target type</param>
/// <returns>Casted object</returns>
public static Object ConvertType(Object source, Type dest) {
return Convert.ChangeType(source, dest);
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
namespace {{packageName}}.Client {
/// <summary>
/// API Exception
/// </summary>
public class ApiException : Exception {
/// <summary>
/// Gets or sets the error code (HTTP status code)
/// </summary>
/// <value>The error code (HTTP status code).</value>
public int ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error content (body json object)
/// </summary>
/// <value>The error content (Http response body).</value>
public Object ErrorContent { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiException() {}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
public ApiException(int errorCode, string message) : base(message) {
this.ErrorCode = errorCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
/// <param name="errorContent">Error content.</param>
public ApiException(int errorCode, string message, Object errorContent = null) : base(message) {
this.ErrorCode = errorCode;
this.ErrorContent = errorContent;
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace {{packageName}}.Client
{
/// <summary>
/// Represents a set of configuration settings
/// </summary>
public class Configuration
{
/// <summary>
/// Version of the package.
/// </summary>
/// <value>Version of the package.</value>
public const string Version = "{{packageVersion}}";
/// <summary>
/// Gets or sets the default API client for making HTTP calls.
/// </summary>
/// <value>The API client.</value>
public static ApiClient DefaultApiClient = new ApiClient();
/// <summary>
/// Gets or sets the username (HTTP basic authentication).
/// </summary>
/// <value>The username.</value>
public static String Username { get; set; }
/// <summary>
/// Gets or sets the password (HTTP basic authentication).
/// </summary>
/// <value>The password.</value>
public static String Password { get; set; }
/// <summary>
/// Gets or sets the API key based on the authentication name.
/// </summary>
/// <value>The API key.</value>
public static Dictionary<String, String> ApiKey = new Dictionary<String, String>();
/// <summary>
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
/// </summary>
/// <value>The prefix of the API key.</value>
public static Dictionary<String, String> ApiKeyPrefix = new Dictionary<String, String>();
private static string _tempFolderPath = Path.GetTempPath();
/// <summary>
/// Gets or sets the temporary folder path to store the files downloaded from the server.
/// </summary>
/// <value>Folder path.</value>
public static String TempFolderPath
{
get { return _tempFolderPath; }
set
{
if (String.IsNullOrEmpty(value))
{
_tempFolderPath = value;
return;
}
// create the directory if it does not exist
if (!Directory.Exists(value))
Directory.CreateDirectory(value);
// check if the path contains directory separator at the end
if (value[value.Length - 1] == Path.DirectorySeparatorChar)
_tempFolderPath = value;
else
_tempFolderPath = value + Path.DirectorySeparatorChar;
}
}
/// <summary>
/// Returns a string with essential information for debugging.
/// </summary>
public static String ToDebugReport()
{
String report = "C# SDK ({{packageName}}) Debug Report:\n";
report += " OS: " + Environment.OSVersion + "\n";
report += " .NET Framework Version: " + Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Where(x => x.Name == "System.Core").First().Version.ToString() + "\n";
report += " Version of the API: {{version}}\n";
report += " SDK Package Version: {{packageVersion}}\n";
return report;
}
}
}

View File

@@ -0,0 +1,10 @@
# Csharp-DotNet2
This generator creates C# code targeting the .Net 2.0 framework. The resulting DLLs can be used in places where .Net 2.0 is the maximum supported version, such as in the Unity3d.
## Dependencies
- Mono compiler
- Note: NuGet is downloaded by the mono compilation script and packages are installed with it. No dependency DLLs are bundled with this generator.

View File

@@ -0,0 +1,127 @@
using System;
using System.IO;
using System.Collections.Generic;
using RestSharp;
using {{packageName}}.Client;
{{#hasImport}}using {{packageName}}.Model;
{{/hasImport}}
namespace {{packageName}}.Api
{
{{#operations}}
public interface I{{classname}}
{
{{#operation}}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
}
/// <summary>
/// Represents a collection of functions to interact with the API endpoints
/// </summary>
public class {{classname}} : I{{classname}}
{
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <param name="apiClient"> an instance of ApiClient (optional)</param>
/// <returns></returns>
public {{classname}}(ApiClient apiClient = null)
{
if (apiClient == null) // use the default one in Configuration
this.ApiClient = Configuration.DefaultApiClient;
else
this.ApiClient = apiClient;
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <returns></returns>
public {{classname}}(String basePath)
{
this.ApiClient = new ApiClient(basePath);
}
/// <summary>
/// Sets the base path of the API client.
/// </summary>
/// <param name="basePath">The base path</param>
/// <value>The base path</value>
public void SetBasePath(String basePath)
{
this.ApiClient.BasePath = basePath;
}
/// <summary>
/// Gets the base path of the API client.
/// </summary>
/// <param name="basePath">The base path</param>
/// <value>The base path</value>
public String GetBasePath(String basePath)
{
return this.ApiClient.BasePath;
}
/// <summary>
/// Gets or sets the API client.
/// </summary>
/// <value>An instance of the ApiClient</param>
public ApiClient ApiClient {get; set;}
{{#operation}}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
{{/required}}{{/allParams}}
var path = "{{path}}";
path = path.Replace("{format}", "json");
{{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", ApiClient.ParameterToString({{{paramName}}}));
{{/pathParams}}
var queryParams = new Dictionary<String, String>();
var headerParams = new Dictionary<String, String>();
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter
{{/queryParams}}
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter
{{/headerParams}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}}
{{#bodyParam}}postBody = ApiClient.Serialize({{paramName}}); // http body (model) parameter
{{/bodyParam}}
// authentication setting, if any
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
// make the HTTP request
IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
if (((int)response.StatusCode) >= 400)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
else if (((int)response.StatusCode) == 0)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.ErrorMessage, response.ErrorMessage);
{{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}), response.Headers);{{/returnType}}{{^returnType}}return;{{/returnType}}
}
{{/operation}}
}
{{/operations}}
}

View File

@@ -0,0 +1,12 @@
wget -nc https://nuget.org/nuget.exe;
mozroots --import --sync
mono nuget.exe install vendor/packages.config -o vendor;
mkdir -p bin;
mcs -sdk:2 -r:vendor/Newtonsoft.Json.7.0.1/lib/net20/Newtonsoft.Json.dll,\
vendor/RestSharp.Net2.1.1.11/lib/net20/RestSharp.Net2.dll,\
System.Runtime.Serialization.dll \
-target:library \
-out:bin/{{packageName}}.dll \
-recurse:src/*.cs \
-doc:bin/{{packageName}}.xml \
-platform:anycpu

View File

@@ -0,0 +1,53 @@
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
{{#models}}
{{#model}}
namespace {{packageName}}.Model {
/// <summary>
/// {{description}}
/// </summary>
[DataContract]
public class {{classname}}{{#parent}} : {{{parent}}}{{/parent}} {
{{#vars}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
/// </summary>{{#description}}
/// <value>{{{description}}}</value>{{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue=false)]
[JsonProperty(PropertyName = "{{baseName}}")]
public {{{datatype}}} {{name}} { get; set; }
{{/vars}}
/// <summary>
/// Get the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
public override string ToString() {
var sb = new StringBuilder();
sb.Append("class {{classname}} {\n");
{{#vars}}
sb.Append(" {{name}}: ").Append({{name}}).Append("\n");
{{/vars}}
sb.Append("}\n");
return sb.ToString();
}
/// <summary>
/// Get the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public {{#parent}} new {{/parent}}string ToJson() {
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
{{/model}}
{{/models}}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp.Net2" version="1.1.11" targetFramework="net20" developmentDependency="true" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net20" developmentDependency="true" />
</packages>

View File

@@ -1,17 +1,14 @@
package {{invokerPackage}};
import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.api.client.WebResource.Builder;
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.file.FileDataBodyPart;
import javax.ws.rs.core.Response.Status.Family;
import javax.ws.rs.core.MediaType;
@@ -22,12 +19,14 @@ 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.net.URLEncoder;
import java.io.IOException;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
@@ -39,11 +38,13 @@ import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
private Map<String, Client> hostMap = new HashMap<String, Client>();
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private boolean debugging = false;
private String basePath = "{{basePath}}";
private JSON json = new JSON();
private Map<String, Authentication> authentications;
@@ -238,6 +239,62 @@ public class ApiClient {
}
}
/*
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;
@@ -280,50 +337,38 @@ public class ApiClient {
}
/**
* Deserialize the given JSON string to Java object.
*
* @param json The JSON string
* @param containerType The container type, one of "list", "array" or ""
* @param cls The type of the Java object
* @return The deserialized Java object
* Serialize the given Java object into string according the given
* Content-Type (only JSON is supported for now).
*/
public Object deserialize(String json, String containerType, Class cls) throws ApiException {
if(null != containerType) {
containerType = containerType.toLowerCase();
}
try{
if("list".equals(containerType) || "array".equals(containerType)) {
JavaType typeInfo = JsonUtil.getJsonMapper().getTypeFactory().constructCollectionType(List.class, cls);
List response = (List<?>) JsonUtil.getJsonMapper().readValue(json, typeInfo);
return response;
}
else if(String.class.equals(cls)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1)
return json.substring(1, json.length() - 2);
else
return json;
}
else {
return JsonUtil.getJsonMapper().readValue(json, cls);
}
}
catch (IOException e) {
throw new ApiException(500, e.getMessage(), null, json);
public String serialize(Object obj, String contentType) throws ApiException {
if (contentType.startsWith("application/json")) {
return json.serialize(obj);
} else {
throw new ApiException(400, "can not serialize object into Content-Type: " + contentType);
}
}
/**
* Serialize the given Java object into JSON string.
* Deserialize response body to Java object according to the Content-Type.
*/
public String serialize(Object obj) throws ApiException {
try {
if (obj != null)
return JsonUtil.getJsonMapper().writeValueAsString(obj);
else
return null;
}
catch (Exception e) {
throw new ApiException(500, e.getMessage());
public <T> T deserialize(ClientResponse response, TypeRef returnType) throws ApiException {
String contentType = null;
List<String> contentTypes = response.getHeaders().get("Content-Type");
if (contentTypes != null && !contentTypes.isEmpty())
contentType = contentTypes.get(0);
if (contentType == null)
throw new ApiException(500, "missing Content-Type in response");
String body;
if (response.hasEntity())
body = (String) response.getEntity(String.class);
else
body = "";
if (contentType.startsWith("application/json")) {
return json.deserialize(body, returnType);
} else {
throw new ApiException(500, "can not deserialize Content-Type: " + contentType);
}
}
@@ -339,25 +384,28 @@ public class ApiClient {
* @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 String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
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 {
updateParamsForAuth(authNames, queryParams, headerParams);
Client client = getClient();
StringBuilder b = new StringBuilder();
for(String key : queryParams.keySet()) {
String value = queryParams.get(key);
if (value != null){
if(b.toString().length() == 0)
b.append("?");
else
b.append("?");
if (queryParams != null){
for (Pair queryParam : queryParams){
if (!queryParam.getName().isEmpty()) {
b.append(escapeString(queryParam.getName()));
b.append("=");
b.append(escapeString(queryParam.getValue()));
b.append("&");
b.append(escapeString(key)).append("=").append(escapeString(value));
}
}
}
String querystring = b.toString();
String querystring = b.substring(0, b.length() - 1);
Builder builder;
if (accept == null)
@@ -365,90 +413,89 @@ public class ApiClient {
else
builder = client.resource(basePath + path + querystring).accept(accept);
for(String key : headerParams.keySet()) {
for (String key : headerParams.keySet()) {
builder = builder.header(key, headerParams.get(key));
}
for(String key : defaultHeaderMap.keySet()) {
if(!headerParams.containsKey(key)) {
for (String key : defaultHeaderMap.keySet()) {
if (!headerParams.containsKey(key)) {
builder = builder.header(key, defaultHeaderMap.get(key));
}
}
String encodedFormParams = null;
if (contentType.startsWith("multipart/form-data")) {
FormDataMultiPart mp = new FormDataMultiPart();
for (Entry<String, Object> param: formParams.entrySet()) {
if (param.getValue() instanceof File) {
File file = (File) param.getValue();
mp.field(param.getKey(), file.getName());
mp.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.MULTIPART_FORM_DATA_TYPE));
} else {
mp.field(param.getKey(), parameterToString(param.getValue()), MediaType.MULTIPART_FORM_DATA_TYPE);
}
}
body = mp;
} else if (contentType.startsWith("application/x-www-form-urlencoded")) {
encodedFormParams = this.getXWWWFormUrlencodedParams(formParams);
}
ClientResponse response = null;
if("GET".equals(method)) {
if ("GET".equals(method)) {
response = (ClientResponse) builder.get(ClientResponse.class);
}
else if ("POST".equals(method)) {
if (contentType.startsWith("application/x-www-form-urlencoded")) {
String encodedFormParams = this
.getXWWWFormUrlencodedParams(formParams);
response = builder.type(contentType).post(ClientResponse.class,
encodedFormParams);
} else if ("POST".equals(method)) {
if (encodedFormParams != null) {
response = builder.type(contentType).post(ClientResponse.class, encodedFormParams);
} else if (body == null) {
response = builder.post(ClientResponse.class, null);
} else if(body instanceof FormDataMultiPart) {
} else if (body instanceof FormDataMultiPart) {
response = builder.type(contentType).post(ClientResponse.class, body);
}
else
response = builder.type(contentType).post(ClientResponse.class, serialize(body));
}
else if ("PUT".equals(method)) {
if ("application/x-www-form-urlencoded".equals(contentType)) {
String encodedFormParams = this
.getXWWWFormUrlencodedParams(formParams);
response = builder.type(contentType).put(ClientResponse.class,
encodedFormParams);
} else if(body == null) {
response = builder.put(ClientResponse.class, serialize(body));
} else {
response = builder.type(contentType).put(ClientResponse.class, serialize(body));
response = builder.type(contentType).post(ClientResponse.class, serialize(body, contentType));
}
}
else if ("DELETE".equals(method)) {
if ("application/x-www-form-urlencoded".equals(contentType)) {
String encodedFormParams = this
.getXWWWFormUrlencodedParams(formParams);
response = builder.type(contentType).delete(ClientResponse.class,
encodedFormParams);
} else if ("PUT".equals(method)) {
if (encodedFormParams != null) {
response = builder.type(contentType).put(ClientResponse.class, encodedFormParams);
} else if(body == null) {
response = builder.put(ClientResponse.class, serialize(body, contentType));
} else {
response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType));
}
} else if ("DELETE".equals(method)) {
if (encodedFormParams != null) {
response = builder.type(contentType).delete(ClientResponse.class, encodedFormParams);
} else if(body == null) {
response = builder.delete(ClientResponse.class);
} else {
response = builder.type(contentType).delete(ClientResponse.class, serialize(body));
response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType));
}
}
else {
} else {
throw new ApiException(500, "unknown method type " + method);
}
if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) {
if (response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) {
return null;
}
else if(response.getClientResponseStatus().getFamily() == Family.SUCCESSFUL) {
if(response.hasEntity()) {
return (String) response.getEntity(String.class);
}
else {
return "";
}
}
else {
} else if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
if (returnType == null)
return null;
else
return deserialize(response, returnType);
} else {
String message = "error";
String respBody = null;
if(response.hasEntity()) {
try{
if (response.hasEntity()) {
try {
respBody = String.valueOf(response.getEntity(String.class));
message = respBody;
}
catch (RuntimeException e) {
} catch (RuntimeException e) {
// e.printStackTrace();
}
}
throw new ApiException(
response.getClientResponseStatus().getStatusCode(),
message,
response.getHeaders(),
respBody);
response.getStatusInfo().getStatusCode(),
message,
response.getHeaders(),
respBody);
}
}
@@ -457,7 +504,7 @@ public class ApiClient {
*
* @param authNames The authentications to apply
*/
private void updateParamsForAuth(String[] authNames, Map<String, String> queryParams, Map<String, String> headerParams) {
private 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);
@@ -468,15 +515,14 @@ public class ApiClient {
/**
* Encode the given form parameters as request body.
*/
private String getXWWWFormUrlencodedParams(Map<String, String> formParams) {
private String getXWWWFormUrlencodedParams(Map<String, Object> formParams) {
StringBuilder formParamBuilder = new StringBuilder();
for (Entry<String, String> param : formParams.entrySet()) {
String keyStr = parameterToString(param.getKey());
for (Entry<String, Object> param : formParams.entrySet()) {
String keyStr = param.getKey();
String valueStr = parameterToString(param.getValue());
try {
formParamBuilder.append(URLEncoder.encode(keyStr, "utf8"))
formParamBuilder.append(URLEncoder.encode(param.getKey(), "utf8"))
.append("=")
.append(URLEncoder.encode(valueStr, "utf8"));
formParamBuilder.append("&");
@@ -484,11 +530,12 @@ public class ApiClient {
// move on to next
}
}
String encodedFormParams = formParamBuilder.toString();
if (encodedFormParams.endsWith("&")) {
encodedFormParams = encodedFormParams.substring(0,
encodedFormParams.length() - 1);
encodedFormParams = encodedFormParams.substring(0, encodedFormParams.length() - 1);
}
return encodedFormParams;
}

View File

@@ -1,5 +1,6 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class Configuration {
private static ApiClient defaultApiClient = new ApiClient();

View File

@@ -0,0 +1,52 @@
package {{invokerPackage}};
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.joda.*;
import java.io.IOException;
{{>generatedAnnotation}}
public class JSON {
private ObjectMapper mapper;
public JSON() {
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.registerModule(new JodaModule());
}
/**
* Serialize the given Java object into JSON string.
*/
public String serialize(Object obj) throws ApiException {
try {
if (obj != null)
return mapper.writeValueAsString(obj);
else
return null;
} catch (Exception e) {
throw new ApiException(400, e.getMessage());
}
}
/**
* 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, TypeRef returnType) throws ApiException {
JavaType javaType = mapper.constructType(returnType.getType());
try {
return mapper.readValue(body, javaType);
} catch (IOException e) {
if (returnType.getType().equals(String.class))
return (T) body;
else
throw new ApiException(500, e.getMessage(), null, body);
}
}
}

View File

@@ -1,23 +0,0 @@
package {{invokerPackage}};
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.datatype.joda.*;
public class JsonUtil {
public static ObjectMapper mapper;
static {
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.registerModule(new JodaModule());
}
public static ObjectMapper getJsonMapper() {
return mapper;
}
}

View File

@@ -0,0 +1,39 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class Pair {
private String name = "";
private String value = "";
public Pair (String name, String value) {
setName(name);
setValue(value);
}
private void setName(String name) {
if (!isValidString(name)) return;
this.name = name;
}
private void setValue(String value) {
if (!isValidString(value)) return;
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
private boolean isValidString(String arg) {
if (arg == null) return false;
if (arg.trim().isEmpty()) return false;
return true;
}
}

View File

@@ -1,5 +1,6 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class StringUtil {
/**
* Check if the given array contains the given value (with case-insensitive comparison).

View File

@@ -0,0 +1,26 @@
package {{invokerPackage}};
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
{{>generatedAnnotation}}
public class TypeRef<T> {
private final Type type;
public TypeRef() {
this.type = getGenericType(getClass());
}
private static Type getGenericType(Class<?> klass) {
Type superclass = klass.getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("No type parameter provided");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return parameterized.getActualTypeArguments()[0];
}
public Type getType() {
return type;
}
}

View File

@@ -3,6 +3,8 @@ package {{package}};
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;
import {{invokerPackage}}.TypeRef;
import {{modelPackage}}.*;
@@ -11,33 +13,29 @@ import java.util.*;
{{#imports}}import {{import}};
{{/imports}}
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.file.FileDataBodyPart;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.util.Map;
import java.util.HashMap;
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
private ApiClient apiClient;
private ApiClient {{localVariablePrefix}}apiClient;
public {{classname}}() {
this(Configuration.getDefaultApiClient());
}
public {{classname}}(ApiClient apiClient) {
this.apiClient = apiClient;
this.{{localVariablePrefix}}apiClient = apiClient;
}
public ApiClient getApiClient() {
return apiClient;
return {{localVariablePrefix}}apiClient;
}
public void setApiClient(ApiClient apiClient) {
this.apiClient = apiClient;
this.{{localVariablePrefix}}apiClient = apiClient;
}
{{#operation}}
@@ -48,7 +46,7 @@ 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 postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
@@ -57,68 +55,43 @@ public class {{classname}} {
{{/required}}{{/allParams}}
// create path and map variables
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
String {{localVariablePrefix}}path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params
Map<String, String> queryParams = new HashMap<String, String>();
Map<String, String> headerParams = new HashMap<String, String>();
Map<String, String> formParams = new HashMap<String, String>();
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>();
{{#queryParams}}if ({{paramName}} != null)
queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
{{#queryParams}}
{{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
{{/queryParams}}
{{#headerParams}}if ({{paramName}} != null)
headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
{{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));
{{/headerParams}}
final String[] accepts = {
{{#formParams}}if ({{paramName}} != null)
{{localVariablePrefix}}formParams.put("{{baseName}}", {{paramName}});
{{/formParams}}
final String[] {{localVariablePrefix}}accepts = {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
final String accept = apiClient.selectHeaderAccept(accepts);
final String {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts);
final String[] contentTypes = {
final String[] {{localVariablePrefix}}contentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
final String contentType = apiClient.selectHeaderContentType(contentTypes);
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
if(contentType.startsWith("multipart/form-data")) {
boolean hasFields = false;
FormDataMultiPart mp = new FormDataMultiPart();
{{#formParams}}{{#notFile}}
if ({{paramName}} != null) {
hasFields = true;
mp.field("{{baseName}}", apiClient.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
}
{{/notFile}}{{#isFile}}
if ({{paramName}} != null) {
hasFields = true;
mp.field("{{baseName}}", {{paramName}}.getName());
mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE));
}
{{/isFile}}{{/formParams}}
if(hasFields)
postBody = mp;
}
else {
{{#formParams}}{{#notFile}}if ({{paramName}} != null)
formParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));{{/notFile}}
{{/formParams}}
}
try {
String[] authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
if(response != null){
return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
}
else {
return {{#returnType}}null{{/returnType}};
}
} catch (ApiException ex) {
throw ex;
}
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}}
}

View File

@@ -3,6 +3,7 @@ package {{invokerPackage}};
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public class ApiException extends Exception {
private int code = 0;
private String message = null;

View File

@@ -1,7 +1,11 @@
package {{invokerPackage}}.auth;
import java.util.Map;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public class ApiKeyAuth implements Authentication {
private final String location;
private final String paramName;
@@ -39,7 +43,7 @@ public class ApiKeyAuth implements Authentication {
}
@Override
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
String value;
if (apiKeyPrefix != null) {
value = apiKeyPrefix + " " + apiKey;
@@ -47,7 +51,7 @@ public class ApiKeyAuth implements Authentication {
value = apiKey;
}
if (location == "query") {
queryParams.put(paramName, value);
queryParams.add(new Pair(paramName, value));
} else if (location == "header") {
headerParams.put(paramName, value);
}

View File

@@ -1,8 +1,12 @@
package {{invokerPackage}}.auth;
import java.util.Map;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public interface Authentication {
/** Apply authentication settings to header and query params. */
void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams);
void applyToParams(List<Pair> queryParams, Map<String, String> headerParams);
}

View File

@@ -1,10 +1,14 @@
package {{invokerPackage}}.auth;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
import java.io.UnsupportedEncodingException;
import javax.xml.bind.DatatypeConverter;
{{>generatedAnnotation}}
public class HttpBasicAuth implements Authentication {
private String username;
private String password;
@@ -26,7 +30,7 @@ public class HttpBasicAuth implements Authentication {
}
@Override
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
try {
headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8")));

View File

@@ -1,10 +1,14 @@
package {{invokerPackage}}.auth;
import java.util.Map;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public class OAuth implements Authentication {
@Override
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
// TODO: support oauth
}
}

View File

@@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@@ -0,0 +1,534 @@
package {{invokerPackage}};
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
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.net.URLEncoder;
import java.io.IOException;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import {{invokerPackage}}.auth.Authentication;
import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
private Map<String, Client> hostMap = new HashMap<String, Client>();
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private boolean debugging = false;
private String basePath = "{{basePath}}";
private JSON json = new JSON();
private Map<String, Authentication> authentications;
private DateFormat dateFormat;
public ApiClient() {
// Use ISO 8601 format for date and datetime.
// See https://en.wikipedia.org/wiki/ISO_8601
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
// Use UTC as the default time zone.
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
// 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;
}
/**
* 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;
}
/**
* 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;
}
/**
* Get the date format used to parse/format date parameters.
*/
public DateFormat getDateFormat() {
return dateFormat;
}
/**
* Set the date format used to parse/format date parameters.
*/
public ApiClient getDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
return this;
}
/**
* Parse the given string into Date object.
*/
public Date parseDate(String str) {
try {
return dateFormat.parse(str);
} catch (java.text.ParseException e) {
throw new RuntimeException(e);
}
}
/**
* Format the given Date object into string.
*/
public String formatDate(Date date) {
return dateFormat.format(date);
}
/**
* Format the given parameter object into string.
*/
public String parameterToString(Object param) {
if (param == null) {
return "";
} else if (param instanceof Date) {
return formatDate((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;
}
}
/**
* Serialize the given Java object into string entity according the given
* Content-Type (only JSON is supported for now).
*/
public Entity<String> serialize(Object obj, String contentType) throws ApiException {
if (contentType.startsWith("application/json")) {
return Entity.json(json.serialize(obj));
} else {
throw new ApiException(400, "can not serialize object into Content-Type: " + contentType);
}
}
/**
* Deserialize response body to Java object according to the Content-Type.
*/
public <T> T deserialize(Response response, TypeRef returnType) throws ApiException {
String contentType = null;
List<Object> contentTypes = response.getHeaders().get("Content-Type");
if (contentTypes != null && !contentTypes.isEmpty())
contentType = String.valueOf(contentTypes.get(0));
if (contentType == null)
throw new ApiException(500, "missing Content-Type in response");
String body;
if (response.hasEntity())
body = (String) response.readEntity(String.class);
else
body = "";
if (contentType.startsWith("application/json")) {
return json.deserialize(body, returnType);
} else {
throw new ApiException(500, "can not deserialize Content-Type: " + contentType);
}
}
/**
* 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 {
updateParamsForAuth(authNames, queryParams, headerParams);
final ClientConfig clientConfig = new ClientConfig();
clientConfig.register(MultiPartFeature.class);
if (debugging) {
clientConfig.register(LoggingFilter.class);
}
Client client = ClientBuilder.newClient(clientConfig);
WebTarget target = client.target(this.basePath).path(path);
if (queryParams != null) {
for (Pair queryParam : queryParams) {
if (queryParam.getValue() != null) {
target = target.queryParam(queryParam.getName(), queryParam.getValue());
}
}
}
Invocation.Builder invocationBuilder = target.request(contentType).accept(accept);
for (String key : headerParams.keySet()) {
String value = headerParams.get(key);
if (value != null) {
invocationBuilder = invocationBuilder.header(key, value);
}
}
for (String key : defaultHeaderMap.keySet()) {
if (!headerParams.containsKey(key)) {
String value = defaultHeaderMap.get(key);
if (value != null) {
invocationBuilder = invocationBuilder.header(key, value);
}
}
}
Entity<?> formEntity = null;
if (contentType.startsWith("multipart/form-data")) {
MultiPart multipart = new MultiPart();
for (Entry<String, Object> param: formParams.entrySet()) {
if (param.getValue() instanceof File) {
File file = (File) param.getValue();
FormDataMultiPart mp = new FormDataMultiPart();
mp.bodyPart(new FormDataBodyPart(param.getKey(), file.getName()));
multipart.bodyPart(mp, MediaType.MULTIPART_FORM_DATA_TYPE);
multipart.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.APPLICATION_OCTET_STREAM_TYPE));
} else {
FormDataMultiPart mp = new FormDataMultiPart();
mp.bodyPart(new FormDataBodyPart(param.getKey(), parameterToString(param.getValue())));
multipart.bodyPart(mp, MediaType.MULTIPART_FORM_DATA_TYPE);
}
}
formEntity = Entity.entity(multipart, MediaType.MULTIPART_FORM_DATA_TYPE);
} else if (contentType.startsWith("application/x-www-form-urlencoded")) {
Form form = new Form();
for (Entry<String, Object> param: formParams.entrySet()) {
form.param(param.getKey(), parameterToString(param.getValue()));
}
formEntity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
}
Response response = null;
if ("GET".equals(method)) {
response = invocationBuilder.get();
} else if ("POST".equals(method)) {
if (formEntity != null) {
response = invocationBuilder.post(formEntity);
} else if (body == null) {
response = invocationBuilder.post(null);
} else {
response = invocationBuilder.post(serialize(body, contentType));
}
} else if ("PUT".equals(method)) {
if (formEntity != null) {
response = invocationBuilder.put(formEntity);
} else if (body == null) {
response = invocationBuilder.put(null);
} else {
response = invocationBuilder.put(serialize(body, contentType));
}
} else if ("DELETE".equals(method)) {
response = invocationBuilder.delete();
} else {
throw new ApiException(500, "unknown method type " + method);
}
if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
return null;
} else if (response.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL)) {
if (returnType == null)
return null;
else
return deserialize(response, returnType);
} else {
String message = "error";
String respBody = null;
if (response.hasEntity()) {
try {
respBody = String.valueOf(response.readEntity(String.class));
message = respBody;
} catch (RuntimeException e) {
// 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,
respBody);
}
}
/**
* Update query and header parameters based on authentication settings.
*
* @param authNames The authentications to apply
*/
private 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);
}
}
}

View File

@@ -0,0 +1,171 @@
<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>
<!-- HTTP client: jersey-client -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey-version}</version>
</dependency>
<!-- JSON processing: jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime-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>
<jersey-version>2.6</jersey-version>
<jackson-version>2.4.2</jackson-version>
<jodatime-version>2.3</jodatime-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.8.1</junit-version>
</properties>
</project>

View File

@@ -3,6 +3,9 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#serializableModel}}
import java.io.Serializable;{{/serializableModel}}
import io.swagger.annotations.*;
import com.fasterxml.jackson.annotation.JsonProperty;
{{#models}}
@@ -12,13 +15,17 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{>generatedAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
{{#vars}}{{#isEnum}}
public enum {{datatypeWithEnum}} {
{{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}}
};{{/isEnum}}{{#items.isEnum}}{{#items}}
public enum {{datatypeWithEnum}} {
{{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}}
};
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{^isEnum}}
private {{{datatype}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{/vars}}
{{/items}}{{/items.isEnum}}
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/vars}}
{{#vars}}
/**{{#description}}

View File

@@ -112,6 +112,8 @@
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
<!-- HTTP client: jersey-client -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
@@ -122,6 +124,8 @@
<artifactId>jersey-multipart</artifactId>
<version>${jersey-version}</version>
</dependency>
<!-- JSON processing: jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
@@ -141,7 +145,7 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.1.5</version>
</dependency>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>

View File

@@ -0,0 +1,8 @@
# Swagger Inflector
Run with
```
mvn package jetty:run
``

View File

@@ -0,0 +1,27 @@
package {{invokerPackage}};
import io.swagger.inflector.models.RequestContext;
import io.swagger.inflector.models.ResponseContext;
import javax.ws.rs.core.Response.Status;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import java.io.File;
import java.util.List;
import {{modelPackage}}.*;
{{#imports}}import {{import}};
{{/imports}}
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
{{#operation}}
public ResponseContext {{nickname}}(RequestContext request {{#allParams}}, {{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{/allParams}}) {
return new ResponseContext().status(Status.INTERNAL_SERVER_ERROR).entity( "Not implemented" );
}
{{/operation}}
}
{{/operations}}

View File

@@ -0,0 +1 @@
{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}

View File

@@ -0,0 +1 @@
{{#isFormParam}}{{#notFile}}{{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}FormDataContentDisposition fileDetail{{/isFile}}{{/isFormParam}}

View File

@@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@@ -0,0 +1 @@
{{#isHeaderParam}}{{{dataType}}} {{paramName}}{{/isHeaderParam}}

View File

@@ -0,0 +1,6 @@
controllerPackage: {{invokerPackage}}
modelPackage: {{modelPackage}}
swaggerUrl: ./src/main/swagger/swagger.json
modelMappings:
{{#models}}{{#model}}{{classname}} : {{modelPackage}}.{{classname}}{{/model}}
{{/models}}

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