Compare commits

..

95 Commits

Author SHA1 Message Date
devhl a60677705f why do i have to build again? 2023-01-28 23:39:07 -05:00
devhl a5cf2fac8f build all samples 2023-01-28 23:17:48 -05:00
devhl 70f4fcc872 build more csharp samples 2023-01-28 22:58:05 -05:00
devhl 6043942c1b fixed serialization of nullable guids 2023-01-28 22:43:49 -05:00
devhl-labs 57546d49c2 renamed json converter variables (#14555) 2023-01-29 10:58:53 +08:00
Beppe Catanese 1c157a2847 Support examples in Response Content (#14336)
* Add examples map and overload constructor

* Create CodegenMediaType with examples

* Add test
2023-01-28 12:42:00 +08:00
Martin Delille 03299528e9 Add conan badge (#14537) 2023-01-28 12:12:20 +08:00
bgong-mdsol 47813a88a2 update imports for enum (#14546) 2023-01-28 12:10:59 +08:00
itaru2622 4ffdadfbcc [python-nextgen] fix issue on API example doc autogeneration (#14539)
* [python-nextgen] fix template to make auto-generated example runnable when spec has no auth methods

* update samples with ./bin/generate-samples.sh

* add unit test code
2023-01-28 12:03:17 +08:00
DevFlorian 6a2d8d23da #8792 [Java] [jaxrs-cxf] "useAbstractionForFiles" config option for jaxrs-cxf (#14316)
* [REQ] Add equals and hashcode to java-cxf pojo #12519

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* fix sample

* fix sample

---------

Co-authored-by: FWermelskirchen <fwermelskirchen@eitco.de>
2023-01-28 11:37:08 +08:00
Oleh Kurpiak ac5134acf3 [Java] fix JsonTypeName import (#14474) (fix #12524) 2023-01-25 14:39:58 +02:00
Michael Ramstein 5047273f1e [elixir] Properly map AnyType (#14497) 2023-01-24 07:48:49 +01:00
tjbdev 82ac92aed6 [elixir] connection.ex typo fix (#14512) 2023-01-24 07:12:32 +01:00
Michael Ramstein ccbea26390 [elixir] Fixes issue with setting Header parameters (#14511)
* Fixes issue with request not beeing struct of Tesla.Env when setting a header parameter.
2023-01-23 22:03:05 +01:00
William Cheng 90e468b9a3 [java] Fix template logic related to supportUrlQuery (#14496)
* [java] Fix template logic related to supportUrlQuery

Generated models for arrays marked with uniqueItems: true (which end up as a Set<> in java) won't
compile because the templates are in some places using .get(i) on the sets.

Also, when the supportUrlQuery property is present in the additionalProperties map the
resulting value will be read using the key SUPPORT_STREAMING instead of 'supportUrlQuery'.

* fix NPE

Co-authored-by: Björgvin <bjorgvino@gmail.com>
2023-01-21 11:10:30 +08:00
devhl-labs d4c8c97e19 [csharp-netcore] Pipeline fix (#14495)
* trying to fix pipeline

* forcing pipeline to run

* reverting change to wrong branch

* forcing pipeline to run

* reverting change
2023-01-21 10:46:42 +08:00
William Cheng 5e7d31a83b add a rule to keep only the first tag (#14465) 2023-01-20 15:50:31 +08:00
William Cheng 4ecb9f4186 [java][native] Fix urlQuery string method in oneOf (#14488)
* better tests, fix oneOf in urlquery string method

* update samples

* update
2023-01-20 01:57:32 +08:00
Ian Cubbon 6e780218ad [Go] Client Models using AllOf, OneOf, or AnyOf Correctly Include time and os imports (Attempt 2) (#14459)
* Currently, if a Model is an allOf the time and os imports are not correctly added to the generated file. This was introduced recently with a fix to not include those imports when the model is a composedSchema #13833. The logic in that fix was just slightly off as an allOf should be treated the same as a standard model.

If a model is an AllOf or does not have any composed schemas at all, the sub-models are in-lined defined in the struct. In this case, the standard logic of including the time and os imports apply.

If a model is a OneOf or AnyOf, the sub-models are included as pointers to the defined model. In this case, do not include those items in the logic of including time and os imports.

* Update example to include a time in an allOf

* Add back the accidentally removed nil check
2023-01-20 01:53:19 +08:00
William Cheng 6cd7989e9e [Java][native][apache-httpclient] Update toUrlQueryString to support form style for object (#14478)
* update toUrlQueryString

* add new files

* minor bug fixes

* support object in query parameter - java apache httpclient

* rename variable - java native

* update samples

* fix try catch
2023-01-19 16:13:51 +08:00
William Cheng d1cde7febe Add 2 rules to OpenAPI Normalizer (#14463)
* add REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIIES_ONLY

* add rules to simplify anyOf

* fix rules, update docs

* remove test

* fix doc
2023-01-17 21:27:57 +08:00
Johnny Marnell c912bae3bc [Spring] Fix bean name collisions (#14092) (fix #14094)
* Use correct Pascal case for java enum

* Uniquely name @Bean annotations

* Use existing mustache var instead, run generate files

* rebase, re-run generators

* try to undo botched rebase/merge

* Attempt to manually undo whatever is going on w/ build, oops

* Attempt to manually undo whatever is going on w/ build, oops
2023-01-17 11:24:15 +02:00
Vikrant Balyan 9f502930ea [Go] Adds a sha256 configuration option to hs2019 (#14467)
* enables configuration of sha256 with hs2019

* committing generated examples

Co-authored-by: Aanisha Mishra <aanisha.mishra05@gmail.com>
Co-authored-by: Sebastien Rosset <serosset@cisco.com>
2023-01-16 23:21:53 +08:00
Marvin Rensing 4cd080762a [Java][Spring] fix RequestPart/RequestParam handling on multipart request for arrays (#14450) (fix #14449) 2023-01-16 11:39:51 +02:00
Ian Cubbon 74073df27c [GO][Client] Use a *os.File for the API Client when uploading and downloading (#14340)
* Change the return type of a file back to a pointer

* Change the api template to handle not double pointer-ing return types of os.File

* Fix unit tests

* Couple more unit test fixes
2023-01-16 16:51:04 +08:00
Oleh Kurpiak 27137e75ce [Java][Spring] fix ParameterObject import for Spring Boot 3 (#14454)
fix #14077
2023-01-14 08:00:32 -08:00
Paul Parenko be87382fde [Java][Spring] Fix #14398 springboot 3 schema required (#14402)
* fix depricated @Schema(required) since swagger 2.2.5

* use same swagger-annotations version which is used by swagger-core which is a dependency of springdoc

* generated java sampes
2023-01-14 06:59:33 -08:00
philkild 7958990254 Add CancellationToken to generated aspnetcore controller methods. (#14326) 2023-01-14 22:15:53 +08:00
Ian Cubbon 92775ceffc [Go] [Client] Don't Explode Query Params (#14447)
* If the collection type is csv, that means 'dont explode the query params'.

* Simplify the logic just a tad

* url.Values -> Has was added in go1.17 but there are CI tests running at 1.16
2023-01-14 00:48:27 +08:00
Bruno Coelho d348754399 [kotlin][client] add info if endpoints requires authentication or not (#14445)
* [kotlin][client] add info if endpoints requires authentication or not

* [kotlin][client] update sample projects

* [kotlin][client] add info if endpoints requires authentication or not

* [kotlin][client] update sample projects
2023-01-13 10:29:27 +00:00
Bruno Coelho b6ad68baca [swift5][client] - fix combine warning (#14444)
* [swift5][client] - fix combine warning

* [swift5][client] - fix combine warning

* [swift5][client] - update samples
2023-01-13 10:29:00 +00:00
William Cheng 079ad1742e update useRuntimeException description (#14452) 2023-01-13 17:38:31 +08:00
William Cheng cf4f2c76b2 Use inline allof instead of $ref in echo test (#14429)
* use inline allof instead of $ref in echo test

* update samples

* update samples

* fix tests
2023-01-13 17:21:28 +08:00
Sebastian Saip ed2029f863 [Java][Microprofile] fix useRuntimeException (#14409) (#14414)
Co-authored-by: Sebastian Saip <sebastian.saip@senacor.com>
2023-01-13 15:42:07 +08:00
devhl-labs 8abc750c0e [csharp-netcore] Added isNew property to CodegenProperty (#14412)
* added isNew property to CodegenModel

* build all samples
2023-01-13 14:43:33 +08:00
William Cheng 9fae221f1d [Java][okhttp-gson] add echo client test (#14442)
* add echo api tests for java okhttp client

* test okhttp gson echo client in jdk8 workflow

* update samples
2023-01-13 00:15:29 +08:00
Bruno Coelho b1f8f976c0 [swift5][client] - enable swift unit tests (#14441) 2023-01-12 15:10:15 +00:00
William Cheng a584f32d68 Add workflow to test java apache client with jdk8 (#14437)
* add workflow to test java apache client with jdk8

* fix url encode issue with jdk8

* update samples

* minor improvements in java native client

* minor fix
2023-01-12 22:12:08 +08:00
Paul Parenko c2c91e2d2e [Java][Spring] Fix #14362 when useSpringBoot3=true, then useJakartaEe=true (#14373) 2023-01-12 19:54:42 +08:00
Oleh Kurpiak 076b88429e [Java][Spring] fix param docs (#14426) 2023-01-12 19:53:01 +08:00
Chao Yang e1e291bc12 [Crystal] Skip primitive types from ModelImportMap (#14436)
* Support requiring models in crystal lang

* Return null instead of empty string
2023-01-12 19:42:33 +08:00
Bruno Coelho e8811ecd28 [swift5][client] - simplify async await (#14430)
* [swift5][client] - simplify async await

* [swift5][client] - update sample projects

* [swift5][client] - add more tests
2023-01-12 10:55:41 +00:00
William Cheng cffacc8023 fix deploy in travis (#14428) 2023-01-12 01:05:52 +08:00
Tino Fuhrmann a31b5b119e Documentation of Configuration/ConfigurationParameter for consolidated TypeScript generator (#10283)
* Added additional documentation for configuration object

* Regenerate samples

* Added exemplary usage of API to README.md

* Updated README, refined wording

* Added example for calling the API

* Regenerated samples

* Updated samples
2023-01-11 15:18:53 +01:00
Oleh Kurpiak 5dbfea6ecc [Java][Spring] fix default response code (#14399) 2023-01-11 20:34:58 +08:00
William Cheng 50e295e3c6 Fix missing import in allOf query parameters (#14408)
* add test for allOf in query parameter

* fix missing import in allof query parameter

* update samples

* update samples
2023-01-11 20:29:13 +08:00
William Cheng 3f96cdb756 Fix circleci build failure (node1) and Travis build failure (#14425)
* move python fastapi test to another node

* fix travis build

* fix install

* fix install

* fix install

* skip php test

* fix

* use trusty

* test bionic

* fix install

* fix pom

* skip perl test

* skip fastapitest
2023-01-11 20:28:53 +08:00
William Cheng e825f27b0b [java][apache-httpclient] Add deep object url query parameter support (#14417)
* add deep object url query parameter to java apache-httpclient

* update doc string
2023-01-11 11:04:14 +08:00
yosshi4486 4044e724c0 [Swift5] Add an async execute API to RequestBuilder<T> (#14416)
* Add async `execute` interface

* Update samples

Run `./bin/generate-samples.sh`

* Add an explicit `self`

I forgot to add it

* Add an availability condition
2023-01-10 17:05:52 +00:00
Maxime Dufour c6ea564600 [Java][Client Default] Support of AWS Signature V4 (#14287)
* Add support of AWSV4 Signature in Java

* Add Petstore sample for AWSV4 Signature

* Update other sample examples

* Sync Documentation and sample

* Specify only available for okhttp-gson in doc
2023-01-10 19:29:20 +08:00
Kalarrs Topham 0b8c08c7a0 Add .ToString() if is Uuid/Guid (#14321) 2023-01-10 09:17:04 +08:00
William Cheng a010713c42 update cli module dependencies (#14400) 2023-01-09 21:21:55 +08:00
William Cheng d269a2a09d Add deepObject query string support in Java native client (#14378)
* add deepObject query string support in java native client

* fix array of query parameters

* minor fix

* update samples

* fix test
2023-01-06 17:10:06 +08:00
William Cheng b22bf0a071 [js] fix boolean in oneOf, add tests (#14380) 2023-01-06 11:26:32 +08:00
William Cheng c514dc3c1b add java native jakarta samples for test (#14381) 2023-01-05 21:55:53 +08:00
William Cheng 9bbf729d5e Merge branch 'master' of https://github.com/OpenAPITools/openapi-generator 2023-01-05 15:48:56 +08:00
William Cheng 95eaff0a00 update samples 2023-01-05 15:48:45 +08:00
s-jepsen f848651b84 Fix @Generated annotation import for Java Native client. (#14376)
* Fix @Generated annotation import.

Apply fix to generatedAnnotation.mustache
Add changes to generated clients.

* Add changed files.
2023-01-05 15:42:20 +08:00
Oleh Kurpiak e1220071f0 [Java][Spring] fix RequestPart/RequestParam handling on multipart request (#14357) 2023-01-05 10:22:32 +08:00
Oleh Kurpiak ec9c7bdf2c [Java][Spring] fix EnumConverterConfiguration (#14356) 2023-01-05 10:19:17 +08:00
s-jepsen cce3c963f3 Added check for hasHttpSignatureMethods. (#14339) 2023-01-04 15:26:06 +08:00
David Gamero babfdff78a [typescript] migrate url-parse to URL WHATGW in https.ts (#14319)
* migrate

* remove extra blank line
2023-01-04 07:35:23 +01:00
Antoine Rey 917892db7d #14141 Add externalDocs to @Operation to the JavaSpring generator (#14177)
* #14141 Add externalDocs to @Operation to the JavaSpring generator

* #14141 Add externalDocs to @Operation to the JavaSpring generator : fix mustache template with #hasExternalDocs

* #14141 Add externalDocs to @Operation to the JavaSpring generator: fix indentation

* #14141 Add externalDocs to @Operation to the JavaSpring generator: fix carriage return

* #14141 Add externalDocs to @Operation to the JavaSpring generator: regenerate the spring-boot-oas3.yaml sample

* #14141 Add externalDocs to @Operation to the JavaSpring generator: generate-samples.sh

* #14141 Add externalDocs to @Operation to the JavaSpring generator: remove hasExternalDocs

* Fix ExternalDocumentation import generation and order

* #14141 Add externalDocs to @Operation to the JavaSpring generator: generate-samples.sh
2023-01-04 10:15:23 +08:00
Dan Michael O. Heggø 3dd313d35c [typescript] Add importFileExtension option to support ECMAScript module resolution (#14371)
* Rename 'extensionForDeno' to 'importFileExtension'

* Add importFileExtension option to typescript generator

* Fix typo, update docs

* Update docstring
2023-01-03 17:45:49 +01:00
Oleh Kurpiak 38fdbe0c2c [Java] fix bigDecimalAsString config option (#14370) 2023-01-03 23:49:08 +08:00
stropho a6eb96ea34 typescript-axios single request param in factory (#14358) 2023-01-03 08:22:38 +01:00
Beppe Catanese d0800c46e1 12551 [Go] Skipping marshalling of readonly fields (#14335)
* Skip toSerialize for readOnly fields

* Commit regenerated files
2023-01-02 23:35:54 +08:00
Julien Herr 921199bba7 [kotlin-spring] Move Jackson annotation from field to getter (#10825)
* Move Jackson annotation from field to getter

In some case, Jackson will duplicate entries when the annotation is on field
See https://github.com/FasterXML/jackson-databind/issues/1609

* Update samples
2023-01-02 15:32:57 +00:00
devhl-labs b8b8c5c208 [csharp-netcore] Added samples for composed schemas (#14348)
* added samples for composed schemas

* continue ignoring standard for now
2023-01-02 23:27:01 +08:00
devhl-labs 466495e919 added new pipeline to build standard (#14349) 2023-01-02 23:25:05 +08:00
William Cheng 421e7c9d3e [Java] Better tests for jakarta option (webclient, resttemplate) (#14363)
* test java jakarta in new workflow jdk 17

* update workflow

* skip jakarta test in jdk11
2023-01-02 20:55:39 +08:00
Paul Parenko fd2b141c53 when using useJakartaEe=true also set java 17 (#14360)
webclient now uses Sring Boot 3.0.1 with `useJakartaEe`
2023-01-02 20:29:32 +08:00
Ahmed Fwela da8d984ea4 [dart-dio] Fix non legacy discriminator behavior (#14291)
* override createDiscriminator

* assign discriminator = null to remove duplicates

* added discriminatorValue extension

* added _defaults

* formatting

* samples

* use gitter instead

* remove comment

* updated samples

* revert formatting changes

* update samples

* change file permissions

* remove discriminator check for anyOf

* add comment to createDiscriminator
2023-01-02 18:59:33 +08:00
Nick Ufer 16a7fb8acd [KOTLIN] feat: adds maven-publish to 'kotlin' client generator (#14344)
* [KOTLIN] feat: adds maven-publish to 'kotlin' client generator

* [KOTLIN] chore: regenerate samples
2023-01-02 09:20:41 +00:00
Oleh Kurpiak dc99a450dd [Java][Spring] fix @Operation content for array response (#14201) 2023-01-02 17:10:48 +08:00
Paul Parenko 456cca1a28 [Java] Fix #14276 Java Templates uses jakarta or javax package if useJakartaEe is enabled (#14343)
* Fix #14276 Java Templates uses jakarta or javax package if useJakartaEe
is true

* generated samples after useJakartaEe changes

* generated docs after useJakartaEe changes
2023-01-02 16:28:44 +08:00
William Cheng dee0703269 remove empty spaces in blank lines in python nextgen client (#14347) 2023-01-02 00:59:24 +08:00
tom300z 2236cebe02 Bugfixes for python-nextgen (#14334)
* Fix swapped operators

Signed-off-by: Tom Hörberg <tom@hoerberg.de>

* add conversion to support non-string params

Signed-off-by: Tom Hörberg <tom@hoerberg.de>

* Provide better fix for nonstring url param values

Signed-off-by: Tom Hörberg <tom@hoerberg.de>

* Updated python-nextgen sample files

Signed-off-by: Tom Hörberg <tom@hoerberg.de>

Signed-off-by: Tom Hörberg <tom@hoerberg.de>
2023-01-02 00:06:25 +08:00
Oleh Kurpiak be93d1f839 [Java][Jersey2] revert configurable javax package for javax.net (#14341) 2023-01-01 22:41:14 +08:00
Oleh Kurpiak 7c587ce061 [Java] configurable Javax/Jakarta package (#14310) 2022-12-30 22:33:55 +08:00
William Cheng b71aecbe9e Add OpenAPI Normalizer (#14172)
* add x-parent support

* add docstring

* add openapi normalizer rule to use ref as parent in allof

* add openapi normalizer with 1 rule

* revise wordings

* fix javadoc warnings

* better test

* fix docstring

* minor update

* minor improvements

* fix typo
2022-12-30 16:03:21 +08:00
William Cheng 3a8265b6ee Update opeanpi-generator dependencies (#14328)
* update openapi-generator dep

* update dep, fix tests with new spec

* update kotlin version

* revert cafferine version

* add back testng version and scope
2022-12-28 17:28:07 +08:00
Hui Yu 04ebe9e1a0 [C][Client] Check cJSON_IsNull when the data type is string (#14332) 2022-12-28 16:32:13 +08:00
Thomas von Rosenberg 88fa9ef3c2 [rust] Fix declaration for arrays with object and array references (#14198)
* [rust] Fix declaration for arrays with object and array references

For arrays with an item defined by reference to an array or an object,
the generated type declaration was `Vec<core::models::Array>` or
`Vec<core::models::Map>` without defining a `Array` or `Map` so that the
code didn't compile.

* [rust] Fix trailing whitespace in petstore definition
2022-12-28 15:08:21 +08:00
0xNF 341a8535c7 [Dart] Fix array of array nullable and non-nullable value generation (#13461)
* [Dart] Added non-invalid defaults for non nullable array of arrays (#13460)

* [Dart] Update samples
2022-12-28 00:01:08 +08:00
renaud-twd efdc94b113 Fix enum generation for php-symfony generator (#14105)
* fix(symfony): enum generation

* docs(php symfony): update samples and docs
2022-12-27 23:42:41 +08:00
Kristof Neirynck 8a2a059887 [Java] fix LocalTime import for dateLibrary java8 (#14111)
The import mapping for LocalTime still pointed to org.joda.time.*.
This one line made the jodatime dependency required.
2022-12-27 23:41:42 +08:00
Thomas von Rosenberg 63f6569e6f [rust] Fix model constructor for required enum array (#14196)
For a required enum array property the generated model constructor used
the type `RequiredEnums` instead of `Vec<RequiredEnums>`.
2022-12-27 23:25:01 +08:00
Dee Luo 444d411b5e perf: \GuzzleHttp\json_encode is deprecated, use \GuzzleHttp\Utils::jsonEncode instead (#14323) 2022-12-27 16:58:44 +08:00
William Cheng ad2e1b7e62 add test for debugSupportingFiles (#14331) 2022-12-27 16:53:54 +08:00
John Mitchell fd0bfae65a Java Feign - DefaultApi20Impl is only needed if OAuth is enabled (#14289)
* DefaultApi20Impl is only needed if OAuth is enabled

* Checking updated generate files
2022-12-27 16:50:08 +08:00
julien Lengrand-Lambert a99c58011a Add JsonIgnore annotation to avoid debugSupportingFiles creating heap space issues (#14298)
* Updates Codegen operation to ignore debugSupportingFiles

* Removes JsonIgnore annotation and rename method instead

* Remove unused import
2022-12-27 16:39:42 +08:00
William Cheng c27180849f fix gem bundler version (#14329) 2022-12-27 16:37:58 +08:00
William Cheng 68beec623f update swift samples 2022-12-27 16:00:36 +08:00
jase cfef750e18 [BUG][Swift] fix decimal encoding referencing not existing extension method "encodeToJSON" (#14307)
* feat: add decimal extension "encodeToJSON"

* feat: add decimal extension "encodeToJSON"
2022-12-25 11:02:07 +00:00
2929 changed files with 143705 additions and 19731 deletions
@@ -91,5 +91,7 @@ jobs:
git config --global core.safecrlf false
git config --global core.autocrlf true
mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true
# test with java (jersey2) client generation only as ensure-uptodate script is run in another job instead
# test with java (jersey2) client generation only as ensure-up-to-date script is run in another job instead
./bin/generate-samples.sh ./bin/configs/java-jersey2-8.yaml
# test debugSupportingFiles
./bin/generate-samples.sh ./bin/configs/python.yaml -- --global-property debugSupportingFiles
@@ -0,0 +1,30 @@
name: Samples C# .Net Standard
on:
push:
paths:
- 'samples/client/petstore/csharp-netcore/**netstandard**/'
pull_request:
paths:
- 'samples/client/petstore/csharp-netcore/**netstandard**/'
jobs:
build:
name: Build .Net projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# clients
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netstandard2.0
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.0.3
with:
dotnet-version: 3.1.*
- name: Build
working-directory: ${{ matrix.sample }}
run: dotnet build Org.OpenAPITools.sln
- name: Test
working-directory: ${{ matrix.sample }}
run: dotnet test Org.OpenAPITools.sln
+5
View File
@@ -4,11 +4,13 @@ on:
push:
paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore**/'
- 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
pull_request:
paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore**/'
- 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
jobs:
@@ -22,6 +24,9 @@ jobs:
# clients
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0-nrt
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore-latest-allOf
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore-latest-oneOf
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore-latest-anyOf
- samples/server/petstore/aspnetcore-6.0
- samples/server/petstore/aspnetcore-6.0-pocoModels
- samples/server/petstore/aspnetcore-6.0-project4Models
@@ -0,0 +1,48 @@
name: Java Client (Echo API) JDK8
on:
push:
paths:
- samples/client/echo_api/java/apache-httpclient/**
- samples/client/echo_api/java/feign-gson/**
- samples/client/echo_api/java/okhttp-gson/**
pull_request:
paths:
- samples/client/echo_api/java/apache-httpclient/**
- samples/client/echo_api/java/feign-gson/**
- samples/client/echo_api/java/okhttp-gson/**
jobs:
build:
name: Build Java Client JDK8
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# clients
- samples/client/echo_api/java/apache-httpclient
- samples/client/echo_api/java/feign-gson
- samples/client/echo_api/java/okhttp-gson
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 8
- name: Cache maven dependencies
uses: actions/cache@v3
env:
cache-name: maven-repository
with:
path: |
~/.m2
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Setup node.js
uses: actions/setup-node@v3
- name: Run echo server
run: |
git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server
(cd http-echo-server && npm install && npm start &)
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package
@@ -8,7 +8,7 @@ on:
- samples/client/petstore/java-micronaut-client/**
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters/**
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
- samples/openapi3/client/petstore/java/native/**
- samples/openapi3/client/petstore/java/native**
pull_request:
paths:
- 'samples/client/petstore/java/**'
@@ -16,7 +16,7 @@ on:
- samples/client/petstore/java-micronaut-client/**
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters/**
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
- samples/openapi3/client/petstore/java/native/**
- samples/openapi3/client/petstore/java/native**
jobs:
build:
name: Build Java Client JDK11
@@ -29,6 +29,7 @@ jobs:
- samples/client/petstore/jaxrs-cxf-client
- samples/client/petstore/java/native
- samples/client/petstore/java/native-async
- samples/client/petstore/java/native-jakarta
- samples/client/petstore/java/retrofit2
- samples/client/petstore/java/retrofit2rx2
- samples/client/petstore/java/retrofit2rx3
@@ -0,0 +1,39 @@
name: Samples Java Client JDK17
on:
push:
paths:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
pull_request:
paths:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
jobs:
build:
name: Build Java Client JDK17
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# clients
- samples/client/petstore/java/resttemplate-jakarta
- samples/client/petstore/java/webclient-jakarta
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
- name: Cache maven dependencies
uses: actions/cache@v3
env:
cache-name: maven-repository
with:
path: |
~/.m2
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package
+31 -30
View File
@@ -50,15 +50,16 @@ before_install:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge"
- sudo apt-get update
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
#- sudo apt-get install -qqy --no-install-recommends google-chrome-stable
#- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- mkdir -vp ~/.docker/cli-plugins/
- curl --silent -L "https://github.com/docker/buildx/releases/download/v0.3.0/buildx-v0.3.0.linux-amd64" > ~/.docker/cli-plugins/docker-buildx
- chmod a+x ~/.docker/cli-plugins/docker-buildx
# to run petstore server locally via docker
- echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin || true
- docker pull swaggerapi/petstore
- docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
- docker ps -a
#- echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin || true
#- docker pull swaggerapi/petstore
#- docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
#- docker ps -a
# comment out crystal installation as the tests will run on circleci or github action instead
# install crystal
#- echo 'deb http://download.opensuse.org/repositories/devel:/languages:/crystal/xUbuntu_16.04/ /' | sudo tee /etc/apt/sources.list.d/devel:languages:crystal.list
@@ -69,11 +70,11 @@ before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.22.0
- export PATH="$HOME/.yarn/bin:$PATH"
# install rust
- curl https://sh.rustup.rs -sSf | sh -s -- -y -v
# required when sudo: required for the Ruby petstore tests
- gem install bundler
# set python 3.6.3 as default
- source ~/virtualenv/python3.6/bin/activate
#- curl https://sh.rustup.rs -sSf | sh -s -- -y -v
## required when sudo: required for the Ruby petstore tests
#- gem install bundler -v 2.3.26
## set python 3.6.3 as default
#- source ~/virtualenv/python3.6/bin/activate
# -- skip bash test to shorten build time
# Add bats test framework and cURL for Bash script integration tests
#- sudo add-apt-repository ppa:duggan/bats --yes
@@ -88,18 +89,18 @@ before_install:
#- sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
#- sudo apt-get update
#- sudo apt-get install dart
# switch to php7
- sudo apt-get install libonig-dev libzip-dev
- git clone https://github.com/php-build/php-build $(phpenv root)/plugins/php-build
- git clone https://github.com/ngyuki/phpenv-composer.git $(phpenv root)/plugins/phpenv-composer
- if [ $(ls -A "$HOME/.phpenv/versions/8.1.4" | wc -l) -eq 0 ]; then
phpenv install 8.1.4;
fi;
- phpenv rehash
- phpenv versions
#- phpenv global 7.2.15
- phpenv global 8.1.4
- php -v
# switch to php8
#- sudo apt-get install -f libonig-dev libzip-dev
#- git clone https://github.com/php-build/php-build $(phpenv root)/plugins/php-build
#- git clone https://github.com/ngyuki/phpenv-composer.git $(phpenv root)/plugins/phpenv-composer
#- if [ $(ls -A "$HOME/.phpenv/versions/8.1.4" | wc -l) -eq 0 ]; then
# phpenv install 8.1.4;
# fi;
#- phpenv rehash
#- phpenv versions
##- phpenv global 7.2.15
#- phpenv global 8.1.4
#- php -v
# comment out below as installation failed in travis
# Add rebar3 build tool and recent Erlang/OTP for Erlang petstore server tests.
# - Travis CI does not support rebar3 [yet](https://github.com/travis-ci/travis-ci/issues/6506#issuecomment-275189490).
@@ -107,15 +108,15 @@ before_install:
# - . ~/otp/18.2.1/activate && erl -version
#- curl -f -L -o ./rebar3 https://s3.amazonaws.com/rebar3/rebar3 && chmod +x ./rebar3 && ./rebar3 version && export PATH="${TRAVIS_BUILD_DIR}:$PATH"
# install C++ tools
- sudo apt install -y --no-install-recommends valgrind cmake build-essential
- cmake --version
#- sudo apt install -y --no-install-recommends valgrind cmake build-essential
#- cmake --version
# install Qt5
#- sudo apt install -y --no-install-recommends qt5-default
# install boost
- sudo apt install -y --no-install-recommends libboost-all-dev
#- sudo apt install -y --no-install-recommends libboost-all-dev
# perl dep
- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
- cpanm --quiet --no-interactive Test::Exception Test::More Log::Any LWP::UserAgent URI::Query Module::Runtime DateTime Module::Find Moose::Role JSON || echo "Ignored failure from cpanm"
#- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
#- cpanm --quiet --no-interactive Test::Exception Test::More Log::Any LWP::UserAgent URI::Query Module::Runtime DateTime Module::Find Moose::Role JSON || echo "Ignored failure from cpanm"
# show host table to confirm petstore.swagger.io is mapped to localhost
- cat /etc/hosts
# show java version
@@ -127,8 +128,8 @@ before_install:
fi;
- pushd .; cd website; yarn install; popd
# install Deno
- sh -s v1.6.2 < ./CI/deno_install.sh
- export PATH="$HOME/.deno/bin:$PATH"
#- sh -s v1.6.2 < ./CI/deno_install.sh
#- export PATH="$HOME/.deno/bin:$PATH"
install:
# Add Godeps dependencies to GOPATH and PATH
@@ -150,7 +151,7 @@ script:
# run integration tests defined in maven pom.xml
# WARN: Travis will timeout after 10 minutes of no stdout/stderr activity, which is problematic with mvn --quiet.
- mvn -e --no-snapshot-updates --quiet --batch-mode --show-version clean install -Dorg.slf4j.simpleLogger.defaultLogLevel=error
- mvn -e --no-snapshot-updates --quiet --batch-mode --show-version verify -Psamples -Dorg.slf4j.simpleLogger.defaultLogLevel=error
#- mvn -e --no-snapshot-updates --quiet --batch-mode --show-version verify -Psamples -Dorg.slf4j.simpleLogger.defaultLogLevel=error
after_success:
# push to maven repo
- if [ $SONATYPE_USERNAME ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
+7 -1
View File
@@ -3,7 +3,13 @@
<div align="center">
[![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22) [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE) [![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator) [![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g) [![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator) [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/OpenAPITools/openapi-generator)
[![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22)
[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE)
[![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator)
[![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g)
[![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator)
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/OpenAPITools/openapi-generator)
[![Conan Center](https://shields.io/conan/v/openapi-generator)](https://conan.io/center/openapi-generator)
</div>
@@ -0,0 +1,12 @@
# for csharp-netcore generichost
generatorName: csharp-netcore
outputDir: samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore-latest-allOf
inputSpec: modules/openapi-generator/src/test/resources/3_0/allOf.yaml
library: generichost
templateDir: modules/openapi-generator/src/main/resources/csharp-netcore
additionalProperties:
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
useCompareNetObjects: true
disallowAdditionalPropertiesIfNotPresent: false
targetFramework: net7.0
nullableReferenceTypes: true
@@ -0,0 +1,12 @@
# for csharp-netcore generichost
generatorName: csharp-netcore
outputDir: samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore-latest-anyOf
inputSpec: modules/openapi-generator/src/test/resources/3_0/anyOf.yaml
library: generichost
templateDir: modules/openapi-generator/src/main/resources/csharp-netcore
additionalProperties:
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
useCompareNetObjects: true
disallowAdditionalPropertiesIfNotPresent: false
targetFramework: net7.0
nullableReferenceTypes: true
@@ -0,0 +1,12 @@
# for csharp-netcore generichost
generatorName: csharp-netcore
outputDir: samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-netcore-latest-oneOf
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOf.yaml
library: generichost
templateDir: modules/openapi-generator/src/main/resources/csharp-netcore
additionalProperties:
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
useCompareNetObjects: true
disallowAdditionalPropertiesIfNotPresent: false
targetFramework: net7.0
nullableReferenceTypes: true
+1 -1
View File
@@ -1,7 +1,7 @@
generatorName: java
outputDir: samples/client/petstore/java/native-async
library: native
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/native/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-native
+9
View File
@@ -0,0 +1,9 @@
generatorName: java
outputDir: samples/client/petstore/java/native-jakarta
library: native
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-native-jakarta
hideGenerationTimestamp: "true"
useJakartaEe: "true"
+1 -1
View File
@@ -1,7 +1,7 @@
generatorName: java
outputDir: samples/client/petstore/java/native
library: native
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/native/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-native
@@ -0,0 +1,11 @@
generatorName: java
outputDir: samples/client/petstore/java/okhttp-gson-awsv4signature
library: okhttp-gson
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: okhttp-gson-awsv4signature
hideGenerationTimestamp: "true"
useOneOfDiscriminatorLookup: "true"
disallowAdditionalPropertiesIfNotPresent: false
withAWSV4Signature: true
@@ -0,0 +1,8 @@
generatorName: java
outputDir: samples/client/echo_api/java/okhttp-gson
#library: okhttp-gson
inputSpec: modules/openapi-generator/src/test/resources/3_0/echo_api.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: echo-api-okhttp-gson
hideGenerationTimestamp: "true"
@@ -0,0 +1,10 @@
generatorName: java
outputDir: samples/client/petstore/java/resttemplate-jakarta
library: resttemplate
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-resttemplate
hideGenerationTimestamp: "true"
java8: true
useJakartaEe: true
+9
View File
@@ -0,0 +1,9 @@
generatorName: java
outputDir: samples/client/petstore/java/webclient-jakarta
library: webclient
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-webclient
hideGenerationTimestamp: "true"
useJakartaEe: true
+1
View File
@@ -8,3 +8,4 @@ additionalProperties:
snapshotVersion: "true"
hideGenerationTimestamp: "true"
camelCaseDollarSign: "true"
modelNameSuffix: 'Dto'
-8
View File
@@ -1,8 +0,0 @@
generatorName: typescript-koa-server
outputDir: samples/server/petstore/typescript-koa-server
#outputDir: /Users/williamcheng/Code/typescript/PetStore
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-koa-server/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-koa-server
additionalProperties:
ngVersion: 15.0.3
supportsES6: true
+26
View File
@@ -451,3 +451,29 @@ Another useful option is `inlineSchemaNameDefaults`, which allows you to customi
```
Note: Only arrayItemSuffix, mapItemSuffix are supported at the moment. `SKIP_SCHEMA_REUSE=true` is a special value to skip reusing inline schemas.
## OpenAPI Normalizer
OpenAPI Normalizer (off by default) transforms the input OpenAPI doc/spec (which may not perfectly conform to the specification) to make it workable with OpenAPI Generator. Here is a list of rules supported:
- `REF_AS_PARENT_IN_ALLOF`: when set to `true`, child schemas in `allOf` is considered a parent if it's a `$ref` (instead of inline schema).
Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/allOf_extension_parent.yaml -o /tmp/java-okhttp/ --openapi-normalizer REF_AS_PARENT_IN_ALLOF=true
```
- `REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIES_ONLY`: when set to `true`, oneOf/anyOf schema with only required properies only in a schema with properties will be removed. [(example)](modules/openapi-generator/src/test/resources/3_0/removeAnyOfOneOfAndKeepPropertiesOnly_test.yaml)
Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/removeAnyOfOneOfAndKeepPropertiesOnly_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIES_ONLY=true
```
- `SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING`: when set to `true`, simplify anyOf schema with string and enum of string to just `string`
Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyAnyOfStringAndEnumString_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING=true
```
+3 -1
View File
@@ -45,6 +45,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>AnyType</li>
<li>Atom</li>
<li>Boolean</li>
<li>DateTime</li>
@@ -56,6 +57,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>PID</li>
<li>String</li>
<li>Tuple</li>
<li>any()</li>
<li>map()</li>
</ul>
@@ -103,7 +105,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|Uuid|✗|
|Array|✓|OAS2,OAS3
|Null|✗|OAS3
|AnyType||OAS2,OAS3
|AnyType||OAS2,OAS3
|Object|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
+1
View File
@@ -63,6 +63,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/groovy|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+2 -1
View File
@@ -93,8 +93,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOptional|Use Optional container for optional parameters| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).| |true|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false|
+1
View File
@@ -60,6 +60,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+1
View File
@@ -63,6 +63,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useAbstractClass|Whether to generate abstract classes for REST API instead of interfaces.| |false|
|useBeanValidation|Use Bean Validation| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+1
View File
@@ -65,6 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/gen/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+1
View File
@@ -80,6 +80,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|Client service name| |null|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOptional|Use Optional container for optional parameters| |false|
|visitable|Generate visitor for subtypes with a discriminator| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+1
View File
@@ -82,6 +82,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|Client service name| |null|
|useAuth|Whether to import authorization and to annotate controller methods accordingly| |true|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOptional|Use Optional container for optional parameters| |false|
|visitable|Generate visitor for subtypes with a discriminator| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+1
View File
@@ -70,6 +70,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+1
View File
@@ -71,6 +71,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|springBootAdminUri|Spring-Boot URI| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|server title name or client service name| |null|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|zipkinUri|Zipkin URI| |null|
+1
View File
@@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|server title name or client service name| |openapi-java-playframework|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useInterfaces|Makes the controllerImp implements an interface to facilitate automatic completion when updating from version x to y of your spec| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useSwaggerUI|Add a route to /api which show your documentation in swagger-ui. Will also import needed dependencies| |true|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|wrapCalls|Add a wrapper to each controller function to handle things like metrics, response modification, etc..| |true|
+1
View File
@@ -65,6 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+1
View File
@@ -65,6 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+1
View File
@@ -67,6 +67,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|vertxSwaggerRouterVersion|Specify the version of the swagger router library| |null|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+3 -1
View File
@@ -83,14 +83,16 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk. Available on resttemplate, webclient, libraries| |false|
|useBeanValidation|Use BeanValidation API annotations| |false|
|useGzipFeature|Send gzip-encoded requests| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |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.| |false|
|useRuntimeException|Use RuntimeException instead of Exception| |false|
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey, jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson support this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
+1
View File
@@ -76,6 +76,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useSwaggerAnnotations|Whether to generate Swagger annotations.| |true|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+2
View File
@@ -65,9 +65,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/gen/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false|
|useBeanValidation|Use BeanValidation API annotations| |false|
|useGenericResponse|Use generic response| |false|
|useGzipFeatureForTests|Use Gzip Feature for tests| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useLoggingFeatureForTests|Use Logging Feature for tests| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+2
View File
@@ -78,12 +78,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testDataFile|JSON file to contain generated test data| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false|
|useAnnotatedBasePath|Use @Path annotations for basePath| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useBeanValidationFeature|Use BeanValidation Feature| |false|
|useGenericResponse|Use generic response| |false|
|useGzipFeature|Use Gzip Feature| |false|
|useGzipFeatureForTests|Use Gzip Feature for tests| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useLoggingFeature|Use Logging Feature| |false|
|useLoggingFeatureForTests|Use Logging Feature for tests| |false|
|useMultipartFeature|Use Multipart Feature| |false|
+2
View File
@@ -73,12 +73,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/gen/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false|
|useAnnotatedBasePath|Use @Path annotations for basePath| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useBeanValidationFeature|Use BeanValidation Feature| |false|
|useGenericResponse|Use generic response| |false|
|useGzipFeature|Use Gzip Feature| |false|
|useGzipFeatureForTests|Use Gzip Feature for tests| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useLoggingFeature|Use Logging Feature| |false|
|useLoggingFeatureForTests|Use Logging Feature for tests| |false|
|useMultipartFeature|Use Multipart Feature| |false|
+1
View File
@@ -71,6 +71,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+1
View File
@@ -70,6 +70,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useSwaggerFeature|Use dynamic Swagger generator| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+1
View File
@@ -70,6 +70,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+1
View File
@@ -76,6 +76,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useSwaggerAnnotations|Whether to generate Swagger annotations.| |true|
|useTags|use tags for creating interface and controller classnames| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
+2 -1
View File
@@ -86,8 +86,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOptional|Use Optional container for optional parameters| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).| |true|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.| |false|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false|
+1
View File
@@ -24,6 +24,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|fileContentDataType|Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)| |Buffer|
|framework|Specify the framework which should be used in the client code.|<dl><dt>**fetch-api**</dt><dd>fetch-api</dd><dt>**jquery**</dt><dd>jquery</dd></dl>|fetch-api|
|importFileExtension|File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html). Defaults to '.ts' when 'platform' is set to 'deno'.| |null|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null|
+3 -3
View File
@@ -125,7 +125,7 @@
<dependency>
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
<version>0.8</version>
<version>0.9</version>
</dependency>
<dependency>
<groupId>com.googlecode.lambdaj</groupId>
@@ -135,12 +135,12 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.1.0</version>
<version>3.1.9</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
@@ -80,6 +80,9 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
@Option(name = {"--inline-schema-name-defaults"}, title = "inline schema name defaults", description = "default values used when naming inline schema name")
private Boolean inlineSchemaNameDefaults;
@Option(name = {"--openapi-normalizer"}, title = "openapi normalizer rules", description = "displays the OpenAPI normalizer rules (none)")
private Boolean openapiNormalizer;
@Option(name = {"--metadata"}, title = "metadata", description = "displays the generator metadata like the help txt for the generator and generator type etc")
private Boolean metadata;
@@ -494,6 +497,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
sb.append(newline);
}
if (Boolean.TRUE.equals(openapiNormalizer)) {
sb.append(newline).append("OPENAPI NORMALIZER RULES").append(newline).append(newline);
Map<String, String> map = config.openapiNormalizer()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b));
}, TreeMap::new));
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "OpenAPI normalizer rule", "Set to");
sb.append(newline);
}
if (Boolean.TRUE.equals(instantiationTypes)) {
sb.append(newline).append("INSTANTIATION TYPES").append(newline).append(newline);
Map<String, String> map = config.instantiationTypes()
@@ -180,6 +180,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " ONLY arrayItemSuffix, mapItemSuffix are supported at the moment. `SKIP_SCHEMA_REUSE=true` is a special value to skip reusing inline schemas.")
private List<String> inlineSchemaNameDefaults = new ArrayList<>();
@Option(
name = {"--openapi-normalizer"},
title = "OpenAPI normalizer rules",
description = "specifies the rules to be enabled in OpenAPI normalizer in the form of RULE_1=true,RULE_2=original."
+ " You can also have multiple occurrences of this option.")
private List<String> openapiNormalizer = new ArrayList<>();
@Option(
name = {"--server-variables"},
title = "server variables",
@@ -447,6 +454,7 @@ public class Generate extends OpenApiGeneratorCommand {
applySchemaMappingsKvpList(schemaMappings, configurator);
applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator);
applyInlineSchemaNameDefaultsKvpList(inlineSchemaNameDefaults, configurator);
applyOpenAPINormalizerKvpList(openapiNormalizer, configurator);
applyTypeMappingsKvpList(typeMappings, configurator);
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
@@ -53,6 +53,7 @@ public final class GeneratorSettings implements Serializable {
private final Map<String, String> schemaMappings;
private final Map<String, String> inlineSchemaNameMappings;
private final Map<String, String> inlineSchemaNameDefaults;
private final Map<String, String> openapiNormalizer;
private final Set<String> languageSpecificPrimitives;
private final Map<String, String> reservedWordsMappings;
private final Map<String, String> serverVariables;
@@ -264,6 +265,15 @@ public final class GeneratorSettings implements Serializable {
return inlineSchemaNameDefaults;
}
/**
* Gets OpenAPI normalizer rules
*
* @return a map of rules
*/
public Map<String, String> getOpenAPINormalizer() {
return openapiNormalizer;
}
/**
* Gets language specific primitives. These are in addition to the "base" primitives defined in a generator.
* <p>
@@ -382,6 +392,7 @@ public final class GeneratorSettings implements Serializable {
schemaMappings = Collections.unmodifiableMap(builder.schemaMappings);
inlineSchemaNameMappings = Collections.unmodifiableMap(builder.inlineSchemaNameMappings);
inlineSchemaNameDefaults = Collections.unmodifiableMap(builder.inlineSchemaNameDefaults);
openapiNormalizer = Collections.unmodifiableMap(builder.openapiNormalizer);
languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives);
reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings);
serverVariables = Collections.unmodifiableMap(builder.serverVariables);
@@ -455,6 +466,7 @@ public final class GeneratorSettings implements Serializable {
schemaMappings = Collections.unmodifiableMap(new HashMap<>(0));
inlineSchemaNameMappings = Collections.unmodifiableMap(new HashMap<>(0));
inlineSchemaNameDefaults = Collections.unmodifiableMap(new HashMap<>(0));
openapiNormalizer = Collections.unmodifiableMap(new HashMap<>(0));
languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0));
reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0));
serverVariables = Collections.unmodifiableMap(new HashMap<>(0));
@@ -515,6 +527,9 @@ public final class GeneratorSettings implements Serializable {
if (copy.getInlineSchemaNameDefaults() != null) {
builder.inlineSchemaNameDefaults.putAll(copy.getInlineSchemaNameDefaults());
}
if (copy.getOpenAPINormalizer() != null) {
builder.openapiNormalizer.putAll(copy.getOpenAPINormalizer());
}
if (copy.getLanguageSpecificPrimitives() != null) {
builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives());
}
@@ -557,6 +572,7 @@ public final class GeneratorSettings implements Serializable {
private Map<String, String> schemaMappings;
private Map<String, String> inlineSchemaNameMappings;
private Map<String, String> inlineSchemaNameDefaults;
private Map<String, String> openapiNormalizer;
private Set<String> languageSpecificPrimitives;
private Map<String, String> reservedWordsMappings;
private Map<String, String> serverVariables;
@@ -577,6 +593,7 @@ public final class GeneratorSettings implements Serializable {
schemaMappings = new HashMap<>();
inlineSchemaNameMappings = new HashMap<>();
inlineSchemaNameDefaults = new HashMap<>();
openapiNormalizer = new HashMap<>();
languageSpecificPrimitives = new HashSet<>();
reservedWordsMappings = new HashMap<>();
serverVariables = new HashMap<>();
@@ -897,6 +914,32 @@ public final class GeneratorSettings implements Serializable {
return this;
}
/**
* Sets the {@code openapiNormalizer} and returns a reference to this Builder so that the methods can be chained together.
*
* @param openapiNormalizer the {@code openapiNormalizer} to set
* @return a reference to this Builder
*/
public Builder withOpenAPINormalizer(Map<String, String> openapiNormalizer) {
this.openapiNormalizer = openapiNormalizer;
return this;
}
/**
* Sets a single {@code openapiNormalizer} and returns a reference to this Builder so that the methods can be chained together.
*
* @param key A key for the OpenAPI normalizer rule
* @param value The value of the OpenAPI normalizer rule
* @return a reference to this Builder
*/
public Builder withOpenAPINormalizer(String key, String value) {
if (this.openapiNormalizer == null) {
this.openapiNormalizer = new HashMap<>();
}
this.openapiNormalizer.put(key, value);
return this;
}
/**
* Sets the {@code languageSpecificPrimitives} and returns a reference to this Builder so that the methods can be chained together.
*
@@ -1085,6 +1128,7 @@ public final class GeneratorSettings implements Serializable {
Objects.equals(getSchemaMappings(), that.getSchemaMappings()) &&
Objects.equals(getInlineSchemaNameMappings(), that.getInlineSchemaNameMappings()) &&
Objects.equals(getInlineSchemaNameDefaults(), that.getInlineSchemaNameDefaults()) &&
Objects.equals(getOpenAPINormalizer(), that.getOpenAPINormalizer()) &&
Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) &&
Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) &&
Objects.equals(getGitHost(), that.getGitHost()) &&
@@ -1116,6 +1160,7 @@ public final class GeneratorSettings implements Serializable {
getSchemaMappings(),
getInlineSchemaNameMappings(),
getInlineSchemaNameDefaults(),
getOpenAPINormalizer(),
getLanguageSpecificPrimitives(),
getReservedWordsMappings(),
getGitHost(),
@@ -118,6 +118,7 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
schemaMappings.set(generate.schemaMappings)
inlineSchemaNameMappings.set(generate.inlineSchemaNameMappings)
inlineSchemaNameDefaults.set(generate.inlineSchemaNameDefaults)
openapiNormalizer.set(generate.openapiNormalizer)
invokerPackage.set(generate.invokerPackage)
groupId.set(generate.groupId)
id.set(generate.id)
@@ -162,6 +162,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
*/
val inlineSchemaNameDefaults = project.objects.mapProperty<String, String>()
/**
* Specifies mappings (rules) in OpenAPI normalizer
*/
val openapiNormalizer = project.objects.mapProperty<String, String>()
/**
* Root package for generated code.
*/
@@ -250,6 +250,13 @@ open class GenerateTask : DefaultTask() {
@Input
val inlineSchemaNameDefaults = project.objects.mapProperty<String, String>()
/**
* Specifies mappings (rules) in OpenAPI normalizer
*/
@Optional
@Input
val openapiNormalizer = project.objects.mapProperty<String, String>()
/**
* Root package for generated code.
*/
@@ -758,6 +765,12 @@ open class GenerateTask : DefaultTask() {
}
}
if (openapiNormalizer.isPresent) {
openapiNormalizer.get().forEach { entry ->
configurator.addOpenAPINormalizer(entry.key, entry.value)
}
}
if (typeMappings.isPresent) {
typeMappings.get().forEach { entry ->
configurator.addTypeMapping(entry.key, entry.value)
@@ -315,6 +315,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "inlineSchemaNameDefaults", property = "openapi.generator.maven.plugin.inlineSchemaNameDefaults")
private List<String> inlineSchemaNameDefaults;
/**
* A set of rules for OpenAPI normalizer
*/
@Parameter(name = "openapiNormalizer", property = "openapi.generator.maven.plugin.openapiNormalizer")
private List<String> openapiNormalizer;
/**
* A map of swagger spec types and the generated code types to use for them
*/
@@ -700,6 +706,12 @@ public class CodeGenMojo extends AbstractMojo {
configurator);
}
// Retained for backwards-compatibility with configOptions -> openapi-normalizer
if (openapiNormalizer == null && configOptions.containsKey("openapi-normalizer")) {
applyOpenAPINormalizerKvp(configOptions.get("openapi-normalizer").toString(),
configurator);
}
// Retained for backwards-compatibility with configOptions -> type-mappings
if (typeMappings == null && configOptions.containsKey("type-mappings")) {
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
@@ -753,6 +765,11 @@ public class CodeGenMojo extends AbstractMojo {
applyInlineSchemaNameDefaultsKvpList(inlineSchemaNameDefaults, configurator);
}
// Apply OpenAPI normalizer rules
if (openapiNormalizer != null && (configOptions == null || !configOptions.containsKey("openapi-normalizer"))) {
applyOpenAPINormalizerKvpList(openapiNormalizer, configurator);
}
// Apply Type Mappings
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
applyTypeMappingsKvpList(typeMappings, configurator);
+2 -2
View File
@@ -333,7 +333,7 @@
<dependency>
<groupId>com.github.javaparser</groupId>
<artifactId>javaparser-core</artifactId>
<version>3.24.0</version>
<version>3.24.9</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -356,7 +356,7 @@
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark</artifactId>
<version>0.20.0</version>
<version>0.21.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
@@ -147,6 +147,8 @@ public interface CodegenConfig {
Map<String, String> inlineSchemaNameDefault();
Map<String, String> openapiNormalizer();
Map<String, String> apiTemplateFiles();
Map<String, String> modelTemplateFiles();
@@ -330,4 +332,7 @@ public interface CodegenConfig {
boolean getUseInlineModelResolver();
boolean getAddSuffixToDuplicateOperationNicknames();
boolean getUseOpenAPINormalizer();
}
@@ -1,13 +1,17 @@
package org.openapitools.codegen;
import io.swagger.v3.oas.models.examples.Example;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
public class CodegenMediaType {
private CodegenProperty schema;
private LinkedHashMap<String, CodegenEncoding> encoding;
private HashMap<String, SchemaTestCase> testCases = new HashMap<>();
private Map<String, Example> examples = null;
public CodegenMediaType(CodegenProperty schema, LinkedHashMap<String, CodegenEncoding> encoding, HashMap<String, SchemaTestCase> testCases) {
this.schema = schema;
@@ -17,6 +21,11 @@ public class CodegenMediaType {
}
}
public CodegenMediaType(CodegenProperty schema, LinkedHashMap<String, CodegenEncoding> encoding, HashMap<String, SchemaTestCase> testCases, Map<String, Example> examples) {
this(schema, encoding, testCases);
this.examples = examples;
}
public CodegenProperty getSchema() {
return schema;
}
@@ -27,6 +36,10 @@ public class CodegenMediaType {
public HashMap<String, SchemaTestCase> getTestCases() { return testCases; }
public Map<String, Example> getExamples() {
return examples;
}
public String toString() {
final StringBuilder sb = new StringBuilder("CodegenMediaType{");
sb.append("schema=").append(schema);
@@ -207,7 +207,7 @@ public class CodegenOperation {
* returns a map where the key is the request body content type and the value is the current CodegenOperation
* this is needed by templates when a different signature is needed for each request body content type
*/
public Map<String, CodegenOperation> getContentTypeToOperation() {
public Map<String, CodegenOperation> contentTypeToOperation() {
LinkedHashMap<String, CodegenOperation> contentTypeToOperation = new LinkedHashMap<>();
if (bodyParam == null) {
return null;
@@ -157,6 +157,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
public boolean isSelfReference;
public boolean isCircularReference;
public boolean isDiscriminator;
public boolean isNew; // true when this property overrides an inherited property
public List<String> _enum;
public Map<String, Object> allowableValues;
// If 'additionalProperties' is not set, items is null.
@@ -1063,6 +1064,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
sb.append(", isSelfReference=").append(isSelfReference);
sb.append(", isCircularReference=").append(isCircularReference);
sb.append(", isDiscriminator=").append(isDiscriminator);
sb.append(", isNew=").append(isNew);
sb.append(", _enum=").append(_enum);
sb.append(", allowableValues=").append(allowableValues);
sb.append(", items=").append(items);
@@ -1153,6 +1155,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
isSelfReference == that.isSelfReference &&
isCircularReference == that.isCircularReference &&
isDiscriminator == that.isDiscriminator &&
isNew == that.isNew &&
hasValidation == that.hasValidation &&
isInherited == that.isInherited &&
isXmlAttribute == that.isXmlAttribute &&
@@ -1230,7 +1233,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti
isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBinary, isFile,
isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isFreeFormObject,
isArray, isMap, isEnum, isInnerEnum, isEnumRef, isAnyType, isReadOnly, isWriteOnly, isNullable, isShort,
isUnboundedInteger, isSelfReference, isCircularReference, isDiscriminator, _enum,
isUnboundedInteger, isSelfReference, isCircularReference, isDiscriminator, isNew, _enum,
allowableValues, items, mostInnerItems, additionalProperties, vars, requiredVars,
vendorExtensions, hasValidation, isInherited, discriminatorValue, nameInCamelCase,
nameInSnakeCase, enumName, maxItems, minItems, isXmlAttribute, xmlPrefix, xmlName,
@@ -167,6 +167,8 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> inlineSchemaNameMapping = new HashMap<>();
// a map to store the inline schema naming conventions
protected Map<String, String> inlineSchemaNameDefault = new HashMap<>();
// a map to store the rules in OpenAPI Normalizer
protected Map<String, String> openapiNormalizer = new HashMap<>();
protected String modelPackage = "", apiPackage = "", fileSuffix;
protected String modelNamePrefix = "", modelNameSuffix = "";
protected String apiNamePrefix = "", apiNameSuffix = "Api";
@@ -468,6 +470,35 @@ public class DefaultCodegen implements CodegenConfig {
@Override
@SuppressWarnings("static-method")
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
for (Map.Entry<String, ModelsMap> entry : objs.entrySet()) {
CodegenModel model = ModelUtils.getModelByName(entry.getKey(), objs);
for (CodegenProperty property : model.allVars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.vars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.readWriteVars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.optionalVars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.parentVars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.requiredVars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.readOnlyVars){
property.isNew = codegenPropertyIsNew(model, property);
}
for (CodegenProperty property : model.nonNullableVars){
property.isNew = codegenPropertyIsNew(model, property);
}
}
if (this.useOneOfInterfaces) {
// First, add newly created oneOf interfaces
for (CodegenModel cm : addOneOfInterfaces) {
@@ -522,6 +553,12 @@ public class DefaultCodegen implements CodegenConfig {
return objs;
}
private boolean codegenPropertyIsNew(CodegenModel model, CodegenProperty property) {
return model.parentModel == null
? false
: model.parentModel.allVars.stream().anyMatch(p -> p.name.equals(property.name) && (p.dataType.equals(property.dataType) == false || p.datatypeWithEnum.equals(property.datatypeWithEnum) == false));
}
/**
* Return a map from model name to Schema for efficient lookup.
*
@@ -1137,6 +1174,11 @@ public class DefaultCodegen implements CodegenConfig {
return inlineSchemaNameDefault;
}
@Override
public Map<String, String> openapiNormalizer() {
return openapiNormalizer;
}
@Override
public String testPackage() {
return testPackage;
@@ -5024,7 +5066,7 @@ public class DefaultCodegen implements CodegenConfig {
if (parameterModelName != null) {
codegenParameter.dataType = parameterModelName;
if (ModelUtils.isObjectSchema(parameterSchema)) {
if (ModelUtils.isObjectSchema(parameterSchema) || ModelUtils.isComposedSchema(parameterSchema)) {
codegenProperty.complexType = codegenParameter.dataType;
}
} else {
@@ -6455,7 +6497,7 @@ public class DefaultCodegen implements CodegenConfig {
return result;
}
public void writePropertyBack(String propertyKey, boolean value) {
public void writePropertyBack(String propertyKey, Object value) {
additionalProperties.put(propertyKey, value);
}
@@ -7194,7 +7236,7 @@ public class DefaultCodegen implements CodegenConfig {
}
}
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap, schemaTestCases);
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap, schemaTestCases, mt.getExamples());
cmtContent.put(contentType, codegenMt);
if (schemaProp != null) {
if (addSchemaImportsFromV3SpecLocations) {
@@ -7939,6 +7981,9 @@ public class DefaultCodegen implements CodegenConfig {
@Override
public boolean getUseInlineModelResolver() { return true; }
@Override
public boolean getUseOpenAPINormalizer() { return true; }
/*
A function to convert yaml or json ingested strings like property names
And convert special characters like newline, tab, carriage return
@@ -255,6 +255,12 @@ public class DefaultGenerator implements Generator {
config.processOpts();
// normalize the spec
if (config.getUseOpenAPINormalizer()) {
OpenAPINormalizer openapiNormalizer = new OpenAPINormalizer(openAPI, config.openapiNormalizer());
openapiNormalizer.normalize();
}
// resolve inline models
if (config.getUseInlineModelResolver()) {
InlineModelResolver inlineModelResolver = new InlineModelResolver();
@@ -0,0 +1,532 @@
/*
* 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
*
* https://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;
import io.swagger.v3.oas.models.*;
import io.swagger.v3.oas.models.callbacks.Callback;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.stream.Collectors;
public class OpenAPINormalizer {
private OpenAPI openAPI;
private Map<String, String> rules = new HashMap<>();
final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class);
// ============= a list of rules =============
// when set to true, all rules are enabled
final String ALL = "ALL";
boolean enableAll;
// when set to true, $ref in allOf is treated as parent so that x-parent: true will be added
// to the schema in $ref (if x-parent is not present)
final String REF_AS_PARENT_IN_ALLOF = "REF_AS_PARENT_IN_ALLOF";
boolean enableRefAsParentInAllOf;
// when set to true, only keep the first tag in operation if there are more than one tag defined.
final String KEEP_ONLY_FIRST_TAG_IN_OPERATION = "KEEP_ONLY_FIRST_TAG_IN_OPERATION";
boolean enableKeepOnlyFirstTagInOperation;
// when set to true, complex composed schemas (a mix of oneOf/anyOf/anyOf and properties) with
// oneOf/anyOf containing only `required` and no properties (these are properties inter-dependency rules)
// are removed as most generators cannot handle such case at the moment
final String REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIES_ONLY = "REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIES_ONLY";
boolean removeAnyOfOneOfAndKeepPropertiesOnly;
// when set to true, oneOf/anyOf with either string or enum string as sub schemas will be simplified
// to just string
final String SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING = "SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING";
boolean simplifyAnyOfStringAndEnumString;
// ============= end of rules =============
/**
* Initializes OpenAPI Normalizer with a set of rules
*
* @param openAPI OpenAPI
* @param rules a map of rules
*/
public OpenAPINormalizer(OpenAPI openAPI, Map<String, String> rules) {
this.openAPI = openAPI;
this.rules = rules;
parseRules(rules);
}
/**
* Parses the rules.
*
* @param rules a map of rules
*/
public void parseRules(Map<String, String> rules) {
if (rules == null) {
return;
}
if ("true".equalsIgnoreCase(rules.get(ALL))) {
enableAll = true;
}
if (enableAll || "true".equalsIgnoreCase(rules.get(REF_AS_PARENT_IN_ALLOF))) {
enableRefAsParentInAllOf = true;
}
if (enableAll || "true".equalsIgnoreCase(rules.get(KEEP_ONLY_FIRST_TAG_IN_OPERATION))) {
enableKeepOnlyFirstTagInOperation = true;
}
if (enableAll || "true".equalsIgnoreCase(rules.get(REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIES_ONLY))) {
removeAnyOfOneOfAndKeepPropertiesOnly = true;
}
if (enableAll || "true".equalsIgnoreCase(rules.get(SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING))) {
simplifyAnyOfStringAndEnumString = true;
}
}
/**
* Normalizes the OpenAPI input, which may not perfectly conform to
* the specification.
*/
void normalize() {
if (rules == null || rules.isEmpty()) {
return;
}
if (this.openAPI.getComponents() == null) {
this.openAPI.setComponents(new Components());
}
if (this.openAPI.getComponents().getSchemas() == null) {
this.openAPI.getComponents().setSchemas(new HashMap<String, Schema>());
}
normalizePaths();
normalizeComponents();
}
/**
* Normalizes inline models in Paths
*/
private void normalizePaths() {
Paths paths = openAPI.getPaths();
if (paths == null) {
return;
}
for (Map.Entry<String, PathItem> pathsEntry : paths.entrySet()) {
PathItem path = pathsEntry.getValue();
List<Operation> operations = new ArrayList<>(path.readOperations());
// Include callback operation as well
for (Operation operation : path.readOperations()) {
Map<String, Callback> callbacks = operation.getCallbacks();
if (callbacks != null) {
operations.addAll(callbacks.values().stream()
.flatMap(callback -> callback.values().stream())
.flatMap(pathItem -> pathItem.readOperations().stream())
.collect(Collectors.toList()));
}
}
for (Operation operation : operations) {
normalizeOperation(operation);
normalizeRequestBody(operation);
normalizeParameters(operation);
normalizeResponses(operation);
}
}
}
/**
* Normalizes operation
*
* @param operation Operation
*/
private void normalizeOperation(Operation operation) {
processKeepOnlyFirstTagInOperation(operation);
}
/**
* Normalizes schemas in content
*
* @param content target content
*/
private void normalizeContent(Content content) {
if (content == null || content.isEmpty()) {
return;
}
for (String contentType : content.keySet()) {
MediaType mediaType = content.get(contentType);
if (mediaType == null) {
continue;
} else if (mediaType.getSchema() == null) {
continue;
} else {
normalizeSchema(mediaType.getSchema(), new HashSet<>());
}
}
}
/**
* Normalizes schemas in RequestBody
*
* @param operation target operation
*/
private void normalizeRequestBody(Operation operation) {
RequestBody requestBody = operation.getRequestBody();
if (requestBody == null) {
return;
}
// unalias $ref
if (requestBody.get$ref() != null) {
String ref = ModelUtils.getSimpleRef(requestBody.get$ref());
requestBody = openAPI.getComponents().getRequestBodies().get(ref);
if (requestBody == null) {
return;
}
}
normalizeContent(requestBody.getContent());
}
/**
* Normalizes schemas in parameters
*
* @param operation target operation
*/
private void normalizeParameters(Operation operation) {
List<Parameter> parameters = operation.getParameters();
if (parameters == null) {
return;
}
for (Parameter parameter : parameters) {
if (parameter.getSchema() == null) {
continue;
} else {
normalizeSchema(parameter.getSchema(), new HashSet<>());
}
}
}
/**
* Normalizes schemas in ApiResponses
*
* @param operation target operation
*/
private void normalizeResponses(Operation operation) {
ApiResponses responses = operation.getResponses();
if (responses == null) {
return;
}
for (Map.Entry<String, ApiResponse> responsesEntry : responses.entrySet()) {
if (responsesEntry.getValue() == null) {
continue;
} else {
normalizeContent(responsesEntry.getValue().getContent());
}
}
}
/**
* Normalizes schemas in components
*/
private void normalizeComponents() {
Map<String, Schema> schemas = openAPI.getComponents().getSchemas();
if (schemas == null) {
return;
}
List<String> schemaNames = new ArrayList<String>(schemas.keySet());
for (String schemaName : schemaNames) {
Schema schema = schemas.get(schemaName);
if (schema == null) {
LOGGER.warn("{} not fount found in openapi/components/schemas.", schemaName);
} else {
Schema result = normalizeSchema(schema, new HashSet<>());
schemas.put(schemaName, result);
}
}
}
/**
* Normalizes a schema
*
* @param schema Schema
* @param visitedSchemas a set of visited schemas
* @return Schema
*/
public Schema normalizeSchema(Schema schema, Set<Schema> visitedSchemas) {
if (schema == null) {
return schema;
}
if (StringUtils.isNotEmpty(schema.get$ref())) {
// not need to process $ref
return schema;
}
if ((visitedSchemas.contains(schema))) {
return schema; // skip due to circular reference
} else {
visitedSchemas.add(schema);
}
if (schema instanceof ArraySchema) {
normalizeSchema(schema.getItems(), visitedSchemas);
} else if (schema.getAdditionalProperties() instanceof Schema) { // map
normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas);
} else if (ModelUtils.isComposedSchema(schema)) {
ComposedSchema cs = (ComposedSchema) schema;
if (ModelUtils.isComplexComposedSchema(cs)) {
cs = (ComposedSchema) normalizeComplexComposedSchema(cs, visitedSchemas);
}
if (cs.getAllOf() != null && !cs.getAllOf().isEmpty()) {
return normalizeAllOf(cs, visitedSchemas);
}
if (cs.getOneOf() != null && !cs.getOneOf().isEmpty()) {
return normalizeOneOf(cs, visitedSchemas);
}
if (cs.getAnyOf() != null && !cs.getAnyOf().isEmpty()) {
return normalizeAnyOf(cs, visitedSchemas);
}
if (cs.getProperties() != null && !cs.getProperties().isEmpty()) {
normalizeProperties(cs.getProperties(), visitedSchemas);
}
if (cs.getAdditionalProperties() != null) {
// normalizeAdditionalProperties(m);
}
return cs;
} else if (schema.getNot() != null) {// not schema
normalizeSchema(schema.getNot(), visitedSchemas);
} else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
normalizeProperties(schema.getProperties(), visitedSchemas);
} else if (schema instanceof Schema) {
normalizeSchemaWithOnlyProperties(schema, visitedSchemas);
} else {
throw new RuntimeException("Unknown schema type found in normalizer: " + schema);
}
return schema;
}
private void normalizeSchemaWithOnlyProperties(Schema schema, Set<Schema> visitedSchemas) {
// normalize non-composed schema (e.g. schema with only properties)
}
private void normalizeProperties(Map<String, Schema> properties, Set<Schema> visitedSchemas) {
if (properties == null) {
return;
}
for (Map.Entry<String, Schema> propertiesEntry : properties.entrySet()) {
Schema property = propertiesEntry.getValue();
normalizeSchema(property, visitedSchemas);
}
}
private Schema normalizeAllOf(Schema schema, Set<Schema> visitedSchemas) {
for (Object item : schema.getAllOf()) {
if (!(item instanceof Schema)) {
throw new RuntimeException("Error! allOf schema is not of the type Schema: " + item);
}
// normalize allOf sub schemas one by one
normalizeSchema((Schema) item, visitedSchemas);
}
// process rules here
processUseAllOfRefAsParent(schema);
return schema;
}
private Schema normalizeOneOf(Schema schema, Set<Schema> visitedSchemas) {
for (Object item : schema.getOneOf()) {
if (!(item instanceof Schema)) {
throw new RuntimeException("Error! allOf schema is not of the type Schema: " + item);
}
// normalize oenOf sub schemas one by one
normalizeSchema((Schema) item, visitedSchemas);
}
// process rules here
return schema;
}
private Schema normalizeAnyOf(Schema schema, Set<Schema> visitedSchemas) {
for (Object item : schema.getAnyOf()) {
if (!(item instanceof Schema)) {
throw new RuntimeException("Error! allOf schema is not of the type Schema: " + item);
}
// normalize anyOf sub schemas one by one
normalizeSchema((Schema) item, visitedSchemas);
}
// process rules here
// last rule to process as the schema may become String schema (not "anyOf") after the completion
return processSimplifyAnyOfStringAndEnumString(schema);
}
private Schema normalizeComplexComposedSchema(Schema schema, Set<Schema> visitedSchemas) {
processRemoveAnyOfOneOfAndKeepPropertiesOnly(schema);
return schema;
}
// ===================== a list of rules =====================
// all rules (fuctions) start with the word "process"
/**
* Child schemas in `allOf` is considered a parent if it's a `$ref` (instead of inline schema).
*
* @param schema Schema
*/
private void processUseAllOfRefAsParent(Schema schema) {
if (!enableRefAsParentInAllOf && !enableAll) {
return;
}
for (Object item : schema.getAllOf()) {
if (!(item instanceof Schema)) {
throw new RuntimeException("Error! allOf schema is not of the type Schema: " + item);
}
Schema s = (Schema) item;
if (StringUtils.isNotEmpty(s.get$ref())) {
String ref = ModelUtils.getSimpleRef(s.get$ref());
// TODO need to check for requestBodies?
Schema refSchema = openAPI.getComponents().getSchemas().get(ref);
if (refSchema == null) {
throw new RuntimeException("schema cannot be null with ref " + ref);
}
if (refSchema.getExtensions() == null) {
refSchema.setExtensions(new HashMap<>());
}
if (refSchema.getExtensions().containsKey("x-parent")) {
// doing nothing as x-parent already exists
} else {
refSchema.getExtensions().put("x-parent", true);
}
LOGGER.debug("processUseAllOfRefAsParent added `x-parent: true` to {}", refSchema);
}
}
}
/**
* Keep only first tag in the operation if the operation has more than
* one tag.
*
* @param operation Operation
*/
private void processKeepOnlyFirstTagInOperation(Operation operation) {
if (!enableKeepOnlyFirstTagInOperation) {
return;
}
if (operation.getTags() != null && !operation.getTags().isEmpty() && operation.getTags().size() > 1) {
// has more than 1 tag
String firstTag = operation.getTags().get(0);
operation.setTags(null);
operation.addTagsItem(firstTag);
}
}
/**
* If the schema contains anyOf/oneOf and properties, remove oneOf/anyOf as these serve as rules to
* ensure inter-dependency between properties. It's a workaround as such validation is not supported at the moment.
*
* @param schema Schema
*/
private void processRemoveAnyOfOneOfAndKeepPropertiesOnly(Schema schema) {
if (!removeAnyOfOneOfAndKeepPropertiesOnly && !enableAll) {
return;
}
if (((schema.getOneOf() != null && !schema.getOneOf().isEmpty())
|| (schema.getAnyOf() != null && !schema.getAnyOf().isEmpty())) // has anyOf or oneOf
&& (schema.getProperties() != null && !schema.getProperties().isEmpty()) // has properties
&& schema.getAllOf() == null) { // not allOf
// clear oneOf, anyOf
schema.setOneOf(null);
schema.setAnyOf(null);
}
}
/**
* If the schema is anyOf and the sub-schemas are either string or enum of string,
* then simply it to just string as many generators do not yet support anyOf.
*
* @param schema Schema
* @return Schema
*/
private Schema processSimplifyAnyOfStringAndEnumString(Schema schema) {
if (!simplifyAnyOfStringAndEnumString && !enableAll) {
return schema;
}
Schema s0 = null, s1 = null;
if (schema.getAnyOf().size() == 2) {
s0 = ModelUtils.unaliasSchema(openAPI, (Schema) schema.getAnyOf().get(0));
s1 = ModelUtils.unaliasSchema(openAPI, (Schema) schema.getAnyOf().get(1));
} else {
return schema;
}
s0 = ModelUtils.getReferencedSchema(openAPI, s0);
s1 = ModelUtils.getReferencedSchema(openAPI, s1);
// find the string schema (not enum)
if (s0 instanceof StringSchema && s1 instanceof StringSchema) {
if (((StringSchema) s0).getEnum() != null) { // s0 is enum, s1 is string
return (StringSchema) s1;
} else if (((StringSchema) s1).getEnum() != null) { // s1 is enum, s0 is string
return (StringSchema) s0;
} else { // both are string
return schema;
}
} else {
return schema;
}
}
// ===================== end of rules =====================
}
@@ -71,6 +71,7 @@ public class CodegenConfigurator {
private Map<String, String> schemaMappings = new HashMap<>();
private Map<String, String> inlineSchemaNameMappings = new HashMap<>();
private Map<String, String> inlineSchemaNameDefaults = new HashMap<>();
private Map<String, String> openapiNormalizer = new HashMap<>();
private Set<String> languageSpecificPrimitives = new HashSet<>();
private Map<String, String> reservedWordsMappings = new HashMap<>();
private Map<String, String> serverVariables = new HashMap<>();
@@ -123,6 +124,9 @@ public class CodegenConfigurator {
if(generatorSettings.getInlineSchemaNameDefaults() != null) {
configurator.inlineSchemaNameDefaults.putAll(generatorSettings.getInlineSchemaNameDefaults());
}
if(generatorSettings.getOpenAPINormalizer() != null) {
configurator.openapiNormalizer.putAll(generatorSettings.getOpenAPINormalizer());
}
if(generatorSettings.getLanguageSpecificPrimitives() != null) {
configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives());
}
@@ -210,6 +214,12 @@ public class CodegenConfigurator {
return this;
}
public CodegenConfigurator addOpenAPINormalizer(String key, String value) {
this.openapiNormalizer.put(key, value);
generatorSettingsBuilder.withOpenAPINormalizer(key, value);
return this;
}
public CodegenConfigurator addInstantiationType(String key, String value) {
this.instantiationTypes.put(key, value);
generatorSettingsBuilder.withInstantiationType(key, value);
@@ -382,6 +392,12 @@ public class CodegenConfigurator {
return this;
}
public CodegenConfigurator setOpenAPINormalizer(Map<String, String> openapiNormalizer) {
this.openapiNormalizer = openapiNormalizer;
generatorSettingsBuilder.withOpenAPINormalizer(openapiNormalizer);
return this;
}
public CodegenConfigurator setInputSpec(String inputSpec) {
this.inputSpec = inputSpec;
workflowSettingsBuilder.withInputSpec(inputSpec);
@@ -661,6 +677,7 @@ public class CodegenConfigurator {
config.schemaMapping().putAll(generatorSettings.getSchemaMappings());
config.inlineSchemaNameMapping().putAll(generatorSettings.getInlineSchemaNameMappings());
config.inlineSchemaNameDefault().putAll(generatorSettings.getInlineSchemaNameDefaults());
config.openapiNormalizer().putAll(generatorSettings.getOpenAPINormalizer());
config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives());
config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings());
config.additionalProperties().putAll(generatorSettings.getAdditionalProperties());
@@ -120,6 +120,19 @@ public final class CodegenConfiguratorUtils {
}
}
public static void applyOpenAPINormalizerKvpList(List<String> openapiNormalizer, CodegenConfigurator configurator) {
for (String propString : openapiNormalizer) {
applyOpenAPINormalizerKvp(propString, configurator);
}
}
public static void applyOpenAPINormalizerKvp(String openapiNormalizer, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(openapiNormalizer);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addOpenAPINormalizer(entry.getKey().trim(), entry.getValue().trim());
}
}
public static void applyTypeMappingsKvpList(List<String> typeMappings, CodegenConfigurator configurator) {
for (String propString : typeMappings) {
applyTypeMappingsKvp(propString, configurator);
@@ -80,12 +80,9 @@ public class ExampleGenerator {
if (ModelUtils.isArraySchema(responseSchema)) { // array of schema
ArraySchema as = (ArraySchema) responseSchema;
if (as.getItems() != null && StringUtils.isEmpty(as.getItems().get$ref())) { // array of primitive types
if (as.getItems() != null) { // array of primitive types
return generate((Map<String, Object>) responseSchema.getExample(),
new ArrayList<String>(producesInfo), as.getItems());
} else if (as.getItems() != null && !StringUtils.isEmpty(as.getItems().get$ref())) { // array of model
return generate((Map<String, Object>) responseSchema.getExample(),
new ArrayList<String>(producesInfo), ModelUtils.getSimpleRef(as.getItems().get$ref()));
new ArrayList<>(producesInfo), as);
} else {
// TODO log warning message as such case is not handled at the moment
return null;
@@ -155,6 +155,9 @@ public class XmlExampleGenerator {
}
} else if (StringUtils.isNotEmpty(schema.get$ref())) {
Schema actualSchema = examples.get(schema.get$ref());
if (actualSchema == null) {
actualSchema = examples.get(ModelUtils.getSimpleRef(schema.get$ref()));
}
sb.append(toXml(actualSchema, indent, path));
} else {
if (name != null) {
@@ -121,9 +121,9 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
typeMapping.put("date", "string");
typeMapping.put("DateTime", "time.Time");
typeMapping.put("password", "string");
typeMapping.put("File", "os.File");
typeMapping.put("file", "os.File");
typeMapping.put("binary", "os.File");
typeMapping.put("File", "*os.File");
typeMapping.put("file", "*os.File");
typeMapping.put("binary", "*os.File");
typeMapping.put("ByteArray", "string");
typeMapping.put("null", "nil");
// A 'type: object' OAS schema without any declared property is
@@ -505,13 +505,13 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
boolean addedReflectImport = false;
for (CodegenOperation operation : operations) {
// import "os" if the operation uses files
if (!addedOSImport && "os.File".equals(operation.returnType)) {
if (!addedOSImport && "*os.File".equals(operation.returnType)) {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
for (CodegenParameter param : operation.allParams) {
// import "os" if the operation uses files
if (!addedOSImport && "os.File".equals(param.dataType)) {
if (!addedOSImport && "*os.File".equals(param.dataType)) {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
@@ -634,9 +634,6 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
List<CodegenProperty> inheritedProperties = new ArrayList<>();
if (model.getComposedSchemas() != null) {
if (model.getComposedSchemas().getAllOf() != null) {
inheritedProperties.addAll(model.getComposedSchemas().getAllOf());
}
if (model.getComposedSchemas().getAnyOf() != null) {
inheritedProperties.addAll(model.getComposedSchemas().getAnyOf());
}
@@ -646,41 +643,31 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
}
List<CodegenProperty> codegenProperties = new ArrayList<>();
if(model.getIsModel() || model.getComposedSchemas() == null) {
// If the model is a model, use model.vars as it only
// contains properties the generated struct will own itself.
// If model is no model and it has no composed schemas use
// model.vars.
if(model.getComposedSchemas() == null || (model.getComposedSchemas() != null && model.getComposedSchemas().getAllOf() != null)) {
// If the model is an allOf or does not have any composed schemas, then we can use the model's properties.
codegenProperties.addAll(model.vars);
} else {
// If the model is no model, but is a
// allOf, anyOf or oneOf, add all first level options
// from allOf, anyOf or oneOf.
// anyOf or oneOf, add all first level options
// from anyOf or oneOf.
codegenProperties.addAll(inheritedProperties);
}
for (CodegenProperty cp : codegenProperties) {
if (!addedTimeImport && ("time.Time".equals(cp.dataType) ||
(cp.items != null && "time.Time".equals(cp.items.dataType)))) {
if (!addedTimeImport && ("time.Time".equals(cp.dataType) || (cp.items != null && "time.Time".equals(cp.items.dataType)))) {
imports.add(createMapping("import", "time"));
addedTimeImport = true;
}
if (!addedOSImport && ("os.File".equals(cp.dataType) ||
(cp.items != null && "os.File".equals(cp.items.dataType)))) {
if (!addedOSImport && ("*os.File".equals(cp.dataType) ||
(cp.items != null && "*os.File".equals(cp.items.dataType)))) {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
}
if (this instanceof GoClientCodegen && model.isEnum) {
imports.add(createMapping("import", "fmt"));
}
// if oneOf contains "time.Time" type
if (!addedTimeImport && model.oneOf != null && model.oneOf.contains("time.Time")) {
imports.add(createMapping("import", "time"));
}
// if oneOf contains "null" type
if (model.oneOf != null && !model.oneOf.isEmpty() && model.oneOf.contains("nil")) {
model.isNullable = true;
@@ -83,6 +83,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public static final String TEST_OUTPUT = "testOutput";
public static final String IMPLICIT_HEADERS = "implicitHeaders";
public static final String IMPLICIT_HEADERS_REGEX = "implicitHeadersRegex";
public static final String JAVAX_PACKAGE = "javaxPackage";
public static final String USE_JAKARTA_EE = "useJakartaEe";
public static final String CAMEL_CASE_DOLLAR_SIGN = "camelCaseDollarSign";
@@ -137,6 +139,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
protected String implicitHeadersRegex = null;
protected boolean camelCaseDollarSign = false;
protected boolean useJakartaEe = false;
private Map<String, String> schemaKeyToModelNameCache = new HashMap<>();
@@ -272,6 +275,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Skip header parameters in the generated API methods using @ApiImplicitParams annotation.", implicitHeaders));
cliOptions.add(CliOption.newString(IMPLICIT_HEADERS_REGEX, "Skip header parameters that matches given regex in the generated API methods using @ApiImplicitParams annotation. Note: this parameter is ignored when implicitHeaders=true"));
cliOptions.add(CliOption.newBoolean(CAMEL_CASE_DOLLAR_SIGN, "Fix camelCase when starting with $ sign. when true : $Value when false : $value"));
cliOptions.add(CliOption.newBoolean(USE_JAKARTA_EE, "whether to use Jakarta EE namespace instead of javax"));
cliOptions.add(CliOption.newString(CodegenConstants.PARENT_GROUP_ID, CodegenConstants.PARENT_GROUP_ID_DESC));
cliOptions.add(CliOption.newString(CodegenConstants.PARENT_ARTIFACT_ID, CodegenConstants.PARENT_ARTIFACT_ID_DESC));
@@ -656,6 +660,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
additionalProperties.put("jsr310", "true");
typeMapping.put("date", "LocalDate");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("LocalTime", "java.time.LocalTime");
if ("java8-localdatetime".equals(dateLibrary)) {
typeMapping.put("DateTime", "LocalDateTime");
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
@@ -670,6 +675,17 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (additionalProperties.containsKey(TEST_OUTPUT)) {
setOutputTestFolder(additionalProperties.get(TEST_OUTPUT).toString());
}
if (additionalProperties.containsKey(USE_JAKARTA_EE)) {
this.setUseJakartaEe(Boolean.parseBoolean(additionalProperties.get(USE_JAKARTA_EE).toString()));
}
additionalProperties.put(USE_JAKARTA_EE, useJakartaEe);
if (useJakartaEe) {
applyJakartaPackage();
} else {
applyJavaxPackage();
}
}
@Override
@@ -721,6 +737,14 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
}
protected void applyJavaxPackage() {
writePropertyBack(JAVAX_PACKAGE, "javax");
}
protected void applyJakartaPackage() {
writePropertyBack(JAVAX_PACKAGE, "jakarta");
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
@@ -1321,6 +1345,9 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
codegenModel.imports.add("JsonTypeInfo");
codegenModel.imports.add("JsonIgnoreProperties");
}
if (codegenModel.getIsClassnameSanitized() && additionalProperties.containsKey(JACKSON) && !codegenModel.isEnum) {
codegenModel.imports.add("JsonTypeName");
}
if (allDefinitions != null && codegenModel.parentSchema != null && codegenModel.hasEnums) {
final Schema parentModel = allDefinitions.get(codegenModel.parentSchema);
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
@@ -1346,12 +1373,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
if (model.getIsClassnameSanitized() && additionalProperties.containsKey(JACKSON)) {
model.imports.add("JsonTypeName");
}
if (serializeBigDecimalAsString) {
if ("decimal".equals(property.baseType)) {
if ("decimal".equals(property.baseType) || "bigdecimal".equalsIgnoreCase(property.baseType)) {
// we serialize BigDecimal as `string` to avoid precision loss
property.vendorExtensions.put("x-extra-annotation", "@JsonSerialize(using = ToStringSerializer.class)");
@@ -1936,6 +1959,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.camelCaseDollarSign = camelCaseDollarSign;
}
public void setUseJakartaEe(boolean useJakartaEe) {
this.useJakartaEe = useJakartaEe;
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
@@ -63,6 +63,7 @@ public class CrystalClientCodegen extends DefaultCodegen {
protected String shardAuthorEmail = "";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected List<String> primitiveTypes = new ArrayList<String>();
public static final String SHARD_NAME = "shardName";
public static final String MODULE_NAME = "moduleName";
@@ -184,6 +185,7 @@ public class CrystalClientCodegen extends DefaultCodegen {
instantiationTypes.put("map", "Hash");
instantiationTypes.put("array", "Array");
instantiationTypes.put("set", "Set");
primitiveTypes = new ArrayList<String>(typeMapping.values());
// remove modelPackage and apiPackage added by default
cliOptions.removeIf(opt -> CodegenConstants.MODEL_PACKAGE.equals(opt.getOpt()) ||
@@ -355,6 +357,15 @@ public class CrystalClientCodegen extends DefaultCodegen {
return toModelName(type);
}
@Override
public String toModelImport(String name) {
if (primitiveTypes.contains(name)) {
return null;
} else {
return toModelFilename(name);
}
}
@Override
public String toModelName(final String name) {
String modelName;
@@ -19,10 +19,13 @@ package org.openapitools.codegen.languages;
import com.google.common.collect.Sets;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
import org.openapitools.codegen.api.TemplatePathLocator;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.meta.GeneratorMetadata;
@@ -44,6 +47,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -275,7 +279,7 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
imports.put("Uint8List", "dart:typed_data");
imports.put("MultipartFile", DIO_IMPORT);
}
private void configureDateLibrary(String srcFolder) {
switch (dateLibrary) {
case DATE_LIBRARY_TIME_MACHINE:
@@ -400,6 +404,7 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
private final String kHasAncestorOnlyProps = "x-has-ancestor-only-props";
private final String kSelfAndAncestorOnlyProps = "x-self-and-ancestor-only-props";
private final String kHasSelfAndAncestorOnlyProps = "x-has-self-and-ancestor-only-props";
private final String kParentDiscriminator = "x-parent-discriminator";
// adapts codegen models and property to dart rules of inheritance
private void adaptToDartInheritance(Map<String, ModelsMap> objs) {
@@ -449,6 +454,14 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
cm.vendorExtensions.put(kIsChild, isChild);
cm.vendorExtensions.put(kIsParent, isParent);
cm.vendorExtensions.put(kIsPure, isPure);
if (!isParent && (cm.oneOf == null || cm.oneOf.isEmpty())) {
//discriminator has no meaning here
if (cm.discriminator!=null) {
cm.vendorExtensions.put(kParentDiscriminator, cm.discriminator);
cm.discriminator=null;
}
}
// when pure:
// vars = allVars = selfOnlyProperties = kSelfAndAncestorOnlyProps
// ancestorOnlyProps = empty
@@ -541,6 +554,30 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
}
}
/// override the default behavior of createDiscriminator
/// to remove extra mappings added as a side effect of setLegacyDiscriminatorBehavior(false)
/// this ensures 1-1 schema mapping instead of 1-many
@Override
protected CodegenDiscriminator createDiscriminator(String schemaName, Schema schema, OpenAPI openAPI) {
CodegenDiscriminator sub = super.createDiscriminator(schemaName, schema, openAPI);
Discriminator originalDiscriminator = schema.getDiscriminator();
if (originalDiscriminator!=null) {
Map<String,String> originalMapping = originalDiscriminator.getMapping();
if (originalMapping != null && !originalMapping.isEmpty()) {
//we already have a discriminator mapping, remove everything else
for (MappedModel currentMappings : new HashSet<>(sub.getMappedModels())) {
if (originalMapping.containsKey(currentMappings.getMappingName())) {
//all good
} else {
sub.getMapping().remove(currentMappings.getMappingName());
sub.getMappedModels().remove(currentMappings);
}
}
}
}
return sub;
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
objs = super.postProcessAllModels(objs);
@@ -88,6 +88,9 @@ public class ElixirClientCodegen extends DefaultCodegen {
.includeClientModificationFeatures(
ClientModificationFeature.BasePath
)
.includeDataTypeFeatures(
DataTypeFeature.AnyType
)
);
// set the output folder here
@@ -188,10 +191,12 @@ public class ElixirClientCodegen extends DefaultCodegen {
"List",
"Atom",
"Map",
"AnyType",
"Tuple",
"PID",
"DateTime",
"map()" // This is a workaround, since the DefaultCodeGen uses our elixir TypeSpec datetype to evaluate the primitive
"map()", // This is a workaround, since the DefaultCodeGen uses our elixir TypeSpec datetype to evaluate the primitive
"any()"
)
);
@@ -575,6 +580,8 @@ public class ElixirClientCodegen extends DefaultCodegen {
return "String.t";
} else if (ModelUtils.isStringSchema(p)) {
return "String.t";
} else if (p.getType() == null) {
return "any()";
}
return super.getTypeDeclaration(p);
}
@@ -785,8 +792,13 @@ public class ElixirClientCodegen extends DefaultCodegen {
returnEntry.append(moduleName);
returnEntry.append(".Model.");
}
returnEntry.append(exResponse.baseType);
returnEntry.append(".t");
if (exResponse.baseType.equals("AnyType")) {
returnEntry.append("any()");
}else {
returnEntry.append(exResponse.baseType);
returnEntry.append(".t");
}
} else {
if (exResponse.containerType.equals("array") ||
exResponse.containerType.equals("set")) {
@@ -795,8 +807,13 @@ public class ElixirClientCodegen extends DefaultCodegen {
returnEntry.append(moduleName);
returnEntry.append(".Model.");
}
returnEntry.append(exResponse.baseType);
returnEntry.append(".t)");
if (exResponse.baseType.equals("AnyType")) {
returnEntry.append("any())");
}else {
returnEntry.append(exResponse.baseType);
returnEntry.append(".t)");
}
} else if (exResponse.containerType.equals("map")) {
returnEntry.append("map()");
}
@@ -305,7 +305,7 @@ public class GoServerCodegen extends AbstractGoCodegen {
for (CodegenOperation operation : operations) {
for (CodegenParameter param : operation.allParams) {
// import "os" if the operation uses files
if (!addedOSImport && ("os.File".equals(param.dataType) || ("[]os.File".equals(param.dataType)))) {
if (!addedOSImport && ("*os.File".equals(param.dataType) || ("[]*os.File".equals(param.dataType)))) {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
@@ -43,6 +43,8 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
*/
protected static final String JAXRS_TEMPLATE_DIRECTORY_NAME = "JavaJaxRS";
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
protected boolean useBeanValidation = false;
protected boolean useGenericResponse = false;
@@ -53,6 +55,8 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
private boolean useJackson = false;
protected boolean useAbstractionForFiles = false;
public JavaCXFClientCodegen() {
super();
@@ -90,6 +94,7 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_GZIP_FEATURE_FOR_TESTS, "Use Gzip Feature for tests"));
cliOptions.add(CliOption.newBoolean(USE_LOGGING_FEATURE_FOR_TESTS, "Use Logging Feature for tests"));
cliOptions.add(CliOption.newBoolean(USE_GENERIC_RESPONSE, "Use generic response"));
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk."));
}
@Override
@@ -116,6 +121,10 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
useJackson = convertPropertyToBooleanAndWriteBack(JACKSON);
}
if (additionalProperties.containsKey(USE_ABSTRACTION_FOR_FILES)) {
this.setUseAbstractionForFiles(convertPropertyToBooleanAndWriteBack(USE_ABSTRACTION_FOR_FILES));
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")
@@ -218,4 +227,8 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
public boolean isUseJackson() {
return useJackson;
}
public void setUseAbstractionForFiles(boolean useAbstractionForFiles) {
this.useAbstractionForFiles = useAbstractionForFiles;
}
}
@@ -36,6 +36,8 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
implements CXFServerFeatures, GzipTestFeatures, LoggingTestFeatures, UseGenericResponseFeatures {
private final Logger LOGGER = LoggerFactory.getLogger(JavaCXFServerCodegen.class);
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
protected boolean addConsumesProducesJson = true;
protected boolean generateSpringApplication = false;
@@ -70,6 +72,8 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean useGenericResponse = false;
protected boolean useAbstractionForFiles = false;
public JavaCXFServerCodegen() {
super();
@@ -126,6 +130,7 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions.add(CliOption.newBoolean(GENERATE_NON_SPRING_APPLICATION, "Generate non-Spring application"));
cliOptions.add(CliOption.newBoolean(USE_GENERIC_RESPONSE, "Use generic response"));
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk."));
}
@@ -184,6 +189,10 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.setGenerateNonSpringApplication(generateNonSpringApplication);
}
if (additionalProperties.containsKey(USE_ABSTRACTION_FOR_FILES)) {
this.setUseAbstractionForFiles(convertPropertyToBooleanAndWriteBack(USE_ABSTRACTION_FOR_FILES));
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
supportingFiles.add(new SupportingFile("server/pom.mustache", "", "pom.xml")
@@ -332,6 +341,10 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.useGenericResponse = useGenericResponse;
}
public void setUseAbstractionForFiles(boolean useAbstractionForFiles) {
this.useAbstractionForFiles = useAbstractionForFiles;
}
@Override
protected void updateModelForObject(CodegenModel m, Schema schema) {
/**
@@ -68,6 +68,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
public static final String DYNAMIC_OPERATIONS = "dynamicOperations";
public static final String SUPPORT_STREAMING = "supportStreaming";
public static final String SUPPORT_URL_QUERY = "supportUrlQuery";
public static final String GRADLE_PROPERTIES = "gradleProperties";
public static final String ERROR_OBJECT_TYPE = "errorObjectType";
@@ -119,6 +120,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected boolean useAbstractionForFiles = false;
protected boolean dynamicOperations = false;
protected boolean supportStreaming = false;
protected boolean withAWSV4Signature = false;
protected String gradleProperties;
protected String errorObjectType;
protected String authFolder;
@@ -192,7 +194,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
cliOptions.add(CliOption.newBoolean(PERFORM_BEANVALIDATION, "Perform BeanValidation"));
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(USE_RUNTIME_EXCEPTION, "Use RuntimeException instead of Exception. Only jersey, jersey2, jersey3, okhttp-gson, vertx, microprofile support this option."));
cliOptions.add(CliOption.newBoolean(ASYNC_NATIVE, "If true, async handlers will be used, instead of the sync version"));
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."));
cliOptions.add(CliOption.newBoolean(CASE_INSENSITIVE_RESPONSE_HEADERS, "Make API response's headers case-insensitive. Available on " + OKHTTP_GSON + ", " + JERSEY2 + " libraries"));
@@ -200,6 +202,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk. Available on resttemplate, webclient, libraries"));
cliOptions.add(CliOption.newBoolean(DYNAMIC_OPERATIONS, "Generate operations dynamically at runtime from an OAS", this.dynamicOperations));
cliOptions.add(CliOption.newBoolean(SUPPORT_STREAMING, "Support streaming endpoint (beta)", this.supportStreaming));
cliOptions.add(CliOption.newBoolean(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT, CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT_DESC + " (only available for okhttp-gson library)", this.withAWSV4Signature));
cliOptions.add(CliOption.newString(GRADLE_PROPERTIES, "Append additional Gradle properties to the gradle.properties file"));
cliOptions.add(CliOption.newString(ERROR_OBJECT_TYPE, "Error Object type. (This option is for okhttp-gson-next-gen only)"));
cliOptions.add(CliOption.newString(CONFIG_KEY, "Config key in @RegisterRestClient. Default to none. Only `microprofile` supports this option."));
@@ -407,6 +410,11 @@ public class JavaClientCodegen extends AbstractJavaCodegen
}
additionalProperties.put(SUPPORT_STREAMING, supportStreaming);
if (additionalProperties.containsKey(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT)) {
this.setWithAWSV4Signature(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT).toString()));
}
additionalProperties.put(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT, withAWSV4Signature);
if (additionalProperties.containsKey(GRADLE_PROPERTIES)) {
this.setGradleProperties(additionalProperties.get(GRADLE_PROPERTIES).toString());
}
@@ -420,6 +428,16 @@ public class JavaClientCodegen extends AbstractJavaCodegen
this.webclientBlockingOperations = Boolean.parseBoolean(additionalProperties.get(WEBCLIENT_BLOCKING_OPERATIONS).toString());
}
// add URL query deepObject support to native, apache-httpclient by default
if (!additionalProperties.containsKey(SUPPORT_URL_QUERY)) {
if (isLibrary(NATIVE) || isLibrary(APACHE)) {
// default to true for native and apache-httpclient
additionalProperties.put(SUPPORT_URL_QUERY, true);
}
} else {
additionalProperties.put(SUPPORT_URL_QUERY, Boolean.parseBoolean(additionalProperties.get(SUPPORT_URL_QUERY).toString()));
}
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
final String apiFolder = (sourceFolder + '/' + apiPackage).replace(".", "/");
final String modelsFolder = (sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
@@ -459,6 +477,9 @@ public class JavaClientCodegen extends AbstractJavaCodegen
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/HttpBearerAuth.mustache", authFolder, "HttpBearerAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
if (OKHTTP_GSON.equals(getLibrary()) && withAWSV4Signature) {
supportingFiles.add(new SupportingFile("auth/AWS4Auth.mustache", authFolder, "AWS4Auth.java"));
}
}
supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew"));
@@ -511,7 +532,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
supportingFiles.add(new SupportingFile("ParamExpander.mustache", invokerFolder, "ParamExpander.java"));
}
supportingFiles.add(new SupportingFile("EncodingUtils.mustache", invokerFolder, "EncodingUtils.java"));
supportingFiles.add(new SupportingFile("auth/DefaultApi20Impl.mustache", authFolder, "DefaultApi20Impl.java"));
} else if (OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) {
// the "okhttp-gson" library template requires "ApiCallback.mustache" for async call
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
@@ -576,7 +596,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
// The flag below should be set for all Java libraries, but the templates need to be ported
// one by one for each library.
supportsAdditionalPropertiesWithComposedSchema = true;
applyJakartaPackage();
} else if (NATIVE.equals(getLibrary())) {
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
@@ -714,6 +734,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
// Add OauthPasswordGrant.java and OauthClientCredentialsGrant.java for feign library
if (FEIGN.equals(getLibrary())) {
supportingFiles.add(new SupportingFile("auth/DefaultApi20Impl.mustache", authFolder, "DefaultApi20Impl.java"));
supportingFiles.add(new SupportingFile("auth/OauthPasswordGrant.mustache", authFolder, "OauthPasswordGrant.java"));
supportingFiles.add(new SupportingFile("auth/OauthClientCredentialsGrant.mustache", authFolder, "OauthClientCredentialsGrant.java"));
supportingFiles.add(new SupportingFile("auth/ApiErrorDecoder.mustache", authFolder, "ApiErrorDecoder.java"));
@@ -1146,6 +1167,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
this.supportStreaming = supportStreaming;
}
public void setWithAWSV4Signature(boolean withAWSV4Signature) {
this.withAWSV4Signature = withAWSV4Signature;
}
public void setGradleProperties(final String gradleProperties) {
this.gradleProperties = gradleProperties;
}
@@ -457,16 +457,16 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements
fieldCustomization.add("strict=True");
if (cp.getMaximum() != null) {
if (cp.getExclusiveMaximum()) {
fieldCustomization.add("gt=" + cp.getMaximum());
fieldCustomization.add("lt=" + cp.getMaximum());
} else {
fieldCustomization.add("ge=" + cp.getMaximum());
fieldCustomization.add("le=" + cp.getMaximum());
}
}
if (cp.getMinimum() != null) {
if (cp.getExclusiveMinimum()) {
fieldCustomization.add("lt=" + cp.getMinimum());
fieldCustomization.add("gt=" + cp.getMinimum());
} else {
fieldCustomization.add("le=" + cp.getMinimum());
fieldCustomization.add("ge=" + cp.getMinimum());
}
}
if (cp.getMultipleOf() != null) {
@@ -424,8 +424,9 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema unaliasSchema = unaliasSchema(p);
if (ModelUtils.isArraySchema(unaliasSchema)) {
ArraySchema ap = (ArraySchema) unaliasSchema;
Schema inner = ap.getItems();
if (inner == null) {
LOGGER.warn("{}(array property) does not have a proper inner type defined.Default to string",
@@ -433,10 +434,10 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
inner = new StringSchema().description("TODO default missing array inner type to string");
}
return "Vec<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = getAdditionalProperties(p);
} else if (ModelUtils.isMapSchema(unaliasSchema)) {
Schema inner = getAdditionalProperties(unaliasSchema);
if (inner == null) {
LOGGER.warn("{}(map property) does not have a proper inner type defined. Default to string", p.getName());
LOGGER.warn("{}(map property) does not have a proper inner type defined. Default to string", unaliasSchema.getName());
inner = new StringSchema().description("TODO default missing map inner type to string");
}
return "::std::collections::HashMap<String, " + getTypeDeclaration(inner) + ">";
@@ -444,7 +445,7 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
// Not using the supertype invocation, because we want to UpperCamelize
// the type.
String schemaType = getSchemaType(p);
String schemaType = getSchemaType(unaliasSchema);
if (typeMapping.containsKey(schemaType)) {
return typeMapping.get(schemaType);
}
@@ -79,6 +79,8 @@ public class ScalaSttpClientCodegen extends AbstractScalaCodegen implements Code
protected boolean renderJavadoc = true;
protected boolean removeOAuthSecurities = true;
Map<String, ModelsMap> enumRefs = new HashMap<>();
public ScalaSttpClientCodegen() {
super();
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
@@ -261,14 +263,8 @@ public class ScalaSttpClientCodegen extends AbstractScalaCodegen implements Code
@SuppressWarnings("unchecked")
private void postProcessUpdateImports(final Map<String, ModelsMap> models) {
final String prefix = modelPackage() + ".";
Map<String, ModelsMap> enumRefs = new HashMap<>();
for (String key : models.keySet()) {
CodegenModel model = ModelUtils.getModelByName(key, models);
if (model.isEnum) {
ModelsMap objs = models.get(key);
enumRefs.put(key, objs);
}
}
enumRefs = getEnumRefs(models);
for (String openAPIName : models.keySet()) {
CodegenModel model = ModelUtils.getModelByName(openAPIName, models);
@@ -276,6 +272,7 @@ public class ScalaSttpClientCodegen extends AbstractScalaCodegen implements Code
LOGGER.warn("Expected to retrieve model {} by name, but no model was found. Check your -Dmodels inclusions.", openAPIName);
continue;
}
ModelsMap objs = models.get(openAPIName);
List<Map<String, String>> imports = objs.getImports();
if (imports == null || imports.isEmpty()) {
@@ -285,25 +282,35 @@ public class ScalaSttpClientCodegen extends AbstractScalaCodegen implements Code
Iterator<Map<String, String>> iterator = imports.iterator();
while (iterator.hasNext()) {
String importPath = iterator.next().get("import");
Map<String, String> item = new HashMap<>();
if (importPath.startsWith(prefix)) {
if (isEnumClass(importPath, enumRefs)) {
Map<String, String> item = new HashMap<>();
item.put("import", importPath.concat("._"));
newImports.add(item);
}
}
else {
Map<String, String> item = new HashMap<>();
item.put("import", importPath);
newImports.add(item);
}
if (isEnumClass(importPath, enumRefs)) {
item.put("import", importPath.concat("._"));
newImports.add(item);
}
}
else {
item.put("import", importPath);
newImports.add(item);
}
}
// reset imports
objs.setImports(newImports);
}
}
private Map<String, ModelsMap> getEnumRefs(final Map<String, ModelsMap> models) {
Map<String, ModelsMap> enums = new HashMap<>();
for (String key : models.keySet()) {
CodegenModel model = ModelUtils.getModelByName(key, models);
if (model.isEnum) {
ModelsMap objs = models.get(key);
enums.put(key, objs);
}
}
return enums;
}
private boolean isEnumClass(final String importPath, final Map<String, ModelsMap> enumModels) {
if (enumModels == null || enumModels.isEmpty()) {
return false;
@@ -351,6 +358,26 @@ public class ScalaSttpClientCodegen extends AbstractScalaCodegen implements Code
LOGGER.error("Unable to find operations List", e);
}
}
// update imports for enum class
List<Map<String, String>> newImports = new ArrayList<>();
List<Map<String, String>> imports = objs.getImports();
if (imports != null && !imports.isEmpty()) {
Iterator<Map<String, String>> iterator = imports.iterator();
while (iterator.hasNext()) {
String importPath = iterator.next().get("import");
Map<String, String> item = new HashMap<>();
if (isEnumClass(importPath, enumRefs)) {
item.put("import", importPath.concat("._"));
}
else {
item.put("import", importPath);
}
newImports.add(item);
}
}
objs.setImports(newImports);
return super.postProcessOperationsWithModels(objs, allModels);
}
@@ -105,7 +105,6 @@ public class SpringCodegen extends AbstractJavaCodegen
public static final String RETURN_SUCCESS_CODE = "returnSuccessCode";
public static final String UNHANDLED_EXCEPTION_HANDLING = "unhandledException";
public static final String USE_SPRING_BOOT3 = "useSpringBoot3";
public static final String USE_JAKARTA_EE = "useJakartaEe";
public static final String REQUEST_MAPPING_OPTION = "requestMappingMode";
public static final String USE_REQUEST_MAPPING_ON_CONTROLLER = "useRequestMappingOnController";
public static final String USE_REQUEST_MAPPING_ON_INTERFACE = "useRequestMappingOnInterface";
@@ -242,8 +241,8 @@ public class SpringCodegen extends AbstractJavaCodegen
"Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies",
useSwaggerUI));
cliOptions.add(CliOption.newBoolean(USE_SPRING_BOOT3,
"Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).",
useSwaggerUI));
"Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.",
useSpringBoot3));
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
@@ -474,9 +473,9 @@ public class SpringCodegen extends AbstractJavaCodegen
if (AnnotationLibrary.SWAGGER1.equals(getAnnotationLibrary())) {
throw new IllegalArgumentException(AnnotationLibrary.SWAGGER1.getPropertyName() + " is not supported with Spring Boot > 3.x");
}
writePropertyBack(USE_JAKARTA_EE, true);
} else {
writePropertyBack(USE_JAKARTA_EE, false);
useJakartaEe=true;
additionalProperties.put(USE_JAKARTA_EE, useJakartaEe);
applyJakartaPackage();
}
writePropertyBack(USE_SPRING_BOOT3, isUseSpringBoot3());
@@ -486,6 +485,9 @@ public class SpringCodegen extends AbstractJavaCodegen
importMapping.put("DateTimeFormat", "org.springframework.format.annotation.DateTimeFormat");
importMapping.put("ApiIgnore", "springfox.documentation.annotations.ApiIgnore");
importMapping.put("ParameterObject", "org.springdoc.api.annotations.ParameterObject");
if (isUseSpringBoot3()) {
importMapping.put("ParameterObject", "org.springdoc.core.annotations.ParameterObject");
}
if (useOptional) {
writePropertyBack(USE_OPTIONAL, useOptional);
@@ -73,6 +73,8 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
private static final String PLATFORM_SWITCH = "platform";
private static final String PLATFORM_SWITCH_DESC = "Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.";
private static final String[] PLATFORMS = { "browser", "node", "deno" };
private static final String IMPORT_FILE_EXTENSION_SWITCH = "importFileExtension";
private static final String IMPORT_FILE_EXTENSION_SWITCH_DESC = "File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html). Defaults to '.ts' when 'platform' is set to 'deno'.";
private static final String FILE_CONTENT_DATA_TYPE= "fileContentDataType";
private static final String FILE_CONTENT_DATA_TYPE_DESC = "Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)";
private static final String USE_RXJS_SWITCH = "useRxJS";
@@ -198,6 +200,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_RXJS_SWITCH, TypeScriptClientCodegen.USE_RXJS_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_INVERSIFY_SWITCH, TypeScriptClientCodegen.USE_INVERSIFY_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH, TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH_DESC));
CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
for (String option: TypeScriptClientCodegen.FRAMEWORKS) {
@@ -835,8 +838,9 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
}
if ("deno".equals(propPlatform)) {
additionalProperties.put("extensionForDeno", ".ts");
Object fileExtension = additionalProperties.get(IMPORT_FILE_EXTENSION_SWITCH);
if (fileExtension == null && "deno".equals(propPlatform)) {
additionalProperties.put(IMPORT_FILE_EXTENSION_SWITCH, ".ts");
}
final boolean useRxJS = convertPropertyToBooleanAndWriteBack(USE_RXJS_SWITCH);
@@ -1,633 +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
*
* https://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.languages;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.meta.features.GlobalFeature;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.SemVer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.*;
public class TypeScriptKoaServerCodegen extends AbstractTypeScriptClientCodegen {
private final Logger LOGGER = LoggerFactory.getLogger(TypeScriptKoaServerCodegen.class);
private static String CLASS_NAME_PREFIX_PATTERN = "^[a-zA-Z0-9]*$";
private static String CLASS_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9]*$";
private static String FILE_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9.-]*$";
public static enum QUERY_PARAM_OBJECT_FORMAT_TYPE {dot, json, key}
public static enum PROVIDED_IN_LEVEL {none, root, any, platform}
private static final String DEFAULT_IMPORT_PREFIX = "./";
private static final String DEFAULT_MODEL_IMPORT_DIRECTORY_PREFIX = "../";
public static final String NPM_REPOSITORY = "npmRepository";
public static final String WITH_INTERFACES = "withInterfaces";
public static final String USE_SINGLE_REQUEST_PARAMETER = "useSingleRequestParameter";
public static final String TAGGED_UNIONS = "taggedUnions";
public static final String NG_VERSION = "ngVersion";
public static final String PROVIDED_IN = "providedIn";
public static final String ENFORCE_GENERIC_MODULE_WITH_PROVIDERS = "enforceGenericModuleWithProviders";
public static final String HTTP_CONTEXT_IN_OPTIONS = "httpContextInOptions";
public static final String API_MODULE_PREFIX = "apiModulePrefix";
public static final String CONFIGURATION_PREFIX = "configurationPrefix";
public static final String SERVICE_SUFFIX = "serviceSuffix";
public static final String SERVICE_FILE_SUFFIX = "serviceFileSuffix";
public static final String MODEL_SUFFIX = "modelSuffix";
public static final String MODEL_FILE_SUFFIX = "modelFileSuffix";
public static final String FILE_NAMING = "fileNaming";
public static final String STRING_ENUMS = "stringEnums";
public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
public static final String QUERY_PARAM_OBJECT_FORMAT = "queryParamObjectFormat";
protected String ngVersion = "15.0.3";
protected String npmRepository = null;
private boolean useSingleRequestParameter = false;
protected String serviceSuffix = "Service";
protected String serviceFileSuffix = ".service";
protected String modelSuffix = "";
protected String modelFileSuffix = "";
protected String fileNaming = "camelCase";
protected Boolean stringEnums = false;
protected QUERY_PARAM_OBJECT_FORMAT_TYPE queryParamObjectFormat = QUERY_PARAM_OBJECT_FORMAT_TYPE.dot;
protected PROVIDED_IN_LEVEL providedIn = PROVIDED_IN_LEVEL.root;
private boolean taggedUnions = false;
public TypeScriptKoaServerCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.includeGlobalFeatures(GlobalFeature.ParameterStyling)
);
this.outputFolder = "generated-code/typescript-koa";
supportsMultipleInheritance = true;
embeddedTemplateDir = templateDir = "typescript-koa";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.service.mustache", ".ts");
languageSpecificPrimitives.add("Blob");
typeMapping.put("file", "Blob");
apiPackage = "api";
modelPackage = "model";
this.cliOptions.add(new CliOption(NPM_REPOSITORY,
"Use this property to set an url your private npmRepo in the package.json"));
this.cliOptions.add(CliOption.newBoolean(WITH_INTERFACES,
"Setting this property to true will generate interfaces next to the default class implementations.",
false));
this.cliOptions.add(CliOption.newBoolean(USE_SINGLE_REQUEST_PARAMETER,
"Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.",
false));
this.cliOptions.add(CliOption.newBoolean(TAGGED_UNIONS,
"Use discriminators to create tagged unions instead of extending interfaces.",
this.taggedUnions));
CliOption providedInCliOpt = new CliOption(PROVIDED_IN,
"Use this property to provide Injectables in wanted level.").defaultValue("root");
Map<String, String> providedInOptions = new HashMap<>();
providedInOptions.put(PROVIDED_IN_LEVEL.none.toString(), "No providedIn)");
providedInOptions.put(PROVIDED_IN_LEVEL.root.toString(), "The application-level injector in most apps.");
providedInOptions.put(PROVIDED_IN_LEVEL.platform.toString(), "A special singleton platform injector shared by all applications on the page.");
providedInOptions.put(PROVIDED_IN_LEVEL.any.toString(), "Provides a unique instance in each lazy loaded module while all eagerly loaded modules share one instance.");
providedInCliOpt.setEnum(providedInOptions);
this.cliOptions.add(providedInCliOpt);
this.cliOptions.add(new CliOption(API_MODULE_PREFIX, "The prefix of the generated ApiModule."));
this.cliOptions.add(new CliOption(CONFIGURATION_PREFIX, "The prefix of the generated Configuration."));
this.cliOptions.add(new CliOption(SERVICE_SUFFIX, "The suffix of the generated service.").defaultValue(this.serviceSuffix));
this.cliOptions.add(new CliOption(SERVICE_FILE_SUFFIX, "The suffix of the file of the generated service (service<suffix>.ts).").defaultValue(this.serviceFileSuffix));
this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model."));
this.cliOptions.add(new CliOption(MODEL_FILE_SUFFIX, "The suffix of the file of the generated model (model<suffix>.ts)."));
this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums)));
this.cliOptions.add(new CliOption(QUERY_PARAM_OBJECT_FORMAT, "The format for query param objects: 'dot', 'json', 'key'.").defaultValue(this.queryParamObjectFormat.name()));
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
codegenModel.additionalPropertiesType = getTypeDeclaration(getAdditionalProperties(schema));
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
@Override
public String getName() {
return "typescript-koa-server";
}
@Override
public String getHelp() {
return "Generates a TypeScript Koa (2.x) server.";
}
@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(new SupportingFile("env.example.mustache", "", ".env.example"));
supportingFiles.add(new SupportingFile("jest.config.js.mustache", "", ".jest.config.js"));
supportingFiles.add(new SupportingFile("app.ts.mustache", "", "app.ts"));
supportingFiles.add(new SupportingFile("build.js.mustache", "", "build.js"));
supportingFiles.add(new SupportingFile("docker-compose.mustache", "", "docker-compose.yml"));
supportingFiles.add(new SupportingFile("nodemon.mustache", "", "nodemon.json"));
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
// app/session folder
supportingFiles.add(new SupportingFile("sessions.service.ts.mustache", "app" + File.separator + "services", "sessions.service.ts"));
supportingFiles.add(new SupportingFile("sessions.index.ts.mustache", "app" + File.separator + "ervices", "index.ts"));
// app/helpers folder
supportingFiles.add(new SupportingFile("client.ts.mustache", "app" + File.separator + "helpers", "client.ts"));
// app/jobs folder
supportingFiles.add(new SupportingFile("jobs.README.mustache", "app" + File.separator + "jobs", "README.md"));
// app/controllers
supportingFiles.add(new SupportingFile("index.ts.mustache", "app" + File.separator + "controllers", "index.ts"));
supportingFiles.add(new SupportingFile("sessions.controller.ts.mustache", "app" + File.separator + "controllers", "sessions.controller.ts"));
// app/controllers/__tests__
supportingFiles.add(new SupportingFile("session.test.js.mustache", "app" + File.separator + "controllers" + File.separator + "__tests__", "session.test.js"));
// configs
supportingFiles.add(new SupportingFile("application.ts.mustache", "configs", "application.ts"));
supportingFiles.add(new SupportingFile("bootstrap.ts.mustache", "configs", "bootstrap.ts"));
supportingFiles.add(new SupportingFile("interceptors.ts.mustache", "configs", "interceptors.ts"));
supportingFiles.add(new SupportingFile("koa.middlewares.ts.mustache", "configs", "koa.middlewares.ts"));
supportingFiles.add(new SupportingFile("routing.middlewares.ts.mustache", "configs", "routing.middlewares.ts"));
supportingFiles.add(new SupportingFile("routing.options.ts.mustache", "configs", "routing.options.ts"));
supportingFiles.add(new SupportingFile("utils.ts.mustache", "configs", "utils.ts"));
// configs/constants
supportingFiles.add(new SupportingFile("development.ts.mustache", "configs" + File.separator + "constants", "development.ts"));
supportingFiles.add(new SupportingFile("envs.ts.mustache", "configs" + File.separator + "constants", "envs.ts"));
supportingFiles.add(new SupportingFile("configs.constants.index.ts.mustache", "configs" + File.separator + "constants", "index.ts"));
supportingFiles.add(new SupportingFile("production.ts.mustache", "configs" + File.separator + "constants", "production.ts"));
supportingFiles.add(new SupportingFile("staging.ts.mustache", "configs" + File.separator + "constants", "staging.ts"));
// prisma
supportingFiles.add(new SupportingFile("schema.prisma.mustache", "prisma", "schema.prisma"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
if (additionalProperties.containsKey(CONFIGURATION_PREFIX)) {
String configurationPrefix = additionalProperties.get(CONFIGURATION_PREFIX).toString();
validateClassPrefixArgument("Configuration", configurationPrefix);
additionalProperties.put("configurationClassName", configurationPrefix + "Configuration");
additionalProperties.put("configurationParametersInterfaceName", configurationPrefix + "ConfigurationParameters");
} else {
additionalProperties.put("configurationClassName", "Configuration");
additionalProperties.put("configurationParametersInterfaceName", "ConfigurationParameters");
}
}
private String getIndexDirectory() {
String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.')));
return indexPackage.replace('.', File.separatorChar);
}
public void setStringEnums(boolean value) {
stringEnums = value;
}
public Boolean getStringEnums() {
return stringEnums;
}
public boolean getQueryParamObjectFormatDot() {
return QUERY_PARAM_OBJECT_FORMAT_TYPE.dot.equals(queryParamObjectFormat);
}
public boolean getQueryParamObjectFormatJson() {
return QUERY_PARAM_OBJECT_FORMAT_TYPE.json.equals(queryParamObjectFormat);
}
public boolean getQueryParamObjectFormatKey() {
return QUERY_PARAM_OBJECT_FORMAT_TYPE.key.equals(queryParamObjectFormat);
}
@Override
public boolean isDataTypeFile(final String dataType) {
return "Blob".equals(dataType);
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isFileSchema(p)) {
return "Blob";
} else {
return super.getTypeDeclaration(p);
}
}
private String applyLocalTypeMapping(String type) {
if (typeMapping.containsKey(type)) {
type = typeMapping.get(type);
}
return type;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
parameter.dataType = applyLocalTypeMapping(parameter.dataType);
}
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap operations, List<ModelMap> allModels) {
OperationMap objs = operations.getOperations();
// Add filename information for api imports
objs.put("apiFilename", getApiFilenameFromClassname(objs.getClassname()));
List<CodegenOperation> ops = objs.getOperation();
boolean hasSomeFormParams = false;
boolean hasSomeEncodableParams = false;
for (CodegenOperation op : ops) {
if (op.getHasFormParams()) {
hasSomeFormParams = true;
}
op.httpMethod = op.httpMethod.toLowerCase(Locale.ENGLISH);
// Prep a string buffer where we're going to set up our new version of the string.
StringBuilder pathBuffer = new StringBuilder();
ParameterExpander paramExpander = new ParameterExpander(op, this::toParamName);
int insideCurly = 0;
// Iterate through existing string, one character at a time.
for (int i = 0; i < op.path.length(); i++) {
switch (op.path.charAt(i)) {
case '{':
// We entered curly braces, so track that.
insideCurly++;
break;
case '}':
// We exited curly braces, so track that.
insideCurly--;
pathBuffer.append(paramExpander.buildPathEntry());
hasSomeEncodableParams = true;
break;
default:
char nextChar = op.path.charAt(i);
if (insideCurly > 0) {
paramExpander.appendToParameterName(nextChar);
} else {
pathBuffer.append(nextChar);
}
break;
}
}
// Overwrite path to TypeScript template string, after applying everything we just did.
op.path = pathBuffer.toString();
}
operations.put("hasSomeFormParams", hasSomeFormParams);
operations.put("hasSomeEncodableParams", hasSomeEncodableParams);
// Add additional filename information for model imports in the services
List<Map<String, String>> imports = operations.getImports();
for (Map<String, String> im : imports) {
// This property is not used in the templates any more, subject for removal
im.put("filename", im.get("import"));
im.put("classname", im.get("classname"));
}
return operations;
}
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
ModelsMap result = super.postProcessModels(objs);
return postProcessModelsEnum(result);
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> result = super.postProcessAllModels(objs);
for (ModelsMap entry : result.values()) {
for (ModelMap mo : entry.getModels()) {
CodegenModel cm = mo.getModel();
if (taggedUnions) {
mo.put(TAGGED_UNIONS, true);
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
cm.imports.add(child.classname);
setChildDiscriminatorValue(cm, child);
}
}
// with tagged union, a child model doesn't extend the parent (all properties are just copied over)
// it means we don't need to import that parent any more
if (cm.parent != null) {
cm.imports.remove(cm.parent);
// however, it's possible that the child model contains a recursive reference to the parent
// in order to support this case, we update the list of imports from properties once again
for (CodegenProperty cp : cm.allVars) {
addImportsForPropertyType(cm, cp);
}
removeSelfReferenceImports(cm);
}
}
// Add additional filename information for imports
Set<String> parsedImports = parseImports(cm);
mo.put("tsImports", toTsImports(cm, parsedImports));
}
}
return result;
}
private void setChildDiscriminatorValue(CodegenModel parent, CodegenModel child) {
if (child.vendorExtensions.isEmpty() ||
!child.vendorExtensions.containsKey("x-discriminator-value")
) {
for (CodegenProperty prop : child.allVars) {
if (prop.baseName.equals(parent.discriminator.getPropertyName())) {
for (CodegenDiscriminator.MappedModel mappedModel : parent.discriminator.getMappedModels()) {
if (mappedModel.getModelName().equals(child.classname)) {
prop.discriminatorValue = mappedModel.getMappingName();
}
}
}
}
}
}
/**
* Parse imports
*/
private Set<String> parseImports(CodegenModel cm) {
Set<String> newImports = new HashSet<>();
if (cm.imports.size() > 0) {
for (String name : cm.imports) {
if (name.indexOf(" | ") >= 0) {
String[] parts = name.split(" \\| ");
Collections.addAll(newImports, parts);
} else {
newImports.add(name);
}
}
}
return newImports;
}
private List<Map<String, String>> toTsImports(CodegenModel cm, Set<String> imports) {
List<Map<String, String>> tsImports = new ArrayList<>();
for (String im : imports) {
if (!im.equals(cm.classname)) {
HashMap<String, String> tsImport = new HashMap<>();
// TVG: This is used as class name in the import statements of the model file
tsImport.put("classname", im);
tsImport.put("filename", toModelFilename(removeModelPrefixSuffix(im)));
tsImports.add(tsImport);
}
}
return tsImports;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultService";
}
return camelize(name) + serviceSuffix;
}
@Override
public String toApiFilename(String name) {
if (name.length() == 0) {
return "default.service";
}
return this.convertUsingFileNamingConvention(name) + serviceFileSuffix;
}
@Override
public String toApiImport(String name) {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
return apiPackage() + "/" + toApiFilename(name);
}
@Override
public String toModelFilename(String name) {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
return DEFAULT_IMPORT_PREFIX + this.convertUsingFileNamingConvention(super.toModelFilename(name)) + modelFileSuffix;
}
@Override
public String toModelImport(String name) {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
return DEFAULT_MODEL_IMPORT_DIRECTORY_PREFIX + modelPackage() + "/" + toModelFilename(name).substring(DEFAULT_IMPORT_PREFIX.length());
}
public String getNpmRepository() {
return npmRepository;
}
public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository;
}
private boolean getUseSingleRequestParameter() {
return useSingleRequestParameter;
}
private void setUseSingleRequestParameter(boolean useSingleRequestParameter) {
this.useSingleRequestParameter = useSingleRequestParameter;
}
private String getApiFilenameFromClassname(String classname) {
String name = classname.substring(0, classname.length() - serviceSuffix.length());
return toApiFilename(name);
}
@Override
public String toModelName(String name) {
name = addSuffix(name, modelSuffix);
return super.toModelName(name);
}
public String removeModelPrefixSuffix(String name) {
String result = name;
if (modelSuffix.length() > 0 && result.endsWith(modelSuffix)) {
result = result.substring(0, result.length() - modelSuffix.length());
}
String prefix = capitalize(this.modelNamePrefix);
String suffix = capitalize(this.modelNameSuffix);
if (prefix.length() > 0 && result.startsWith(prefix)) {
result = result.substring(prefix.length());
}
if (suffix.length() > 0 && result.endsWith(suffix)) {
result = result.substring(0, result.length() - suffix.length());
}
return result;
}
/**
* Validates that the given string value only contains '-', '.' and alpha numeric characters.
* Throws an IllegalArgumentException, if the string contains any other characters.
*
* @param argument The name of the argument being validated. This is only used for displaying an error message.
* @param value The value that is being validated.
*/
private void validateFileSuffixArgument(String argument, String value) {
if (!value.matches(FILE_NAME_SUFFIX_PATTERN)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "%s file suffix only allows '.', '-' and alphanumeric characters.", argument)
);
}
}
/**
* Validates that the given string value only contains alpha numeric characters.
* Throws an IllegalArgumentException, if the string contains any other characters.
*
* @param argument The name of the argument being validated. This is only used for displaying an error message.
* @param value The value that is being validated.
*/
private void validateClassPrefixArgument(String argument, String value) {
if (!value.matches(CLASS_NAME_PREFIX_PATTERN)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "%s class prefix only allows alphanumeric characters.", argument)
);
}
}
/**
* Validates that the given string value only contains alpha numeric characters.
* Throws an IllegalArgumentException, if the string contains any other characters.
*
* @param argument The name of the argument being validated. This is only used for displaying an error message.
* @param value The value that is being validated.
*/
private void validateClassSuffixArgument(String argument, String value) {
if (!value.matches(CLASS_NAME_SUFFIX_PATTERN)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "%s class suffix only allows alphanumeric characters.", argument)
);
}
}
/**
* Set the query param object format.
*
* @param format the query param object format to use
*/
public void setQueryParamObjectFormat(String format) {
try {
queryParamObjectFormat = QUERY_PARAM_OBJECT_FORMAT_TYPE.valueOf(format);
} catch (IllegalArgumentException e) {
String values = Stream.of(QUERY_PARAM_OBJECT_FORMAT_TYPE.values())
.map(value -> "'" + value.name() + "'")
.collect(Collectors.joining(", "));
String msg = String.format(Locale.ROOT, "Invalid query param object format '%s'. Must be one of %s.", format, values);
throw new IllegalArgumentException(msg);
}
}
/**
* Set the file naming type.
*
* @param fileNaming the file naming to use
*/
private void setFileNaming(String fileNaming) {
if ("camelCase".equals(fileNaming) || "kebab-case".equals(fileNaming)) {
this.fileNaming = fileNaming;
} else {
throw new IllegalArgumentException("Invalid file naming '" +
fileNaming + "'. Must be 'camelCase' or 'kebab-case'");
}
}
/**
* Converts the original name according to the current <code>fileNaming</code> strategy.
*
* @param originalName the original name to transform
* @return the transformed name
*/
private String convertUsingFileNamingConvention(String originalName) {
String name = this.removeModelPrefixSuffix(originalName);
if ("kebab-case".equals(fileNaming)) {
name = dashize(underscore(name));
} else {
name = camelize(name, LOWERCASE_FIRST_LETTER);
}
return name;
}
/**
* Set the Injectable level
*
* @param level the wanted level
*/
public void setProvidedIn(String level) {
try {
providedIn = PROVIDED_IN_LEVEL.valueOf(level);
} catch (IllegalArgumentException e) {
String values = Stream.of(PROVIDED_IN_LEVEL.values())
.map(value -> "'" + value.name() + "'")
.collect(Collectors.joining(", "));
String msg = String.format(Locale.ROOT, "Invalid providedIn level '%s'. Must be one of %s.", level, values);
throw new IllegalArgumentException(msg);
}
}
/**
*
*/
private boolean getIsProvidedInNone() {
return PROVIDED_IN_LEVEL.none.equals(providedIn);
}
}
@@ -308,15 +308,15 @@ public class ModelUtils {
/**
* Invoke the specified visitor function for every schema that matches mimeType in the OpenAPI document.
*
* <p>
* To avoid infinite recursion, referenced schemas are visited only once. When a referenced schema is visited,
* it is added to visitedSchemas.
*
* @param openAPI the OpenAPI document that contains schema objects.
* @param schema the root schema object to be visited.
* @param mimeType the mime type. TODO: does not seem to be used in a meaningful way.
* @param openAPI the OpenAPI document that contains schema objects.
* @param schema the root schema object to be visited.
* @param mimeType the mime type. TODO: does not seem to be used in a meaningful way.
* @param visitedSchemas the list of referenced schemas that have been visited.
* @param visitor the visitor function which is invoked for every visited schema.
* @param visitor the visitor function which is invoked for every visited schema.
*/
private static void visitSchema(OpenAPI openAPI, Schema schema, String mimeType, List<String> visitedSchemas, OpenAPISchemaVisitor visitor) {
visitor.visit(schema, mimeType);
@@ -425,13 +425,14 @@ public class ModelUtils {
/**
* Return true if the specified schema is an object with a fixed number of properties.
*
* <p>
* A ObjectSchema differs from a MapSchema in the following way:
* - An ObjectSchema is not extensible, i.e. it has a fixed number of properties.
* - A MapSchema is an object that can be extended with an arbitrary set of properties.
* The payload may include dynamic properties.
*
* <p>
* For example, an OpenAPI schema is considered an ObjectSchema in the following scenarios:
* <p>
*
* type: object
* additionalProperties: false
@@ -475,20 +476,58 @@ public class ModelUtils {
return false;
}
/**
* Return true if the specified schema is composed with more than one of the following:
* 'oneOf', 'anyOf' or 'allOf'.
*
* @param schema the OAS schema
* @return true if the specified schema is a Composed schema.
*/
public static boolean isComplexComposedSchema(Schema schema) {
if (!(schema instanceof ComposedSchema)) {
return false;
}
int count = 0;
if (schema.getAllOf() != null && !schema.getAllOf().isEmpty()) {
count++;
}
if (schema.getOneOf() != null && !schema.getOneOf().isEmpty()) {
count++;
}
if (schema.getAnyOf() != null && !schema.getAnyOf().isEmpty()) {
count++;
}
if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
count++;
}
if (count > 1) {
return true;
}
return false;
}
/**
* Return true if the specified 'schema' is an object that can be extended with additional properties.
* Additional properties means a Schema should support all explicitly defined properties plus any
* undeclared properties.
*
* <p>
* A MapSchema differs from an ObjectSchema in the following way:
* - An ObjectSchema is not extensible, i.e. it has a fixed number of properties.
* - A MapSchema is an object that can be extended with an arbitrary set of properties.
* The payload may include dynamic properties.
*
* The payload may include dynamic properties.
* <p>
* Note that isMapSchema returns true for a composed schema (allOf, anyOf, oneOf) that also defines
* additionalproperties.
*
* <p>
* For example, an OpenAPI schema is considered a MapSchema in the following scenarios:
* <p>
*
* type: object
* additionalProperties: true
@@ -772,14 +811,14 @@ public class ModelUtils {
/**
* Check to see if the schema is a free form object.
*
* <p>
* A free form object is an object (i.e. 'type: object' in a OAS document) that:
* 1) Does not define properties, and
* 2) Is not a composed schema (no anyOf, oneOf, allOf), and
* 3) additionalproperties is not defined, or additionalproperties: true, or additionalproperties: {}.
*
* <p>
* Examples:
*
* <p>
* components:
* schemas:
* arbitraryObject:
@@ -798,7 +837,7 @@ public class ModelUtils {
* The value can be any type except the 'null' value.
*
* @param openAPI the object that encapsulates the OAS document.
* @param schema potentially containing a '$ref'
* @param schema potentially containing a '$ref'
* @return true if it's a free-form object
*/
public static boolean isFreeFormObject(OpenAPI openAPI, Schema schema) {
@@ -1054,10 +1093,10 @@ public class ModelUtils {
/**
* Return the first Schema from a specified OAS 'content' section.
*
* <p>
* For example, given the following OAS, this method returns the schema
* for the 'application/json' content type because it is listed first in the OAS.
*
* <p>
* responses:
* '200':
* content:
@@ -1099,8 +1138,8 @@ public class ModelUtils {
/**
* Has self reference?
*
* @param openAPI OpenAPI spec.
* @param schema Schema
* @param openAPI OpenAPI spec.
* @param schema Schema
* @param visitedSchemaNames A set of visited schema names
* @return boolean true if it has at least one self reference
*/
@@ -1257,7 +1296,7 @@ public class ModelUtils {
/**
* Returns the additionalProperties Schema for the specified input schema.
*
* <p>
* The additionalProperties keyword is used to control the handling of additional, undeclared
* properties, that is, properties whose names are not listed in the properties keyword.
* The additionalProperties keyword may be either a boolean or an object.
@@ -1267,9 +1306,9 @@ public class ModelUtils {
* to the boolean value True or setting additionalProperties: {}
*
* @param openAPI the object that encapsulates the OAS document.
* @param schema the input schema that may or may not have the additionalProperties keyword.
* @param schema the input schema that may or may not have the additionalProperties keyword.
* @return the Schema of the additionalProperties. The null value is returned if no additional
* properties are allowed.
* properties are allowed.
*/
public static Schema getAdditionalProperties(OpenAPI openAPI, Schema schema) {
Object addProps = schema.getAdditionalProperties();
@@ -1380,10 +1419,10 @@ public class ModelUtils {
* that specify a determinator.
* If there are multiple elements in the composed schema and it is not clear
* which one should be the parent, return null.
*
* <p>
* For example, given the following OAS spec, the parent of 'Dog' is Animal
* because 'Animal' specifies a discriminator.
*
* <p>
* animal:
* type: object
* discriminator:
@@ -1391,6 +1430,7 @@ public class ModelUtils {
* properties:
* type: string
*
* <p>
* dog:
* allOf:
* - $ref: '#/components/schemas/animal'
@@ -1418,10 +1458,10 @@ public class ModelUtils {
LOGGER.error("Failed to obtain schema from {}", parentName);
return "UNKNOWN_PARENT_NAME";
} else if (hasOrInheritsDiscriminator(s, allSchemas)) {
// discriminator.propertyName is used
// discriminator.propertyName is used or x-parent is used
return parentName;
} else {
// not a parent since discriminator.propertyName is not set
// not a parent since discriminator.propertyName or x-parent is not set
hasAmbiguousParents = true;
refedWithoutDiscriminator.add(parentName);
}
@@ -1476,7 +1516,7 @@ public class ModelUtils {
LOGGER.error("Failed to obtain schema from {}", parentName);
names.add("UNKNOWN_PARENT_NAME");
} else if (hasOrInheritsDiscriminator(s, allSchemas)) {
// discriminator.propertyName is used
// discriminator.propertyName is used or x-parent is used
names.add(parentName);
if (includeAncestors && s instanceof ComposedSchema) {
names.addAll(getAllParentsName((ComposedSchema) s, allSchemas, true));
@@ -1501,7 +1541,8 @@ public class ModelUtils {
}
private static boolean hasOrInheritsDiscriminator(Schema schema, Map<String, Schema> allSchemas) {
if (schema.getDiscriminator() != null && StringUtils.isNotEmpty(schema.getDiscriminator().getPropertyName())) {
if ((schema.getDiscriminator() != null && StringUtils.isNotEmpty(schema.getDiscriminator().getPropertyName()))
|| (isExtensionParent(schema))) { // x-parent is used
return true;
} else if (StringUtils.isNotEmpty(schema.get$ref())) {
String parentName = getSimpleRef(schema.get$ref());
@@ -1523,18 +1564,43 @@ public class ModelUtils {
return false;
}
/**
* If it's a boolean, returns the value of the extension `x-parent`.
* If it's string, return true if it's non-empty.
* If the return value is `true`, the schema is a parent.
*
* @param schema Schema
* @return boolean
*/
public static boolean isExtensionParent(Schema schema) {
if (schema.getExtensions() == null) {
return false;
} else {
Object xParent = schema.getExtensions().get("x-parent");
if (xParent == null) {
return false;
} else if (xParent instanceof Boolean) {
return (Boolean) xParent;
} else if (xParent instanceof String) {
return StringUtils.isNotEmpty((String) xParent);
} else {
return false;
}
}
}
/**
* Return true if the 'nullable' attribute is set to true in the schema, i.e. if the value
* of the property can be the null value.
*
* <p>
* In addition, if the OAS document is 3.1 or above, isNullable returns true if the input
* schema is a 'oneOf' composed document with at most two children, and one of the children
* is the 'null' type.
*
* <p>
* The caller is responsible for resolving schema references before invoking isNullable.
* If the input schema is a $ref and the referenced schema has 'nullable: true', this method
* returns false (because the nullable attribute is defined in the referenced schema).
*
* <p>
* The 'nullable' attribute was introduced in OAS 3.0.
* The 'nullable' attribute is deprecated in OAS 3.1. In a OAS 3.1 document, the preferred way
* to specify nullable properties is to use the 'null' type.
@@ -1564,11 +1630,11 @@ public class ModelUtils {
/**
* Return true if the specified composed schema is 'oneOf', contains one or two elements,
* and at least one of the elements is the 'null' type.
*
* <p>
* The 'null' type is supported in OAS 3.1 and above.
* In the example below, the 'OptionalOrder' can have the null value because the 'null'
* type is one of the elements under 'oneOf'.
*
* <p>
* OptionalOrder:
* oneOf:
* - type: 'null'
@@ -1591,13 +1657,13 @@ public class ModelUtils {
/**
* isNullType returns true if the input schema is the 'null' type.
*
* <p>
* The 'null' type is supported in OAS 3.1 and above. It is not supported
* in OAS 2.0 and OAS 3.0.x.
*
* <p>
* For example, the "null" type could be used to specify that a value must
* either be null or a specified type:
*
* <p>
* OptionalOrder:
* oneOf:
* - type: 'null'
@@ -1617,6 +1683,7 @@ public class ModelUtils {
* For when a type is not defined on a schema
* Note: properties, additionalProperties, enums, validations, items, and composed schemas (oneOf/anyOf/allOf)
* can be defined or omitted on these any type schemas
*
* @param schema the schema that we are checking
* @return boolean
*/
@@ -1713,7 +1780,7 @@ public class ModelUtils {
private static ObjectMapper getRightMapper(String data) {
ObjectMapper mapper;
if (data.trim().startsWith("{")) {
if (data.trim().startsWith("{")) {
mapper = JSON_MAPPER;
} else {
mapper = YAML_MAPPER;
@@ -1725,11 +1792,9 @@ public class ModelUtils {
* Parse and return a JsonNode representation of the input OAS document.
*
* @param location the URL of the OAS document.
* @param auths the list of authorization values to access the remote URL.
*
* @throws java.lang.Exception if an error occurs while retrieving the OpenAPI document.
*
* @param auths the list of authorization values to access the remote URL.
* @return A JsonNode representation of the input OAS document.
* @throws java.lang.Exception if an error occurs while retrieving the OpenAPI document.
*/
public static JsonNode readWithInfo(String location, List<AuthorizationValue> auths) throws Exception {
String data;
@@ -1756,14 +1821,13 @@ public class ModelUtils {
/**
* Parse the OAS document at the specified location, get the swagger or openapi version
* as specified in the source document, and return the version.
*
* <p>
* For OAS 2.0 documents, return the value of the 'swagger' attribute.
* For OAS 3.x documents, return the value of the 'openapi' attribute.
*
* @param openAPI the object that encapsulates the OAS document.
* @param openAPI the object that encapsulates the OAS document.
* @param location the URL of the OAS document.
* @param auths the list of authorization values to access the remote URL.
*
* @param auths the list of authorization values to access the remote URL.
* @return the version of the OpenAPI document.
*/
public static SemVer getOpenApiVersion(OpenAPI openAPI, String location, List<AuthorizationValue> auths) {
@@ -635,7 +635,7 @@ fail:
{{^isEnum}}
{{#isString}}
{{^required}}if ({{{name}}}) { {{/required}}
if(!cJSON_IsString({{{name}}}))
if(!cJSON_IsString({{{name}}}){{^required}} && !cJSON_IsNull({{{name}}}){{/required}})
{
goto end; //String
}
@@ -880,7 +880,7 @@ fail:
{{/isEnum}}
{{^isEnum}}
{{#isString}}
{{^required}}{{{name}}} ? {{/required}}strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
{{^required}}{{{name}}} && !cJSON_IsNull({{{name}}}) ? {{/required}}strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
{{/isString}}
{{/isEnum}}
{{#isByteArray}}
@@ -21,9 +21,9 @@ import com.sun.jersey.api.client.WebResource.Builder;
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.file.FileDataBodyPart;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.Response.Status.Family;
import javax.ws.rs.core.MediaType;
import {{javaxPackage}}.ws.rs.core.Cookie;
import {{javaxPackage}}.ws.rs.core.Response.Status.Family;
import {{javaxPackage}}.ws.rs.core.MediaType;
import java.util.Collection;
import java.util.Collections;
@@ -2,8 +2,8 @@ package {{invokerPackage}};
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import {{javaxPackage}}.validation.ConstraintViolation;
import {{javaxPackage}}.validation.ValidationException;
public class BeanValidationException extends ValidationException {
/**
@@ -1 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})
@{{javaxPackage}}.annotation.Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})
@@ -893,9 +893,10 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param path The sub path
* @param queryParams The query parameters
* @param collectionQueryParams The collection query parameters
* @param urlQueryDeepObject URL query string of the deep object parameters
* @return The full URL
*/
private String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams) {
private String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams, String urlQueryDeepObject) {
String baseURL;
if (serverIndex != null) {
if (serverIndex < 0 || serverIndex >= servers.size()) {
@@ -946,6 +947,11 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
}
if (urlQueryDeepObject != null && urlQueryDeepObject.length() > 0) {
url.append(url.toString().contains("?") ? "&" : "?");
url.append(urlQueryDeepObject);
}
return url.toString();
}
@@ -987,6 +993,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
* @param queryParams The query parameters
* @param collectionQueryParams The collection query parameters
* @param urlQueryDeepObject A URL query string for deep object parameters
* @param body The request body object - if it is not binary, otherwise null
* @param headerParams The header parameters
* @param cookieParams The cookie parameters
@@ -1003,6 +1010,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
String method,
List<Pair> queryParams,
List<Pair> collectionQueryParams,
String urlQueryDeepObject,
Object body,
Map<String, String> headerParams,
Map<String, String> cookieParams,
@@ -1016,7 +1024,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
}
updateParamsForAuth(authNames, queryParams, headerParams, cookieParams);
final String url = buildUrl(path, queryParams, collectionQueryParams);
final String url = buildUrl(path, queryParams, collectionQueryParams, urlQueryDeepObject);
RequestBuilder builder = RequestBuilder.create(method);
builder.setUri(url);
@@ -18,6 +18,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
{{/fullJavaUtil}}
{{>generatedAnnotation}}
@@ -75,7 +76,8 @@ public class {{classname}} {
String localVarPath = "{{{path}}}"{{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params
{{javaUtilPrefix}}StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
String localVarQueryParameterBaseName;
{{javaUtilPrefix}}List<Pair> localVarQueryParams = new {{javaUtilPrefix}}ArrayList<Pair>();
{{javaUtilPrefix}}List<Pair> localVarCollectionQueryParams = new {{javaUtilPrefix}}ArrayList<Pair>();
{{javaUtilPrefix}}Map<String, String> localVarHeaderParams = new {{javaUtilPrefix}}HashMap<String, String>();
@@ -84,7 +86,15 @@ public class {{classname}} {
{{#queryParams}}
{{#isDeepObject}}
{{#collectionFormat}}localVarCollectionQueryParams.addAll(apiClient.parameterToPairs("{{{collectionFormat}}}", {{/collectionFormat}}{{^collectionFormat}}localVarQueryParams.addAll(apiClient.parameterToPair({{/collectionFormat}}"{{baseName}}", {{paramName}}));
localVarQueryParameterBaseName = "{{{baseName}}}";
{{#isArray}}
for (int i=0; i < {{paramName}}.size(); i++) {
localVarQueryStringJoiner.add({{paramName}}.get(i).toUrlQueryString(String.format("{{baseName}}[%d]", i)));
}
{{/isArray}}
{{^isArray}}
localVarQueryStringJoiner.add({{paramName}}.toUrlQueryString("{{baseName}}"));
{{/isArray}}
{{/isDeepObject}}
{{^isDeepObject}}
{{#isExplode}}
@@ -99,7 +109,12 @@ public class {{classname}} {
{{/vars}}
{{/hasVars}}
{{^hasVars}}
{{#isModel}}
localVarQueryStringJoiner.add({{paramName}}.toUrlQueryString());
{{/isModel}}
{{^isModel}}
{{#collectionFormat}}localVarCollectionQueryParams.addAll(apiClient.parameterToPairs("{{{collectionFormat}}}", {{/collectionFormat}}{{^collectionFormat}}localVarQueryParams.addAll(apiClient.parameterToPair({{/collectionFormat}}"{{baseName}}", {{paramName}}));
{{/isModel}}
{{/hasVars}}
{{/isExplode}}
{{^isExplode}}
@@ -142,6 +157,7 @@ public class {{classname}} {
"{{httpMethod}}",
localVarQueryParams,
localVarCollectionQueryParams,
localVarQueryStringJoiner.toString(),
localVarPostBody,
localVarHeaderParams,
localVarCookieParams,
@@ -343,7 +343,12 @@
{{#openApiNullable}}
<jackson-databind-nullable-version>0.2.4</jackson-databind-nullable-version>
{{/openApiNullable}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
{{/useJakartaEe}}
{{#useBeanValidation}}
<beanvalidation-version>3.0.2</beanvalidation-version>
{{/useBeanValidation}}
@@ -386,7 +386,12 @@
<jackson-databind-nullable-version>0.2.4</jackson-databind-nullable-version>
{{/openApiNullable}}
<jackson-databind-version>2.13.4.2</jackson-databind-version>
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
{{/useJakartaEe}}
<junit-version>5.7.0</junit-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<scribejava-version>8.0.0</scribejava-version>
@@ -14,7 +14,7 @@ import com.google.api.client.http.HttpMethods;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.Json;
import javax.ws.rs.core.UriBuilder;
import {{javaxPackage}}.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
@@ -307,7 +307,12 @@
{{#joda}}
<jodatime-version>2.9.9</jodatime-version>
{{/joda}}
{{#useJakartaEe}}
<jakarta-annotation-version>2.1.1</jakarta-annotation-version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<jakarta-annotation-version>1.3.5</jakarta-annotation-version>
{{/useJakartaEe}}
<maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.13.2</junit-version>
</properties>
@@ -6,7 +6,7 @@ import {{invokerPackage}}.ApiException;
import java.util.Objects;
import java.lang.reflect.Type;
import java.util.Map;
import javax.ws.rs.core.GenericType;
import {{javaxPackage}}.ws.rs.core.GenericType;
import com.fasterxml.jackson.annotation.JsonValue;
@@ -1,15 +1,15 @@
package {{invokerPackage}};
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import {{javaxPackage}}.ws.rs.client.Client;
import {{javaxPackage}}.ws.rs.client.ClientBuilder;
import {{javaxPackage}}.ws.rs.client.Entity;
import {{javaxPackage}}.ws.rs.client.Invocation;
import {{javaxPackage}}.ws.rs.client.WebTarget;
import {{javaxPackage}}.ws.rs.core.Form;
import {{javaxPackage}}.ws.rs.core.GenericType;
import {{javaxPackage}}.ws.rs.core.MediaType;
import {{javaxPackage}}.ws.rs.core.Response;
import {{javaxPackage}}.ws.rs.core.Response.Status;
{{#hasOAuthMethods}}
import com.github.scribejava.core.model.OAuth2AccessToken;
@@ -251,7 +251,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* <p>Getter for the field <code>httpClient</code>.</p>
*
* @return a {@link javax.ws.rs.client.Client} object.
* @return a {@link {{javaxPackage}}.ws.rs.client.Client} object.
*/
public Client getHttpClient() {
return httpClient;
@@ -260,7 +260,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* <p>Setter for the field <code>httpClient</code>.</p>
*
* @param httpClient a {@link javax.ws.rs.client.Client} object.
* @param httpClient a {@link {{javaxPackage}}.ws.rs.client.Client} object.
* @return a {@link org.openapitools.client.ApiClient} object.
*/
public ApiClient setHttpClient(Client httpClient) {
@@ -1098,7 +1098,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* <p>Prepare the file for download from the response.</p>
*
* @param response a {@link javax.ws.rs.core.Response} object.
* @param response a {@link {{javaxPackage}}.ws.rs.core.Response} object.
* @return a {@link java.io.File} object.
* @throws java.io.IOException if any.
*/
@@ -1387,7 +1387,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* To completely disable certificate validation (at your own risk), you can
* override this method and invoke disableCertificateValidation(clientBuilder).
*
* @param clientBuilder a {@link javax.ws.rs.client.ClientBuilder} object.
* @param clientBuilder a {@link {{javaxPackage}}.ws.rs.client.ClientBuilder} object.
*/
protected void customizeClientBuilder(ClientBuilder clientBuilder) {
// No-op extension point
@@ -1399,7 +1399,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* Please note that trusting all certificates is extremely risky.
* This may be useful in a development environment with self-signed certificates.
*
* @param clientBuilder a {@link javax.ws.rs.client.ClientBuilder} object.
* @param clientBuilder a {@link {{javaxPackage}}.ws.rs.client.ClientBuilder} object.
* @throws java.security.KeyManagementException if any.
* @throws java.security.NoSuchAlgorithmException if any.
*/
@@ -1426,7 +1426,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
/**
* <p>Build the response headers.</p>
*
* @param response a {@link javax.ws.rs.core.Response} object.
* @param response a {@link {{javaxPackage}}.ws.rs.core.Response} object.
* @return a {@link java.util.Map} of response headers.
*/
protected Map<String, List<String>> buildResponseHeaders(Response response) {
@@ -19,8 +19,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.ext.ContextResolver;
import {{javaxPackage}}.ws.rs.core.GenericType;
import {{javaxPackage}}.ws.rs.ext.ContextResolver;
{{>generatedAnnotation}}
public class JSON implements ContextResolver<ObjectMapper> {
@@ -1,5 +1,5 @@
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import {{javaxPackage}}.ws.rs.core.GenericType;
import {{javaxPackage}}.ws.rs.core.Response;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -6,7 +6,7 @@ import {{invokerPackage}}.ApiResponse;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;
import javax.ws.rs.core.GenericType;
import {{javaxPackage}}.ws.rs.core.GenericType;
{{#imports}}import {{import}};
{{/imports}}
@@ -10,7 +10,7 @@ import com.github.scribejava.core.exceptions.OAuthException;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.oauth.OAuth20Service;
import javax.ws.rs.core.UriBuilder;
import {{javaxPackage}}.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
@@ -36,15 +36,15 @@ import com.fasterxml.jackson.annotation.JsonCreator;
{{/vendorExtensions.x-has-readonly-properties}}
{{/jackson}}
{{#withXml}}
import javax.xml.bind.annotation.*;
import {{javaxPackage}}.xml.bind.annotation.*;
{{/withXml}}
{{#parcelableModel}}
import android.os.Parcelable;
import android.os.Parcel;
{{/parcelableModel}}
{{#useBeanValidation}}
import javax.validation.constraints.*;
import javax.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
{{#performBeanValidation}}
import org.hibernate.validator.constraints.*;
@@ -1,5 +1,5 @@
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import {{javaxPackage}}.ws.rs.core.GenericType;
import {{javaxPackage}}.ws.rs.core.Response;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

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