Compare commits

...

144 Commits

Author SHA1 Message Date
akihito.nakano
1641e5f60b Update samples 2019-02-04 19:45:36 +09:00
akihito.nakano
376e1bacac Run bin/openapi3/go-petstore.sh 2019-02-04 19:27:00 +09:00
akihito.nakano
f498681c68 Fix output folder (openapi3) 2019-02-04 19:26:25 +09:00
akihito.nakano
2a09e8f90f Add sample script for OAS3 2019-02-04 19:18:59 +09:00
akihito.nakano
7037ca88ee Add "nullable" to fake yaml 2019-02-04 19:15:05 +09:00
Alex Korobko
b63242219c Issue 1766 Modified mustache files for Go to support nullable in the spec v3.0+; Updated model files running .sh scripts for Go. 2019-01-09 16:22:20 -05:00
Sebastian Rühl
faf1f5d81d [BUG-1848] Remove redundant right parenthesis (#1864) 2019-01-10 02:33:16 +08:00
Jérémie Bresson
d584833781 Support for "x-enum-descriptions" (#1752) 2019-01-10 00:47:55 +08:00
William Cheng
992ca3e8ed Merge branch 'master' of https://github.com/OpenAPITools/openapi-generator 2019-01-09 23:49:50 +08:00
William Cheng
12a5ba2bee add new sample files 2019-01-09 23:49:34 +08:00
William Cheng
814a697c81 Add a checklist to issue report (#1851) 2019-01-09 10:14:56 +01:00
sunn
3b7f4c3879 Fix typo in template (#1859) 2019-01-09 16:13:10 +08:00
William Cheng
b87a507a13 update samples 2019-01-09 15:57:31 +08:00
Hemant Zope
87d5484f2e add isModel to updatebooleanflagwithcodegenproperty (#1844) 2019-01-09 11:22:51 +08:00
William Cheng
581bac83e9 Merge branch 'master' of https://github.com/OpenAPITools/openapi-generator 2019-01-09 11:19:48 +08:00
William Cheng
8539831126 Merge remote-tracking branch 'origin/restore_c_test' 2019-01-09 11:19:21 +08:00
Justin Black
539ec23298 [python-client] Add model default values (#1776)
* Adds two models to the v2.0 spec, uses examples as defaults in python client

* Adds array default and type_holder_default and type_holder_example tests

* Re-generated python security client with ./bin/security/python-petstore.sh

* Changes comment text, rebased master

* Updates client + server samples

* Adds missing samples updates

* Changes python client to look for true or false with booleans in toDefaultValue

* Changes boolean casting to use Boolean.valueOf

* Adds deserialization fix for python tests

* Changes Mock to namedtuple in python deserialization tests

* Actually remove unittest.mock
2019-01-09 11:18:35 +08:00
Daisuke Shimada
189849319c fix: force to decode as utf-8 when header contains application/json to avoid text garbling. (#1700)
* fix: force to decode as utf-8 when header contains application/json to avoid text garbling.

The original processing is using `response.body` to deserialize as json.
However, this is decoded by latin1 if the header contains only "application/json" instead of "application/json; charset=utf-8".

Because of this behavior, if the response body is encoded UTF-8 but the headers doesn't contain charset, the body will garbling.

cf: https://github.com/dart-lang/http/issues/175

Since playframework 2.6 returns "Content-Type: application/json" without "charset=utf-8", I changed this parsing algolithm.

* fix: force to decode as utf-8 when header contains application/json to avoid text garbling on error.
2019-01-09 11:08:35 +08:00
William Cheng
60dd3d51be Better support for composed schema (allOf) (#1842)
* better support for composed schema

* remove commented code
2019-01-09 10:50:02 +08:00
Adrian Price
4c14c85542 Add additional properties to Java CodegenModel (#1854)
Fixes the first part of https://github.com/OpenAPITools/openapi-generator/pull/1729#issuecomment-451991109 (see https://github.com/OpenAPITools/openapi-generator/pull/1729#issuecomment-449937728). The second part was fixed by https://github.com/OpenAPITools/openapi-generator/pull/1845 (commit d65dd763d8).
2019-01-09 10:49:43 +08:00
FallenRiteMonk
9331df791f Minor Angular type improvements (#1843)
Update api.service.mustache

update samples
2019-01-09 00:30:37 +08:00
d3v-cl
9ccf872290 [DART] fix: set fields to null if json value is null. (#1798)
* fix: set fields to null if json value is null.

* rebuild dart2 petstore

* rebuild dart petstore

* rebuild petstore

* [DART]fix: set fields to null if json value is null.
2019-01-09 00:26:46 +08:00
William Cheng
293066bb0d add options to maven plugin (#1845) 2019-01-08 21:32:51 +08:00
William Cheng
fbf570e7bd fix unqiue name in handling forward slash (#1839) 2019-01-08 07:51:25 +08:00
William Cheng
ed5bd5ffb0 better handle of oauth (#1838) 2019-01-08 07:51:02 +08:00
Hemant Zope
233ce093e5 [C] Support for authentication methods (#1628)
* added auth support in apiClient

* added httperror response in detail

* added apikey to apiClient create

* remove unnecessary print statements

* remove freeing of apiclient object from apiclient_free function

* added auth params to apiClient_free function

* free only received data and apiClient object to be freed by user
2019-01-07 23:31:42 +08:00
William Cheng
b7971e2e3d better error message when parameter ref not defined (#1837) 2019-01-08 00:29:13 +09:00
William Cheng
1ef56b44c2 Add links to articles about openapi generator 2019-01-07 22:54:43 +08:00
William Cheng
22a3f7ee0e Add a link to @watiko article 2019-01-07 22:45:46 +08:00
Akihito Nakano
6e4556772c Delete langs command (#1836)
* Delete langs command

* Delete "langs" from docker entrypoint script

* langs -> list

* langs -> list
2019-01-07 08:57:05 -05:00
William Cheng
549197cce5 restore c test 2019-01-07 19:01:00 +08:00
William Cheng
60776b8cb5 deprecated initialCaps (#1821) 2019-01-07 17:47:07 +08:00
sredbull
eff0c5e8d0 Added proper error response (#1814) 2019-01-07 12:19:50 +08:00
sredbull
1189362466 [JavaScript] Added plugins variable for the javascript/ES6 client (#1797)
* Added plugins variable for the javascript/ES6 client

* Ran the javascript and javascript-es6 shell script
2019-01-07 12:18:03 +08:00
William Cheng
f0f214743e Use JS ES6 as the default (#1825)
* set JS ES6 as the default

* update doc
2019-01-07 11:43:11 +08:00
sunn
651395d426 Update base class due to failed compilation in case of plain object type with no properties or additionalProperties specified (#1826) 2019-01-06 18:20:23 +01:00
sunn
fda35ea263 Fix missing const keyword in array and maps (#1828) 2019-01-06 18:19:08 +01:00
sunn
c65ef987af Emit worker also in response signal (#1829) 2019-01-06 18:18:20 +01:00
William Cheng
b015ac9307 use 4-space instead of tab in perl templates (#1830) 2019-01-07 00:22:24 +08:00
Akihito Nakano
bdf32775fb Add test cases for ExampleGenerator (#1802)
* Add test case : generateFromResponseSchemaWithArrayOfModel

* Add test case : generateFromResponseSchemaWithArrayOfPrimitiveTypes

* Add test case : generateFromResponseSchemaWithModel

* Add test case : generateFromResponseSchemaWithNoExample

* Use String.format for windows

* Specify locale to prevent issues due to locale
2019-01-06 13:27:27 +09:00
William Cheng
1a2deb016b Fix security issue with dependencies (#1820)
* fix security issue with dependency

* update samples

* update pom and sample
2019-01-05 23:30:59 +08:00
William Cheng
b25eeebf03 Update Elixir technical committee 2019-01-05 19:18:49 +08:00
William Cheng
8f561f1ef3 [C#][Refactor] Fix nullable required property in the constructor (#1819)
* add serialization test, fix nulllable reuqired

* remove vs folder
2019-01-05 18:54:29 +08:00
Marco
b931da2909 [java][webclient] Register Jackson modules on ObjectMapper (#911)
* [java][webclient] register jackson modules on object mapper

* Regenerate client

* Removed findAndRegisterModules() call

* ObjectMapper is initialized only if NOT provided by client

* Remove (now) useless DateFormat inside buildWebClient signature and regenerate client
2019-01-05 18:29:49 +08:00
Yuriy Belenko
fa9bd1f567 [Slim] Add ApiKey and OAuth authentication middleware (#1207)
* [Slim] Add fork of token middleware

This commit will be dropped, when official repo approves submitted PRs.
Right now it's for test purposes only.

* [Slim] Adds token middleware to template

* [Slim] Move auth implementation to external classes

* [Slim] Update readme

* [Slim] Add config example

* [Slim] Remove deprecated package

Considered to use dyorg/slim-token-authentication for all authentication
schemes. User needs to decode and parse Basic token himself, but it's
pretty simple task and there are many code examples in
the web. Most of time solution is two lines of code.

* [Slim] Format phpdoc comments

I've changed PHP version to 7 and updated comments to follow  main
recommendations. Used PHPCodesniffer rules are Generic.Commenting,
Squiz.Commenting, PEAR.Commenting. Of course I applied only reasonable
sniffs from this standards.

@category tag has been deleted as deprecated accordingly to
phpDocumentor offical docs.

Ref: http://docs.phpdoc.org/references/phpdoc/tags/category.html

* [Slim] Refresh samples
2019-01-05 11:32:23 +09:00
William Cheng
d35f4b08d9 Fix various typos in the templates (Ruby, C#) (#1803)
* Fix typos

* update petstore samples
2019-01-05 09:39:10 +08:00
Erik Timmers
be262384cd Change renamed user @trenneman to @eriktim (#1809) 2019-01-04 11:49:50 +08:00
William Cheng
5729ce176c Add GenFlow to the company/project list (#1806) 2019-01-04 00:39:41 +08:00
William Cheng
3d59d8b58f Add GenFlow to the company/project list 2019-01-03 22:31:10 +08:00
Tomer Cohen
59db7cc568 remove unnecessary words from migration-from-swagger-codegen.md (#1791)
Removed 'an existing '.
2019-01-03 18:53:58 +08:00
William Cheng
ad5184efc1 Add process utils class to add index to properties (#1796)
* add process utils to add index to properties

* fix javadoc warning
2019-01-03 16:06:22 +08:00
William Cheng
92db181d97 Fix Shippable CI (#1799)
* comment out apt-get update

* test php slim in travis

* comment out php verison check
2019-01-03 16:04:35 +08:00
Jim Schubert
8fd474d4a7 [gradle-plugin] Fix test, ensure tests run in CI (#1789)
* Update GenerateTaskDslTest to remove "Pets" array model which is no longer generated
* Ensure check on uploadArchives task
2019-01-02 17:15:01 +08:00
Akihito Nakano
af6757ccde Refactor InlineModelResolver (#1788)
* Extract a method "flattenPaths" to reduce the scope of method

* Tweak

* Rename parameter name

* Extract a method "flattenModels" to reduce the scope of method

* Rename parameter name

* Rename: models -> components

* Delete comment

* Extract a method "flattenRequestBody" to reduce the scope of method

* Extract a method "flattenParameters" to reduce the scope of method

* Extract a method "flattenResponses" to reduce the scope of method

* Tweak types

* Reduce indentation
2019-01-02 17:14:34 +08:00
Akihito Nakano
9334dd391a Improve test codes of InlineModelResolver (#1787)
* Delete unnecessary "throws"

* Delete unnecessary cast expressions

* Tweak redundant assertions

* Delete unnecessary comment
2019-01-01 13:14:23 +09:00
Akihito Nakano
d6fa9e60c6 Add test case for InlineModelResolver: arbitrary models (#1786)
* Add test case : arbitraryObjectModelInline

* Delete legacy test case : testArbitraryObjectModelInline

* Add test case : arbitraryObjectModelWithArrayInlineWithoutTitle

* Delete legacy test case : testArbitraryObjectModelWithArrayInlineWithoutTitle

* Add test case : arbitraryObjectModelWithArrayInlineWithTitle

* Delete legacy test case :
testArbitraryObjectModelWithArrayInlineWithTitle

* Add test case : emptyExampleOnStringTypeModels

* Delete legacy test case : testEmptyExampleOnStrinngTypeModels
2019-01-01 11:51:20 +09:00
Akihito Nakano
6abb9ddf30 Add test case for InlineModelResolver: arbitrary response (#1785)
* Add test case : arbitraryObjectResponse

* Delete legacy test case : testArbitraryObjectResponse

* Add test case : arbitraryObjectResponseArray

* Delete legacy test case : testArbitraryObjectResponseArray

* Add test case : arbitraryObjectResponseArrayInline

* Delete legacy test case : testArbitraryObjectResponseArrayInline

* Add test case : arbitraryObjectResponseWithAdditionalProperty

* Delete legacy test case : testArbitraryObjectResponseMapInline
2019-01-01 10:27:52 +09:00
Akihito Nakano
e559474880 Add test case for InlineModelResolver: arbitrary request body (#1784)
* Uncomment a valid test case

* Add test case : inline request body with title

* Delete legacy test case

* Delete unused import

* Delete legacy test case which is already implemented by other test

see InlineModelResolverTest#resolveInlineArrayResponseWithTitle()

* Delete legacy test case which is covered by other test

* Add test case : arbitraryObjectBodyParam

* Delete legacy test case : testArbitraryObjectBodyParam

* Add test case : arbitraryObjectRequestBodyProperty

* Delete legacy test case : testArbitraryObjectBodyParamInline

* Add test case : arbitraryRequestBodyArray

* Delete legacy test case : testArbitraryObjectBodyParamWithArray

* Add test case : arbitraryRequestBodyArrayProperty

* Delete legacy test case
2019-01-01 07:28:29 +09:00
Akihito Nakano
354db2f3e6 Fix: Inline models can't be generated (#1768)
* Add a test case

* Fix that the inline models couldn't be flatten when "components" doesn't exist

* Rename yaml file

* Rename method name
2018-12-31 17:00:28 +08:00
Akihito Nakano
f96e64bd9e Add test case for InlineModelResolver: inline object response with additionalProperties (#1781)
* Add test case : inline object response with additionalProperties

* Delete legacy test case
2018-12-31 14:36:30 +08:00
William Cheng
3ec90a86cb Add an option to generate the alias (map, array) as model (#1729)
* add option to generate alias as model

* fix issue due to incorrect merge
2018-12-31 11:59:58 +08:00
William Cheng
2f6381cb19 Add nullable support to C# client (refactor) (#1775)
* add nullable support to c# client (refactor)

* clean up methods

* move typemapping to constructor
2018-12-31 10:44:02 +08:00
Akihito Nakano
5730f6224a Delete unused method (#1744)
* Delete unused method

* Delete unused property "typeMapping"

* Delete unused "import" declaration
2018-12-31 10:10:07 +08:00
Christophe Bornet
0fca90133c Use JsonNullable wrapper on nullable/x-nullable fields (#1762)
* Use JsonNullable wrapper on nullable/x-nullable fields

Fix #1250

* update samples
2018-12-31 10:04:26 +08:00
William Cheng
2c051f265c Add an option to use reflection in equals, hashCode (Java client) (#1767)
* add option to use reflection in equals, hashcode (java)

* add model test template to java client only

* update pestore samples

* update java samples

* update doc

* update usage, remove unused file
2018-12-31 10:03:05 +08:00
Yuriy Belenko
e8ac630ca5 [Slim] Encode path to support non-latin characters (#1687)
* [Slim] Add encodePath method

* [Slim] Add tests for encodePath method

* [Slim] Use unescaped path in router

Both variables basePathWithoutHost and path are already urlEncoded in
codegen itself. Builtin html encoding in mustache is redundant. We can
use these raw codegen values with no fear.

* [Slim] Refresh samples
2018-12-31 10:02:45 +08:00
Erik Timmers
a0e5b74b2b [elm] Add support for sending headers (#1704) 2018-12-31 09:58:45 +08:00
Akihito Nakano
321416e960 Add test case for InlineModelResolver: inline array response (#1778)
* Add test case : inline array response

* Add test case : inline array response with title

* Delete legacy test cases
2018-12-30 17:53:36 +09:00
William Cheng
2e727f6dc7 fix group parameter logic (#1779) 2018-12-30 16:50:21 +08:00
Akihito Nakano
7cee999543 Add test case for InlineModelResolver: inline array request body (#1777)
* Add test case : inline array request body

* Delete legacy test case

* Tweak code format

* Delete unused import
2018-12-30 12:12:50 +09:00
Akihito Nakano
77b5cea518 Add test case for InlineModelResolver: inline array schema (#1772)
* Add test case

* Delete legacy test case

* Add a test case: inline array schema

* Delete legacy test case

* Fix test yaml
2018-12-30 10:32:02 +09:00
Akihito Nakano
6a4f3385d8 Fix type inference error (#1773)
* Fix type inference error

* Update samples

bin/openapi3/kotlin-client-petstore.sh
bin/kotlin-client-petstore.sh

* Update samples
2018-12-29 12:14:34 -05:00
William Cheng
e821a58fd1 skip default value for contaier in spring (#1725) 2018-12-29 18:50:10 +08:00
Yuriy Belenko
5400a7e445 [Slim] Add PHP CodeSniffer config template (#1764)
* [Slim] Add PHP_CodeSniffer config template

* [Slim] Update doc

* [Slim] Add local configs to gitignore

PHPUnit and PHP_CodeSniffer provides the same developing pattern when
user overrides global config with local one. In local config he can
set environment variables. Official doc recommends to not commit local
config files.

* [Slim] Remove phpcsStandard CLI option

Now user have full freedom to override config file. This option is not
used and not necessary anymore.

* [Slim] Refresh samples
2018-12-29 15:58:15 +09:00
William Cheng
1db105b6f9 Use CompareNetObject for object comparison in C# client (refactor) (#1765)
* add pet, array of array test, use CompareNetObject for comparision

* add an option, should trigger ci failure

* update doc

* use useCompareNetObjects in csharp-refactor petstore

* fix project template
2018-12-29 14:45:49 +08:00
Akihito Nakano
06a67ce6e4 Add test case for InlineModelResolver (#1771)
* Add a test case of resolving inline request body

* Delete legacy test case

* Add a test case of resolve inline request body with required

* Delete legacy test case
2018-12-29 14:38:46 +09:00
Christophe Bornet
5952bec6bf Add online gen tests (#1759) 2018-12-28 14:18:43 +08:00
Akihito Nakano
5f2d79b669 Resolve inline models before preprocess (#1761) 2018-12-28 11:13:30 +08:00
William Cheng
177deb918a better handling of allOf (composition) (#1757) 2018-12-27 16:01:18 +08:00
Akihito Nakano
5d98fc6beb Fix UUID support (#1746)
* Add custom type adapter to deserialize UUID

* Update samples

./bin/kotlin-client-threetenbp.sh
./bin/kotlin-client-string.sh
./bin/kotlin-client-petstore.sh
2018-12-27 08:59:57 +09:00
Daiki Matsudate
292d987f15 Use appInfo.version for podspec (#1760) 2018-12-27 00:19:29 +08:00
Daiki Matsudate
c2273a651a [Swift 4] Add createURLRequest method (#1727)
* add create URL Request method

* add comment
2018-12-27 00:19:11 +08:00
William Cheng
902a4b4099 remove self-reference import (#1758) 2018-12-26 18:11:26 +08:00
Daiki Matsudate
c13e089c85 [swift4] Use RequestBuilder directly for RxSwift and PromiseKit (#1718)
* remove default implementation

* avoid insert blank lines
2018-12-26 18:01:26 +08:00
William Cheng
c62a1f11ee maven dep version update (#1754) 2018-12-26 10:53:53 +08:00
Akihito Nakano
aa1cfd81fe Minor fixes for InlineModelResolver (#1756)
* Delete unused methods

* Improve access modifiers declaration

* InlineModelResolver#flatten can be package-private

* Delete unused import declaration

* Sort properties
2018-12-26 10:53:39 +08:00
William Cheng
e4f80dcc0e various fix for free-form object (#1751) 2018-12-26 10:38:07 +08:00
William Cheng
120c0a05f0 Restore Ruby tests after parser update (#1753)
* uncomment ruby test after parser update

* remove comment
2018-12-26 10:36:58 +08:00
zigen
7595baef00 Fix composed oneof type 1749 (#1750)
* add test to check that DefaultCodegen generates composed oneof schema properly

* fix composed-oneof type generation bug (#1749)
2018-12-24 17:46:42 +08:00
William Cheng
0dee995ebb Fix discriminator name not following variable naming convention (#1742)
* fix discrimintator name not following variable naming convention

* fix test

* update samples

* use discriminator name directly in php

* single quote array index
2018-12-24 10:17:43 +08:00
tanmen
aed2c882da add nullable support to typescript-axios (#1743) 2018-12-24 00:59:13 +08:00
Jim Schubert
92badd8d49 [kotlin-spring] Allow DateTime to be remapped to others (LocalDateTIme) (#1740) 2018-12-24 00:34:47 +08:00
Yuriy Belenko
72dcee9d86 [Slim] Abstract API controllers (#1483)
* [Slim] Add abstract prefix to API controllers

* [Slim] Add userClassname property to codegen

* [Slim] Add src folder to Composer autoload

* [Slim] Change template to produce abstract controllers

* [Slim] Update API tests template

* [Slim] Add implementation note

* [Slim] Remove deprecated AbstractApiController

* [Slim] Refresh samples
2018-12-23 23:51:26 +08:00
Akihito Nakano
f1831533d4 [Java] Update dependencies (#1735)
* Update retrofit2

refs:
https://nvd.nist.gov/vuln/detail/CVE-2018-1000850
https://nvd.nist.gov/vuln/detail/CVE-2018-1000844

* Update samples

./bin/java-petstore-all.sh

* Implement okhttp3.Call#timeout

refs https://github.com/square/okhttp/pull/4363

* Update samples

./bin/java-petstore-all.sh

* Update Play26CallFactory

* Fix indent
2018-12-23 19:03:50 +08:00
Akihito Nakano
05107032d1 Fix missing closing parenthesis (#1739)
* Add a script to generate kotlin client samples from OAS3

* Generate kotlin client

* Fix missing closing parenthesis

* Update samples

* Add build folder to gitignore
2018-12-23 09:54:51 +09:00
William Cheng
2ccfdc8e5d Add C# client (refactor) to Appveyor CI (#1738)
* add c# client (refactor) to CI

* fix typo
2018-12-23 08:08:05 +08:00
Jim Schubert
13f5064ea4 Update auto-labeler.yml (#1741)
Change wording about reviewing the labels, so it doesn't sound like the user should apply labels (they can't).
2018-12-23 08:07:11 +08:00
William Cheng
667275fb25 Fix C# client warnings (#1737)
* fix csharp warnings

* fix incorrect line break removal
2018-12-23 08:06:55 +08:00
Jérémie Bresson
a7dfc650b6 Swagger parser update: 2.0.8-OpenAPITools.org-1 (#1721)
* Update Swagger-Parser Version

* Update samples

* surpress javadoc warning

* fix TS tests

* Set version to 2.0.8-OpenAPITools.org-1
2018-12-22 18:12:08 +08:00
Steven Masala
43abd61144 Typescript nullable (#1730)
* fix name sanitation when using kebab case filenaming

* remove whitespaces

* nullable

* remove test comment
2018-12-22 16:49:44 +08:00
William Cheng
2a11f55267 Re-enable the rust reqwest client test 2018-12-22 16:30:19 +08:00
William Cheng
77edec0c65 Revert "[Rust] Support formParams and fix list-params." (#1732)
* Revert "Disable rust-reqwest petstore test"

This reverts commit 9e1cce2e7b.

* Revert "Fix various CI issues (#1722)"

This reverts commit 77270a0118.

* Revert "[Rust] Support formParams and fix list-params. (#1678)"

This reverts commit 4a494b45d3.
2018-12-22 16:28:55 +08:00
William Cheng
9e1cce2e7b Disable rust-reqwest petstore test 2018-12-21 10:52:58 +08:00
William Cheng
77270a0118 Fix various CI issues (#1722)
* fix shippable failure

* fix warning in javadoc, test ruby in shippable

* update mvn command

* move ruby test to circleci

* remove additional option
2018-12-21 10:16:31 +08:00
Marco Farrugia
4a494b45d3 [Rust] Support formParams and fix list-params. (#1678)
* [Rust] Support formParams and fix list-params.

Form params were previously unsupported, and list-params would produce code that didn't compile.

* update rust samples
2018-12-21 10:08:00 +08:00
Jim Schubert
10ecc0e52f [csharp-refactor] Minor csharp refactor changes (#1723)
* [csharp-refactor] Minor changes to JSON mime usage

🐎 This maeks the regex static to reduce GC overhead for active clients.
This also removes the lowercase call on the mimetype before evaluating,
as the regex already uses the inline modifier for case insensitivity.

* [csharp-refactor] Regenerate sample
2018-12-21 09:57:38 +08:00
Tomasz Prus
89a0ffa66c feat: [python/asyncio] use ssl argument instead of ssl_context (deprecated from aiohttp>=3.0.0) (#1724) 2018-12-21 09:52:27 +08:00
Jérémie Bresson
d38b9e588b [core] support for 'x-enum-varnames' for enums in arrays (#1703) 2018-12-20 16:30:34 +01:00
William Cheng
b6e80e86b2 Add nullable support to JAXRS-CXF parameters (#1679)
* add nullable support to jaxrs cxf parameters

* remove end of file line break

* fix default value for list

* update samples
2018-12-20 16:07:45 +08:00
William Cheng
f188fa08e5 fix enum and map of neum (regression) (#1706) 2018-12-20 16:07:22 +08:00
William Cheng
93c13074ff various fixes to csharp refactor client (#1711) 2018-12-20 16:06:29 +08:00
Daiki Matsudate
9ff8a24895 fix description (#1710) 2018-12-20 15:55:29 +08:00
gndrm
98ae7a816c Introduced GeneratorProperties as a thread-safe clone of System Properties (#1598)
* Introduced GeneratorProperties as a thread-safe clone of System Properties

* Removed unnecessary SmartBear copyright
2018-12-19 21:46:05 +08:00
Jim Schubert
2025d128b3 Creating regex for our generators which will allow the bot to au… (#1639)
* WIP: creating regex for our generators which will allow the bot to automatically label issues and PRs

* Include additional WIP regex

* Remainder of implemented generators

* Add tests for regex in auto labeling
2018-12-17 17:56:00 +08:00
William Cheng
81cf611aa4 add nullable support to perl api parameter (#1690) 2018-12-17 17:11:23 +08:00
William Cheng
d7d994620c Add multiple inheritance support to Perl client (#1681)
* add multiple inheritance support to perl client

* remove allof test from fake petstore
2018-12-17 15:28:20 +08:00
William Cheng
b6a23986b3 fix java instantiated lists (#1683) 2018-12-17 14:42:04 +08:00
Joe Elliott
33fbd9c78b [Swift] Updates for Swift 4.2 (#1443)
* [Swift] Update Alamofire version and update tests and Swift version to 4.2 for default and RxSwift variants

* Update promiseKit for Swift 4.0

* Update project files.

* Merge branch 'master' of https://github.com/OpenAPITools/openapi-generator into OpenAPITools-master

# Conflicts:
#	samples/client/petstore/swift4/default/SwaggerClientTests/SwaggerClient.xcodeproj/project.pbxproj

* Merge in latest master

* Remove typo in bash file
2018-12-17 15:41:06 +09:00
Yuriy Belenko
3896821d5e [Slim] Add phplint cache to gitignore (#1686)
* [Slim] Add phplint cache to gitignore

* [Slim] Refresh samples
2018-12-17 14:21:39 +08:00
William Cheng
fb15a4baf3 [core] Update parser and core to latest version (#1569)
* Update swagger-parser to 2.0.7
* Update swagger-core to 2.0.6
2018-12-17 06:56:46 +01:00
William Cheng
c05dc24e6a Mark swift3 generator as deprecated (#1675)
* mark swift3 as deprecated

* update windows batch scripts
2018-12-16 19:20:37 +08:00
David Cloutier
06150767f4 Proposed fix for issues #1654. fix isSerializable for java jaxrs-cxf (#1656)
* Update model.mustache

fix serializable import for cxf-cdi

* Update pojo.mustache

add implements to the pojo if isSerializable is true

* Update model.mustache

add import statement to fix compile issue when {{#serializableModel}} is true

* Update pojo.mustache

remove extra space to prevent unecessary diffs in petstore examples: diff --git a/samples/server/petstore/jaxrs-cxf/src/gen/java/org/openapitools/model/*
2018-12-15 17:04:45 +08:00
Dec12 | Fujigon
7609398150 Fix the bug header bean validation is not performed (#1661)
* update template

* update template

* update samples
2018-12-15 16:37:25 +08:00
meganemura
82fcde1d91 Improve model class of ruby-client (#1670)
* Add Model.build_from_hash

* Use Model.build_from_hash instead of Model.new.build_from_hash

* Update sample for ruby-client

* Update sample for openapi3 ruby-client
2018-12-15 16:24:03 +08:00
Nicolas Ochem
cacce1f707 fix typo in README (#1677)
Fix typo in README
2018-12-15 16:23:48 +08:00
William Cheng
8c599ebf12 Add support for multiple inheritance (#1664)
* add all parent names

* clean up supportsInheritance

* fix npe

* fix allVars, fix test cases

* add more tests, remove comments

* update docker m2 cache dir, add more tests, fix mandatory

* update samples

* regenerate js spec files

* add logic to detect self reference

* add isSelfReference flag to codegen property

* add ruby tests for cat model

* remove debugging info

* fix JS allvars not have x-js-doctype

* update samples

* update js samples
2018-12-15 00:24:36 +08:00
William Cheng
587bd56655 add mavencentral to build.gradle (#1674) 2018-12-15 00:22:11 +08:00
Jim Schubert
1f95b54cef Include mavenCentral in java build.gradle (#1653)
the android dep is currently missing from jcenter. This adds
mavenCentral as an additional repository to the default java generator's
build.gradle.
2018-12-14 21:23:06 +08:00
ccozzolino
95c744381b [JAVA][Server] Fixed issue #1525: Fix model class field initializations (Regression since 3.3.1) (#1549)
* Fixed issue #1525. Adjust class field declarations with proper initializations.

* Adjusted templates to add default only when it is exists.
2018-12-13 01:11:47 +08:00
Jean-François Côté
0b029088f4 Add Stingray to company using openspi-generator 2018-12-10 09:48:28 -05:00
William Cheng
66cff2b05a fix alias to free form object & map (#1638) 2018-12-10 22:46:41 +08:00
feihongmeilian
489c404783 Add instructions for erlang-server (#1643) 2018-12-10 17:45:19 +08:00
Denis Korenevskiy
a27224e50d [php] bugfix: Array and Map inner schema definition can be missing. (#1586) 2018-12-10 17:43:44 +08:00
William Cheng
98aa5f8db2 add erlang-proper to shippable CI (#1642) 2018-12-10 17:43:00 +08:00
Juan Facorro
87bc9d436f Introduce optional weight function for commands and other improvements (#1618)
* Generator erlang-proper

Used to generate PropEr generators for property-based testing

* Rearrange *_statem.erl functions and remove *_statem.hrl

* Optional weight function

* Optional argument to override generated values

* Export function with arity 1

* Move syntactic sugar to header file

* Only provide body when its allowed

* The weight function should not depend on the state
2018-12-10 11:41:12 +08:00
Jim Schubert
5b91d40a8a Update issue templates (#1636)
This updates issue templates to support auto-labeling, and multiple issue formats.
2018-12-10 11:30:55 +08:00
Akihito Nakano
f19794464b Delete --lang option (#1592)
* Delete --lang option

* Fix -l

* Fix -l flag (windows)

* Add migration guide

* Change to -g

* Remove lang option

* Change to -g
2018-12-09 19:26:51 +09:00
Akihito Nakano
7e3e9dba11 Replace Class.newInstance() with Constructor.newInstance() (#1635) 2018-12-08 22:31:57 +08:00
John Bush
c4f0521e10 Fix escaped regex values in Python client (#1517). (#1539)
* Fix escaped regex values in Python client (#1517).

* Override PythonClientCodegen toRegularExpression() method to correct
  issue with backslashes being escaped. This issue was a result of
  calling escapeText() in the parent DefaultCodegen class.

* Only escape unescaped forward slashes in PythonClientCodegen.

* Override addRegularExpressionDelimiter in PythonClientCodegen.java
  such that only unescaped forward slashes in the pattern get escaped.
* Adds a new test resource .yaml file for specifically testing this
  issue.

* Check for regular expression modifiers in PythonClientCodegen.

* Adds check in postProcessPattern() in PythonClientCodegen.java to
  check if regular expression has modifiers defined. If so, it throws an
  exception as modifiers are not currently supported in the Python
  client.

* PythonClientCodegen warns that regex modifiers are not supported.

* Changes behavior in PythonClientCodegen.java to no longer throw an
  IllegalArgumentException in the case that a pattern contains
  modifiers. A warning message will be logged instead stating that
  modifiers are not currently supported by the codegen class.

* Remove warning for PythonClientCodegen regex modifier support.

* Removes warning message from PythonClientCodegen.java stating that
  regular expression modifiers are not currently supported. Further
  code review and testing revealed that this feature is already
  supported and working.

* Add updated Python client sample files.
2018-12-08 11:32:55 +08:00
Phil Adams
2d39f14882 Fix NPE in ModelUtils.isFreeFormObject() (#1625)
Fixes #1696

An object schema containing no properties that also has additionalProperties
set to an object schema with no properties will cause
ModelUtils.isFreeFormObject to throw an NPE.
This PR adds additional checking to avoid the NPE.
2018-12-07 23:16:58 +08:00
William Cheng
2f4bea6967 remove isNotContainer (#1629) 2018-12-07 23:10:35 +08:00
Akihito Nakano
b84ec60306 Add ASKUL (#1631)
* Add ASKUL

* Update link
2018-12-07 23:05:26 +08:00
Benjamin Gill
2a4fe5bc0e @metaswitch is now using openapi-generator (#1632) 2018-12-07 22:23:53 +09:00
Tomek Cejner
922532da6a [core] Prevent NPE when enpoint did not define responses (#1617) 2018-12-07 11:57:16 +01:00
4477 changed files with 134694 additions and 39437 deletions

117
.github/.test/auto-labeler.js vendored Normal file
View File

@@ -0,0 +1,117 @@
let fs = require('fs');
let path = require('path');
let util = require('util');
let yaml = require('./js-yaml.js');
let samples = require('./samples.json');
class LabelMatch {
constructor (match, label) {
this.match = match;
this.label = label;
}
}
class FileError {
constructor (file, actualLabels, expectedLabels) {
this.file = file;
this.actual = actualLabels;
this.expected = expectedLabels;
}
}
class TextError {
constructor (text, actualLabels, expectedLabels) {
this.text = text;
this.actual = actualLabels;
this.expected = expectedLabels;
}
}
let labels = [];
function labelsForFile(file) {
let body = fs.readFileSync(file);
return labelsForText(body)
}
function labelsForText(text) {
let addLabels = new Set();
let body = text;
for (const v of labels) {
if (v.match.test(body)) {
addLabels.add(v.label)
}
// reset regex state
v.match.lastIndex = 0
}
return addLabels;
}
try {
let config = yaml.safeLoad(fs.readFileSync('../auto-labeler.yml', 'utf8'));
if (config && config.labels && Object.keys(config.labels).length > 0) {
for (const labelName in config.labels) {
if (config.labels.hasOwnProperty(labelName)) {
let matchAgainst = config.labels[labelName];
if (Array.isArray(matchAgainst)) {
matchAgainst.forEach(regex => {
// noinspection JSCheckFunctionSignatures
labels.push(new LabelMatch(new RegExp(regex, 'g'), labelName));
})
}
}
}
}
if (labels.length === 0) {
// noinspection ExceptionCaughtLocallyJS
throw new Error("Expected to parse config.labels, but failed.")
}
let fileErrors = [];
samples.files.forEach(function(tester){
let file = path.normalize(path.join('..', '..', 'bin', tester.input));
let expectedLabels = new Set(tester.matches);
let actualLabels = labelsForFile(file);
let difference = new Set([...actualLabels].filter(x => !expectedLabels.has(x)));
if (difference.size > 0) {
fileErrors.push(new FileError(file, actualLabels, expectedLabels));
}
});
let textErrors = [];
samples.text.forEach(function(tester){
let expectedLabels = new Set(tester.matches);
let actualLabels = labelsForText(tester.input);
let difference = new Set([...actualLabels].filter(x => !expectedLabels.has(x)));
if (difference.size > 0) {
textErrors.push(new TextError(tester.input, actualLabels, expectedLabels));
}
});
// These are separate (file vs text) in case we want to preview where these would fail in the file. not priority at the moment.
if (fileErrors.length > 0) {
console.warn('There were %d file tester errors', fileErrors.length);
fileErrors.forEach(function(errs) {
console.log("file: %j\n actual: %j\n expected: %j", errs.file, util.inspect(errs.actual), util.inspect(errs.expected))
});
}
if (textErrors.length > 0) {
console.warn('There were %d text tester errors', textErrors.length);
textErrors.forEach(function(errs){
console.log("input: %j\n actual: %j\n expected: %j", errs.text, util.inspect(errs.actual), util.inspect(errs.expected))
})
}
let totalErrors = fileErrors.length + textErrors.length;
if (totalErrors === 0) {
console.log('Success!');
} else {
console.log('Failure: %d total errors', totalErrors);
}
} catch (e) {
console.log(e);
}

3917
.github/.test/js-yaml.js vendored Normal file

File diff suppressed because it is too large Load Diff

1292
.github/.test/samples.json vendored Normal file

File diff suppressed because it is too large Load Diff

10
.github/ISSUE_TEMPLATE/announcement.md vendored Normal file
View File

@@ -0,0 +1,10 @@
---
name: Announcement
about: Announcements related to the project
title: "[Announcement] TITLE"
labels: Announcement
assignees: ''
---

62
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,62 @@
---
name: Bug report
about: Create a bug report to help us improve
title: "[BUG] Description"
labels: 'Issue: Bug'
assignees: ''
---
#### Bug Report Checklist
- [ ] Have you provided a full/minimal spec to reproduce the issue?
- [ ] What's the version of OpenAPI Generator used?
- [ ] Have you search for related issues/PRs?
- [ ] What's the actual output vs expected output?
- [ ] [Optional] Bounty to sponsor the fix ([example](https://www.bountysource.com/issues/66123212-javascript-client-produces-a-wrong-object-for-a-string-enum-type-that-is-used-with-ref))
<!--
Please follow the issue template below for bug reports.
Also please indicate in the issue title which language/library is concerned. Eg: [BUG][JAVA] Bug generating foo with bar
-->
##### Description
<!-- describe what is the question, suggestion or issue and why this is a problem for you. -->
##### openapi-generator version
<!-- which version of openapi-generator are you using, is it a regression? -->
##### OpenAPI declaration file content or url
<!-- if it is a bug, a json or yaml that produces it.
If you post the code inline, please wrap it with
```yaml
(here your code)
```
(for YAML code) or
```json
(here your code)
```
(for JSON code), so it becomes more readable. If it is longer than about ten lines,
please create a Gist (https://gist.github.com) or upload it somewhere else and
link it here.
-->
##### Command line used for generation
<!-- including the language, libraries and various options -->
##### Steps to reproduce
<!-- unambiguous set of steps to reproduce the bug.-->
##### Related issues/PRs
<!-- has a similar issue/PR been reported/opened before? Please do a search in https://github.com/openapitools/openapi-generator/issues?utf8=%E2%9C%93&q=is%3Aissue%20 -->
##### Suggest a fix
<!-- if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit), or simply make a suggestion -->

View File

@@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[REQ] Feature Request Description"
labels: 'Enhancement: Feature'
assignees: ''
---
### Is your feature request related to a problem? Please describe.
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
## Describe the solution you'd like
<!-- A clear and concise description of what you want to happen. -->
## Describe alternatives you've considered
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
## Additional context
<!-- Add any other context or screenshots about the feature request here. -->

290
.github/auto-labeler.yml vendored Normal file
View File

@@ -0,0 +1,290 @@
comment: |
👍 Thanks for opening this issue!
🏷 I have applied any labels matching special text in your issue.
The team will review the labels and make any necessary changes.
labels:
'Announcement':
- '\s*?\[[Aa]nnouncement\]\s*?'
'Breaking change (with fallback)':
- '\s*?[bB]reaking [cC]hange [wW]ith [fF]allback\s*?'
'Breaking change (without fallback)':
- '\s*?[bB]reaking [cC]hange [wW]ithout [fF]allback\s*?'
'Client: Ada':
- '\s*?\[ada\]\s*?'
- '\s*?-[gl] ada(?!-)\b'
'Client: Android':
- '\s*?\[android\]\s*?'
- '\s*?-[gl] android(?!-)\b'
'Client: Apex':
- '\s*?\[apex\]\s*?'
- '\s*?-[gl] apex(?!-)\b'
'Client: Bash':
- '\s*?\[bash\]\s*?'
- '\s*?-[gl] bash(?!-)\b'
'Client: C':
- '\s*?\[[cC]\]\s*?'
- '\s*?-[gl] c(?!-)\b'
# 'Client: Ceylon':
'Client: C++':
- '\s*?\[cpp(-.*)?-client\]\s*?'
- '\s*?-[gl] cpp(-.*)?-client\s*?'
- '\s*?-[gl] cpp-restsdk(?!-)\b'
- '\s*?-[gl] cpp-tizen(?!-)\b'
'Client: C-Sharp':
- '\s*?-[gl] csharp(?!-)\b'
- '\s*?[cC]-[sS]harp [cC]lient\s*?'
- '\s*?-[gl] csharp-dotnet2\s*?'
- '\s*?-[gl] csharp-refactor?\s*?'
- '\s*?\[[Cc]#\]'
- '\s*?\[csharp\]\s*?'
'Client: Clojure':
- '\s*?\[clojure\]\s*?'
- '\s*?-[gl] clojure(?!-)\b'
# 'Client: Crystal':
'Client: Dart':
- '\s*?\[dart\]\s*?'
- '\s*?-[gl] dart(?!-)\b'
'Client: Dukescript':
- '\s*?\[dukescript\]\s*?'
- '\s*?-g dukescript\s*?'
'Client: Eiffel':
- '\s*?\[eiffel\]\s*?'
- '\s*?-[gl] eiffel(?!-)\b'
'Client: Elixir':
- '\s*?\[elixir\]\s*?'
- '\s*?-[gl] elixir(?!-)\b'
'Client: Elm':
- '\s*?\[elm\]\s*?'
- '\s*?-[gl] elm(?!-)\b'
'Client: Erlang':
- '\s*?\[erlang(-.*)?-client\]\s*?'
- '\s*?-[gl] erlang(-.*)?-client\s*?'
- '\s*?\[erlang-proper\]\s*?'
- '\s*?-[gl] erlang-proper\s*?'
'Client: Flash/ActionScript':
- '\s*?\[flash\]\s*?'
- '\s*?-[gl] flash(?!-)\b'
'Client: Go':
- '\s*?\[go\]\s*?'
- '\s*?-[gl] go(?!-)\b'
'Client: Groovy':
- '\s*?\[groovy\]\s*?'
- '\s*?-[gl] groovy(?!-)\b'
'Client: HTML':
- '\s*?\[html[2]?\]\s*?'
- '\s*?-[gl] html[2]?\s*?'
'Client: Haskell':
- '\s*?\[haskell(-.*)?-client\]\s*?'
- '\s*?-[gl] haskell(-.*)?-client\s*?'
'Client: JMeter':
- '\s*?\[jmeter\]\s*?'
- '\s*?-[gl] jmeter\s*?'
'Client: Java':
- '\s*?\[java\]\s*?'
- '\s*?-[gl] java(?!-)\b'
'Client: JavaScript/Node.js':
- '\s*?\[javascript\]\s*?'
- '\s*?-[gl] javascript\s*?'
- '\s*?-[gl] javascript-(\S)*\s*?'
# 'Client: Julia': # NOTE: Not yet implemented
'Client: Kotlin':
- '\s*?\[kotlin\]\s*?'
- '\s*?-[gl] kotlin(?!-)\b'
'Client: Lisp':
- '\s*?\[lisp\]\s*?'
- '\s*?-[gl] lisp(?!-)\b'
'Client: Lua':
- '\s*?\[lua\]\s*?'
- '\s*?-[gl] lua(?!-)\b'
'Client: Objc':
- '\s*?\[objc\]\s*?'
- '\s*?-[gl] objc\s*?'
# 'Client: OCaml':
'Client: Perl':
- '\s*?\[perl\]\s*?'
- '\s*?-[gl] perl(?!-)\b'
# 'Client: PHP':
'Client: PowerShell':
- '\s*?\[powershell\]\s*?'
- '\s*?-[gl] powershell\s*?'
'Client: Python':
- '\s*?\[python\]\s*?'
- '\s*?-[gl] python(?!-)\b'
'Client: QT':
- '\s*?\[cpp-qt5-client\]\s*?'
- '\s*?-[gl] cpp-qt5-client\s*?'
'Client: R':
- '\s*?\[[rR]\]\s*?'
- '\s*?-[gl] r(?!-)\b'
'Client: Reason ML':
- '\s*?\[reasonml\]\s*?'
- '\s*?-[g] reasonml\s*?'
'Client: Retrofit':
- '\s*?retrofit.*?\s*?'
'Client: Ruby':
- '\s*?\[ruby\]\s*?'
- '\s*?-[gl] ruby(?!-)\b'
'Client: Rust':
- '\s*?\[rust\]\s*?'
- '\s*?-[gl] rust(?!-)\b'
'Client: Scala':
- '\s*?\[scalaz\]\s*?'
- '\s*?-[gl] scalaz\s*?'
- '\s*?\[scala-(?!finch)[a-z]+\]\b'
- '\s*?-[gl] scala-(?!finch)[a-z]+?(?!-)\b'
'Client: Swift':
- '\s*?\[swift[34]+\]\s*?'
- '\s*?-[gl] swift[34]+\s*?'
- '\s*?-[gl] swift2-deprecated\s*?'
'Client: TypeScript':
- '\s*?\[typescript-[\-a-z]+\]\s*?'
- '\s*?-[gl] typescript-[\-a-z]+\s*?'
# 'Client: VB/VB.net': # NOTE: Not yet implemented
# 'Client: Visual Basic': # TODO: REMOVE UNUSED LABEL
'Config: Apache':
- '\s*?\[apache2\]\s*?'
- '\s*?-[gl] apache2\s*?'
'Docker':
- '\s*?\[docker\]\s*?'
'Documentation: Cwiki':
- '\s*?\[cwiki\]\s*?'
- '\s*?-[gl] cwiki\s*?'
'Documentation: Dynamic HTML':
- '\s*?\[dynamic-html\]\s*?'
- '\s*?-[gl] dynamic-html\s*?'
'Enhancement: CI/Test':
- '\s*?\[ci\]\s*?'
'Enhancement: Code format':
- '\s*?\[format(ting)?\]\s*?'
# 'Enhancement: Compatibility':
'Enhancement: Feature':
- '\s*?\[feat(ure)?s*?'
'Enhancement: General':
- '\s*?\[general\]\s*?'
- '\s*?\[core\]\s*?'
# 'Enhancement: New generator':
'Enhancement: Performance':
- '\s*?\[perf\]\s*?'
# 'Feature List: API clients':
# 'Feature List: API documentations':
# 'Feature List: API servers':
# 'Feature: Authentication':
# 'Feature: Composition / Inheritance':
# 'Feature: Documentation':
# 'Feature: Enum':
# 'Feature: Generator':
'Feature: OAS 3.0 spec support':
- '\s*?\[oas3[\.0]?\]\s*?'
# 'General: Awaiting feedback':
'General: Discussion':
- '\s*?\[discussion\]\s*?'
'General: Question':
- '\s*?\[question\]\s*?'
'General: Suggestion':
- '\s*?\[suggestion\]\s*?'
'General: Support':
- '\s*?\[support\]\s*?'
'Issue: Bug':
- '\s*?\[bug(s)?\]\s*?'
- '\s*?\[fix(es)?\]\s*?'
# 'Issue: Invalid spec':
# 'Issue: Migration':
# 'Issue: Non-operational':
# 'Issue: Platform':
# 'Issue: Regression':
'Issue: Security':
- '\s*?\[security\]\s*?'
# 'Issue: Unable to reproduce':
# 'Issue: Undo changes':
# 'Issue: Usage/Installation':
# 'Issue: Workaround available':
'OpenAPI Generator CLI':
- '\s*?\[cli\]\s*?'
'OpenAPI Generator Gradle Plugin':
- '\s*?\[gradle\]\s*?'
'OpenAPI Generator Maven Plugin':
- '\s*?\[maven\]\s*?'
'OpenAPI Generator Online':
- '\s*?\[online\]\s*?'
'Schema: MySQL':
- '\s*?\[mysql\]\s*?'
- '\s*?-[gl] mysql\s*?'
'Schema: GraphQL':
- '\s*?\[graphql-schema\]\s*?'
- '\s*?-[gl] graphql-schema\s*?'
'Server: Ada':
- '\s*?\[ada(-.*)?-server\]\s*?'
- '\s*?-[gl] ada(-.*)?-server\s*?'
'Server: C++':
- '\s*?\[cpp(-.*)?-server\]\s*?'
- '\s*?-[gl] cpp(-.*)?-server\s*?'
'Server: C-Sharp':
- '\s*?\[aspnetcore\]\s*?'
- '\s*?-[gl] aspnetcore\s*?'
- '\s*?\[csharp-nancyfx\]\s*?'
- '\s*?-[gl] csharp-nancyfx\s*?'
# 'Server: Ceylon': # TODO: REMOVE UNUSED LABEL
'Server: Eiffel':
- '\s*?\[eiffel(-.*)?-server\]\s*?'
- '\s*?-[gl] eiffel(-.*)?-server\s*?'
'Server: Elixir':
- '\s*?\[elixir(-.*)?-server\]\s*?'
- '\s*?-[gl] elixir(-.*)?-server\s*?'
'Server: Erlang':
- '\s*?\[erlang-server\]\s*?'
- '\s*?-[gl] erlang-server\s*?'
'Server: Go':
- '\s*?\[go(-.*)?-server\]\s*?'
- '\s*?-[gl] go(-.*)?-server\s*?'
'Server: GraphQL':
- '\s*?\[graphql(-.*)?-server\]\s*?'
- '\s*?-[gl] graphql(-.*)?-server\s*?'
'Server: Haskell':
- '\s*?\[haskell]\s*?'
- '\s*?-[gl] haskell(?!-)\b'
'Server: Java':
- '\s*?\[java-.*?\]\s*?'
- '\s*?-[gl] java-.*?\s*?'
- '\s*?-[gl] jaxrx-.*?\s*?'
'Server: Kotlin':
- '\s*?\[ktor]\s*?'
- '\s*?\[kotlin-spring]\s*?'
- '\s*?\[kotlin(-.*)?-server\]\s*?'
- '\s*?-[gl] kotlin(-.*)?-server\s*?'
- '\s*?-[gl] kotlin-spring\s*?'
'Server: Nodejs':
- '\s*?\[nodejs(-.*)?-server\]\s*?'
- '\s*?-[gl] nodejs(-.*)?-server\s*?'
'Server: PHP':
- '\s*?\[php-.*?\]\s*?'
- '\s*?-[gl] php-.*?\s*?'
'Server: Perl':
- '\s*?\[perl(-.*)?-server\]\s*?'
- '\s*?-g perl(-.*)?-server\s*?'
'Server: Python':
- '\s*?\[python-.*?\]\s*?'
- '\s*?-[gl] python-.*?\s*?'
'Server: Ruby':
- '\s*?\[ruby-.*?\]\s*?'
- '\s*?-[gl] ruby-.*?\s*?'
'Server: Rust':
- '\s*?\[rust(-.*)?-server\]\s*?'
- '\s*?-[gl] rust(-.*)?-server\s*?'
'Server: Scala':
- '\s*?\[scala(-.*)?-server\]\s*?'
- '\s*?-[gl] scala(-.*)?-server\s*?'
- '\s*?\[scalatra\]\s*?'
- '\s*?-[gl] scalatra\s*?'
- '\s*?\[scala-finch\]\s*?'
- '\s*?-[gl] scala-finch\s*?'
'Server: Spring':
- '\s*?\[spring\]\s*?'
- '\s*?-[g] spring\s*?'
# 'Swagger-Parser':
'WIP':
- '\s*?\[wip\]\s*?'
- '\s*?\[WIP\]\s*?'
- '\bWIP:.*?'
'help wanted':
- '\s*?\[help wanted\]\s*?'

7
.gitignore vendored
View File

@@ -27,6 +27,7 @@ packages/
.packages
.vagrant/
.vscode/
**/.vs
.settings
@@ -128,7 +129,6 @@ samples/client/petstore/swift3/**/SwaggerClientTests/Podfile.lock
# C#
*.csproj.user
samples/client/petstore/csharp/SwaggerClient/IO.Swagger.userprefs
samples/client/petstore/csharp/SwaggerClientTest/.vs
samples/client/petstore/csharp/SwaggerClientTest/obj
samples/client/petstore/csharp/SwaggerClientTest/bin
samples/client/petstore/csharp/SwaggerClientTest/packages
@@ -146,6 +146,8 @@ samples/client/petstore/csharp/SwaggerClient/bin/Debug/
samples/client/petstore/csharp/SwaggerClient/packages
samples/client/petstore/csharp/SwaggerClient/TestResult.xml
samples/client/petstore/csharp/SwaggerClientWithPropertyChanged/IO.Swagger.userprefs
samples/client/petstore/csharp-refactor/OpenAPIClient/TestResult.xml
samples/client/petstore/csharp-refactor/OpenAPIClient/nuget.exe
# Python
*.pyc
@@ -178,6 +180,7 @@ samples/client/petstore/kotlin/src/main/kotlin/test/
samples/client/petstore/kotlin-threetenbp/build
samples/client/petstore/kotlin-string/build
samples/server/petstore/kotlin-server/ktor/build
samples/openapi3/client/petstore/kotlin/build
\?
# haskell
@@ -202,6 +205,8 @@ samples/client/petstore/groovy/build
# erlang
samples/client/petstore/erlang-client/_build/
samples/client/petstore/erlang-client/rebar.lock
samples/client/petstore/erlang-proper/_build/
samples/client/petstore/erlang-proper/rebar.lock
samples/server/petstore/erlang-server/_build/
samples/server/petstore/erlang-server/rebar.lock

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI spec version: 1.0.0
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{19F1DEBC-DE5E-4517-8062-F000CD499087}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Org.OpenAPITools.Test</RootNamespace>
<AssemblyName>Org.OpenAPITools.Test</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<Reference Include="Newtonsoft.Json">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="JsonSubTypes">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\JsonSubTypes.1.5.1\lib\net45\JsonSubTypes.dll</HintPath>
</Reference>
<Reference Include="RestSharp">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\RestSharp.106.5.4\lib\net452\RestSharp.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\..\vendor')">..\..\vendor\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="obj\**" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MsBuildToolsPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\Org.OpenAPITools\Org.OpenAPITools.csproj">
<Project>{321C8C3F-0156-40C1-AE42-D59761FB9B6C}</Project>
<Name>Org.OpenAPITools</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="linux-logo.png" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,70 @@
/*
* OpenAPI Petstore
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package org.openapitools.client.model;
import org.apache.commons.lang3.builder.EqualsBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
/**
* Model tests for ArrayOfArrayOfNumberOnly
*/
public class ArrayOfArrayOfNumberOnlyTest {
private final ArrayOfArrayOfNumberOnly model = new ArrayOfArrayOfNumberOnly();
/**
* Model tests for ArrayOfArrayOfNumberOnly
*/
@Test
public void test() {
// TODO: test ArrayOfArrayOfNumberOnly
}
/**
* Test the property 'arrayArrayNumber'
*/
@Test
public void arrayArrayNumberTest() {
BigDecimal b1 = new BigDecimal("12.3");
BigDecimal b2 = new BigDecimal("5.6");
List<BigDecimal> arrayArrayNumber = new ArrayList<BigDecimal>();
arrayArrayNumber.add(b1);
arrayArrayNumber.add(b2);
model.getArrayArrayNumber().add(arrayArrayNumber);
// create another instance for comparison
BigDecimal b3 = new BigDecimal("12.3");
BigDecimal b4 = new BigDecimal("5.6");
ArrayOfArrayOfNumberOnly model2 = new ArrayOfArrayOfNumberOnly();
List<BigDecimal> arrayArrayNumber2 = new ArrayList<BigDecimal>();
arrayArrayNumber2.add(b1);
arrayArrayNumber2.add(b2);
model2.getArrayArrayNumber().add(arrayArrayNumber2);
Assert.assertTrue(model2.equals(model));
}
}

View File

@@ -0,0 +1,103 @@
/*
* OpenAPI Petstore
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*
* OpenAPI spec version: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package org.openapitools.client.model;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.openapitools.client.model.Category;
import org.openapitools.client.model.Tag;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
/**
* Model tests for Pet
*/
public class PetTest {
private final Pet model = new Pet();
/**
* Model tests for Pet
*/
@Test
public void testPet() {
// test Pet
model.setId(1029L);
model.setName("Dog");
Pet model2 = new Pet();
model2.setId(1029L);
model2.setName("Dog");
Assert.assertTrue(model.equals(model2));
}
/**
* Test the property 'id'
*/
@Test
public void idTest() {
// TODO: test id
}
/**
* Test the property 'category'
*/
@Test
public void categoryTest() {
// TODO: test category
}
/**
* Test the property 'name'
*/
@Test
public void nameTest() {
// TODO: test name
}
/**
* Test the property 'photoUrls'
*/
@Test
public void photoUrlsTest() {
// TODO: test photoUrls
}
/**
* Test the property 'tags'
*/
@Test
public void tagsTest() {
// TODO: test tags
}
/**
* Test the property 'status'
*/
@Test
public void statusTest() {
// TODO: test status
}
}

View File

@@ -27,7 +27,7 @@
:notebook_with_decorative_cover: The eBook [A Beginner's Guide to Code Generation for REST APIs](https://gumroad.com/l/swagger_codegen_beginner) is a good starting point for beginners :notebook_with_decorative_cover:
:warning: If the OpenAPI spec, templates or any input (e.g. options, envirionment variables) is obtained from an untrusted source or environment, please make sure you've reviewed these inputs before using OpenAPI Generator to generate the API client, server stub or documentation to avoid potential security issues (e.g. [code injection](https://en.wikipedia.org/wiki/Code_injection)) :warning:
:warning: If the OpenAPI spec, templates or any input (e.g. options, environment variables) is obtained from an untrusted source or environment, please make sure you've reviewed these inputs before using OpenAPI Generator to generate the API client, server stub or documentation to avoid potential security issues (e.g. [code injection](https://en.wikipedia.org/wiki/Code_injection)) :warning:
:bangbang: Both "OpenAPI Tools" (https://OpenAPITools.org - the parent organization of OpenAPI Generator) and "OpenAPI Generator" are not affiliated with OpenAPI Initiative (OAI) :bangbang:
@@ -425,7 +425,6 @@ SYNOPSIS
[--import-mappings <import mappings>...]
[--instantiation-types <instantiation types>...]
[--invoker-package <invoker package>]
[(-l <language> | --lang <language>)]
[--language-specific-primitives <language specific primitives>...]
[--library <library>] [--log-to-stderr]
[--model-name-prefix <model name prefix>]
@@ -501,16 +500,20 @@ When code is generated from this project, it shall be considered **AS IS** and o
Here are some companies/projects (alphabetical order) using OpenAPI Generator in production. To add your company/project to the list, please visit [README.md](README.md) and click on the icon to edit the page.
- [Angular.Schule](https://angular.schule/)
- [ASKUL](https://www.askul.co.jp)
- [b<>com](https://b-com.com/en)
- [Bithost GmbH](https://www.bithost.ch)
- [Boxever](https://www.boxever.com/)
- [GenFlow](https://github.com/RepreZen/GenFlow)
- [GMO Pepabo](https://pepabo.com/en/)
- [JustStar](https://www.juststarinfo.com)
- [Klarna](https://www.klarna.com/)
- [Metaswitch](https://www.metaswitch.com/)
- [Myworkout](https://myworkout.com)
- [Raiffeisen Schweiz Genossenschaft](https://www.raiffeisen.ch)
- [RepreZen API Studio](https://www.reprezen.com/swagger-openapi-code-generation-api-first-microservices-enterprise-development)
- [REST United](https://restunited.com)
- [Stingray](http://www.stingray.com)
- [Suva](https://www.suva.ch/)
- [Telstra](https://dev.telstra.com)
- [TUI InfoTec GmbH](http://www.tui-infotec.com/)
@@ -527,9 +530,12 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2018/06/27 - [Lessons Learned from Leading an Open-Source Project Supporting 30+ Programming Languages](https://speakerdeck.com/wing328/lessons-learned-from-leading-an-open-source-project-supporting-30-plus-programming-languages) - [William Cheng](https://github.com/wing328) at [LinuxCon + ContainerCon + CloudOpen China 2018](http://bit.ly/2waDKKX)
- 2018/07/19 - [OpenAPI Generator Contribution Quickstart - RingCentral Go SDK](https://medium.com/ringcentral-developers/openapi-generator-for-go-contribution-quickstart-8cc72bf37b53) by [John Wang](https://github.com/grokify)
- 2018/08/22 - [OpenAPI Generatorのプロジェクト構成などのメモ](https://yinm.info/20180822/) by [Yusuke Iinuma](https://github.com/yinm)
- 2018/09/12 - [RepreZen and OpenAPI 3.0: Now is the Time](https://www.reprezen.com/blog/reprezen-openapi-3.0-upgrade-now-is-the-time) by [Miles Daffin](https://www.reprezen.com/blog/author/miles-daffin)
- 2018/10/31 - [A node package wrapper for openapi-generator](https://github.com/HarmoWatch/openapi-generator-cli)
- 2018/11/03 - [OpenAPI Generator + golang + Flutter でアプリ開発](http://ryuichi111std.hatenablog.com/entry/2018/11/03/214005) by [Ryuichi Daigo](https://github.com/ryuichi111)
- 2018/11/19 - [OpenAPIs are everywhere](https://youtu.be/-lDot4Yn7Dg) by [Jeremie Bresson (Unblu)](https://github.com/jmini) at [EclipseCon Europe 2018](https://www.eclipsecon.org/europe2018)
- 2018/12/09 - [openapi-generator をカスタマイズする方法](https://qiita.com/watiko/items/0961287c02eac9211572) by [@watiko](https://qiita.com/watiko)
- 2019/01/03 - [Calling a Swagger service from Apex using openapi-generator](https://lekkimworld.com/2019/01/03/calling-a-swagger-service-from-apex-using-openapi-generator/) by [Mikkel Flindt Heisterberg](https://lekkimworld.com)
## [6 - About Us](#table-of-contents)
@@ -564,7 +570,7 @@ Here is a list of template creators:
* Dart 2: @swipesight
* Dart (Jaguar): @jaumard
* Elixir: @niku
* Elm: @trenneman
* Elm: @eriktim
* Eiffel: @jvelilla
* Erlang: @tsloughter
* Erlang (PropEr): @jfacorro @robertoaloi
@@ -690,8 +696,8 @@ If you want to join the committee, please kindly apply by sending an email to te
| Clojure | |
| Dart | @ircecho (2017/07) @swipesight (2018/09) @jaumard (2018/09) |
| Eiffel | @jvelilla (2017/09) |
| Elixir | |
| Elm | @trenneman (2018/09) |
| Elixir | @mrmstn (2018/12) |
| Elm | @eriktim (2018/09) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
| Go | @antihax (2017/11) @bvwells (2017/12) @grokify (2018/07) @kemokemo (2018/09 |
| GraphQL | @renepardon (2018/12) |
@@ -730,7 +736,7 @@ OpenAPI Generator is a fork of [Swagger Codegen](https://github.com/swagger-api/
- [Daiki Matsudate](https://github.com/d-date)
- [Daniel](https://github.com/Danielku15)
- [Emiliano Bonassi](https://github.com/emilianobonassi)
- [Erik Timmers](https://github.com/trenneman)
- [Erik Timmers](https://github.com/eriktim)
- [Esteban Marin](https://github.com/macjohnny)
- [Gustavo Paz](https://github.com/gustavoapaz)
- [Javier Velilla](https://github.com/jvelilla)

View File

@@ -23,6 +23,9 @@ install:
- git clone https://github.com/wing328/swagger-samples
- ps: Start-Process -FilePath 'C:\maven\apache-maven-3.2.5\bin\mvn' -ArgumentList 'jetty:run' -WorkingDirectory "$env:appveyor_build_folder\swagger-samples\java\java-jersey-jaxrs-ci"
build_script:
# build C# API client (refactor)
- nuget restore samples\client\petstore\csharp-refactor\OpenAPIClient\Org.OpenAPITools.sln
- msbuild samples\client\petstore\csharp-refactor\OpenAPIClient\Org.OpenAPITools.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
# build C# API client
- nuget restore samples\client\petstore\csharp\OpenAPIClient\Org.OpenAPITools.sln
- msbuild samples\client\petstore\csharp\OpenAPIClient\Org.OpenAPITools.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
@@ -37,6 +40,8 @@ build_script:
test_script:
# restore test-related files
- copy /b/v/y CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test c# API client (refactor)
- nunit-console samples\client\petstore\csharp-refactor\OpenAPIClient\src\Org.OpenAPITools.Test\bin\Debug\Org.OpenAPITools.Test.dll --result=myresults.xml;format=AppVeyor
# test c# API client
- nunit-console samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\bin\Debug\Org.OpenAPITools.Test.dll --result=myresults.xml;format=AppVeyor
# test c# API client (with PropertyChanged)

View File

@@ -27,11 +27,11 @@ 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/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp-refactor -o samples/client/petstore/csharp-refactor/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} $@"
ags="generate -t modules/openapi-generator/src/main/resources/csharp-refactor/ -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp-refactor -o samples/client/petstore/csharp-refactor/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C},useCompareNetObjects=true $@"
java $JAVA_OPTS -jar $executable $ags
# restore csproj file
#echo "restore csproject file: CI/samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
#cp ./CI/samples.ci/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/
echo "restore csproject file: CI/samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
cp ./CI/samples.ci/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/

View File

@@ -28,11 +28,11 @@ fi
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
# Generate client
ags="$@ generate -t modules/openapi-generator/src/main/resources/dart-jaguar -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -l dart-jaguar -o samples/client/petstore/dart-jaguar/openapi -DhideGenerationTimestamp=true -DpubName=openapi"
ags="$@ generate -t modules/openapi-generator/src/main/resources/dart-jaguar -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart-jaguar -o samples/client/petstore/dart-jaguar/openapi -DhideGenerationTimestamp=true -DpubName=openapi"
java $JAVA_OPTS -jar $executable $ags
# Generate non-browserClient and put it to the flutter sample app
ags="$@ generate -t modules/openapi-generator/src/main/resources/dart-jaguar -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -l dart-jaguar -o samples/client/petstore/dart-jaguar/flutter_petstore/openapi -DhideGenerationTimestamp=true -DpubName=openapi"
ags="$@ generate -t modules/openapi-generator/src/main/resources/dart-jaguar -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart-jaguar -o samples/client/petstore/dart-jaguar/flutter_petstore/openapi -DhideGenerationTimestamp=true -DpubName=openapi"
java $JAVA_OPTS -jar $executable $ags
# There is a proposal to allow importing different libraries depending on the environment:

View File

@@ -44,4 +44,6 @@ cp CI/samples.ci/client/petstore/java/test-manual/common/ConfigurationTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/auth/ApiKeyAuthTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/auth/ApiKeyAuthTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/auth/HttpBasicAuthTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/auth/HttpBasicAuthTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/model/EnumValueTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/EnumValueTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/model/PetTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/PetTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/model/ArrayOfArrayOfNumberOnly.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/ArrayOfArrayOfNumberOnlyTest.java
cp CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/JSONTest.java samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java

View File

@@ -29,7 +29,6 @@ fi
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Javascript/es6 \
-i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g javascript \
-o samples/client/petstore/javascript-es6 \
--additional-properties useES6=true $@"
-o samples/client/petstore/javascript-es6 $@"
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags

38
bin/openapi3/go-petstore.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
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/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn -B clean package
fi
SPEC="modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml"
GENERATOR="go"
STUB_DIR="samples/openapi3/client/petstore/go/go-petstore"
echo "Removing files and folders under $STUB_DIR"
rm -rf $STUB_DIR
# 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/openapi-generator/src/main/resources/go -i $SPEC -g $GENERATOR -o $STUB_DIR -DpackageName=petstore $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -0,0 +1,35 @@
#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
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/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -t modules/openapi-generator/src/main/resources/kotlin-client -g kotlin --artifact-id kotlin-petstore-client -D dateLibrary=java8 -o samples/openapi3/client/petstore/kotlin $@"
echo "Cleaning previously generated files if any from samples/openapi3/client/petstore/kotlin"
rm -rf samples/openapi3/client/petstore/kotlin
echo "Generating Kotling client..."
java $JAVA_OPTS -jar $executable $ags

View File

@@ -28,6 +28,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"
# complex module name used for testing
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g perl -o samples/client/petstore/perl -DhideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/perl -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g perl -o samples/client/petstore/perl -DhideGenerationTimestamp=true $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -28,7 +28,7 @@ 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"
# complex module name used for testing
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore-security-test.yaml -l perl -o samples/client/petstore-security-test/perl $@"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore-security-test.yaml -g perl -o samples/client/petstore-security-test/perl $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,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/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-objcCompatible.json -o samples/client/petstore/swift3/objcCompatible $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-objcCompatible.json -o samples/client/petstore/swift3/objcCompatible $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,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/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-promisekit.json -o samples/client/petstore/swift3/promisekit $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-promisekit.json -o samples/client/petstore/swift3/promisekit $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,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/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-rxswift.json -o samples/client/petstore/swift3/rxswift $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-rxswift.json -o samples/client/petstore/swift3/rxswift $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,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/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore-unwraprequired.json -o samples/client/petstore/swift3/unwraprequired $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore-unwraprequired.json -o samples/client/petstore/swift3/unwraprequired $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -27,6 +27,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/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c ./bin/swift3-petstore.json -o samples/client/petstore/swift3/default $@"
ags="generate -t modules/openapi-generator/src/main/resources/swift3 -i modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c ./bin/swift3-petstore.json -o samples/client/petstore/swift3/default $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -5,8 +5,8 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l dart-jaguar -o samples\client\petstore\dart-jaguar\swagger -DhideGenerationTimestamp=true -DbrowserClient=false
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -g dart-jaguar -o samples\client\petstore\dart-jaguar\swagger -DhideGenerationTimestamp=true -DbrowserClient=false
java %JAVA_OPTS% -jar %executable% %ags%
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l dart-jaguar -o samples\client\petstore\dart-jaguar\flutter_petstore\swagger -DhideGenerationTimestamp=true
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -g dart-jaguar -o samples\client\petstore\dart-jaguar\flutter_petstore\swagger -DhideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c bin\swift3-petstore-promisekit.json -o samples\client\petstore\swift3\promisekit
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c bin\swift3-petstore-promisekit.json -o samples\client\petstore\swift3\promisekit
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -c bin\swift3-petstore-rxswift.json -o samples\client\petstore\swift3\rxswift
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -c bin\swift3-petstore-rxswift.json -o samples\client\petstore\swift3\rxswift
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3 -o samples\client\petstore\swift3\default
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g swift3-deprecated -o samples\client\petstore\swift3\default
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -c bin\typescript-angular-v6-petstore-not-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v6-not-provided-in-root\builds\with-npm -D providedInRoot=false --additional-properties ngVersion=6.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -c bin\typescript-angular-v6-petstore-not-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v6-not-provided-in-root\builds\with-npm -D providedInRoot=false --additional-properties ngVersion=6.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -o samples\client\petstore\typescript-angular-v6-not-provided-in-root\builds\default -D providedInRoot=false --additional-properties ngVersion=6.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -o samples\client\petstore\typescript-angular-v6-not-provided-in-root\builds\default -D providedInRoot=false --additional-properties ngVersion=6.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -4,6 +4,6 @@ If Not Exist %executable% (
mvn clean package
)
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -c bin/typescript-angular-v6-petstore-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v6-provided-in-root\builds\with-npm --additional-properties ngVersion=6.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -c bin/typescript-angular-v6-petstore-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v6-provided-in-root\builds\with-npm --additional-properties ngVersion=6.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -4,6 +4,6 @@ If Not Exist %executable% (
mvn clean package
)
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -o samples\client\petstore\typescript-angular-v6-provided-in-root\builds\default --additional-properties ngVersion=6.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -o samples\client\petstore\typescript-angular-v6-provided-in-root\builds\default --additional-properties ngVersion=6.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -c bin\typescript-angular-v7-petstore-not-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v7-not-provided-in-root\builds\with-npm -D providedInRoot=false --additional-properties ngVersion=7.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -c bin\typescript-angular-v7-petstore-not-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v7-not-provided-in-root\builds\with-npm -D providedInRoot=false --additional-properties ngVersion=7.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -o samples\client\petstore\typescript-angular-v7-not-provided-in-root\builds\default -D providedInRoot=false --additional-properties ngVersion=7.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -o samples\client\petstore\typescript-angular-v7-not-provided-in-root\builds\default -D providedInRoot=false --additional-properties ngVersion=7.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -4,6 +4,6 @@ If Not Exist %executable% (
mvn clean package
)
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -c bin/typescript-angular-v7-petstore-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v7-provided-in-root\builds\with-npm --additional-properties ngVersion=7.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -c bin/typescript-angular-v7-petstore-provided-in-root-with-npm.json -o samples\client\petstore\typescript-angular-v7-provided-in-root\builds\with-npm --additional-properties ngVersion=7.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -4,6 +4,6 @@ If Not Exist %executable% (
mvn clean package
)
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -l typescript-angular -o samples\client\petstore\typescript-angular-v7-provided-in-root\builds\default --additional-properties ngVersion=7.0.0
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g typescript-angular -o samples\client\petstore\typescript-angular-v7-provided-in-root\builds\default --additional-properties ngVersion=7.0.0
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -12,7 +12,7 @@ codegen="${cli}/target/openapi-generator-cli.jar"
# We code in a list of commands here as source processing is potentially buggy (requires undocumented conventional use of annotations).
# A list of known commands helps us determine if we should compile CLI. There's an edge-case where a new command not added to this
# list won't be considered a "real" command. We can get around that a bit by checking CLI completions beforehand if it exists.
commands="list,generate,meta,langs,help,config-help,validate,version"
commands="list,generate,meta,help,config-help,validate,version"
# if CLI jar exists, check $1 against completions available in the CLI
if [[ -f "${codegen}" && -n "$(java ${JAVA_OPTS} -jar "${codegen}" completion | grep "^$1\$" )" ]]; then

19
docs/generators/c.md Normal file
View File

@@ -0,0 +1,19 @@
CONFIG OPTIONS for c
sortParamsByRequiredFlag
Sort method arguments to place required parameters before optional parameters. (Default: true)
ensureUniqueParams
Whether to ensure parameter names are unique in an operation (rename parameters that are not). (Default: true)
allowUnicodeIdentifiers
boolean, toggles whether unicode identifiers are allowed in names or not, default is false (Default: false)
prependFormOrBodyParameters
Add form or body parameters to the beginning of the parameter list. (Default: false)
hideGenerationTimestamp
Hides the generation timestamp when files are generated. (Default: true)
Back to the [generators list](README.md)

View File

@@ -0,0 +1,25 @@
CONFIG OPTIONS for cpp-qt5-client
sortParamsByRequiredFlag
Sort method arguments to place required parameters before optional parameters. (Default: true)
ensureUniqueParams
Whether to ensure parameter names are unique in an operation (rename parameters that are not). (Default: true)
allowUnicodeIdentifiers
boolean, toggles whether unicode identifiers are allowed in names or not, default is false (Default: false)
prependFormOrBodyParameters
Add form or body parameters to the beginning of the parameter list. (Default: false)
cppNamespace
C++ namespace (convention: name::space::for::api). (Default: OpenAPI)
cppNamespace
C++ namespace (convention: name::space::for::api). (Default: OpenAPI)
optionalProjectFile
Generate client.pri. (Default: true)
Back to the [generators list](README.md)

View File

@@ -69,4 +69,7 @@ CONFIG OPTIONS for csharp
validatable
Generates self-validatable models. (Default: true)
useCompareNetObjects
Use KellermanSoftware.CompareNetObjects for deep recursive object comparison. WARNING: this option incurs potential performance impact. (Default: false)
Back to the [generators list](README.md)

View File

@@ -0,0 +1,10 @@
CONFIG OPTIONS for erlang-proper
packageName
Erlang application name (convention: lowercase). (Default: openapi)
packageName
Erlang application version (Default: 1.0.0)
Back to the [generators list](README.md)

View File

@@ -0,0 +1,13 @@
CONFIG OPTIONS for graphql-schema
packageName
GraphQL package name (convention: lowercase). (Default: openapi2graphql)
packageVersion
GraphQL package version. (Default: 1.0.0)
hideGenerationTimestamp
Hides the generation timestamp when files are generated. (Default: true)
Back to the [generators list](README.md)

View File

@@ -0,0 +1,13 @@
CONFIG OPTIONS for graphql-server
packageName
GraphQL express server package name (convention: lowercase). (Default: openapi3graphql-server)
packageVersion
GraphQL express server package version. (Default: 1.0.0)
hideGenerationTimestamp
Hides the generation timestamp when files are generated. (Default: true)
Back to the [generators list](README.md)

View File

@@ -146,6 +146,9 @@ CONFIG OPTIONS for java
feignVersion
Version of OpenFeign: '10.x', '9.x' (default) (Default: false)
useReflectionEqualsHashCode
Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact. (Default: false)
library
library template (sub-template) to use (Default: okhttp-gson)
jersey1 - HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.8.9. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.

View File

@@ -59,7 +59,7 @@ CONFIG OPTIONS for javascript
Hides the generation timestamp when files are generated. (Default: true)
useES6
use JavaScript ES6 (ECMAScript 6) (beta). Default is ES5. (Default: false)
use JavaScript ES6 (ECMAScript 6) (beta). Default is ES6. (Default: true)
modelPropertyNaming
Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name (Default: camelCase)

View File

@@ -40,7 +40,4 @@ CONFIG OPTIONS for php-slim
artifactVersion
The version to use in the composer package version field. e.g. 1.2.3
phpcsStandard
PHP CodeSniffer <standard> option. Accepts name or path of the coding standard to use. (Default: PSR12)
Back to the [generators list](README.md)

View File

@@ -156,7 +156,7 @@ Corresponding java code: `CodegenProperty.datatype` is renamed to `CodegenProper
`.swagger-codegen-ignore` is replaced by `.openapi-generator-ignore`.
The syntax inside the file stays the same.
You don't need to rename the file manually, OpenAPI Generator will do it when your run it against an existing an existing output directory.
You don't need to rename the file manually, OpenAPI Generator will do it when your run it against an existing output directory.
(When there is no `.openapi-generator-ignore` in a folder, if a `.swagger-codegen-ignore` file is present it will be considered and renamed to `.openapi-generator-ignore`).

View File

@@ -11,6 +11,17 @@ Another approach to find breaking changes is to look at issue and pull requests
* link:https://github.com/OpenAPITools/openapi-generator/labels/Breaking%20change%20%28with%20fallback%29[Breaking change (with fallback)]
* link:https://github.com/OpenAPITools/openapi-generator/labels/Breaking%20change%20%28without%20fallback%29[Breaking change (without fallback)]
=== From 3.x to 4.0.0
Version `4.0.0` is a major release, which contains some breaking changes without fallback.
==== The `-l` (`--lang`) option has been deleted
The option is replaced with `-g` (`--generator-name`).
* `-g` allows the same values as `-l`
* See `list` command for the list of generator name
=== From 3.1.x to 3.2.0
Version `3.2.0` is a minor version of OpenAPI-Generator, in comparison to `3.1.x` it contains some breaking changes, but with the possibility to fallback to the old behavior.

View File

@@ -50,7 +50,6 @@ public class OpenAPIGenerator {
ListGenerators.class,
Generate.class,
Meta.class,
Langs.class,
Help.class,
ConfigHelp.class,
Validate.class,
@@ -72,7 +71,7 @@ public class OpenAPIGenerator {
System.exit(1);
}
} catch (ParseArgumentsUnexpectedException e) {
System.err.printf(Locale.ROOT,"[error] %s%n%nSee 'openapi-generator-cli help' for usage.%n", e.getMessage());
System.err.printf(Locale.ROOT,"[error] %s%n%nSee 'openapi-generator help' for usage.%n", e.getMessage());
System.exit(1);
} catch (ParseOptionMissingException | ParseOptionMissingValueException e) {
System.err.printf(Locale.ROOT,"[error] %s%n", e.getMessage());

View File

@@ -37,10 +37,6 @@ public class ConfigHelp implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(Generate.class);
@Option(name = {"-l", "--lang"}, title = "language",
description = "language to get config help for")
private String lang;
@Option(name = {"-g", "--generator-name"}, title = "generator name",
description = "generator to get config help for")
private String generatorName;
@@ -57,16 +53,9 @@ public class ConfigHelp implements Runnable {
@Override
public void run() {
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
if (isEmpty(generatorName)) {
if (isNotEmpty(lang)) {
LOGGER.warn("The '--lang' and '-l' are deprecated and may reference language names only in the next major release (4.0). Please use --generator-name /-g instead.");
generatorName = lang;
} else {
System.err.println("[error] A generator name (--generator-name / -g) is required.");
System.exit(1);
}
System.err.println("[error] A generator name (--generator-name / -g) is required.");
System.exit(1);
}
try {

View File

@@ -49,12 +49,8 @@ public class Generate implements Runnable {
@Option(name = {"-v", "--verbose"}, description = "verbose mode")
private Boolean verbose;
@Option(name = {"-l", "--lang"}, title = "language",
description = "client language to generate (maybe class name in classpath, required)")
private String lang;
@Option(name = {"-g", "--generator-name"}, title = "generator name",
description = "generator to use (see langs command for list)")
description = "generator to use (see list command for list)")
private String generatorName;
@Option(name = {"-o", "--output"}, title = "output directory",
@@ -212,6 +208,9 @@ public class Generate implements Runnable {
@Option(name = {"--enable-post-process-file"}, title = "enable post-process file", description = CodegenConstants.ENABLE_POST_PROCESS_FILE)
private Boolean enablePostProcessFile;
@Option(name = {"--generate-alias-as-model"}, title = "generate alias (array, map) as model", description = CodegenConstants.GENERATE_ALIAS_AS_MODEL_DESC)
private Boolean generateAliasAsModel;
@Override
public void run() {
if (logToStderr != null) {
@@ -255,12 +254,8 @@ public class Generate implements Runnable {
configurator.setInputSpec(spec);
}
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
if (isNotEmpty(generatorName)) {
configurator.setGeneratorName(generatorName);
} else if (isNotEmpty(lang)) {
LOGGER.warn("The '--lang' and '-l' are deprecated and may reference language names only in the next major release (4.0). Please use --generator-name /-g instead.");
configurator.setGeneratorName(lang);
} else {
System.err.println("[error] A generator name (--generator-name / -g) is required.");
System.exit(1);
@@ -342,6 +337,10 @@ public class Generate implements Runnable {
configurator.setEnablePostProcessFile(enablePostProcessFile);
}
if (generateAliasAsModel != null) {
configurator.setGenerateAliasAsModel(generateAliasAsModel);
}
applySystemPropertiesKvpList(systemProperties, configurator);
applyInstantiationTypesKvpList(instantiationTypes, configurator);
applyImportMappingsKvpList(importMappings, configurator);

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.cmd;
import ch.lambdaj.collection.LambdaIterable;
import io.airlift.airline.Command;
import org.openapitools.codegen.CodegenConfig;
import java.util.Locale;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.collection.LambdaCollections.with;
import static java.util.ServiceLoader.load;
/**
* User: lanwen Date: 24.03.15 Time: 20:25
*/
@Command(name = "langs", description = "Shows available languages (deprecated. use 'list' instead)")
public class Langs implements Runnable {
@Override
public void run() {
LambdaIterable<String> langs =
with(load(CodegenConfig.class)).extract(on(CodegenConfig.class).getName());
System.out.printf(Locale.ROOT, "Available languages (generators): %s%n", langs);
}
}

View File

@@ -1,131 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.invoke
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorGenerateExtension
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorMetaExtension
import org.openapitools.generator.gradle.plugin.extensions.OpenApiGeneratorValidateExtension
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
import org.openapitools.generator.gradle.plugin.tasks.GeneratorsTask
import org.openapitools.generator.gradle.plugin.tasks.MetaTask
import org.openapitools.generator.gradle.plugin.tasks.ValidateTask
/**
* A plugin providing common Open API Generator use cases.
*
* @author Jim Schubert
*/
@Suppress("unused")
class OpenApiGeneratorPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.run {
val meta = extensions.create(
"openApiMeta",
OpenApiGeneratorMetaExtension::class.java,
project
)
val validate = extensions.create(
"openApiValidate",
OpenApiGeneratorValidateExtension::class.java,
project
)
val generate = extensions.create(
"openApiGenerate",
OpenApiGeneratorGenerateExtension::class.java,
project
)
generate.outputDir.set("$buildDir/generate-resources/main")
tasks {
"openApiGenerators"(GeneratorsTask::class) {
group = pluginGroup
description = "Lists generators available via Open API Generators."
}
"openApiMeta"(MetaTask::class) {
group = pluginGroup
description = "Generates a new generator to be consumed via Open API Generator."
generatorName.set(meta.generatorName)
packageName.set(meta.packageName)
outputFolder.set(meta.outputFolder)
}
"openApiValidate"(ValidateTask::class) {
group = pluginGroup
description = "Validates an Open API 2.0 or 3.x specification document."
inputSpec.set(validate.inputSpec)
}
"openApiGenerate"(GenerateTask::class) {
group = pluginGroup
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
verbose.set(generate.verbose)
validateSpec.set(generate.validateSpec)
generatorName.set(generate.generatorName)
outputDir.set(generate.outputDir)
inputSpec.set(generate.inputSpec)
templateDir.set(generate.templateDir)
auth.set(generate.auth)
systemProperties.set(generate.systemProperties)
configFile.set(generate.configFile)
skipOverwrite.set(generate.skipOverwrite)
apiPackage.set(generate.apiPackage)
modelPackage.set(generate.modelPackage)
modelNamePrefix.set(generate.modelNamePrefix)
modelNameSuffix.set(generate.modelNameSuffix)
instantiationTypes.set(generate.instantiationTypes)
typeMappings.set(generate.typeMappings)
additionalProperties.set(generate.additionalProperties)
languageSpecificPrimitives.set(generate.languageSpecificPrimitives)
importMappings.set(generate.importMappings)
invokerPackage.set(generate.invokerPackage)
groupId.set(generate.groupId)
id.set(generate.id)
version.set(generate.version)
library.set(generate.library)
gitUserId.set(generate.gitUserId)
gitRepoId.set(generate.gitRepoId)
releaseNote.set(generate.releaseNote)
httpUserAgent.set(generate.httpUserAgent)
reservedWordsMappings.set(generate.reservedWordsMappings)
ignoreFileOverride.set(generate.ignoreFileOverride)
removeOperationIdPrefix.set(generate.removeOperationIdPrefix)
apiFilesConstrainedTo.set(generate.apiFilesConstrainedTo)
modelFilesConstrainedTo.set(generate.modelFilesConstrainedTo)
supportingFilesConstrainedTo.set(generate.supportingFilesConstrainedTo)
generateModelTests.set(generate.generateModelTests)
generateModelDocumentation.set(generate.generateModelDocumentation)
generateApiTests.set(generate.generateApiTests)
generateApiDocumentation.set(generate.generateApiDocumentation)
withXml.set(generate.withXml)
configOptions.set(generate.configOptions)
}
}
}
}
companion object {
const val pluginGroup = "OpenAPI Tools"
}
}

View File

@@ -1,286 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the generate task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* The verbosity of generation
*/
val verbose = project.objects.property<Boolean>()
/**
* Whether or not an input specification should be validated upon generation.
*/
val validateSpec = project.objects.property<Boolean>()
/**
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
*/
val generatorName = project.objects.property<String>()
/**
* The output target directory into which code will be generated.
*/
val outputDir = project.objects.property<String>()
/**
* The Open API 2.0/3.x specification location.
*/
val inputSpec = project.objects.property<String>()
/**
* The template directory holding a custom template.
*/
val templateDir = project.objects.property<String?>()
/**
* Adds authorization headers when fetching the OpenAPI definitions remotely.
* Pass in a URL-encoded string of name:header with a comma separating multiple values
*/
val auth = project.objects.property<String>()
/**
* Sets specified system properties.
*/
val systemProperties = project.objects.property<Map<String, String>>()
/**
* Path to json configuration file.
* File content should be in a json format { "optionKey":"optionValue", "optionKey1":"optionValue1"...}
* Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.
*/
val configFile = project.objects.property<String>()
/**
* Specifies if the existing files should be overwritten during the generation.
*/
val skipOverwrite = project.objects.property<Boolean?>()
/**
* Package for generated api classes
*/
val apiPackage = project.objects.property<String>()
/**
* Package for generated models
*/
val modelPackage = project.objects.property<String>()
/**
* Prefix that will be prepended to all model names. Default is the empty string.
*/
val modelNamePrefix = project.objects.property<String>()
/**
* Suffix that will be appended to all model names. Default is the empty string.
*/
val modelNameSuffix = project.objects.property<String>()
/**
* Sets instantiation type mappings.
*/
val instantiationTypes = project.objects.property<Map<String, String>>()
/**
* Sets mappings between OpenAPI spec types and generated code types.
*/
val typeMappings = project.objects.property<Map<String, String>>()
/**
* Sets additional properties that can be referenced by the mustache templates.
*/
val additionalProperties = project.objects.property<Map<String, String>>()
/**
* Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.
*/
val languageSpecificPrimitives = project.objects.listProperty<String>()
/**
* Specifies mappings between a given class and the import that should be used for that class.
*/
val importMappings = project.objects.property<Map<String, String>>()
/**
* Root package for generated code.
*/
val invokerPackage = project.objects.property<String>()
/**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
val groupId = project.objects.property<String>()
/**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
val id = project.objects.property<String>()
/**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
val version = project.objects.property<String>()
/**
* Reference the library template (sub-template) of a generator.
*/
val library = project.objects.property<String?>()
/**
* Git user ID, e.g. openapitools.
*/
val gitUserId = project.objects.property<String?>()
/**
* Git repo ID, e.g. openapi-generator.
*/
val gitRepoId = project.objects.property<String?>()
/**
* Release note, default to 'Minor update'.
*/
val releaseNote = project.objects.property<String?>()
/**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}'
*/
val httpUserAgent = project.objects.property<String?>()
/**
* Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used.
*/
val reservedWordsMappings = project.objects.property<Map<String, String>>()
/**
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
*/
val ignoreFileOverride = project.objects.property<String?>()
/**
* Remove prefix of operationId, e.g. config_getId => getId
*/
val removeOperationIdPrefix = project.objects.property<Boolean?>()
/**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
val apiFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
val modelFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
*
* Supporting files are those related to projects/frameworks which may be modified
* by consumers.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines whether or not model-related _test_ files should be generated.
*
* This option enables/disables generation of ALL model-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateModelTests = project.objects.property<Boolean>()
/**
* Defines whether or not model-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL model-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateModelDocumentation = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _test_ files should be generated.
*
* This option enables/disables generation of ALL api-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateApiTests = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL api-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
val generateApiDocumentation = project.objects.property<Boolean>()
/**
* A special-case setting which configures some generators with XML support. In some cases,
* this forces json OR xml, so the default here is false.
*/
val withXml = project.objects.property<Boolean>()
/**
* A map of options specific to a generator.
*/
val configOptions = project.objects.property<Map<String, String>>()
init {
applyDefaults()
}
@Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){
releaseNote.set("Minor update")
modelNamePrefix.set("")
modelNameSuffix.set("")
generateModelTests.set(true)
generateModelDocumentation.set(true)
generateApiTests.set(true)
generateApiDocumentation.set(true)
withXml.set(false)
configOptions.set(mapOf())
validateSpec.set(true)
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the meta-generator task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorMetaExtension(project: Project) {
/**
* The human-readable generator name of the newly created template generator.
*/
val generatorName = project.objects.property<String>()
/**
* The packageName generatorName to put the main class into (defaults to org.openapitools.codegen)
*/
val packageName = project.objects.property<String>()
/**
* Where to write the generated files (current dir by default).
*/
val outputFolder = project.objects.property<String>()
init {
generatorName.set("default")
packageName.set("org.openapitools.codegen")
outputFolder.set("")
}
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the generators task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorValidateExtension(project: Project) {
/**
* The input specification to validate. Supports all formats supported by the Parser.
*/
val inputSpec = project.objects.property<String>()
}

View File

@@ -1,554 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.property
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.config.CodegenConfigurator
/**
* A task which generates the desired code.
*
* Example (CLI):
*
* ./gradlew -q openApiGenerate
*
* @author Jim Schubert
*/
open class GenerateTask : DefaultTask() {
/**
* The verbosity of generation
*/
@get:Internal
val verbose = project.objects.property<Boolean>()
/**
* Whether or not an input specification should be validated upon generation.
*/
@get:Internal
val validateSpec = project.objects.property<Boolean>()
/**
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
*/
@get:Internal
val generatorName = project.objects.property<String>()
/**
* The output target directory into which code will be generated.
*/
@get:Internal
val outputDir = project.objects.property<String>()
/**
* The Open API 2.0/3.x specification location.
*/
@get:Internal
val inputSpec = project.objects.property<String>()
/**
* The template directory holding a custom template.
*/
@get:Internal
val templateDir = project.objects.property<String?>()
/**
* Adds authorization headers when fetching the OpenAPI definitions remotely.
* Pass in a URL-encoded string of name:header with a comma separating multiple values
*/
@get:Internal
val auth = project.objects.property<String>()
/**
* Sets specified system properties.
*/
@get:Internal
val systemProperties = project.objects.property<Map<String, String>>()
/**
* Path to json configuration file.
* File content should be in a json format { "optionKey":"optionValue", "optionKey1":"optionValue1"...}
* Supported options can be different for each language. Run config-help -g {generator name} command for language specific config options.
*/
@get:Internal
val configFile = project.objects.property<String>()
/**
* Specifies if the existing files should be overwritten during the generation.
*/
@get:Internal
val skipOverwrite = project.objects.property<Boolean?>()
/**
* Package for generated api classes
*/
@get:Internal
val apiPackage = project.objects.property<String>()
/**
* Package for generated models
*/
@get:Internal
val modelPackage = project.objects.property<String>()
/**
* Prefix that will be prepended to all model names. Default is the empty string.
*/
@get:Internal
val modelNamePrefix = project.objects.property<String>()
/**
* Suffix that will be appended to all model names. Default is the empty string.
*/
@get:Internal
val modelNameSuffix = project.objects.property<String>()
/**
* Sets instantiation type mappings.
*/
@get:Internal
val instantiationTypes = project.objects.property<Map<String, String>>()
/**
* Sets mappings between OpenAPI spec types and generated code types.
*/
@get:Internal
val typeMappings = project.objects.property<Map<String, String>>()
/**
* Sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value.
* You can also have multiple occurrences of this option.
*/
@get:Internal
val additionalProperties = project.objects.property<Map<String, String>>()
/**
* Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.
*/
@get:Internal
val languageSpecificPrimitives = project.objects.listProperty<String>()
/**
* Specifies mappings between a given class and the import that should be used for that class.
*/
@get:Internal
val importMappings = project.objects.property<Map<String, String>>()
/**
* Root package for generated code.
*/
@get:Internal
val invokerPackage = project.objects.property<String>()
/**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
@get:Internal
val groupId = project.objects.property<String>()
/**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
@get:Internal
val id = project.objects.property<String>()
/**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
*/
@get:Internal
val version = project.objects.property<String>()
/**
* Reference the library template (sub-template) of a generator.
*/
@get:Internal
val library = project.objects.property<String?>()
/**
* Git user ID, e.g. openapitools.
*/
@get:Internal
val gitUserId = project.objects.property<String?>()
/**
* Git repo ID, e.g. openapi-generator.
*/
@get:Internal
val gitRepoId = project.objects.property<String?>()
/**
* Release note, default to 'Minor update'.
*/
@get:Internal
val releaseNote = project.objects.property<String?>()
/**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}}/{language}'
*/
@get:Internal
val httpUserAgent = project.objects.property<String?>()
/**
* Specifies how a reserved name should be escaped to.
*/
@get:Internal
val reservedWordsMappings = project.objects.property<Map<String, String>>()
/**
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
*/
@get:Internal
val ignoreFileOverride = project.objects.property<String?>()
/**
* Remove prefix of operationId, e.g. config_getId => getId
*/
@get:Internal
val removeOperationIdPrefix = project.objects.property<Boolean?>()
/**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* This option enables/disables generation of ALL api-related files.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
@get:Internal
val apiFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all).
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
@get:Internal
val modelFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
*
* Supporting files are those related to projects/frameworks which may be modified
* by consumers.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
* in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.
* For more control over generation of individual files, configure an ignore file and refer to it via [ignoreFileOverride].
*/
@get:Internal
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines whether or not model-related _test_ files should be generated.
*
* This option enables/disables generation of ALL model-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateModelTests = project.objects.property<Boolean>()
/**
* Defines whether or not model-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL model-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateModelDocumentation = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _test_ files should be generated.
*
* This option enables/disables generation of ALL api-related _test_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateApiTests = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL api-related _documentation_ files.
*
* For more control over generation of individual files, configure an ignore file and
* refer to it via [ignoreFileOverride].
*/
@get:Internal
val generateApiDocumentation = project.objects.property<Boolean>()
/**
* A special-case setting which configures some generators with XML support. In some cases,
* this forces json OR xml, so the default here is false.
*/
@get:Internal
val withXml = project.objects.property<Boolean>()
/**
* A dynamic map of options specific to a generator.
*/
@get:Internal
val configOptions = project.objects.property<Map<String, String>>()
private val originalEnvironmentVariables = mutableMapOf<String, String?>()
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) {
val item: T? = get()
if (item != null) {
when (get()) {
is String -> if ((get() as String).isNotEmpty()) {
block(get())
}
is String? -> if (true == (get() as String?)?.isNotEmpty()) {
block(get())
}
else -> block(get())
}
}
}
}
@Suppress("unused")
@TaskAction
fun doWork() {
val configurator: CodegenConfigurator = if (configFile.isPresent) {
CodegenConfigurator.fromFile(configFile.get())
} else CodegenConfigurator()
try {
if (systemProperties.isPresent) {
systemProperties.get().forEach { (key, value) ->
// System.setProperty returns the original value for a key, or null.
// Cache the original value or null…we will late put the properties back in their original state.
originalEnvironmentVariables[key] = System.setProperty(key, value)
configurator.addSystemProperty(key, value)
}
}
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.SUPPORTING_FILES)
}
if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.MODELS)
}
if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.APIS)
}
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
System.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
// now override with any specified parameters
verbose.ifNotEmpty { value ->
configurator.isVerbose = value
}
validateSpec.ifNotEmpty { value ->
configurator.isValidateSpec = value
}
skipOverwrite.ifNotEmpty { value ->
configurator.isSkipOverwrite = value ?: false
}
inputSpec.ifNotEmpty { value ->
configurator.inputSpec = value
}
generatorName.ifNotEmpty { value ->
configurator.generatorName = value
}
outputDir.ifNotEmpty { value ->
configurator.outputDir = value
}
auth.ifNotEmpty { value ->
configurator.auth = value
}
templateDir.ifNotEmpty { value ->
configurator.templateDir = value
}
apiPackage.ifNotEmpty { value ->
configurator.apiPackage = value
}
modelPackage.ifNotEmpty { value ->
configurator.modelPackage = value
}
modelNamePrefix.ifNotEmpty { value ->
configurator.modelNamePrefix = value
}
modelNameSuffix.ifNotEmpty { value ->
configurator.modelNameSuffix = value
}
invokerPackage.ifNotEmpty { value ->
configurator.invokerPackage = value
}
groupId.ifNotEmpty { value ->
configurator.groupId = value
}
id.ifNotEmpty { value ->
configurator.artifactId = value
}
version.ifNotEmpty { value ->
configurator.artifactVersion = value
}
library.ifNotEmpty { value ->
configurator.library = value
}
gitUserId.ifNotEmpty { value ->
configurator.gitUserId = value
}
gitRepoId.ifNotEmpty { value ->
configurator.gitRepoId = value
}
releaseNote.ifNotEmpty { value ->
configurator.releaseNote = value
}
httpUserAgent.ifNotEmpty { value ->
configurator.httpUserAgent = value
}
ignoreFileOverride.ifNotEmpty { value ->
configurator.ignoreFileOverride = value
}
removeOperationIdPrefix.ifNotEmpty { value ->
configurator.removeOperationIdPrefix = value!!
}
if (systemProperties.isPresent) {
systemProperties.get().forEach { entry ->
configurator.addSystemProperty(entry.key, entry.value)
}
}
if (instantiationTypes.isPresent) {
instantiationTypes.get().forEach { entry ->
configurator.addInstantiationType(entry.key, entry.value)
}
}
if (importMappings.isPresent) {
importMappings.get().forEach { entry ->
configurator.addImportMapping(entry.key, entry.value)
}
}
if (typeMappings.isPresent) {
typeMappings.get().forEach { entry ->
configurator.addTypeMapping(entry.key, entry.value)
}
}
if (additionalProperties.isPresent) {
additionalProperties.get().forEach { entry ->
configurator.addAdditionalProperty(entry.key, entry.value)
}
}
if (languageSpecificPrimitives.isPresent) {
languageSpecificPrimitives.get().forEach {
configurator.addLanguageSpecificPrimitive(it)
}
}
if (reservedWordsMappings.isPresent) {
reservedWordsMappings.get().forEach { entry ->
configurator.addAdditionalReservedWordMapping(entry.key, entry.value)
}
}
val clientOptInput = configurator.toClientOptInput()
val codgenConfig = clientOptInput.config
if (configOptions.isPresent) {
val userSpecifiedConfigOptions = configOptions.get()
codgenConfig.cliOptions().forEach {
if (userSpecifiedConfigOptions.containsKey(it.opt)) {
clientOptInput.config.additionalProperties()[it.opt] = userSpecifiedConfigOptions[it.opt]
}
}
}
try {
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
out.withStyle(StyledTextOutput.Style.Success)
DefaultGenerator().opts(clientOptInput).generate()
out.println("Successfully generated code to ${configurator.outputDir}")
} catch (e: RuntimeException) {
throw GradleException("Code generation failed.", e)
}
} finally {
// Reset all modified system properties back to their original state
originalEnvironmentVariables.forEach {
when {
it.value == null -> System.clearProperty(it.key)
else -> System.setProperty(it.key, it.value)
}
}
originalEnvironmentVariables.clear()
}
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.openapitools.codegen.CodegenConfigLoader
import org.openapitools.codegen.CodegenType
/**
* A task which lists out the generators available in OpenAPI Generator
*
* Example (CLI):
*
* ./gradlew -q openApiGenerators
*
* @author Jim Schubert
*/
open class GeneratorsTask : DefaultTask() {
@Suppress("unused")
@TaskAction
fun doWork() {
val generators = CodegenConfigLoader.getAll()
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
StringBuilder().apply {
val types = CodegenType.values()
append("The following generators are available:")
append(System.lineSeparator())
append(System.lineSeparator())
for (type in types) {
append(type.name).append(" generators:")
append(System.lineSeparator())
generators.filter { it.tag == type }
.sortedBy { it.name }
.forEach({ generator ->
append(" - ")
append(generator.name)
append(System.lineSeparator())
})
append(System.lineSeparator())
append(System.lineSeparator())
}
out.withStyle(StyledTextOutput.Style.Success)
out.formatln("%s%n", toString())
}
}
}

View File

@@ -1,132 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import com.samskivert.mustache.Mustache
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.property
import org.openapitools.codegen.CodegenConfig
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.SupportingFile
import java.io.File
import java.io.IOException
import java.nio.charset.Charset
/**
* A task which generates a new generator (meta). Useful for redistributable generator packages.
*
* @author Jim Schubert
*/
open class MetaTask : DefaultTask() {
@get:Internal
val generatorName = project.objects.property<String>()
@get:Internal
val packageName = project.objects.property<String>()
@get:Internal
val outputFolder = project.objects.property<String>()
@Suppress("unused")
@TaskAction
fun doWork() {
val packageToPath = packageName.get().replace(".", File.separator)
val dir = File(outputFolder.get())
val klass = "${generatorName.get().titleCasedTextOnly()}Generator"
val templateResourceDir = generatorName.get().hyphenatedTextOnly()
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
out.withStyle(StyledTextOutput.Style.Info)
logger.debug("package: {}", packageName.get())
logger.debug("dir: {}", dir.absolutePath)
logger.debug("generator class: {}", klass)
val supportingFiles = listOf(
SupportingFile("pom.mustache", "", "pom.xml"),
SupportingFile("generatorClass.mustache", dir("src", "main", "java", packageToPath), "$klass.java"),
SupportingFile("README.mustache", "", "README.md"),
SupportingFile("api.template", dir("src", "main", "resources", templateResourceDir), "api.mustache"),
SupportingFile("model.template", dir("src", "main", "resources", templateResourceDir), "model.mustache"),
SupportingFile("myFile.template", dir("src", "main", "resources", templateResourceDir), "myFile.mustache"),
SupportingFile("services.mustache", dir("src", "main", "resources", "META-INF", "services"), CodegenConfig::class.java.canonicalName))
val currentVersion = CodegenConstants::class.java.`package`.implementationVersion
val data = mapOf("generatorPackage" to packageToPath,
"generatorClass" to klass,
"name" to templateResourceDir,
"fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass",
"openapiGeneratorVersion" to currentVersion)
val generator = DefaultGenerator()
supportingFiles.map {
try {
val destinationFolder = File(File(dir.absolutePath), it.folder)
destinationFolder.mkdirs()
val outputFile = File(destinationFolder, it.destinationFilename)
val template = generator.readTemplate(File("codegen", it.templateFile).path)
var formatted = template
if (it.templateFile.endsWith(".mustache")) {
formatted = Mustache.compiler()
.withLoader(loader(generator))
.defaultValue("")
.compile(template).execute(data)
}
outputFile.writeText(formatted, Charset.forName("UTF8"))
out.formatln("Wrote file to %s", outputFile.absolutePath)
// TODO: register outputs
// return outputFile
} catch (e: IOException) {
logger.error(e.message)
throw GradleException("Can't generate project", e)
}
}
out.withStyle(StyledTextOutput.Style.Success)
out.formatln("Created generator %s", klass)
}
private fun loader(generator: DefaultGenerator): Mustache.TemplateLoader {
return Mustache.TemplateLoader { name ->
generator.getTemplateReader("codegen${File.separator}$name.mustache")
}
}
private fun String.titleCasedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)
private fun String.hyphenatedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase)
private fun dir(vararg parts: String): String =
parts.joinToString(separator = File.separator)
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.generator.gradle.plugin.tasks
import io.swagger.parser.OpenAPIParser
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.property
/**
* A generator which validates an Open API spec. This task outputs a list of validation issues and errors.
*
* Example:
* cli:
*
* ./gradlew openApiValidate --input=/path/to/file
*
* build.gradle:
*
* openApiMeta {
* inputSpec = "path/to/spec.yaml"
* }
*
* @author Jim Schubert
*/
open class ValidateTask : DefaultTask() {
@get:Internal
var inputSpec = project.objects.property<String>()
@Suppress("unused")
@get:Internal
@set:Option(option = "input", description = "The input specification.")
var input: String? = null
set(value) {
inputSpec.set(value)
}
@Suppress("unused")
@TaskAction
fun doWork() {
val spec = inputSpec.get()
logger.quiet("Validating spec $spec")
val result = OpenAPIParser().readLocation(spec, null, null)
val messages = result.messages.toSet()
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
if (messages.isNotEmpty()) {
out.withStyle(StyledTextOutput.Style.Error)
out.println("\nSpec is invalid.\nIssues:\n")
messages.forEach {
out.withStyle(StyledTextOutput.Style.Error)
out.println("\t$it\n")
}
throw GradleException("Validation failed.")
} else {
out.withStyle(StyledTextOutput.Style.Success)
out.println("Spec is valid.")
}
}
}

View File

@@ -1,71 +0,0 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GenerateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
private val defaultBuildGradle = """
plugins {
id 'org.openapi.generator'
}
openApiGenerate {
generatorName = "kotlin"
inputSpec = file("spec.yaml").absolutePath
outputDir = file("build/kotlin").absolutePath
apiPackage = "org.openapitools.example.api"
invokerPackage = "org.openapitools.example.invoker"
modelPackage = "org.openapitools.example.model"
configOptions = [
dateLibrary: "java8"
]
}
""".trimIndent()
@Test
fun `openApiGenerate should create an expected file structure from DSL config`() {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject(defaultBuildGradle, projectFiles)
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiGenerate")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("Successfully generated code to"), "User friendly generate notice is missing.")
listOf(
"build/kotlin/.openapi-generator-ignore",
"build/kotlin/docs/PetsApi.md",
"build/kotlin/docs/Pets.md",
"build/kotlin/docs/Error.md",
"build/kotlin/docs/Pet.md",
"build/kotlin/README.md",
"build/kotlin/build.gradle",
"build/kotlin/.openapi-generator/VERSION",
"build/kotlin/settings.gradle",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pets.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pet.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Error.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/api/PetsApi.kt",
"build/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt"
).map {
val f = File(temp, it)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation.")
}
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiGenerate")?.outcome}")
}
}

View File

@@ -1,38 +0,0 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GeneratorsTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
@Test
fun `openApiGenerators should list generators available to the user`() {
// Arrange
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
""".trimMargin())
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiGenerators")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("The following generators are available:"), "User friendly generator notice is missing.")
assertTrue(result.output.contains("CLIENT generators:"), "Expected client generator header is missing.")
assertTrue(result.output.contains("android"), "Spot-checking listed client generators is missing a client generator.")
assertTrue(result.output.contains("SERVER generators:"), "Expected server generator header is missing.")
assertTrue(result.output.contains("kotlin-server"), "Spot-checking listed server generators is missing a server generator.")
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerators")?.outcome,
"Expected a successful run, but found ${result.task(":openApiGenerators")?.outcome}")
}
}

View File

@@ -1,58 +0,0 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class MetaTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
@Test
fun `openApiMeta should generate desired project contents`() {
// Arrange
val buildDirReplacement = "\$buildDir/meta"
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiMeta {
| generatorName = "Sample"
| packageName = "org.openapitools.example"
| outputFolder = "$buildDirReplacement".toString()
| }
""".trimMargin())
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiMeta")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("Wrote file to"), "User friendly write notice is missing.")
// To avoid any OS-specific output causing issues with our stdout comparisons, only compare on expected filenames.
listOf(
"SampleGenerator.java",
"README.md",
"api.mustache",
"model.mustache",
"myFile.mustache",
"org.openapitools.codegen.CodegenConfig",
"pom.xml"
).map {
assertTrue(result.output.contains(it), "Expected $it to be listed in gradle stdout.")
}
assertEquals(
TaskOutcome.SUCCESS,
result.task(":openApiMeta")?.outcome,
"Expected a successful run, but found ${result.task(":openApiMeta")?.outcome}"
)
}
}

View File

@@ -1,34 +0,0 @@
package org.openapitools.generator.gradle.plugin
import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod
import java.io.File
import java.io.InputStream
abstract class TestBase {
protected open lateinit var temp: File
@BeforeMethod
protected fun before() {
temp = createTempDir(javaClass.simpleName)
temp.deleteOnExit()
}
@AfterMethod
protected fun after(){
temp.deleteRecursively()
}
protected fun withProject(
buildContents: String,
projectFiles: Map<String, InputStream> = mapOf()
) {
val buildFile = File(temp,"build.gradle")
buildFile.writeText(buildContents)
projectFiles.forEach { entry ->
val target = File(temp, entry.key)
entry.value.copyTo(target.outputStream())
}
}
}

View File

@@ -1,99 +0,0 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome.FAILED
import org.gradle.testkit.runner.TaskOutcome.SUCCESS
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ValidateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
@Test
fun `openApiValidate should fail on non-file spec`() {
// Arrange
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = "some_location"
| }
""".trimMargin())
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.buildAndFail()
// Assert
assertTrue(result.output.contains("unable to read location `some_location`"), "Unexpected/no message presented to the user for a spec pointing to an invalid URI.")
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
}
@Test
fun `openApiValidate should succeed on valid spec`() {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file("spec.yaml").absolutePath
| }
""".trimMargin(), projectFiles)
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.build()
// Assert
assertTrue(result.output.contains("Spec is valid."), "Unexpected/no message presented to the user for a valid spec.")
assertEquals(SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}")
}
@Test
fun `openApiValidate should fail on invalid spec`() {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
)
withProject("""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file('spec.yaml').absolutePath
| }
""".trimMargin(), projectFiles)
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.buildAndFail()
// Assert
assertTrue(result.output.contains("Spec is invalid."), "Unexpected/no message presented to the user for an invalid spec.")
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
}
}

View File

@@ -1,103 +0,0 @@
openapi: "3.0.0"
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -1,109 +0,0 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -181,3 +181,5 @@ compileTestKotlin {
jvmTarget = "1.8"
}
}
uploadArchives.dependsOn 'check'

View File

@@ -28,6 +28,7 @@ import org.gradle.kotlin.dsl.property
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.config.CodegenConfigurator
import org.openapitools.codegen.config.GeneratorProperties
/**
@@ -323,8 +324,6 @@ open class GenerateTask : DefaultTask() {
@get:Internal
val configOptions = project.objects.property<Map<String, String>>()
private val originalEnvironmentVariables = mutableMapOf<String, String?>()
private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) {
val item: T? = get()
@@ -352,36 +351,33 @@ open class GenerateTask : DefaultTask() {
try {
if (systemProperties.isPresent) {
systemProperties.get().forEach { (key, value) ->
// System.setProperty returns the original value for a key, or null.
// Cache the original value or null…we will late put the properties back in their original state.
originalEnvironmentVariables[key] = System.setProperty(key, value)
configurator.addSystemProperty(key, value)
}
}
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.SUPPORTING_FILES)
GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES)
}
if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
GeneratorProperties.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.MODELS)
GeneratorProperties.clearProperty(CodegenConstants.MODELS)
}
if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
System.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
GeneratorProperties.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
} else {
System.clearProperty(CodegenConstants.APIS)
GeneratorProperties.clearProperty(CodegenConstants.APIS)
}
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
System.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
// now override with any specified parameters
verbose.ifNotEmpty { value ->
@@ -541,14 +537,7 @@ open class GenerateTask : DefaultTask() {
throw GradleException("Code generation failed.", e)
}
} finally {
// Reset all modified system properties back to their original state
originalEnvironmentVariables.forEach {
when {
it.value == null -> System.clearProperty(it.key)
else -> System.setProperty(it.key, it.value)
}
}
originalEnvironmentVariables.clear()
GeneratorProperties.reset()
}
}
}

View File

@@ -48,14 +48,12 @@ class GenerateTaskDslTest : TestBase() {
listOf(
"build/kotlin/.openapi-generator-ignore",
"build/kotlin/docs/PetsApi.md",
"build/kotlin/docs/Pets.md",
"build/kotlin/docs/Error.md",
"build/kotlin/docs/Pet.md",
"build/kotlin/README.md",
"build/kotlin/build.gradle",
"build/kotlin/.openapi-generator/VERSION",
"build/kotlin/settings.gradle",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pets.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Pet.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/model/Error.kt",
"build/kotlin/src/main/kotlin/org/openapitools/example/api/PetsApi.kt",

View File

@@ -23,7 +23,7 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.2.5</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
@@ -34,12 +34,12 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.2.5</version>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.2.5</version>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>

View File

@@ -51,6 +51,7 @@ import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.config.GeneratorProperties;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.sonatype.plexus.build.incremental.DefaultBuildContext;
import org.slf4j.Logger;
@@ -144,12 +145,6 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "skipOverwrite", required = false)
private Boolean skipOverwrite;
/**
* Specifies if the existing files should be overwritten during the generation.
*/
@Parameter(name = "removeOperationIdPrefix", required = false)
private Boolean removeOperationIdPrefix;
/**
* The package to use for generated api objects/classes
*/
@@ -210,6 +205,36 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "ignoreFileOverride", required = false)
private String ignoreFileOverride;
/**
* To remove operationId prefix (e.g. user_getName => getName)
*/
@Parameter(name = "removeOperationIdPrefix", required = false)
private Boolean removeOperationIdPrefix;
/**
* To write all log messages (not just errors) to STDOUT
*/
@Parameter(name = "logToStderr", required = false)
private Boolean logToStderr;
/**
* To file post-processing hook
*/
@Parameter(name = "enablePostProcessFile", required = false)
private Boolean enablePostProcessFile;
/**
* To skip spec validation
*/
@Parameter(name = "skipValidateSpec", required = false)
private Boolean skipValidateSpec;
/**
* To generate alias (array, map) as model
*/
@Parameter(name = "generateAliasAsModel", required = false)
private Boolean generateAliasAsModel;
/**
* A map of language-specific parameters as passed with the -c option to the command line
*/
@@ -432,6 +457,22 @@ public class CodeGenMojo extends AbstractMojo {
configurator.setIgnoreFileOverride(ignoreFileOverride);
}
if (skipValidateSpec != null) {
configurator.setSkipOverwrite(skipValidateSpec);
}
if (logToStderr != null) {
configurator.setLogToStderr(logToStderr);
}
if (enablePostProcessFile != null) {
configurator.setEnablePostProcessFile(enablePostProcessFile);
}
if (generateAliasAsModel != null) {
configurator.setGenerateAliasAsModel(generateAliasAsModel);
}
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
if (isNotEmpty(generatorName)) {
configurator.setGeneratorName(generatorName);
@@ -499,28 +540,28 @@ public class CodeGenMojo extends AbstractMojo {
// Set generation options
if (null != generateApis && generateApis) {
System.setProperty(CodegenConstants.APIS, "");
GeneratorProperties.setProperty(CodegenConstants.APIS, "");
} else {
System.clearProperty(CodegenConstants.APIS);
GeneratorProperties.clearProperty(CodegenConstants.APIS);
}
if (null != generateModels && generateModels) {
System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
GeneratorProperties.setProperty(CodegenConstants.MODELS, modelsToGenerate);
} else {
System.clearProperty(CodegenConstants.MODELS);
GeneratorProperties.clearProperty(CodegenConstants.MODELS);
}
if (null != generateSupportingFiles && generateSupportingFiles) {
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
} else {
System.clearProperty(CodegenConstants.SUPPORTING_FILES);
GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES);
}
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.toString());
if (configOptions != null) {
// Retained for backwards-compataibility with configOptions -> instantiation-types
@@ -593,13 +634,13 @@ public class CodeGenMojo extends AbstractMojo {
if (environmentVariables != null) {
for (String key : environmentVariables.keySet()) {
originalEnvironmentVariables.put(key, System.getProperty(key));
originalEnvironmentVariables.put(key, GeneratorProperties.getProperty(key));
String value = environmentVariables.get(key);
if (value == null) {
// don't put null values
value = "";
}
System.setProperty(key, value);
GeneratorProperties.setProperty(key, value);
configurator.addSystemProperty(key, value);
}
}
@@ -680,9 +721,9 @@ public class CodeGenMojo extends AbstractMojo {
// when running the plugin multiple consecutive times with different configurations.
for (Map.Entry<String, String> entry : originalEnvironmentVariables.entrySet()) {
if (entry.getValue() == null) {
System.clearProperty(entry.getKey());
GeneratorProperties.clearProperty(entry.getKey());
} else {
System.setProperty(entry.getKey(), entry.getValue());
GeneratorProperties.setProperty(entry.getKey(), entry.getValue());
}
}
}

View File

@@ -0,0 +1,129 @@
package org.openapitools.codegen.online.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openapitools.codegen.online.model.ResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.text.MatchesPattern.matchesPattern;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(GenApiController.class)
public class GenApiControllerTest {
private static final String OPENAPI_URL = "http://petstore.swagger.io/v2/swagger.json";
private static final String UUID_REGEX = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[89aAbB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}";
@Autowired
private MockMvc mockMvc;
@Test
public void clientLanguages() throws Exception {
getLanguages("clients", "java");
}
@Test
public void serverFrameworks() throws Exception {
getLanguages("servers", "spring");
}
public void getLanguages(String type, String expected) throws Exception {
mockMvc.perform(get("/api/gen/" + type))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.[*]").value(hasItem(expected)));
}
@Test
public void clientOptions() throws Exception {
getOptions("clients", "java");
}
@Test
public void clientOptionsUnknown() throws Exception {
mockMvc.perform(get("/api/gen/clients/unknown"))
.andExpect(status().isNotFound());
}
@Test
public void serverOptions() throws Exception {
getOptions("servers", "spring");
}
@Test
public void serverOptionsUnknown() throws Exception {
mockMvc.perform(get("/api/gen/servers/unknown"))
.andExpect(status().isNotFound());
}
private void getOptions(String type, String name) throws Exception {
mockMvc.perform(get("/api/gen/" + type + "/" + name))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.sortParamsByRequiredFlag.opt").value("sortParamsByRequiredFlag"));
}
@Test
public void generateClient() throws Exception {
generateAndDownload("clients", "java");
}
@Test
public void generateServer() throws Exception {
generateAndDownload("servers", "spring");
}
private void generateAndDownload(String type, String name) throws Exception {
String result = mockMvc.perform(post("http://test.com:1234/api/gen/" + type + "/" + name)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX)))
.andExpect(jsonPath("$.link").value(matchesPattern("http\\:\\/\\/test.com\\:1234\\/api\\/gen\\/download\\/" + UUID_REGEX)))
.andReturn().getResponse().getContentAsString();
String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode();
mockMvc.perform(get("http://test.com:1234/api/gen/download/" + code))
.andExpect(content().contentType("application/zip"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CONTENT_LENGTH, not(0)));
}
@Test
public void generateWIthForwardedHeaders() throws Exception {
String result = mockMvc.perform(post("http://test.com:1234/api/gen/clients/java")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.header("X-Forwarded-Proto", "https")
.header("X-Forwarded-Host", "forwarded.com")
.header("X-Forwarded-Port", "5678")
.content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX)))
.andExpect(jsonPath("$.link").value(matchesPattern("https\\:\\/\\/forwarded.com\\:5678\\/api\\/gen\\/download\\/" + UUID_REGEX)))
.andReturn().getResponse().getContentAsString();
String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode();
mockMvc.perform(get("http://test.com:1234/api/gen/download/" + code))
.andExpect(content().contentType("application/zip"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CONTENT_LENGTH, not(0)));
}
}

View File

@@ -204,7 +204,7 @@
<version>${swagger-core-version}</version>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<groupId>${swagger-parser-groupid}</groupId>
<artifactId>swagger-parser</artifactId>
<version>${swagger-parser-version}</version>
</dependency>

View File

@@ -81,6 +81,8 @@ public interface CodegenConfig {
String escapeTextWhileAllowingNewLines(String text);
String encodePath(String text);
String escapeUnsafeCharacters(String input);
String escapeReservedWord(String name);
@@ -171,6 +173,8 @@ public interface CodegenConfig {
void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations);
Map<String, Object> updateAllModels(Map<String, Object> objs);
Map<String, Object> postProcessAllModels(Map<String, Object> objs);
Map<String, Object> postProcessModels(Map<String, Object> objs);
@@ -260,11 +264,11 @@ public interface CodegenConfig {
boolean isEnablePostProcessFile();
public void setEnablePostProcessFile(boolean isEnablePostProcessFile);
void setEnablePostProcessFile(boolean isEnablePostProcessFile);
// set OpenAPI and schemas
public void setGlobalOpenAPI(OpenAPI openAPI);
void setGlobalOpenAPI(OpenAPI openAPI);
public void setGlobalSchemas(OpenAPI openAPI);
void setGlobalSchemas(OpenAPI openAPI);
}

View File

@@ -45,7 +45,7 @@ public class CodegenConfigLoader {
// else try to load directly
try {
return (CodegenConfig) Class.forName(name).newInstance();
return (CodegenConfig) Class.forName(name).getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new GeneratorNotFoundException("Can't load config class with name '".concat(name) + "'\nAvailable:\n" + availableConfigs.toString(), e);
}

View File

@@ -283,4 +283,10 @@ public class CodegenConstants {
public static final String ENABLE_POST_PROCESS_FILE_DESC = "Enable post-processing file using environment variables.";
public static final String OPEN_API_SPEC_NAME = "openAPISpecName";
public static final String GENERATE_ALIAS_AS_MODEL = "generateAliasAsModel";
public static final String GENERATE_ALIAS_AS_MODEL_DESC = "Generate alias to map, array as models";
public static final String USE_COMPARE_NET_OBJECTS = "useCompareNetObjects";
public static final String USE_COMPARE_NET_OBJECTS_DESC = "Use KellermanSoftware.CompareNetObjects for deep recursive object comparison. WARNING: this option incurs potential performance impact.";
}

View File

@@ -22,11 +22,13 @@ import io.swagger.v3.oas.models.ExternalDocumentation;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.apache.commons.lang3.builder.ToStringBuilder;
@JsonIgnoreProperties({"parentModel", "interfaceModels"})
public class CodegenModel {
public String parent, parentSchema;
public List<String> interfaces;
public List<String> allParents;
// References to parent and interface CodegenModels. Only set when code generator supports inheritance.
public CodegenModel parentModel;
@@ -46,18 +48,18 @@ public class CodegenModel {
public String arrayModelType;
public boolean isAlias; // Is this effectively an alias of another simple type
public boolean isString, isInteger;
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>(); // all properties (without parent's properties)
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>(); // all properties (with parent's properties)
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties
public List<CodegenProperty> readOnlyVars = new ArrayList<CodegenProperty>(); // a list of read-only properties
public List<CodegenProperty> readWriteVars = new ArrayList<CodegenProperty>(); // a list of properties for read, write
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> parentVars = new ArrayList<CodegenProperty>();
public Map<String, Object> allowableValues;
// Sorted sets of required parameters.
public Set<String> mandatory = new TreeSet<String>();
public Set<String> allMandatory;
public Set<String> mandatory = new TreeSet<String>(); // without parent's required properties
public Set<String> allMandatory = new TreeSet<String>(); // with parent's required properties
public Set<String> imports = new TreeSet<String>();
public boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired, hasOptional, isArrayModel, hasChildren, isMapModel;
@@ -69,16 +71,59 @@ public class CodegenModel {
//The type of the value from additional properties. Used in map like objects.
public String additionalPropertiesType;
{
// By default these are the same collections. Where the code generator supports inheritance, composed models
// store the complete closure of owned and inherited properties in allVars and allMandatory.
allVars = vars;
allMandatory = mandatory;
}
@Override
public String toString() {
return String.format(Locale.ROOT, "%s(%s)", name, classname);
return new ToStringBuilder(this)
.append("parent", parent)
.append("parentSchema", parentSchema)
.append("interfaces", interfaces)
.append("parentModel", parentModel)
.append("interfaceModels", interfaceModels)
.append("children", children)
.append("name", name)
.append("classname", classname)
.append("title", title)
.append("description", description)
.append("classVarName", classVarName)
.append("modelJson", modelJson)
.append("dataType", dataType)
.append("xmlPrefix", xmlPrefix)
.append("xmlNamespace", xmlNamespace)
.append("xmlName", xmlName)
.append("classFilename", classFilename)
.append("unescapedDescription", unescapedDescription)
.append("discriminator", discriminator)
.append("defaultValue", defaultValue)
.append("arrayModelType", arrayModelType)
.append("isAlias", isAlias)
.append("isString", isString)
.append("isInteger", isInteger)
.append("vars", vars)
.append("requiredVars", requiredVars)
.append("optionalVars", optionalVars)
.append("readOnlyVars", readOnlyVars)
.append("readWriteVars", readWriteVars)
.append("allVars", allVars)
.append("parentVars", parentVars)
.append("allowableValues", allowableValues)
.append("mandatory", mandatory)
.append("allMandatory", allMandatory)
.append("imports", imports)
.append("hasVars", hasVars)
.append("emptyVars", emptyVars)
.append("hasMoreModels", hasMoreModels)
.append("hasEnums", hasEnums)
.append("isEnum", isEnum)
.append("hasRequired", hasRequired)
.append("hasOptional", hasOptional)
.append("isArrayModel", isArrayModel)
.append("hasChildren", hasChildren)
.append("isMapModel", isMapModel)
.append("hasOnlyReadOnly", hasOnlyReadOnly)
.append("externalDocumentation", externalDocumentation)
.append("vendorExtensions", vendorExtensions)
.append("additionalPropertiesType", additionalPropertiesType)
.toString();
}
@Override
@@ -94,6 +139,8 @@ public class CodegenModel {
return false;
if (interfaces != null ? !interfaces.equals(that.interfaces) : that.interfaces != null)
return false;
if (allParents != null ? !allParents.equals(that.allParents) : that.allParents != null)
return false;
if (parentModel != null ? !parentModel.equals(that.parentModel) : that.parentModel != null)
return false;
if (interfaceModels != null ? !interfaceModels.equals(that.interfaceModels) : that.interfaceModels != null)
@@ -169,6 +216,7 @@ public class CodegenModel {
int result = parent != null ? parent.hashCode() : 0;
result = 31 * result + (parentSchema != null ? parentSchema.hashCode() : 0);
result = 31 * result + (interfaces != null ? interfaces.hashCode() : 0);
result = 31 * result + (allParents != null ? allParents.hashCode() : 0);
result = 31 * result + (parentModel != null ? parentModel.hashCode() : 0);
result = 31 * result + (interfaceModels != null ? interfaceModels.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
@@ -226,10 +274,18 @@ public class CodegenModel {
return interfaces;
}
public List<String> getAllParents() {
return allParents;
}
public void setInterfaces(List<String> interfaces) {
this.interfaces = interfaces;
}
public void setAllParents(List<String> allParents) {
this.allParents = allParents;
}
public CodegenModel getParentModel() {
return parentModel;
}
@@ -560,4 +616,18 @@ public class CodegenModel {
}
}
}
/**
* Remove self reference import
*/
public void removeSelfReferenceImport() {
for (CodegenProperty cp : allVars) {
// detect self import
if (cp.dataType.equalsIgnoreCase(this.classname) ||
(cp.isContainer && cp.items.dataType.equalsIgnoreCase(this.classname))) {
this.imports.remove(this.classname); // remove self import
cp.isSelfReference = true;
}
}
}
}

View File

@@ -17,37 +17,14 @@
package org.openapitools.codegen;
import java.util.HashMap;
import java.util.Map;
import java.lang.reflect.InvocationTargetException;
public final class CodegenModelFactory {
private static final Map<CodegenModelType, Class<?>> typeMapping = new HashMap<CodegenModelType, Class<?>>();
/**
* Configure a different implementation class.
*
* @param type the type that shall be replaced
* @param implementation the implementation class must extend the default class and must provide a public no-arg constructor
*/
public static void setTypeMapping(CodegenModelType type, Class<?> implementation) {
if (!type.getDefaultImplementation().isAssignableFrom(implementation)) {
throw new IllegalArgumentException(implementation.getSimpleName() + " doesn't extend " + type.getDefaultImplementation().getSimpleName());
}
try {
implementation.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
typeMapping.put(type, implementation);
}
@SuppressWarnings("unchecked")
public static <T> T newInstance(CodegenModelType type) {
Class<?> classType = typeMapping.get(type);
try {
return (T) (classType != null ? classType : type.getDefaultImplementation()).newInstance();
} catch (IllegalAccessException | InstantiationException e) {
return (T) type.getDefaultImplementation().getDeclaredConstructor().newInstance();
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}

View File

@@ -53,7 +53,7 @@ public class CodegenProperty implements Cloneable {
public boolean exclusiveMaximum;
public boolean hasMore, required, secondaryParam;
public boolean hasMoreNonReadOnly; // for model constructor, true if next property is not readonly
public boolean isPrimitiveType, isModel, isContainer, isNotContainer;
public boolean isPrimitiveType, isModel, isContainer;
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile,
isBoolean, isDate, isDateTime, isUuid, isEmail, isFreeFormObject;
public boolean isListContainer, isMapContainer;
@@ -61,6 +61,7 @@ public class CodegenProperty implements Cloneable {
public boolean isReadOnly;
public boolean isWriteOnly;
public boolean isNullable;
public boolean isSelfReference;
public List<String> _enum;
public Map<String, Object> allowableValues;
public CodegenProperty items;
@@ -434,12 +435,12 @@ public class CodegenProperty implements Cloneable {
result = prime * result + ((hasMoreNonReadOnly ? 13 : 31));
result = prime * result + ((isContainer ? 13 : 31));
result = prime * result + (isEnum ? 1231 : 1237);
result = prime * result + ((isNotContainer ? 13 : 31));
result = prime * result + ((isPrimitiveType ? 13 : 31));
result = prime * result + ((isModel ? 13 : 31));
result = prime * result + ((isReadOnly ? 13 : 31));
result = prime * result + ((isWriteOnly ? 13 : 31));
result = prime * result + ((isNullable ? 13 : 31));
result = prime * result + ((isSelfReference ? 13 : 31));
result = prime * result + ((items == null) ? 0 : items.hashCode());
result = prime * result + ((mostInnerItems == null) ? 0 : mostInnerItems.hashCode());
result = prime * result + ((jsonSchema == null) ? 0 : jsonSchema.hashCode());
@@ -586,9 +587,6 @@ public class CodegenProperty implements Cloneable {
if (this.isContainer != other.isContainer) {
return false;
}
if (this.isNotContainer != other.isNotContainer) {
return false;
}
if (this.isEnum != other.isEnum) {
return false;
}
@@ -601,6 +599,9 @@ public class CodegenProperty implements Cloneable {
if (this.isNullable != other.isNullable) {
return false;
}
if (this.isSelfReference != other.isSelfReference ) {
return false;
}
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
return false;
}
@@ -772,7 +773,6 @@ public class CodegenProperty implements Cloneable {
", isPrimitiveType=" + isPrimitiveType +
", isModel=" + isModel +
", isContainer=" + isContainer +
", isNotContainer=" + isNotContainer +
", isString=" + isString +
", isNumeric=" + isNumeric +
", isInteger=" + isInteger +
@@ -795,6 +795,7 @@ public class CodegenProperty implements Cloneable {
", isReadOnly=" + isReadOnly +
", isWriteOnly=" + isWriteOnly +
", isNullable=" + isNullable +
", isSelfReference=" + isSelfReference +
", _enum=" + _enum +
", allowableValues=" + allowableValues +
", items=" + items +

View File

@@ -53,6 +53,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
import org.openapitools.codegen.config.GeneratorProperties;
import org.openapitools.codegen.examples.ExampleGenerator;
import org.openapitools.codegen.serializer.SerializerUtils;
import org.openapitools.codegen.utils.ModelUtils;
@@ -70,7 +71,6 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
@@ -82,8 +82,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
import static org.openapitools.codegen.utils.StringUtils.escape;
import static org.openapitools.codegen.utils.StringUtils.underscore;
public class DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
@@ -115,6 +115,7 @@ public class DefaultCodegen implements CodegenConfig {
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite;
protected boolean removeOperationIdPrefix;
protected boolean supportsMultipleInheritance;
protected boolean supportsInheritance;
protected boolean supportsMixins;
protected Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
@@ -207,58 +208,91 @@ public class DefaultCodegen implements CodegenConfig {
this.setEnablePostProcessFile(Boolean.valueOf(additionalProperties
.get(CodegenConstants.ENABLE_POST_PROCESS_FILE).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.GENERATE_ALIAS_AS_MODEL)) {
ModelUtils.setGenerateAliasAsModel(Boolean.valueOf(additionalProperties
.get(CodegenConstants.GENERATE_ALIAS_AS_MODEL).toString()));
}
}
// override with any special post-processing for all models
@SuppressWarnings({"static-method", "unchecked"})
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
if (supportsInheritance) {
// Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
}
return objs;
}
/**
* Loop through all models to update different flags (e.g. isSelfReference), children models, etc
*
* @param objs Map of models
* @return maps of models with various updates
*/
public Map<String, Object> updateAllModels(Map<String, Object> objs) {
// Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
}
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
}
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.getInterfaceModels().add(intfModel);
}
}
}
}
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
}
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.getChildren().add(cm);
parent.hasChildren = true;
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.getParent());
} else {
parent = null;
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.getInterfaceModels().add(intfModel);
}
}
}
}
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.getChildren().add(cm);
parent.hasChildren = true;
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.getParent());
} else {
parent = null;
}
}
}
// loop through properties of each model to detect self-reference
for (Map.Entry<String, Object> entry : objs.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
for (CodegenProperty cp : cm.allVars) {
// detect self import
if (cp.dataType.equalsIgnoreCase(cm.classname) ||
(cp.isContainer && cp.items.dataType.equalsIgnoreCase(cm.classname))) {
cm.imports.remove(cm.classname); // remove self import
cp.isSelfReference = true;
}
}
}
}
return objs;
}
@@ -303,7 +337,7 @@ public class DefaultCodegen implements CodegenConfig {
enumVar.put("isString", isDataTypeString(cm.dataType));
enumVars.add(enumVar);
}
// if "x-enum-varnames" defined, update varnames
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
updateEnumVarsWithExtensions(enumVars, cm.getVendorExtensions());
cm.allowableValues.put("enumVars", enumVars);
}
@@ -314,6 +348,30 @@ public class DefaultCodegen implements CodegenConfig {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.allVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.requiredVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.optionalVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.parentVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.readOnlyVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.readWriteVars) {
updateCodegenPropertyEnum(var);
}
}
return objs;
}
@@ -503,6 +561,12 @@ public class DefaultCodegen implements CodegenConfig {
.replace("\"", "\\\""));
}
// override with any special encoding and escaping logic
@SuppressWarnings("static-method")
public String encodePath(String input) {
return escapeText(input);
}
/**
* override with any special text escaping logic to handle unsafe
* characters so as to avoid code injection
@@ -1317,64 +1381,53 @@ public class DefaultCodegen implements CodegenConfig {
ComposedSchema cs = (ComposedSchema) schema;
List<Schema> schemas = ModelUtils.getInterfaces(cs);
if (cs.getAllOf() != null) {
for (Schema s : cs.getAllOf()) {
if (s != null) {
//schema = s;
}
//LOGGER.info("ALL OF SCHEMA: {}", s);
List<String> names = new ArrayList<>();
for (Schema s : schemas) {
names.add(getSingleSchemaType(s));
}
LOGGER.info("Composed schema not yet supported: {}", cs);
// get the model (allOf)
return getAlias("UNKNOWN_COMPOSED_SCHMEA");
if (names.size() == 0) {
LOGGER.error("allOf has no member defined: {}. Default to ERROR_ALLOF_SCHEMA", cs);
return "ERROR_ALLOF_SCHEMA";
} else if (names.size() == 1) {
return names.get(0);
} else {
LOGGER.warn("allOf with multiple schemas defined. Using only the first one: {}. To fully utilize allOf, please use $ref instead of inline schema definition", names.get(0));
return names.get(0);
}
} else if (cs.getAnyOf() != null) { // anyOf
List<String> names = new ArrayList<String>();
List<String> names = new ArrayList<>();
for (Schema s : schemas) {
if (StringUtils.isNotBlank(s.get$ref())) { // reference to another definition/schema
String schemaName = ModelUtils.getSimpleRef(s.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
names.add(getAlias(schemaName));
} else {
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
return "object";
}
} else {
// primitive type or model
names.add(getAlias(getPrimitiveType(s)));
}
return "anyOf<" + String.join(",", names) + ">";
names.add(getSingleSchemaType(s));
}
return "anyOf<" + String.join(",", names) + ">";
} else if (cs.getOneOf() != null) { // oneOf
List<String> names = new ArrayList<String>();
List<String> names = new ArrayList<>();
for (Schema s : schemas) {
if (StringUtils.isNotBlank(s.get$ref())) { // reference to another definition/schema
String schemaName = ModelUtils.getSimpleRef(s.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
names.add(getAlias(schemaName));
} else {
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
return "object";
}
} else {
// primitive type or model
names.add(getAlias(getPrimitiveType(s)));
}
return "oneOf<" + String.join(",", names) + ">";
names.add(getSingleSchemaType(s));
}
return "oneOf<" + String.join(",", names) + ">";
}
}
if (StringUtils.isNotBlank(schema.get$ref())) { // reference to another definition/schema
return getSingleSchemaType(schema);
}
private String getSingleSchemaType(Schema schema) {
Schema unaliasSchema = ModelUtils.unaliasSchema(globalSchemas, schema);
if (StringUtils.isNotBlank(unaliasSchema.get$ref())) { // reference to another definition/schema
// get the schema/model name from $ref
String schemaName = ModelUtils.getSimpleRef(schema.get$ref());
String schemaName = ModelUtils.getSimpleRef(unaliasSchema.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
return getAlias(schemaName);
} else {
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
LOGGER.warn("Error obtaining the datatype from ref:" + unaliasSchema.get$ref() + ". Default to 'object'");
return "object";
}
} else { // primitive type or model
return getAlias(getPrimitiveType(schema));
return getAlias(getPrimitiveType(unaliasSchema));
}
}
@@ -1451,14 +1504,15 @@ public class DefaultCodegen implements CodegenConfig {
}
/**
* Capitalize the string
* Capitalize the string. Please use org.openapitools.codegen.utils.StringUtils.camelize instead as this method will be deprecated.
*
* @param name string to be capitalized
* @return capitalized string
* @deprecated
*/
@SuppressWarnings("static-method")
public String initialCaps(String name) {
return StringUtils.capitalize(name);
return camelize(name);
}
/**
@@ -1554,7 +1608,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return capitalized model name
*/
public String toModelName(final String name) {
return initialCaps(modelNamePrefix + name + modelNameSuffix);
return initialCaps(modelNamePrefix + "_" + name + "_" + modelNameSuffix);
}
/**
@@ -1618,6 +1672,7 @@ public class DefaultCodegen implements CodegenConfig {
// parent model
final String parentName = ModelUtils.getParentName(composed, allDefinitions);
final List<String> allParents = ModelUtils.getAllParentsName(composed, allDefinitions);
final Schema parent = StringUtils.isBlank(parentName) || allDefinitions == null ? null : allDefinitions.get(parentName);
final boolean hasParent = StringUtils.isNotBlank(parentName);
@@ -1666,19 +1721,16 @@ public class DefaultCodegen implements CodegenConfig {
m.interfaces.add(modelName);
addImport(m, modelName);
if (allDefinitions != null && refSchema != null) {
if (hasParent || supportsInheritance) {
if (supportsInheritance || parentName.equals(modelName)) {
// inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else {
// composition
//LOGGER.debug("Parent {} not set to model name {}", parentName, modelName);
addProperties(properties, required, refSchema, allDefinitions);
}
} else if (!supportsMixins && !supportsInheritance) {
if (allParents.contains(modelName) && supportsMultipleInheritance) {
// multiple inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else if (parentName != null && parentName.equals(modelName) && supportsInheritance) {
// single inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else {
// composition
addProperties(properties, required, refSchema, allDefinitions);
}
}
if (composed.getAnyOf() != null) {
@@ -1696,13 +1748,16 @@ public class DefaultCodegen implements CodegenConfig {
if (parent != null) {
m.parentSchema = parentName;
m.parent = toModelName(parentName);
addImport(m, m.parent);
if (allDefinitions != null && !allDefinitions.isEmpty()) {
if (hasParent || supportsInheritance) {
addProperties(allProperties, allRequired, parent, allDefinitions);
} else {
addProperties(properties, required, parent, allDefinitions);
if (supportsMultipleInheritance) {
m.allParents = new ArrayList<String>();
for (String pname : allParents) {
String pModelName = toModelName(pname);
m.allParents.add(pModelName);
addImport(m, pModelName);
}
} else { // single inheritance
addImport(m, m.parent);
}
}
@@ -1713,15 +1768,14 @@ public class DefaultCodegen implements CodegenConfig {
// component is the child schema
addProperties(properties, required, component, allDefinitions);
if (hasParent || supportsInheritance) {
addProperties(allProperties, allRequired, component, allDefinitions);
}
// includes child's properties (all, required) in allProperties, allRequired
addProperties(allProperties, allRequired, component, allDefinitions);
}
break; // at most one schema not using $ref
break; // at most one child only
}
}
addVars(m, unaliasPropertySchema(allDefinitions, properties), required, allProperties, allRequired);
addVars(m, unaliasPropertySchema(allDefinitions, properties), required, unaliasPropertySchema(allDefinitions, allProperties), allRequired);
// end of code block for composed schema
} else {
@@ -1745,7 +1799,8 @@ public class DefaultCodegen implements CodegenConfig {
m.isString = Boolean.TRUE;
}
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired());
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired(), null, null);
}
// remove duplicated properties
@@ -1767,7 +1822,7 @@ public class DefaultCodegen implements CodegenConfig {
return null;
}
CodegenDiscriminator discriminator = new CodegenDiscriminator();
discriminator.setPropertyName(schema.getDiscriminator().getPropertyName());
discriminator.setPropertyName(toVarName(schema.getDiscriminator().getPropertyName()));
discriminator.setMapping(schema.getDiscriminator().getMapping());
if (schema.getDiscriminator().getMapping() != null && !schema.getDiscriminator().getMapping().isEmpty()) {
for (Entry<String, String> e : schema.getDiscriminator().getMapping().entrySet()) {
@@ -1785,7 +1840,7 @@ public class DefaultCodegen implements CodegenConfig {
.map(s -> ModelUtils.getSimpleRef(s.get$ref()))
.collect(Collectors.toSet());
if (parentSchemas.contains(schemaName)) {
discriminator.getMappedModels().add(new MappedModel(childName, childName));
discriminator.getMappedModels().add(new MappedModel(childName, toModelName(childName)));
}
}
});
@@ -1797,20 +1852,36 @@ public class DefaultCodegen implements CodegenConfig {
addParentContainer(codegenModel, codegenModel.name, schema);
}
/**
* Add schema's properties to "properties" and "required" list
*
* @param properties all properties
* @param required required property only
* @param schema schema in which the properties will be added to the lists
* @param allSchemas all schemas
*/
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema
schema, Map<String, Schema> allSchemas) {
if (schema instanceof ComposedSchema) {
ComposedSchema composedSchema = (ComposedSchema) schema;
if (composedSchema.getAllOf() == null) {
return;
}
for (Schema component : composedSchema.getAllOf()) {
addProperties(properties, required, component, allSchemas);
}
if (composedSchema.getOneOf() != null) {
throw new RuntimeException("Please report the issue: Cannot process oneOf (Composed Scheme) in addProperties: " + schema);
}
if (composedSchema.getAnyOf() != null) {
throw new RuntimeException("Please report the issue: Cannot process anyOf (Composed Schema) in addProperties: " + schema);
}
return;
}
Schema unaliasSchema = ModelUtils.unaliasSchema(globalSchemas, schema);
if (StringUtils.isNotBlank(schema.get$ref())) {
Schema interfaceSchema = allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref()));
addProperties(properties, required, interfaceSchema, allSchemas);
@@ -2047,6 +2118,8 @@ public class DefaultCodegen implements CodegenConfig {
allowableValues.put("values", _enum);
property.allowableValues = allowableValues;
}
} else if (ModelUtils.isFreeFormObject(p)){
property.isFreeFormObject = true;
}
property.dataType = getTypeDeclaration(p);
@@ -2260,11 +2333,13 @@ public class DefaultCodegen implements CodegenConfig {
if (property.defaultValue != null) {
property.defaultValue = property.defaultValue.replace(", " + property.items.baseType, ", " + toEnumName(property.items));
}
updateCodegenPropertyEnum(property);
}
}
protected void setNonArrayMapProperty(CodegenProperty property, String type) {
property.isNotContainer = true;
property.isContainer = false;
if (languageSpecificPrimitives().contains(type)) {
property.isPrimitiveType = true;
} else {
@@ -2838,7 +2913,7 @@ public class DefaultCodegen implements CodegenConfig {
}
codegenParameter.jsonSchema = Json.pretty(parameter);
if (System.getProperty("debugParser") != null) {
if (GeneratorProperties.getProperty("debugParser") != null) {
LOGGER.info("working on Parameter " + parameter.getName());
LOGGER.info("JSON schema: " + codegenParameter.jsonSchema);
}
@@ -2848,7 +2923,7 @@ public class DefaultCodegen implements CodegenConfig {
}
if (parameter.getSchema() != null) {
Schema parameterSchema = parameter.getSchema();
Schema parameterSchema = ModelUtils.unaliasSchema(globalSchemas, parameter.getSchema());
if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \"" + parameter.getName() + "\", using String");
parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition.");
@@ -2922,7 +2997,6 @@ public class DefaultCodegen implements CodegenConfig {
// set boolean flag (e.g. isString)
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
String parameterDataType = this.getParameterDataType(parameter, parameterSchema);
if (parameterDataType != null) {
codegenParameter.dataType = parameterDataType;
@@ -3425,49 +3499,69 @@ public class DefaultCodegen implements CodegenConfig {
return properties;
}
private void addVars(CodegenModel model, Map<String, Schema> properties, List<String> required) {
addVars(model, properties, required, null, null);
}
private void addVars(CodegenModel m, Map<String, Schema> properties, List<String> required,
Map<String, Schema> allProperties, List<String> allRequired) {
m.hasRequired = false;
if (properties != null && !properties.isEmpty()) {
m.hasVars = true;
m.hasEnums = false;
m.hasEnums = false; // TODO need to fix as its false in both cases
Set<String> mandatory = required == null ? Collections.<String>emptySet()
: new TreeSet<String>(required);
// update "vars" without parent's properties (all, required)
addVars(m, m.vars, properties, mandatory);
m.allMandatory = m.mandatory = mandatory;
} else {
m.emptyVars = true;
m.hasVars = false;
m.hasEnums = false;
m.hasEnums = false; // TODO need to fix as its false in both cases
}
if (allProperties != null) {
Set<String> allMandatory = allRequired == null ? Collections.<String>emptySet()
: new TreeSet<String>(allRequired);
// update "vars" with parent's properties (all, required)
addVars(m, m.allVars, allProperties, allMandatory);
m.allMandatory = allMandatory;
} else { // without parent, allVars and vars are the same
m.allVars = m.vars;
m.allMandatory = m.mandatory;
}
// loop through list to update property name with toVarName
Set<String> renamedMandatory = new TreeSet<String>();
Iterator<String> mandatoryIterator = m.mandatory.iterator();
while (mandatoryIterator.hasNext()) {
renamedMandatory.add(toVarName(mandatoryIterator.next()));
}
m.mandatory = renamedMandatory;
Set<String> renamedAllMandatory = new TreeSet<String>();
Iterator<String> allMandatoryIterator = m.allMandatory.iterator();
while (allMandatoryIterator.hasNext()) {
renamedAllMandatory.add(toVarName(allMandatoryIterator.next()));
}
m.allMandatory = renamedAllMandatory;
}
private void addVars(CodegenModel
m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
// convert set to list so that we can access the next entry in the loop
List<Map.Entry<String, Schema>> propertyList = new ArrayList<Map.Entry<String, Schema>>(properties.entrySet());
final int totalCount = propertyList.size();
for (int i = 0; i < totalCount; i++) {
Map.Entry<String, Schema> entry = propertyList.get(i);
/**
* Add variables (properties) to codegen model (list of properties, various flags, etc)
*
* @param m Codegen model
* @param vars list of codegen properties (e.g. vars, allVars) to be updated with the new properties
* @param properties a map of properties (schema)
* @param mandatory a set of required properties' name
*/
private void addVars(CodegenModel m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
final String key = entry.getKey();
final Schema prop = entry.getValue();
if (prop == null) {
LOGGER.warn("null property for " + key);
LOGGER.warn("Please report the issue. There shouldn't be null property for " + key);
} else {
final CodegenProperty cp = fromProperty(key, prop);
cp.required = mandatory.contains(key);
@@ -3484,14 +3578,7 @@ public class DefaultCodegen implements CodegenConfig {
m.hasOnlyReadOnly = false;
}
if (i + 1 != totalCount) {
cp.hasMore = true;
// check the next entry to see if it's read only
if (!Boolean.TRUE.equals(propertyList.get(i + 1).getValue().getReadOnly())) {
cp.hasMoreNonReadOnly = true; // next entry is not ready only
}
}
// TODO revise the logic to include map
if (cp.isContainer) {
addImport(m, typeMapping.get("array"));
}
@@ -3515,7 +3602,7 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(cp.isReadOnly)) {
m.readOnlyVars.add(cp);
} else { // else add to readWriteVars (list of properties)
// FIXME: readWriteVars can contain duplicated properties. Debug/breakpoint here while running C# generator (Dog and Cat models)
// duplicated properties will be removed by removeAllDuplicatedProperty later
m.readWriteVars.add(cp);
}
}
@@ -3947,6 +4034,9 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(property.isFile)) {
parameter.isFile = true;
}
if (Boolean.TRUE.equals(property.isModel)) {
parameter.isModel = true;
}
}
@@ -3994,8 +4084,9 @@ public class DefaultCodegen implements CodegenConfig {
enumVar.put("isString", isDataTypeString(dataType));
enumVars.add(enumVar);
}
// if "x-enum-varnames" defined, update varnames
updateEnumVarsWithExtensions(enumVars, var.getVendorExtensions());
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
Map<String, Object> extensions = var.mostInnerItems != null ? var.mostInnerItems.getVendorExtensions() : var.getVendorExtensions();
updateEnumVarsWithExtensions(enumVars, extensions);
allowableValues.put("enumVars", enumVars);
// handle default value for enum, e.g. available => StatusEnum.AVAILABLE
@@ -4013,13 +4104,19 @@ public class DefaultCodegen implements CodegenConfig {
}
}
private void updateEnumVarsWithExtensions
(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
if (vendorExtensions != null && vendorExtensions.containsKey("x-enum-varnames")) {
List<String> alias = (List<String>) vendorExtensions.get("x-enum-varnames");
int size = Math.min(enumVars.size(), alias.size());
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
if (vendorExtensions != null) {
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-varnames", "name");
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-descriptions", "enumDescription");
}
}
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions, String extensionKey, String key) {
if (vendorExtensions.containsKey(extensionKey)) {
List<String> values = (List<String>) vendorExtensions.get(extensionKey);
int size = Math.min(enumVars.size(), values.size());
for (int i = 0; i < size; i++) {
enumVars.get(i).put("name", alias.get(i));
enumVars.get(i).put(key, values.get(i));
}
}
}
@@ -4105,6 +4202,9 @@ public class DefaultCodegen implements CodegenConfig {
protected Parameter getParameterFromRef(String ref, OpenAPI openAPI) {
String parameterName = ref.substring(ref.lastIndexOf('/') + 1);
Map<String, Parameter> parameterMap = openAPI.getComponents().getParameters();
if (parameterMap == null ) { // can't find the ref
throw new RuntimeException(ref + " not defined in the spec.");
}
return parameterMap.get(parameterName);
}
@@ -4551,6 +4651,25 @@ public class DefaultCodegen implements CodegenConfig {
codegenProperty = codegenProperty.items;
}
} else if (ModelUtils.isFreeFormObject(schema)) {
// HTTP request body is free form object
CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema);
if (codegenProperty != null) {
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "body"; // default to body
} else {
codegenParameter.baseName = bodyParameterName;
}
codegenParameter.isPrimitiveType = true;
codegenParameter.baseType = codegenProperty.baseType;
codegenParameter.dataType = codegenProperty.dataType;
codegenParameter.description = codegenProperty.description;
codegenParameter.paramName = toParamName(codegenParameter.baseName);
}
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
// set nullable
setParameterNullable(codegenParameter, codegenProperty);
} else if (ModelUtils.isObjectSchema(schema) || ModelUtils.isComposedSchema(schema)) {
CodegenModel codegenModel = null;
if (StringUtils.isNotBlank(name)) {

View File

@@ -37,6 +37,7 @@ import io.swagger.v3.oas.models.tags.Tag;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.config.GeneratorProperties;
import org.openapitools.codegen.ignore.CodegenIgnoreProcessor;
import org.openapitools.codegen.utils.ImplementationVersion;
import org.openapitools.codegen.utils.ModelUtils;
@@ -129,9 +130,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
private void configureGeneratorProperties() {
// allows generating only models by specifying a CSV of models to generate, or empty for all
// NOTE: Boolean.TRUE is required below rather than `true` because of JVM boxing constraints and type inference.
generateApis = System.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
generateModels = System.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null);
generateSupportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null);
generateApis = GeneratorProperties.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
generateModels = GeneratorProperties.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null);
generateSupportingFiles = GeneratorProperties.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null);
if (generateApis == null && generateModels == null && generateSupportingFiles == null) {
// no specifics are set, generate everything
@@ -149,10 +150,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
// model/api tests and documentation options rely on parent generate options (api or model) and no other options.
// They default to true in all scenarios and can only be marked false explicitly
generateModelTests = System.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
generateModelDocumentation = System.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
generateApiTests = System.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
generateApiDocumentation = System.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true);
generateModelTests = GeneratorProperties.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
generateModelDocumentation = GeneratorProperties.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
generateApiTests = GeneratorProperties.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
generateApiDocumentation = GeneratorProperties.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true);
// Additional properties added for tests to exclude references in project related files
@@ -169,9 +170,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
}
if (System.getProperty("debugOpenAPI") != null) {
if (GeneratorProperties.getProperty("debugOpenAPI") != null) {
Json.prettyPrint(openAPI);
} else if (System.getProperty("debugSwagger") != null) {
} else if (GeneratorProperties.getProperty("debugSwagger") != null) {
// This exists for backward compatibility
// We fall to this block only if debugOpenAPI is null. No need to dump this twice.
LOGGER.info("Please use system property 'debugOpenAPI' instead of 'debugSwagger'.");
@@ -330,7 +331,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return;
}
String modelNames = System.getProperty("models");
String modelNames = GeneratorProperties.getProperty("models");
Set<String> modelsToGenerate = null;
if (modelNames != null && !modelNames.isEmpty()) {
modelsToGenerate = new HashSet<String>(Arrays.asList(modelNames.split(",")));
@@ -403,8 +404,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} */
});
Boolean skipFormModel = System.getProperty(CodegenConstants.SKIP_FORM_MODEL) != null ?
Boolean.valueOf(System.getProperty(CodegenConstants.SKIP_FORM_MODEL)) :
Boolean skipFormModel = GeneratorProperties.getProperty(CodegenConstants.SKIP_FORM_MODEL) != null ?
Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.SKIP_FORM_MODEL)) :
getGeneratorPropertyDefaultSwitch(CodegenConstants.SKIP_FORM_MODEL, false);
// process models only
@@ -429,18 +430,17 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Schema schema = schemas.get(name);
// check to see if it's a "map" model
if (ModelUtils.isMapSchema(schema)) {
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
if (ModelUtils.isFreeFormObject(schema)) { // check to see if it'a a free-form object
LOGGER.info("Model " + name + " not generated since it's a free-form object");
continue;
} else if (ModelUtils.isMapSchema(schema)) { // check to see if it's a "map" model
if (!ModelUtils.isGenerateAliasAsModel() && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
// schema without property, i.e. alias to map
LOGGER.info("Model " + name + " not generated since it's an alias to map (without property)");
continue;
}
}
// check to see if it's an "array" model
if (ModelUtils.isArraySchema(schema)) {
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
} else if (ModelUtils.isArraySchema(schema)) { // check to see if it's an "array" model
if (!ModelUtils.isGenerateAliasAsModel() && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
// schema without property, i.e. alias to array
LOGGER.info("Model " + name + " not generated since it's an alias to array (without property)");
continue;
@@ -458,6 +458,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
// loop through all models to update children models, isSelfReference, isCircularReference, etc
allProcessedModels = config.updateAllModels(allProcessedModels);
// post process all processed models
allProcessedModels = config.postProcessAllModels(allProcessedModels);
@@ -471,6 +474,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
continue;
}
// TODO revise below as we've already performed unaliasing so that the isAlias check may be removed
Map<String, Object> modelTemplate = (Map<String, Object>) ((List<Object>) models.get("models")).get(0);
// Special handling of aliases only applies to Java
if (modelTemplate != null && modelTemplate.containsKey("model")) {
@@ -497,7 +501,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
throw new RuntimeException("Could not generate model '" + modelName + "'", e);
}
}
if (System.getProperty("debugModels") != null) {
if (GeneratorProperties.getProperty("debugModels") != null) {
LOGGER.info("############ Model info ############");
Json.prettyPrint(allModels);
}
@@ -510,7 +514,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
Map<String, List<CodegenOperation>> paths = processPaths(this.openAPI.getPaths());
Set<String> apisToGenerate = null;
String apiNames = System.getProperty("apis");
String apiNames = GeneratorProperties.getProperty("apis");
if (apiNames != null && !apiNames.isEmpty()) {
apisToGenerate = new HashSet<String>(Arrays.asList(apiNames.split(",")));
}
@@ -533,9 +537,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
});
Map<String, Object> operation = processOperations(config, tag, ops, allModels);
URL url = URLPathUtils.getServerURL(openAPI);
operation.put("basePath", basePath);
operation.put("basePathWithoutHost", basePathWithoutHost);
operation.put("basePathWithoutHost", config.encodePath(url.getPath()).replaceAll("/$", ""));
operation.put("contextPath", contextPath);
operation.put("baseName", tag);
operation.put("apiPackage", config.apiPackage());
@@ -564,8 +568,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation op : operations) {
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
if (!op.vendorExtensions.containsKey("x-group-parameters")) {
if (isGroupParameters && !op.vendorExtensions.containsKey("x-group-parameters")) {
op.vendorExtensions.put("x-group-parameters", Boolean.TRUE);
}
}
@@ -651,7 +654,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
throw new RuntimeException("Could not generate api file for '" + tag + "'", e);
}
}
if (System.getProperty("debugOperations") != null) {
if (GeneratorProperties.getProperty("debugOperations") != null) {
LOGGER.info("############ Operation info ############");
Json.prettyPrint(allOperations);
}
@@ -663,7 +666,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return;
}
Set<String> supportingFilesToGenerate = null;
String supportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES);
String supportingFiles = GeneratorProperties.getProperty(CodegenConstants.SUPPORTING_FILES);
if (supportingFiles != null && !supportingFiles.isEmpty()) {
supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(",")));
}
@@ -836,6 +839,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (authMethods != null && !authMethods.isEmpty()) {
bundle.put("authMethods", authMethods);
bundle.put("hasAuthMethods", true);
if (hasOAuthMethods(authMethods)) {
bundle.put("hasOAuthMethods", true);
bundle.put("oauthMethods", getOAuthMethods(authMethods));
}
}
List<CodegenServer> servers = config.fromServers(openAPI.getServers());
@@ -856,7 +864,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
config.postProcessSupportingFileData(bundle);
if (System.getProperty("debugSupportingFiles") != null) {
if (GeneratorProperties.getProperty("debugSupportingFiles") != null) {
LOGGER.info("############ Supporting file info ############");
Json.prettyPrint(bundle);
}
@@ -874,13 +882,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
throw new RuntimeException("missing config!");
}
configureGeneratorProperties();
configureOpenAPIInfo();
// resolve inline models
InlineModelResolver inlineModelResolver = new InlineModelResolver();
inlineModelResolver.flatten(openAPI);
configureGeneratorProperties();
configureOpenAPIInfo();
List<File> files = new ArrayList<File>();
// models
List<String> filteredSchemas = ModelUtils.getSchemasUsedOnlyInFormParam(openAPI);
@@ -894,6 +902,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Map<String, Object> bundle = buildSupportFileBundle(allOperations, allModels);
generateSupportingFiles(files, bundle);
config.processOpenAPI(openAPI);
// reset GeneratorProperties, so that the running thread can be reused for another generator-run
GeneratorProperties.reset();
return files;
}
@@ -943,7 +955,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return;
}
if (System.getProperty("debugOperations") != null) {
if (GeneratorProperties.getProperty("debugOperations") != null) {
LOGGER.info("processOperation: resourcePath= " + resourcePath + "\t;" + httpMethod + " " + operation + "\n");
}
@@ -1129,6 +1141,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
mo.put("importPath", config.toModelImport(cm.classname));
models.add(mo);
cm.removeSelfReferenceImport();
allImports.addAll(cm.imports);
}
objs.put("models", models);
@@ -1173,4 +1187,26 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
return authMethods;
}
private boolean hasOAuthMethods(List<CodegenSecurity> authMethods) {
for (CodegenSecurity cs : authMethods) {
if (cs.isOAuth) {
return true;
}
}
return false;
}
private List<CodegenSecurity> getOAuthMethods(List<CodegenSecurity> authMethods) {
List<CodegenSecurity> oauthMethods = new ArrayList<>();
for (CodegenSecurity cs : authMethods) {
if (cs.isOAuth) {
oauthMethods.add(cs);
}
}
return oauthMethods;
}
}

View File

@@ -17,18 +17,16 @@
package org.openapitools.codegen;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.*;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,275 +40,278 @@ import io.swagger.v3.oas.models.media.XML;
public class InlineModelResolver {
private OpenAPI openapi;
private boolean skipMatches;
private Map<String, Schema> addedModels = new HashMap<String, Schema>();
private Map<String, String> generatedSignature = new HashMap<String, String>();
static Logger LOGGER = LoggerFactory.getLogger(InlineModelResolver.class);
Map<String, Schema> addedModels = new HashMap<String, Schema>();
Map<String, String> generatedSignature = new HashMap<String, String>();
public void flatten(OpenAPI openapi) {
void flatten(OpenAPI openapi) {
this.openapi = openapi;
if (openapi.getComponents() == null) {
return; // There's nothing here
openapi.setComponents(new Components());
}
if (openapi.getComponents().getSchemas() == null) {
openapi.getComponents().setSchemas(new HashMap<String, Schema>());
}
// operations
Map<String, PathItem> paths = openapi.getPaths();
Map<String, Schema> models = openapi.getComponents().getSchemas();
if (paths != null) {
for (String pathname : paths.keySet()) {
PathItem path = paths.get(pathname);
for (Operation operation : path.readOperations()) {
RequestBody requestBody = operation.getRequestBody();
if (requestBody != null) {
Schema model = ModelUtils.getSchemaFromRequestBody(requestBody);
if (model instanceof ObjectSchema) {
Schema obj = (Schema) model;
if (obj.getType() == null || "object".equals(obj.getType())) {
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
flattenProperties(obj.getProperties(), pathname);
// for model name, use "title" if defined, otherwise default to 'inline_object'
String modelName = resolveModelName(obj.getTitle(), "inline_object");
addGenerated(modelName, model);
openapi.getComponents().addSchemas(modelName, model);
// create request body
RequestBody rb = new RequestBody();
Content content = new Content();
MediaType mt = new MediaType();
Schema schema = new Schema();
schema.set$ref(modelName);
mt.setSchema(schema);
flattenPaths(openapi);
flattenComponents(openapi);
}
// get "consumes", e.g. application/xml, application/json
Set<String> consumes;
if (requestBody == null || requestBody.getContent() == null || requestBody.getContent().isEmpty()) {
consumes = new HashSet<>();
consumes.add("application/json"); // default to application/json
LOGGER.info("Default to application/json for inline body schema");
} else {
consumes = requestBody.getContent().keySet();
}
/**
* Flatten inline models in Paths
*
* @param openAPI target spec
*/
private void flattenPaths(OpenAPI openAPI) {
Paths paths = openAPI.getPaths();
if (paths == null) {
return;
}
for (String consume : consumes) {
content.addMediaType(consume, mt);
}
for (String pathname : paths.keySet()) {
PathItem path = paths.get(pathname);
for (Operation operation : path.readOperations()) {
flattenRequestBody(openAPI, pathname, operation);
flattenParameters(openAPI, pathname, operation);
flattenResponses(openAPI, pathname, operation);
}
}
}
rb.setContent(content);
/**
* Flatten inline models in RequestBody
*
* @param openAPI target spec
* @param pathname target pathname
* @param operation target operation
*/
private void flattenRequestBody(OpenAPI openAPI, String pathname, Operation operation) {
RequestBody requestBody = operation.getRequestBody();
if (requestBody == null) {
return;
}
// add to openapi "components"
if (openapi.getComponents().getRequestBodies() == null) {
Map<String, RequestBody> requestBodies = new HashMap<String, RequestBody>();
requestBodies.put(modelName, rb);
openapi.getComponents().setRequestBodies(requestBodies);
} else {
openapi.getComponents().getRequestBodies().put(modelName, rb);
}
Schema model = ModelUtils.getSchemaFromRequestBody(requestBody);
if (model instanceof ObjectSchema) {
Schema obj = (Schema) model;
if (obj.getType() == null || "object".equals(obj.getType())) {
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
flattenProperties(obj.getProperties(), pathname);
// for model name, use "title" if defined, otherwise default to 'inline_object'
String modelName = resolveModelName(obj.getTitle(), "inline_object");
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
// update requestBody to use $ref instead of inline def
requestBody.set$ref(modelName);
// create request body
RequestBody rb = new RequestBody();
Content content = new Content();
MediaType mt = new MediaType();
Schema schema = new Schema();
schema.set$ref(modelName);
mt.setSchema(schema);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), null);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
// get "consumes", e.g. application/xml, application/json
Set<String> consumes;
if (requestBody == null || requestBody.getContent() == null || requestBody.getContent().isEmpty()) {
consumes = new HashSet<>();
consumes.add("application/json"); // default to application/json
LOGGER.info("Default to application/json for inline body schema");
} else {
consumes = requestBody.getContent().keySet();
}
List<Parameter> parameters = operation.getParameters();
if (parameters != null) {
for (Parameter parameter : parameters) {
if (parameter.getSchema() != null) {
Schema model = parameter.getSchema();
if (model instanceof ObjectSchema) {
Schema obj = (Schema) model;
if (obj.getType() == null || "object".equals(obj.getType())) {
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
flattenProperties(obj.getProperties(), pathname);
String modelName = resolveModelName(obj.getTitle(), parameter.getName());
parameter.$ref(modelName);
addGenerated(modelName, model);
openapi.getComponents().addSchemas(modelName, model);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), parameter.getName());
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
}
for (String consume : consumes) {
content.addMediaType(consume, mt);
}
Map<String, ApiResponse> responses = operation.getResponses();
if (responses != null) {
for (String key : responses.keySet()) {
ApiResponse response = responses.get(key);
if (ModelUtils.getSchemaFromResponse(response) != null) {
Schema property = ModelUtils.getSchemaFromResponse(response);
if (property instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) property;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String modelName = resolveModelName(op.getTitle(), "inline_response_" + key);
Schema model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
Content content = response.getContent();
for (MediaType mediaType : content.values()) {
if (existing != null) {
Schema schema = this.makeSchema(existing, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
} else {
Schema schema = this.makeSchema(modelName, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
addGenerated(modelName, model);
openapi.getComponents().addSchemas(modelName, model);
}
}
}
} else if (property instanceof ArraySchema) {
ArraySchema ap = (ArraySchema) property;
Schema inner = ap.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = this.makeSchema(existing, op);
schema.setRequired(op.getRequired());
ap.setItems(schema);
} else {
Schema schema = this.makeSchema(modelName, op);
schema.setRequired(op.getRequired());
ap.setItems(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
} else if (property instanceof MapSchema) {
MapSchema mp = (MapSchema) property;
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
if (innerProperty instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) innerProperty;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
addGenerated(modelName, innerModel);
openapi.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
rb.setContent(content);
// add to openapi "components"
if (openAPI.getComponents().getRequestBodies() == null) {
Map<String, RequestBody> requestBodies = new HashMap<String, RequestBody>();
requestBodies.put(modelName, rb);
openAPI.getComponents().setRequestBodies(requestBodies);
} else {
openAPI.getComponents().getRequestBodies().put(modelName, rb);
}
// update requestBody to use $ref instead of inline def
requestBody.set$ref(modelName);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), null);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
/**
* Flatten inline models in parameters
*
* @param openAPI target spec
* @param pathname target pathname
* @param operation target operation
*/
private void flattenParameters(OpenAPI openAPI, String pathname, Operation operation) {
List<Parameter> parameters = operation.getParameters();
if (parameters == null) {
return;
}
for (Parameter parameter : parameters) {
if (parameter.getSchema() == null) {
continue;
}
Schema model = parameter.getSchema();
if (model instanceof ObjectSchema) {
Schema obj = (Schema) model;
if (obj.getType() == null || "object".equals(obj.getType())) {
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
flattenProperties(obj.getProperties(), pathname);
String modelName = resolveModelName(obj.getTitle(), parameter.getName());
parameter.$ref(modelName);
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), parameter.getName());
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
}
}
}
}
}
// definitions
if (models != null) {
List<String> modelNames = new ArrayList<String>(models.keySet());
for (String modelName : modelNames) {
Schema model = models.get(modelName);
if (model instanceof Schema) {
Schema m = (Schema) model;
Map<String, Schema> properties = m.getProperties();
flattenProperties(properties, modelName);
fixStringModel(m);
} else if (ModelUtils.isArraySchema(model)) {
ArraySchema m = (ArraySchema) model;
Schema inner = m.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String innerModelName = resolveModelName(op.getTitle(), modelName + "_inner");
Schema innerModel = modelFromProperty(op, innerModelName);
String existing = matchGenerated(innerModel);
if (existing == null) {
openapi.getComponents().addSchemas(innerModelName, innerModel);
addGenerated(innerModelName, innerModel);
Schema schema = new Schema().$ref(innerModelName);
schema.setRequired(op.getRequired());
m.setItems(schema);
} else {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
m.setItems(schema);
}
}
/**
* Flatten inline models in ApiResponses
*
* @param openAPI target spec
* @param pathname target pathname
* @param operation target operation
*/
private void flattenResponses(OpenAPI openAPI, String pathname, Operation operation) {
ApiResponses responses = operation.getResponses();
if (responses == null) {
return;
}
for (String key : responses.keySet()) {
ApiResponse response = responses.get(key);
if (ModelUtils.getSchemaFromResponse(response) == null) {
continue;
}
Schema property = ModelUtils.getSchemaFromResponse(response);
if (property instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) property;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String modelName = resolveModelName(op.getTitle(), "inline_response_" + key);
Schema model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
Content content = response.getContent();
for (MediaType mediaType : content.values()) {
if (existing != null) {
Schema schema = this.makeSchema(existing, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
} else {
Schema schema = this.makeSchema(modelName, property);
schema.setRequired(op.getRequired());
mediaType.setSchema(schema);
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
}
}
} else if (ModelUtils.isComposedSchema(model)) {
ComposedSchema m = (ComposedSchema) model;
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
Schema child = null;
for (Schema component : m.getAllOf()) {
if (component.get$ref() == null) {
child = component;
}
}
} else if (property instanceof ArraySchema) {
ArraySchema ap = (ArraySchema) property;
Schema inner = ap.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = this.makeSchema(existing, op);
schema.setRequired(op.getRequired());
ap.setItems(schema);
} else {
Schema schema = this.makeSchema(modelName, op);
schema.setRequired(op.getRequired());
ap.setItems(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
}
if (child != null) {
Map<String, Schema> properties = child.getProperties();
flattenProperties(properties, modelName);
}
}
} else if (property instanceof MapSchema) {
MapSchema mp = (MapSchema) property;
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
if (innerProperty instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) innerProperty;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(),
"inline_response_" + key);
Schema innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
} else {
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
mp.setAdditionalProperties(schema);
addGenerated(modelName, innerModel);
openAPI.getComponents().addSchemas(modelName, innerModel);
}
}
}
@@ -318,6 +319,65 @@ public class InlineModelResolver {
}
}
/**
* Flatten inline models in components
*
* @param openAPI target spec
*/
private void flattenComponents(OpenAPI openAPI) {
Map<String, Schema> models = openAPI.getComponents().getSchemas();
if (models == null) {
return;
}
List<String> modelNames = new ArrayList<String>(models.keySet());
for (String modelName : modelNames) {
Schema model = models.get(modelName);
if (model instanceof Schema) {
Schema m = (Schema) model;
Map<String, Schema> properties = m.getProperties();
flattenProperties(properties, modelName);
fixStringModel(m);
} else if (ModelUtils.isArraySchema(model)) {
ArraySchema m = (ArraySchema) model;
Schema inner = m.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String innerModelName = resolveModelName(op.getTitle(), modelName + "_inner");
Schema innerModel = modelFromProperty(op, innerModelName);
String existing = matchGenerated(innerModel);
if (existing == null) {
openAPI.getComponents().addSchemas(innerModelName, innerModel);
addGenerated(innerModelName, innerModel);
Schema schema = new Schema().$ref(innerModelName);
schema.setRequired(op.getRequired());
m.setItems(schema);
} else {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
m.setItems(schema);
}
}
}
} else if (ModelUtils.isComposedSchema(model)) {
ComposedSchema m = (ComposedSchema) model;
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
Schema child = null;
for (Schema component : m.getAllOf()) {
if (component.get$ref() == null) {
child = component;
}
}
if (child != null) {
Map<String, Schema> properties = child.getProperties();
flattenProperties(properties, modelName);
}
}
}
}
}
/**
* This function fix models that are string (mostly enum). Before this fix, the
* example would look something like that in the doc: "\"example from def\""
@@ -341,10 +401,7 @@ public class InlineModelResolver {
}
}
public String matchGenerated(Schema model) {
if (this.skipMatches) {
return null;
}
private String matchGenerated(Schema model) {
String json = Json.pretty(model);
if (generatedSignature.containsKey(json)) {
return generatedSignature.get(json);
@@ -352,17 +409,18 @@ public class InlineModelResolver {
return null;
}
public void addGenerated(String name, Schema model) {
private void addGenerated(String name, Schema model) {
generatedSignature.put(Json.pretty(model), name);
}
public String uniqueName(String key) {
private String uniqueName(String key) {
if (key == null) {
key = "NULL_UNIQUE_NAME";
LOGGER.warn("null key found. Default to NULL_UNIQUE_NAME");
}
int count = 0;
boolean done = false;
key = key.replaceAll("/", "_"); // e.g. /me/videos => _me_videos
key = key.replaceAll("[^a-z_\\.A-Z0-9 ]", ""); // FIXME: a parameter
// should not be assigned. Also declare the methods parameters as 'final'.
while (!done) {
@@ -380,7 +438,7 @@ public class InlineModelResolver {
return key;
}
public void flattenProperties(Map<String, Schema> properties, String path) {
private void flattenProperties(Map<String, Schema> properties, String path) {
if (properties == null) {
return;
}
@@ -465,28 +523,7 @@ public class InlineModelResolver {
}
}
@SuppressWarnings("static-method")
public Schema modelFromProperty(ArraySchema object, @SuppressWarnings("unused") String path) {
String description = object.getDescription();
String example = null;
Object obj = object.getExample();
if (obj != null) {
example = obj.toString();
}
Schema inner = object.getItems();
if (inner instanceof ObjectSchema) {
ArraySchema model = new ArraySchema();
model.setDescription(description);
model.setExample(example);
model.setItems(object.getItems());
model.setName(object.getName());
return model;
}
return null;
}
public Schema modelFromProperty(ObjectSchema object, String path) {
private Schema modelFromProperty(ObjectSchema object, String path) {
String description = object.getDescription();
String example = null;
Object obj = object.getExample();
@@ -508,22 +545,6 @@ public class InlineModelResolver {
return model;
}
@SuppressWarnings("static-method")
public Schema modelFromProperty(MapSchema object, @SuppressWarnings("unused") String path) {
String description = object.getDescription();
String example = null;
Object obj = object.getExample();
if (obj != null) {
example = obj.toString();
}
ArraySchema model = new ArraySchema();
model.setDescription(description);
model.setName(object.getName());
model.setExample(example);
model.setItems(ModelUtils.getAdditionalProperties(object));
return model;
}
/**
* Make a Schema
*
@@ -531,7 +552,7 @@ public class InlineModelResolver {
* @param property Schema
* @return {@link Schema} A constructed OpenAPI property
*/
public Schema makeSchema(String ref, Schema property) {
private Schema makeSchema(String ref, Schema property) {
Schema newProperty = new Schema().$ref(ref);
this.copyVendorExtensions(property, newProperty);
return newProperty;
@@ -544,7 +565,7 @@ public class InlineModelResolver {
* @param target target property
*/
public void copyVendorExtensions(Schema source, Schema target) {
private void copyVendorExtensions(Schema source, Schema target) {
Map<String, Object> vendorExtensions = source.getExtensions();
if (vendorExtensions == null) {
return;
@@ -553,12 +574,4 @@ public class InlineModelResolver {
target.addExtension(extName, vendorExtensions.get(extName));
}
}
public boolean isSkipMatches() {
return skipMatches;
}
public void setSkipMatches(boolean skipMatches) {
this.skipMatches = skipMatches;
}
}

View File

@@ -95,6 +95,7 @@ public class CodegenConfigurator implements Serializable {
private boolean verbose;
private boolean skipOverwrite;
private boolean removeOperationIdPrefix;
private boolean logToStderr;
private boolean validateSpec;
private boolean enablePostProcessFile;
private String templateDir;
@@ -220,6 +221,24 @@ public class CodegenConfigurator implements Serializable {
return this;
}
public boolean getLogToStderr() {
return logToStderr;
}
public CodegenConfigurator setLogToStderr(boolean logToStderrte) {
this.logToStderr = logToStderr;
return this;
}
public boolean isGenerateAliasAsModel() {
return ModelUtils.isGenerateAliasAsModel();
}
public CodegenConfigurator setGenerateAliasAsModel(boolean generateAliasAsModel) {
ModelUtils.setGenerateAliasAsModel(generateAliasAsModel);
return this;
}
public String getModelNameSuffix() {
return modelNameSuffix;
}
@@ -629,15 +648,15 @@ public class CodegenConfigurator implements Serializable {
"\n - [debugOperations] prints operations passed to the template engine" +
"\n - [debugSupportingFiles] prints additional data passed to the template engine");
System.setProperty("debugOpenAPI", "");
System.setProperty("debugModels", "");
System.setProperty("debugOperations", "");
System.setProperty("debugSupportingFiles", "");
GeneratorProperties.setProperty("debugOpenAPI", "");
GeneratorProperties.setProperty("debugModels", "");
GeneratorProperties.setProperty("debugOperations", "");
GeneratorProperties.setProperty("debugSupportingFiles", "");
}
private void setSystemProperties() {
for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
System.setProperty(entry.getKey(), entry.getValue());
GeneratorProperties.setProperty(entry.getKey(), entry.getValue());
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.config;
import java.util.Properties;
/**
* GeneratorProperties encapsulates SystemProperties, since the codegen mechanism heavily relies on a stable,
* non-changing System Property Basis. Using plain System.(get|set|clear)Property raises Race-Conditions in combination
* with Code, that uses System.setProperties (e.g. maven-surefire-plugin).
*
* @author gndrm
* @since 2018
*/
public class GeneratorProperties {
private static ThreadLocal<Properties> properties = new InheritableThreadLocal<Properties>() {
@Override
protected Properties initialValue() {
return (Properties) System.getProperties().clone();
};
};
public static String getProperty(String key, String defaultValue) {
return properties.get().getProperty(key, defaultValue);
}
public static String getProperty(String key) {
return properties.get().getProperty(key);
}
public static void setProperty(String key, String value) {
properties.get().setProperty(key, value);
}
public static void clearProperty(String key) {
properties.get().remove(key);
}
public static void reset() {
properties.remove();
}
}

View File

@@ -75,6 +75,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
protected Set<String> collectionTypes;
protected Set<String> mapTypes;
// true if support nullable type
protected boolean supportNullable = Boolean.FALSE;
// nullable type
protected Set<String> nullableType = new HashSet<String>();
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCSharpCodegen.class);
public AbstractCSharpCodegen() {
@@ -130,19 +136,26 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
"String",
"string",
"bool?",
"bool",
"double?",
"double",
"decimal?",
"decimal",
"int?",
"int",
"long?",
"long",
"float?",
"float",
"byte[]",
"ICollection",
"Collection",
"List",
"Dictionary",
"DateTime?",
"DateTime",
"DateTimeOffset?",
"String",
"DataTimeOffset",
"Boolean",
"Double",
"Int32",
@@ -157,6 +170,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
instantiationTypes.put("list", "List");
instantiationTypes.put("map", "Dictionary");
// Nullable types here assume C# 2 support is not part of base
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
@@ -176,6 +190,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
typeMapping.put("UUID", "Guid?");
// nullable type
nullableType = new HashSet<String>(
Arrays.asList("decimal", "bool", "int", "float", "long", "double", "DateTime", "Guid")
);
}
public void setReturnICollection(boolean returnICollection) {
@@ -209,8 +228,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
this.useDateTimeOffsetFlag = flag;
if (flag) {
typeMapping.put("DateTime", "DateTimeOffset?");
}
else {
} else {
typeMapping.put("DateTime", "DateTime?");
}
}
@@ -421,8 +439,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
for (Map.Entry<String, Object> entry : models.entrySet()) {
String swaggerName = entry.getKey();
CodegenModel model = ModelUtils.getModelByName(swaggerName, models);
String openAPIName = entry.getKey();
CodegenModel model = ModelUtils.getModelByName(openAPIName, models);
if (model != null) {
for (CodegenProperty var : model.allVars) {
if (enumRefs.containsKey(var.dataType)) {
@@ -483,7 +501,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
}
} else {
LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", swaggerName);
LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", openAPIName);
}
}
}
@@ -573,28 +591,30 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
}
for (CodegenParameter parameter: operation.allParams) {
CodegenModel model = null;
for(Object modelHashMap: allModels) {
CodegenModel codegenModel = ((HashMap<String, CodegenModel>) modelHashMap).get("model");
if (codegenModel.getClassname().equals(parameter.dataType)) {
model = codegenModel;
break;
if (!isSupportNullable()) {
for (CodegenParameter parameter : operation.allParams) {
CodegenModel model = null;
for (Object modelHashMap : allModels) {
CodegenModel codegenModel = ((HashMap<String, CodegenModel>) modelHashMap).get("model");
if (codegenModel.getClassname().equals(parameter.dataType)) {
model = codegenModel;
break;
}
}
}
if (model == null) {
// Primitive data types all come already marked
parameter.isNullable = true;
} else {
// Effectively mark enum models as enums and non-nullable
if (model.isEnum) {
parameter.isEnum = true;
parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true;
parameter.isNullable = false;
} else {
if (model == null) {
// Primitive data types all come already marked
parameter.isNullable = true;
} else {
// Effectively mark enum models as enums and non-nullable
if (model.isEnum) {
parameter.isEnum = true;
parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true;
parameter.isNullable = false;
} else {
parameter.isNullable = true;
}
}
}
}
@@ -792,6 +812,14 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return reservedWords.contains(word);
}
public String getNullableType(Schema p, String type) {
if (languageSpecificPrimitives.contains(type)) {
return type;
} else {
return null;
}
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
@@ -804,8 +832,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if (languageSpecificPrimitives.contains(type)) {
return type;
String languageType = getNullableType(p, type);
if (languageType != null) {
return languageType;
}
} else {
type = openAPIType;
@@ -950,6 +979,14 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
this.interfacePrefix = interfacePrefix;
}
public boolean isSupportNullable() {
return supportNullable;
}
public void setSupportNullable(final boolean supportNullable) {
this.supportNullable = supportNullable;
}
@Override
public String toEnumValue(String value, String datatype) {
// C# only supports enums as literals for int, int?, long, long?, byte, and byte?. All else must be treated as strings.
@@ -1011,7 +1048,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
@Override
public boolean isDataTypeString(String dataType) {
// also treat double/decimal/float as "string" in enum so that the values (e.g. 2.8) get double-quoted
return "String".equalsIgnoreCase(dataType) || "double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType);
return "String".equalsIgnoreCase(dataType) ||
"double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType) ||
"double".equals(dataType) || "decimal".equals(dataType) || "float".equals(dataType);
}
@Override

View File

@@ -43,15 +43,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.StringUtils.escape;
@@ -125,6 +117,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
setReservedWordsLowerCase(
Arrays.asList(
// special words
"object",
// used as internal variables, can collide with parameter names
"localVarPath", "localVarQueryParams", "localVarCollectionQueryParams",
"localVarHeaderParams", "localVarFormParams", "localVarPostBody",
@@ -542,17 +536,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/');
return (outputFolder + "/" + sourceFolder + "/" + apiPackage()).replace('.', File.separatorChar);
}
@Override
public String apiTestFileFolder() {
return outputFolder + "/" + testFolder + "/" + apiPackage().replace('.', '/');
return (outputFolder + "/" + testFolder + "/" + apiPackage()).replace('.', File.separatorChar);
}
@Override
public String modelTestFileFolder() {
return (outputFolder + "/" + testFolder + "/" + modelPackage()).replace('.', File.separatorChar);
}
@Override
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/');
return (outputFolder + "/" + sourceFolder + "/" + modelPackage()).replace('.', File.separatorChar);
}
@Override
@@ -580,6 +579,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return toApiName(name) + "Test";
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
@@ -1036,6 +1040,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
continue;
}
for (Operation operation : path.readOperations()) {
LOGGER.info("Processing operation " + operation.getOperationId());
if (hasBodyParameter(openAPI, operation) || hasFormParameter(openAPI, operation)) {
String defaultContentType = hasFormParameter(openAPI, operation) ? "application/x-www-form-urlencoded" : "application/json";
List<String> consumes = new ArrayList<String>(getConsumesInfo(openAPI, operation));
@@ -1052,8 +1057,9 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
protected static String getAccept(OpenAPI openAPI, Operation operation) {
String accepts = null;
String defaultContentType = "application/json";
ArrayList<String> produces = new ArrayList<String>(getProducesInfo(openAPI, operation));
if (produces != null && !produces.isEmpty()) {
Set<String> producesInfo = getProducesInfo(openAPI, operation);
if (producesInfo != null && !producesInfo.isEmpty()) {
ArrayList<String> produces = new ArrayList<String>(producesInfo);
StringBuilder sb = new StringBuilder();
for (String produce : produces) {
if (defaultContentType.equalsIgnoreCase(produce)) {
@@ -1432,4 +1438,13 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public void setParentOverridden(final boolean parentOverridden) {
this.parentOverridden = parentOverridden;
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
// See https://github.com/OpenAPITools/openapi-generator/pull/1729#issuecomment-449937728
codegenModel.additionalPropertiesType = getSchemaType(ModelUtils.getAdditionalProperties(schema));
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
}

View File

@@ -18,6 +18,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
@@ -352,9 +353,17 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
if (inner == null) {
LOGGER.warn(ap.getName() + "(array property) does not have a proper inner type defined.Default to string");
inner = new StringSchema().description("TODO default missing array inner type to string");
}
return getTypeDeclaration(inner) + "[]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
if (inner == null) {
LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined. Default to string");
inner = new StringSchema().description("TODO default missing map inner type to string");
}
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
} else if (StringUtils.isNotBlank(p.get$ref())) { // model
String type = super.getTypeDeclaration(p);

View File

@@ -54,6 +54,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
supportsInheritance = true;
// to support multiple inheritance e.g. export interface ModelC extends ModelA, ModelB
//supportsMultipleInheritance = true;
// NOTE: TypeScript uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
reservedWords.addAll(Arrays.asList(
// local variable names used in API methods (endpoints)

View File

@@ -83,6 +83,9 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
// use KellermanSoftware.CompareNetObjects for deep recursive object comparision
protected boolean useCompareNetObjects = Boolean.FALSE;
public CSharpClientCodegen() {
super();
supportsInheritance = true;
@@ -196,6 +199,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.VALIDATABLE_DESC,
this.validatable);
addSwitch(CodegenConstants.USE_COMPARE_NET_OBJECTS,
CodegenConstants.USE_COMPARE_NET_OBJECTS_DESC,
this.useCompareNetObjects);
regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline");
@@ -769,7 +776,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
}
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
@@ -798,6 +804,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.generatePropertyChanged = generatePropertyChanged;
}
public void setUseCompareNetObjects(final Boolean useCompareNetObjects) {
this.useCompareNetObjects = useCompareNetObjects;
}
public boolean isNonPublicApi() {
return nonPublicApi;
}

View File

@@ -22,6 +22,7 @@ import static org.apache.commons.lang3.StringUtils.isEmpty;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.CliOption;
@@ -32,6 +33,7 @@ import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,7 +51,7 @@ import static org.openapitools.codegen.utils.StringUtils.underscore;
public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
@SuppressWarnings({"hiding"})
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
private static final String NET45 = "v4.5";
private static final String NET45 = "v4.5.2";
private static final String NET40 = "v4.0";
private static final String NET35 = "v3.5";
// TODO: v5.0 is PCL, not netstandard version 1.3, and not a specific .NET Framework. This needs to be updated,
@@ -84,19 +86,39 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
public CSharpRefactorClientCodegen() {
super();
// mapped non-nullable type without ?
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("ByteArray", "byte[]");
typeMapping.put("boolean", "bool");
typeMapping.put("integer", "int");
typeMapping.put("float", "float");
typeMapping.put("long", "long");
typeMapping.put("double", "double");
typeMapping.put("number", "decimal");
typeMapping.put("DateTime", "DateTime");
typeMapping.put("date", "DateTime");
typeMapping.put("file", "System.IO.Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
typeMapping.put("UUID", "Guid");
setSupportNullable(Boolean.TRUE);
hideGenerationTimestamp = Boolean.TRUE;
supportsInheritance = true;
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
embeddedTemplateDir = templateDir = "csharp-refactor";
hideGenerationTimestamp = Boolean.TRUE;
cliOptions.clear();
// CLI options
@@ -127,7 +149,7 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
frameworks = new ImmutableMap.Builder<String, String>()
.put(NET35, ".NET Framework 3.5 compatible")
.put(NET40, ".NET Framework 4.0 compatible")
.put(NET45, ".NET Framework 4.5+ compatible")
.put(NET45, ".NET Framework 4.5.2+ compatible")
.put(NETSTANDARD, ".NET Standard 1.3 compatible")
.put(UWP, "Universal Windows Platform (IMPORTANT: this will be decommissioned and replaced by v5.0)")
.build();
@@ -223,7 +245,6 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
if (isEmpty(apiPackage)) {
setApiPackage("Api");
}
@@ -295,8 +316,10 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
setTargetFrameworkNuget("net40");
setSupportsAsync(Boolean.FALSE);
} else {
} else { // 4.5+
additionalProperties.put(MCS_NET_VERSION_KEY, "4.5.2-api");
// some libs need 452 isntead of 45 in the config
additionalProperties.put("isNet452", true);
setTargetFrameworkNuget("net45");
setSupportsAsync(Boolean.TRUE);
}
@@ -607,6 +630,10 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
public void postProcessParameter(CodegenParameter parameter) {
postProcessPattern(parameter.pattern, parameter.vendorExtensions);
super.postProcessParameter(parameter);
if (!parameter.required && nullableType.contains(parameter.dataType)) { //optional
parameter.dataType = parameter.dataType + "?";
}
}
@Override
@@ -850,4 +877,17 @@ public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
// To avoid unexpected behaviors when options are passed programmatically such as { "supportsAsync": "" }
return super.processCompiler(compiler).emptyStringIsFalse(true);
}
@Override
public String getNullableType(Schema p, String type) {
if (languageSpecificPrimitives.contains(type)) {
if (isSupportNullable() && ModelUtils.isNullable(p) && nullableType.contains(type)) {
return type + "?";
} else {
return type;
}
} else {
return null;
}
}
}

View File

@@ -447,7 +447,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
if (ElmVersion.ELM_018.equals(elmVersion)) {
String path = op.path;
for (CodegenParameter param : op.pathParams) {
final String var = paramToString(param, false, null);
final String var = paramToString("params", param, false, null);
path = path.replace("{" + param.paramName + "}", "\" ++ " + var + " ++ \"");
hasDateTime = hasDateTime || param.isDateTime;
hasDate = hasDate || param.isDate;
@@ -457,7 +457,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
final List<String> paths = Arrays.asList(op.path.substring(1).split("/"));
String path = paths.stream().map(str -> str.charAt(0) == '{' ? str : "\"" + str + "\"").collect(Collectors.joining(", "));
for (CodegenParameter param : op.pathParams) {
String str = paramToString(param, false, null);
String str = paramToString("params", param, false, null);
path = path.replace("{" + param.paramName + "}", str);
hasDateTime = hasDateTime || param.isDateTime;
hasDate = hasDate || param.isDate;
@@ -465,10 +465,15 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
op.path = path;
final String query = op.queryParams.stream()
.map(param -> paramToString(param, true, "Url.string \"" + param.paramName + "\""))
.map(param -> paramToString("params", param, true, "Url.string \"" + param.baseName + "\""))
.collect(Collectors.joining(", "));
op.vendorExtensions.put("query", query);
// TODO headers
final String headers = op.headerParams.stream()
.map(param -> paramToString("headers", param, true, "Http.header \"" + param.baseName + "\""))
.collect(Collectors.joining(", "));
op.vendorExtensions.put("headers", headers);
// TODO cookies
// TODO forms
}
@@ -563,8 +568,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
return "(Just " + value + ")";
}
private String paramToString(final CodegenParameter param, final boolean useMaybe, final String maybeMapResult) {
final String paramName = (ElmVersion.ELM_018.equals(elmVersion) ? "" : "params.") + param.paramName;
private String paramToString(final String prefix, final CodegenParameter param, final boolean useMaybe, final String maybeMapResult) {
final String paramName = (ElmVersion.ELM_018.equals(elmVersion) ? "" : prefix + ".") + param.paramName;
if (!useMaybe) {
param.required = true;
}
@@ -601,11 +606,15 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
}
String mapResult = "";
if (maybeMapResult != null) {
mapResult = maybeMapResult + (param.required ? " <|" : " <<");
if (mapFn == "") {
mapResult = maybeMapResult;
} else {
mapResult = maybeMapResult + (param.required ? " <|" : " <<");
}
}
final String just = useMaybe ? "Just (" : "";
final String justEnd = useMaybe ? ")" : "";
return (param.required ? just : "Maybe.map") + mapResult + " " + mapFn + " " + paramName + (param.required ? justEnd : "");
return (param.required ? just : "Maybe.map (") + mapResult + " " + mapFn + (param.required ? " " : ") ") + paramName + (param.required ? justEnd : "");
}
@Override

View File

@@ -64,6 +64,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String FEIGN_VERSION = "feignVersion";
public static final String PARCELABLE_MODEL = "parcelableModel";
public static final String USE_RUNTIME_EXCEPTION = "useRuntimeException";
public static final String USE_REFLECTION_EQUALS_HASHCODE = "useReflectionEqualsHashCode";
public static final String PLAY_24 = "play24";
public static final String PLAY_25 = "play25";
@@ -88,7 +89,9 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected String gradleWrapperPackage = "gradle.wrapper";
protected boolean useRxJava = false;
protected boolean useRxJava2 = false;
protected boolean doNotUseRx = true; // backwards compatibility for swagger configs that specify neither rx1 nor rx2 (mustache does not allow for boolean operators so we need this extra field)
// backwards compatibility for openapi configs that specify neither rx1 nor rx2
// (mustache does not allow for boolean operators so we need this extra field)
protected boolean doNotUseRx = true;
protected boolean usePlayWS = false;
protected String playVersion = PLAY_25;
protected String feignVersion = FEIGN_9;
@@ -97,7 +100,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected boolean performBeanValidation = false;
protected boolean useGzipFeature = false;
protected boolean useRuntimeException = false;
protected boolean useReflectionEqualsHashCode = false;
public JavaClientCodegen() {
super();
@@ -108,6 +111,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
apiPackage = "org.openapitools.client.api";
modelPackage = "org.openapitools.client.model";
modelTestTemplateFiles.put("model_test.mustache", ".java");
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA, "Whether to use the RxJava adapter with the retrofit2 library."));
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA2, "Whether to use the RxJava2 adapter with the retrofit2 library."));
cliOptions.add(CliOption.newBoolean(PARCELABLE_MODEL, "Whether to generate models for Android that implement Parcelable with the okhttp-gson library."));
@@ -119,6 +124,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_GZIP_FEATURE, "Send gzip-encoded requests"));
cliOptions.add(CliOption.newBoolean(USE_RUNTIME_EXCEPTION, "Use RuntimeException instead of Exception"));
cliOptions.add(CliOption.newBoolean(FEIGN_VERSION, "Version of OpenFeign: '10.x', '9.x' (default)"));
cliOptions.add(CliOption.newBoolean(USE_REFLECTION_EQUALS_HASHCODE, "Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact."));
supportedLibraries.put(JERSEY1, "HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.8.9. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.");
supportedLibraries.put(FEIGN, "HTTP client: OpenFeign 9.4.0. JSON processing: Jackson 2.8.9. To enable OpenFeign 10.x, set the 'feignVersion' option to '10.x'");
@@ -225,6 +231,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
this.setUseRuntimeException(convertPropertyToBooleanAndWriteBack(USE_RUNTIME_EXCEPTION));
}
if (additionalProperties.containsKey(USE_REFLECTION_EQUALS_HASHCODE)) {
this.setUseReflectionEqualsHashCode(convertPropertyToBooleanAndWriteBack(USE_REFLECTION_EQUALS_HASHCODE));
}
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
final String apiFolder = (sourceFolder + '/' + apiPackage).replace(".", "/");
@@ -632,6 +642,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
this.useRuntimeException = useRuntimeException;
}
public void setUseReflectionEqualsHashCode(boolean useReflectionEqualsHashCode) {
this.useReflectionEqualsHashCode = useReflectionEqualsHashCode;
}
final private static Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)application\\/json(;.*)?");
final private static Pattern JSON_VENDOR_MIME_PATTERN = Pattern.compile("(?i)application\\/vnd.(.*)+json(;.*)?");

View File

@@ -25,6 +25,7 @@ import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GeneratorProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,8 +61,8 @@ public class JavaInflectorServerCodegen extends AbstractJavaCodegen {
apiDocTemplateFiles.remove("api_doc.mustache");
apiPackage = System.getProperty("swagger.codegen.inflector.apipackage", "org.openapitools.controllers");
modelPackage = System.getProperty("swagger.codegen.inflector.modelpackage", "org.openapitools.model");
apiPackage = GeneratorProperties.getProperty("swagger.codegen.inflector.apipackage", "org.openapitools.controllers");
modelPackage = GeneratorProperties.getProperty("swagger.codegen.inflector.modelpackage", "org.openapitools.model");
additionalProperties.put("title", title);
// java inflector uses the jackson lib

View File

@@ -23,6 +23,7 @@ import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GeneratorProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,17 +56,17 @@ public class JavaUndertowServerCodegen extends AbstractJavaCodegen {
modelDocTemplateFiles.remove("model_doc.mustache");
apiDocTemplateFiles.remove("api_doc.mustache");
if(System.getProperty("swagger.codegen.undertow.apipackage") != null && System.getProperty("openapi.codegen.undertow.apipackage") == null) {
if(GeneratorProperties.getProperty("swagger.codegen.undertow.apipackage") != null && GeneratorProperties.getProperty("openapi.codegen.undertow.apipackage") == null) {
LOGGER.warn("System property 'swagger.codegen.undertow.apipackage' was renamed to 'swagger.codegen.undertow.apipackage'");
apiPackage = System.getProperty("swagger.codegen.undertow.apipackage", "org.openapitools.handler");
apiPackage = GeneratorProperties.getProperty("swagger.codegen.undertow.apipackage", "org.openapitools.handler");
} else {
apiPackage = System.getProperty("openapi.codegen.undertow.apipackage", "org.openapitools.handler");
apiPackage = GeneratorProperties.getProperty("openapi.codegen.undertow.apipackage", "org.openapitools.handler");
}
if(System.getProperty("swagger.codegen.undertow.modelpackage") != null && System.getProperty("openapi.codegen.undertow.modelpackage") == null) {
if(GeneratorProperties.getProperty("swagger.codegen.undertow.modelpackage") != null && GeneratorProperties.getProperty("openapi.codegen.undertow.modelpackage") == null) {
LOGGER.warn("System property 'swagger.codegen.undertow.modelpackage' was renamed to 'openapi.codegen.undertow.modelpackage'");
modelPackage = System.getProperty("swagger.codegen.undertow.modelpackage", "org.openapitools.model");
modelPackage = GeneratorProperties.getProperty("swagger.codegen.undertow.modelpackage", "org.openapitools.model");
} else {
modelPackage = System.getProperty("openapi.codegen.undertow.modelpackage", "org.openapitools.model");
modelPackage = GeneratorProperties.getProperty("openapi.codegen.undertow.modelpackage", "org.openapitools.model");
}
additionalProperties.put("title", title);

View File

@@ -103,7 +103,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
protected String modelDocPath = "docs/";
protected String apiTestPath = "api/";
protected String modelTestPath = "model/";
protected boolean useES6 = false; // default is ES5
protected boolean useES6 = true; // default is ES5
private String modelPropertyNaming = "camelCase";
public JavascriptClientCodegen() {
@@ -207,8 +207,8 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(USE_ES6,
"use JavaScript ES6 (ECMAScript 6) (beta). Default is ES5.")
.defaultValue(Boolean.FALSE.toString()));
"use JavaScript ES6 (ECMAScript 6) (beta). Default is ES6.")
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
}
@@ -1046,6 +1046,16 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
}
for (CodegenProperty var : cm.allVars) {
// Add JSDoc @type value for this property.
String jsDocType = getJSDocType(cm, var);
var.vendorExtensions.put("x-jsdoc-type", jsDocType);
if (Boolean.TRUE.equals(var.required)) {
required.add(var);
}
}
if (supportsInheritance || supportsMixins) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.required)) {

View File

@@ -101,6 +101,14 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
typeMapping.put("object", "Any");
typeMapping.put("binary", "Array<kotlin.Byte>");
typeMapping.put("date", "java.time.LocalDate");
typeMapping.put("date-time", "java.time.OffsetDateTime");
typeMapping.put("Date", "java.time.LocalDate");
typeMapping.put("DateTime", "java.time.OffsetDateTime");
importMapping.put("Date", "java.time.LocalDate");
importMapping.put("DateTime", "java.time.OffsetDateTime");
languageSpecificPrimitives.addAll(Arrays.asList(
"Any",
"Byte",
@@ -243,14 +251,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
public void processOpts() {
super.processOpts();
typeMapping.put("date", "java.time.LocalDate");
typeMapping.put("date-time", "java.time.OffsetDateTime");
typeMapping.put("Date", "java.time.LocalDate");
typeMapping.put("DateTime", "java.time.OffsetDateTime");
importMapping.put("Date", "java.time.LocalDate");
importMapping.put("DateTime", "java.time.OffsetDateTime");
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");

View File

@@ -34,6 +34,7 @@ import org.openapitools.codegen.CodegenResponse;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GeneratorProperties;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -351,7 +352,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
}
writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
if (System.getProperty("noservice") == null) {
if (GeneratorProperties.getProperty("noservice") == null) {
apiTemplateFiles.put(
"service.mustache", // the template to use
"Service.js"); // the extension for each file to write

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