Compare commits

..

5 Commits

Author SHA1 Message Date
William Cheng
e26400a300 Merge branch 'kotlin_kotlinxserialization_polymorphism' of https://github.com/Nuglif/openapi-generator into Nuglif-kotlin_kotlinxserialization_polymorphism 2023-08-30 20:24:55 +08:00
Loïc Siret
47b38469a3 Merge branch 'OpenAPITools:master' into kotlin_kotlinxserialization_polymorphism 2023-01-20 14:11:43 -05:00
lsiret
82367bbeec Update the sample to reflect changes 2022-12-20 15:04:49 -05:00
lsiret
7decab556b Create a custom Serializer
The Serializer check the mapping value in the discriminator field
of the json we received to find the children Serializer
2022-12-20 14:09:30 -05:00
lsiret
755eb43a49 Convert interface to a sealed class 2022-12-20 14:06:22 -05:00
2152 changed files with 3658 additions and 221306 deletions

View File

@@ -8,7 +8,7 @@
- [ ] Run the following to [build the project](https://github.com/OpenAPITools/openapi-generator#14---build-projects) and update samples:
```
./mvnw clean package
./bin/generate-samples.sh ./bin/configs/*.yaml
./bin/generate-samples.sh
./bin/utils/export_docs_generators.sh
```
Commit all changed files.
@@ -16,5 +16,10 @@
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example `./bin/generate-samples.sh bin/configs/java*`.
For Windows users, please run the script in [Git BASH](https://gitforwindows.org/).
- [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (upcoming 7.1.0 minor release - breaking changes with fallbacks), `8.0.x` (breaking changes without fallbacks)
- [ ] In case you are adding a new generator, run the following additional script :
```
./bin/utils/ensure-up-to-date
```
Commit all changed files.
- [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (7.0.1 - patch release), `7.1.x` (minor release - breaking changes with fallbacks), `8.0.x` (breaking changes without fallbacks)
- [ ] If your PR is targeting a particular programming language, @mention the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) members, so they are more likely to review the pull request.

View File

@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Test run-in-docker.sh
shell: bash

View File

@@ -13,7 +13,7 @@ jobs:
name: Gradle plugin tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:

View File

@@ -30,7 +30,7 @@ jobs:
- samples/client/petstore/java/okhttp-gson-group-parameter
- samples/client/petstore/java/webclient-swagger2
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -20,7 +20,7 @@ jobs:
os: [ubuntu-latest]
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
@@ -85,7 +85,7 @@ jobs:
os: [ubuntu-latest]
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Setup Maven
uses: s4u/setup-maven-action@v1.9.0
with:

View File

@@ -13,7 +13,7 @@ jobs:
name: Maven plugin tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:

View File

@@ -15,7 +15,7 @@ jobs:
name: Misc tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: '2.6'

View File

@@ -15,7 +15,7 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
@@ -53,7 +53,7 @@ jobs:
needs:
- build
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
@@ -90,7 +90,7 @@ jobs:
needs:
- build
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
@@ -129,7 +129,7 @@ jobs:
- build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:

View File

@@ -13,7 +13,7 @@ jobs:
name: Build c libcurl client
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Prepare
run: |
sudo apt-get update

View File

@@ -28,7 +28,7 @@ jobs:
tools: 'tools_openssl_x64'
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: jurplel/install-qt-action@v3
with:
version: ${{ matrix.qt-version }}

View File

@@ -17,7 +17,7 @@ jobs:
name: Tests Dart
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -18,7 +18,7 @@ jobs:
# clients
- samples/client/petstore/csharp/OpenAPIClient-generichost-netstandard2.0
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: 3.1.*

View File

@@ -42,7 +42,7 @@ jobs:
- samples/server/petstore/aspnetcore-6.0-NewtonsoftFalse
- samples/server/petstore/aspnetcore-6.0-nullableReferenceTypes
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: '7.0.x'

View File

@@ -18,7 +18,7 @@ jobs:
# clients
- samples/client/echo_api/csharp-restsharp/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: '6.0.x'

View File

@@ -72,7 +72,7 @@ jobs:
# build C# API client (property, parameter name mappings)
- samples/client/petstore/csharp-restsharp-name-parameter-mappings
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: '6.0.x'

View File

@@ -29,7 +29,7 @@ jobs:
- samples/server/petstore/aspnetcore-6.0-NewtonsoftFalse
- samples/server/petstore/aspnetcore-6.0-nullableReferenceTypes
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: '6.0.x'

View File

@@ -21,7 +21,7 @@ jobs:
- samples/client/petstore/elm
- samples/openapi3/client/elm
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: jorelali/setup-elm@v5
with:
elm-version: 0.19.1

View File

@@ -26,7 +26,7 @@ jobs:
- samples/client/petstore/erlang-client/
- samples/client/petstore/erlang-proper/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: '22.2'

View File

@@ -24,7 +24,7 @@ jobs:
- samples/server/petstore/go-api-server/
- samples/server/petstore/go-chi-server/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: "stable"

View File

@@ -21,7 +21,7 @@ jobs:
sample:
- samples/client/petstore/groovy
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -24,7 +24,7 @@ jobs:
- samples/server/petstore/haskell-servant/
- samples/client/petstore/haskell-http-client/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: haskell/actions/setup@v2
with:
# ghc-version: '8.8.4' # Exact version of ghc to use

View File

@@ -20,7 +20,7 @@ jobs:
- samples/client/echo_api/java/native
- samples/client/echo_api/java/feign-gson
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -24,7 +24,7 @@ jobs:
- samples/client/echo_api/java/feign-gson
- samples/client/echo_api/java/okhttp-gson
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -43,6 +43,7 @@ jobs:
- samples/client/petstore/java/webclient-swagger2
- samples/client/petstore/java/vertx
- samples/client/petstore/java/jersey2-java8-localdatetime
- samples/client/petstore/java/resteasy
- samples/client/petstore/java/google-api-client
- samples/client/petstore/java/rest-assured
- samples/client/petstore/java/rest-assured-jackson
@@ -62,7 +63,7 @@ jobs:
- samples/client/petstore/java/resttemplate-swagger2/
- samples/openapi3/client/petstore/java/jersey2-java8-swagger2/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
@@ -77,4 +78,4 @@ jobs:
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package
run: mvn clean package

View File

@@ -21,7 +21,7 @@ jobs:
- samples/client/petstore/java/resttemplate-jakarta
- samples/client/petstore/java/webclient-jakarta
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -23,7 +23,7 @@ jobs:
- samples/server/petstore/java-helidon-server/se
version: [17]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -29,7 +29,7 @@ jobs:
- samples/server/petstore/java-play-framework-no-swagger-ui
- samples/server/petstore/java-play-framework-no-wrap-calls
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -8,7 +8,6 @@ on:
- 'samples/server/petstore/java-vertx-web/**'
- 'samples/server/petstore/java-inflector/**'
- 'samples/server/petstore/java-pkmst/**'
# test in circleci instead
- 'samples/server/petstore/java-undertow/**'
pull_request:
paths:
@@ -16,7 +15,7 @@ on:
- 'samples/server/petstore/java-vertx-web/**'
- 'samples/server/petstore/java-inflector/**'
- 'samples/server/petstore/java-pkmst/**'
#- 'samples/server/petstore/java-undertow/**'
- 'samples/server/petstore/java-undertow/**'
jobs:
build:
name: Build Java Server
@@ -30,9 +29,9 @@ jobs:
- samples/server/petstore/java-vertx-web/
- samples/server/petstore/java-inflector/
- samples/server/petstore/java-pkmst/
#- samples/server/petstore/java-undertow/
- samples/server/petstore/java-undertow/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -40,7 +40,7 @@ jobs:
- samples/server/petstore/jaxrs-cxf-non-spring-app
- samples/server/petstore/jaxrs-spec-microprofile-openapi-annotations
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -45,7 +45,7 @@ jobs:
- samples/client/petstore/spring-http-interface-reactive
- samples/client/petstore/spring-http-interface
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -15,7 +15,7 @@ jobs:
name: Tests Julia
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
version: 1.8

View File

@@ -65,7 +65,7 @@ jobs:
- samples/client/petstore/kotlin-name-parameter-mappings
- samples/client/others/kotlin-jvm-okhttp-parameter-tests
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -28,7 +28,7 @@ jobs:
# comment out due to gradle build failure
# - samples/server/petstore/kotlin-spring-default/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -43,7 +43,7 @@ jobs:
# no build.gradle file
#- samples/server/petstore/kotlin-vertx-modelMutable
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -18,7 +18,7 @@ jobs:
# servers
- samples/server/petstore/php-laravel/lib/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:

View File

@@ -18,7 +18,7 @@ jobs:
# servers
- samples/server/petstore/php-symfony/SymfonyBundle-php/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:

View File

@@ -18,7 +18,7 @@ jobs:
# clients
- samples/client/echo_api/python
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.7'

View File

@@ -18,7 +18,7 @@ jobs:
# servers
- samples/server/petstore/python-aiohttp/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.7'

View File

@@ -25,7 +25,7 @@ jobs:
- samples/client/petstore/rust/
- samples/server/petstore/rust-server/
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable

View File

@@ -31,7 +31,7 @@ jobs:
- samples/server/petstore/scalatra
- samples/server/petstore/scala-finch # cannot be tested with jdk11
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -18,7 +18,7 @@ jobs:
# clients
- samples/openapi3/client/petstore/spring-cloud-3-with-optional
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -3,16 +3,10 @@ name: Samples Java Spring
on:
push:
paths:
# clients
- 'samples/client/petstore/spring*/**'
# servers
- 'samples/server/petstore/spring*/**'
- 'samples/openapi3/server/petstore/spring*/**'
pull_request:
paths:
# clients
- 'samples/client/petstore/spring*/**'
# servers
- 'samples/server/petstore/spring*/**'
- 'samples/openapi3/server/petstore/spring*/**'
jobs:
@@ -33,7 +27,6 @@ jobs:
- samples/openapi3/client/petstore/spring-cloud-async
- samples/openapi3/client/petstore/spring-cloud-spring-pageable
- samples/client/petstore/spring-cloud-tags
- samples/client/petstore/spring-cloud-deprecated
# servers
- samples/server/petstore/springboot
- samples/openapi3/server/petstore/springboot
@@ -56,7 +49,7 @@ jobs:
- samples/server/petstore/springboot-spring-pageable-without-j8
- samples/server/petstore/springboot-spring-pageable
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'

View File

@@ -40,7 +40,7 @@ jobs:
name: Build Swift samples
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: swift-actions/setup-swift@v1
if: ${{ matrix.os == 'ubuntu-latest' }}
with:

View File

@@ -18,7 +18,7 @@ jobs:
sample:
- samples/client/petstore/zapier
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
- name: Install dependencies

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'OpenAPITools' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:

View File

@@ -18,7 +18,7 @@ jobs:
matrix:
java: [11, 17]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
with:

3
.gitignore vendored
View File

@@ -89,7 +89,6 @@ samples/client/petstore/cpp-restsdk/cmake_install.cmake
**/.gradle
samples/client/petstore/java/hello.txt
samples/client/petstore/java/okhttp-gson/hello.txt
samples/client/petstore/java/okhttp-gson-3.1/hello.txt
samples/client/petstore/java/jersey1/hello.txt
samples/client/petstore/java/jersey2-java8/hello.txt
samples/client/petstore/java/jersey2/hello.txt
@@ -184,7 +183,6 @@ samples/client/petstore/python-asyncio/.pytest_cache/
# PHP
samples/client/petstore/php/OpenAPIClient-php/composer.lock
samples/client/petstore/php-nextgen/OpenAPIClient-php/composer.lock
samples/client/petstore/php-dt/composer.lock
samples/client/petstore/php-dt-modern/composer.lock
samples/openapi3/server/petstore/php-symfony/SymfonyBundle-php/composer.lock
@@ -212,7 +210,6 @@ samples/server/petstore/kotlin-server/ktor/build
samples/server/petstore/kotlin-springboot/build
samples/client/petstore/kotlin*/src/main/kotlin/test/
samples/client/petstore/kotlin*/build/
samples/server/others/kotlin-server/jaxrs-spec/build/
# haskell
.stack-work

View File

@@ -1 +1 @@
11
1.8

View File

@@ -121,8 +121,6 @@ before_install:
- cat /etc/hosts
# show java version
- java -version
- export TRAVIS_BRANCH=master
- export TRAVIS_TAG=v7.0.1
- if [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
openssl aes-256-cbc -K $encrypted_6e2c8bba47c6_key -iv $encrypted_6e2c8bba47c6_iv -in sec.gpg.enc -out sec.gpg -d ;
gpg --keyserver keyserver.ubuntu.com --recv-key $SIGNING_KEY ;
@@ -142,6 +140,25 @@ script:
after_success:
# push to maven repo
- if [ $SONATYPE_USERNAME ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
if [ "$TRAVIS_BRANCH" = "master" ] && [ -z $TRAVIS_TAG ]; then
echo "Publishing from branch $TRAVIS_BRANCH";
./mvnw clean deploy --quiet -DskipTests=true -B -U -P release --settings CI/settings.xml -Dorg.slf4j.simpleLogger.defaultLogLevel=error;
echo "Finished mvn clean deploy for $TRAVIS_BRANCH";
pushd .;
cd modules/openapi-generator-gradle-plugin;
./gradlew -Psigning.keyId="$SIGNING_KEY" -Psigning.password="$SIGNING_PASSPHRASE" -Psigning.secretKeyRingFile="${TRAVIS_BUILD_DIR}/sec.gpg" -PossrhUsername="${SONATYPE_USERNAME}" -PossrhPassword="${SONATYPE_PASSWORD}" publishPluginMavenPublicationToSonatypeRepository closeAndReleaseSonatypeStagingRepository;
echo "Finished ./gradlew publishPluginMavenPublicationToSonatypeRepository closeAndReleaseSonatypeStagingRepository";
popd;
elif [ -z $TRAVIS_TAG ] && [[ "$TRAVIS_BRANCH" =~ ^[0-9]+\.[0-9]+\.x$ ]]; then
echo "Publishing from branch $TRAVIS_BRANCH";
./mvnw clean deploy --quiet --settings CI/settings.xml -Dorg.slf4j.simpleLogger.defaultLogLevel=error;
echo "Finished mvn clean deploy for $TRAVIS_BRANCH";
pushd .;
cd modules/openapi-generator-gradle-plugin;
./gradlew -PossrhUsername="${SONATYPE_USERNAME}" -PossrhPassword="${SONATYPE_PASSWORD}" publishPluginMavenPublicationToSonatypeRepository closeAndReleaseSonatypeStagingRepository;
echo "Finished ./gradlew publishPluginMavenPublicationToSonatypeRepository closeAndReleaseSonatypeStagingRepository";
popd;
fi;
if [ -n $TRAVIS_TAG ] && [[ "$TRAVIS_TAG" =~ ^[v][0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Publishing the gradle plugin to Gradle Portal on tag $TRAVIS_TAG (only)";
pushd .;

View File

@@ -15,7 +15,7 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.1.0`):
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.0.1`):
[![Build Status](https://api.travis-ci.com/OpenAPITools/openapi-generator.svg?branch=master&status=passed)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
@@ -77,7 +77,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, Azure Functions), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant, Yesod), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/), [Apache Camel](https://camel.apache.org/), [Helidon](https://helidon.io/)), **Julia**, **Kotlin** (Spring Boot, [Ktor](https://github.com/ktorio/ktor), [Vert.x](https://vertx.io/)), **PHP** (Laravel, Lumen, [Mezzio (fka Zend Expressive)](https://github.com/mezzio/mezzio), Slim, Silex, [Symfony](https://symfony.com/)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** ([rust-server](https://openapi-generator.tech/docs/generators/rust-server/)), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) |
| **API documentation generators** | **HTML**, **Confluence Wiki**, **Asciidoc**, **Markdown**, **PlantUML** |
| **Configuration files** | [**Apache2**](https://httpd.apache.org/) |
| **Others** | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Postman Collection**, **Protocol Buffer**, **WSDL** |
| **Others** | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Protocol Buffer**, **WSDL** |
## Table of contents
@@ -115,13 +115,13 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.1.0 (upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.1.0-SNAPSHOT/) | 18.10.2023 | Minor release with breaking changes (with fallback) |
| [7.0.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.0.1) (latest stable release) | 18.09.2023 | Patch release (enhancements, bug fixes, etc) |
| 7.0.1 (upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.1-SNAPSHOT/) | 08.09.2023 | Patch release (enhancements, bug fixes, etc) |
| [7.0.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.0.0) (latest stable release) | 25.08.2023 | Major release with breaking changes (no fallback) |
| [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.2023 | Minor release with breaking changes (with fallback) |
| [5.4.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.4.0) | 31.01.2022 | Minor release with breaking changes (with fallback) |
| [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0, 3.1 (beta support)
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
(We do not publish daily/nightly build. Please use SNAPSHOT instead)
@@ -179,16 +179,16 @@ See the different versions of the [openapi-generator-cli](https://search.maven.o
<!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.1/openapi-generator-cli-7.0.1.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.0/openapi-generator-cli-7.0.0.jar`
For **Mac/Linux** users:
```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.1/openapi-generator-cli-7.0.1.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.0/openapi-generator-cli-7.0.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.1/openapi-generator-cli-7.0.1.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.0/openapi-generator-cli-7.0.0.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -423,7 +423,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli"
```sh
openapi-generator-cli version-manager set 7.0.1
openapi-generator-cli version-manager set 7.0.0
```
Or install it as dev-dependency:
@@ -447,7 +447,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
<!-- RELEASE_VERSION -->
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.1/openapi-generator-cli-7.0.1.jar)
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.0.0/openapi-generator-cli-7.0.0.jar)
<!-- /RELEASE_VERSION -->
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
@@ -928,9 +928,12 @@ OpenAPI Generator core team members are contributors who have been making signif
* [@cbornet](https://github.com/cbornet) (2016/05)
* [@jmini](https://github.com/jmini) (2018/04) [:heart:](https://www.patreon.com/jmini)
* [@etherealjoy](https://github.com/etherealjoy) (2019/06)
* [@spacether](https://github.com/spacether) (2020/05) [:heart:][spacether sponsorship]
:heart: = Link to support the contributor directly
[spacether sponsorship]: https://github.com/sponsors/spacether/
#### Template Creator
**NOTE**: Embedded templates are only supported in _Mustache_ format. Support for all other formats is experimental and subject to change at any time.
@@ -1001,7 +1004,6 @@ Here is a list of template creators:
* PowerShell (refactored in 5.0.0): @wing328
* Python: @spacether [:heart:][spacether sponsorship]
* Python-Experimental: @spacether [:heart:][spacether sponsorship]
* Python (refactored in 7.0.0): @wing328
* R: @ramnov
* Ruby (Faraday): @meganemura @dkliban
* Rust: @farcaller
@@ -1166,7 +1168,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Perl | @wing328 (2017/07) [:heart:](https://www.patreon.com/wing328) @yue9944882 (2019/06) |
| PHP | @jebentier (2017/07), @dkarlovi (2017/07), @mandrean (2017/08), @jfastnacht (2017/09), [@ybelenko](https://github.com/ybelenko) (2018/07), @renepardon (2018/12) |
| PowerShell | @wing328 (2020/05) |
| Python | @krjakbrjak (2023/02) |
| Python | @spacether (2019/11) [:heart:][spacether sponsorship] @krjakbrjak (2023/02) |
| R | @Ramanth (2019/07) @saigiridhar21 (2019/07) |
| Ruby | @cliffano (2017/07) @zlx (2017/09) @autopp (2019/02) |
| Rust | @frol (2017/07) @farcaller (2017/08) @richardwhiuk (2019/07) @paladinzh (2020/05) @jacob-pro (2022/10) |
@@ -1260,4 +1262,3 @@ limitations under the License.
---

View File

@@ -1,12 +0,0 @@
# for csharp generichost
generatorName: csharp
outputDir: samples/client/petstore/csharp/OpenAPIClient-generichost-net6.0-nrt-useSourceGeneration
inputSpec: modules/openapi-generator/src/test/resources/3_0/csharp/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
library: generichost
templateDir: modules/openapi-generator/src/main/resources/csharp
additionalProperties:
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
useCompareNetObjects: true
disallowAdditionalPropertiesIfNotPresent: false
useSourceGeneration: true
packageName: UseSourceGeneration

View File

@@ -1,6 +0,0 @@
generatorName: go
outputDir: samples/client/echo_api/go
inputSpec: modules/openapi-generator/src/test/resources/3_0/echo_api.yaml
templateDir: modules/openapi-generator/src/main/resources/go
additionalProperties:
hideGenerationTimestamp: "true"

View File

@@ -1,16 +0,0 @@
generatorName: java
outputDir: samples/client/petstore/java/okhttp-gson-3.1
library: okhttp-gson
inputSpec: modules/openapi-generator/src/test/resources/3_1/java/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
nameMappings:
_type: underscoreType
type_: typeWithUnderscore
parameterNameMappings:
_type: underscoreType
type_: typeWithUnderscore
additionalProperties:
artifactId: petstore-okhttp-gson-31
hideGenerationTimestamp: "true"
useOneOfDiscriminatorLookup: "true"
disallowAdditionalPropertiesIfNotPresent: false

View File

@@ -1,6 +1,6 @@
generatorName: java-undertow-server
outputDir: samples/server/petstore/java-undertow
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/java-undertow-server
additionalProperties:
hideGenerationTimestamp: "true"

View File

@@ -4,5 +4,3 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/lua
additionalProperties:
packageName: petstore
nameMappings:
phone: mobile

View File

@@ -4,7 +4,3 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-e
templateDir: modules/openapi-generator/src/main/resources/perl
additionalProperties:
hideGenerationTimestamp: "true"
nameMappings:
NullableMessage: system_message
modelNameMappings:
DeprecatedObject: DeprecatedModel

View File

@@ -1,6 +0,0 @@
generatorName: php-nextgen
outputDir: samples/client/echo_api/php-nextgen
inputSpec: modules/openapi-generator/src/test/resources/3_0/echo_api.yaml
templateDir: modules/openapi-generator/src/main/resources/php-nextgen
additionalProperties:
hideGenerationTimestamp: "true"

View File

@@ -1,4 +0,0 @@
generatorName: php-nextgen
outputDir: samples/client/petstore/php-nextgen/OpenAPIClient-php
inputSpec: modules/openapi-generator/src/test/resources/3_0/php-nextgen/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/php-nextgen

View File

@@ -14,7 +14,3 @@ additionalProperties:
projectUri: https://github.com/OpenAPITools/openapi-generator
releaseNotes: 'This is a sample project'
tags: 'PetStore,powershell,sdk'
nameMappings:
name_mapping: SomethingElse
modelNameMappings:
model-mapping: NewModel

View File

@@ -1,4 +1,4 @@
generatorName: python-flask
outputDir: samples/server/petstore/python-flask
inputSpec: modules/openapi-generator/src/test/resources/2_0/python-flask/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/python-flask

View File

@@ -1,13 +0,0 @@
generatorName: spring
library: spring-cloud
outputDir: samples/client/petstore/spring-cloud-deprecated
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-deprecated-fields.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties:
groupId: org.openapitools.openapi3
documentationProvider: springdoc
artifactId: spring-cloud-deprecated
interfaceOnly: "true"
singleContentTypes: "true"
hideGenerationTimestamp: "true"
useTags: "true"

View File

@@ -50,7 +50,6 @@ The following generators are available:
* [perl](generators/perl.md)
* [php](generators/php.md)
* [php-dt (beta)](generators/php-dt.md)
* [php-nextgen (beta)](generators/php-nextgen.md)
* [powershell (beta)](generators/powershell.md)
* [python](generators/python.md)
* [r](generators/r.md)

View File

@@ -49,7 +49,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useCollection|Deserialize array types to Collection&lt;T&gt; instead of List&lt;T&gt;.| |false|
|useDateTimeOffset|Use DateTimeOffset to model date-time properties| |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.| |false|
|useSourceGeneration|Use source generation where available (only `generichost` library supports this option).| |false|
|validatable|Generates self-validatable models.| |true|
|zeroBasedEnums|Enumerations with string values will start from 0 when true, 1 when false. If not set, enumerations with string values will start from 0 if the first value is 'unknown', case insensitive.| |null|

View File

@@ -34,7 +34,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|interfaceOnly|Whether to generate only API interface stubs without the server files. This option is currently supported only when using jaxrs-spec library.| |false|
|library|library template (sub-template)|<dl><dt>**ktor**</dt><dd>ktor framework</dd><dt>**jaxrs-spec**</dt><dd>JAX-RS spec only</dd></dl>|ktor|
|modelMutable|Create mutable models| |false|
|omitGradleWrapper|Whether to omit Gradle wrapper for creating a sub project.| |false|
|packageName|Generated artifact package name.| |org.openapitools.server|
|parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null|
|returnResponse|Whether generate API interface should return javax.ws.rs.core.Response instead of a deserialized entity. Only useful if interfaceOnly is true. This option is currently supported only when using jaxrs-spec library.| |false|

View File

@@ -1,269 +0,0 @@
---
title: Documentation for the php-nextgen Generator
---
## METADATA
| Property | Value | Notes |
| -------- | ----- | ----- |
| generator name | php-nextgen | pass this to the generate command after -g |
| generator stability | BETA | |
| generator type | CLIENT | |
| generator language | PHP | |
| generator default templating engine | mustache | |
| helpTxt | Generates a PHP client library (beta). | |
## CONFIG OPTIONS
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|apiPackage|package for generated api classes| |null|
|artifactUrl|artifact URL in generated pom.xml| |null|
|artifactVersion|The version to use in the composer package version field. e.g. 1.2.3| |null|
|composerPackageName|The name to use in the composer package name field. e.g. `vendor/project` (must be lowercase and consist of words separated by `-`, `.` or `_`).| |null|
|developerOrganization|developer organization in generated pom.xml| |null|
|developerOrganizationUrl|developer organization URL in generated pom.xml| |null|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|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|
|hideGenerationTimestamp|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |true|
|invokerPackage|The main namespace to use for all classes. e.g. Yay\Pets| |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|
|licenseName|The name of the license| |null|
|modelPackage|package for generated models| |null|
|packageName|The main package name for classes. e.g. GeneratedPetstore| |null|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|srcBasePath|The directory to serve as source root.| |null|
|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|array|
|map|array|
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>\DateTime</li>
<li>\SplFileObject</li>
<li>array</li>
<li>bool</li>
<li>boolean</li>
<li>byte</li>
<li>float</li>
<li>int</li>
<li>integer</li>
<li>mixed</li>
<li>number</li>
<li>object</li>
<li>string</li>
<li>void</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>__halt_compiler</li>
<li>_header_accept</li>
<li>_tempbody</li>
<li>abstract</li>
<li>and</li>
<li>array</li>
<li>as</li>
<li>break</li>
<li>callable</li>
<li>case</li>
<li>catch</li>
<li>class</li>
<li>clone</li>
<li>const</li>
<li>continue</li>
<li>declare</li>
<li>default</li>
<li>die</li>
<li>do</li>
<li>echo</li>
<li>else</li>
<li>elseif</li>
<li>empty</li>
<li>enddeclare</li>
<li>endfor</li>
<li>endforeach</li>
<li>endif</li>
<li>endswitch</li>
<li>endwhile</li>
<li>eval</li>
<li>exit</li>
<li>extends</li>
<li>final</li>
<li>for</li>
<li>foreach</li>
<li>formparams</li>
<li>function</li>
<li>global</li>
<li>goto</li>
<li>headerparams</li>
<li>httpbody</li>
<li>if</li>
<li>implements</li>
<li>include</li>
<li>include_once</li>
<li>instanceof</li>
<li>insteadof</li>
<li>interface</li>
<li>isset</li>
<li>list</li>
<li>namespace</li>
<li>new</li>
<li>or</li>
<li>print</li>
<li>private</li>
<li>protected</li>
<li>public</li>
<li>queryparams</li>
<li>require</li>
<li>require_once</li>
<li>resourcepath</li>
<li>return</li>
<li>static</li>
<li>switch</li>
<li>throw</li>
<li>trait</li>
<li>try</li>
<li>unset</li>
<li>use</li>
<li>var</li>
<li>while</li>
<li>xor</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Uuid|✗|
|Array|✓|OAS2,OAS3
|Null|✗|OAS3
|AnyType|✗|OAS2,OAS3
|Object|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✓|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✗|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✓|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✗|OAS2,OAS3
|Union|✗|OAS3
|allOf|✗|OAS2,OAS3
|anyOf|✗|OAS3
|oneOf|✗|OAS3
|not|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✗|OAS2,OAS3
|ApiKey|✗|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✗|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|SignatureAuth|✗|OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@@ -14,9 +14,9 @@ title: Global Properties
| verbose | Defines the verbosity | `true` or `false` |
| generateAliasAsModel | Defines whether primitive types defined at the model/schema level will be wrapped in a model | `true` or `false` |
| org.openapitools.codegen.utils.oncelogger.enabled | Enable/disable the "OnceLogger" which reduces noise for select repeated logs | `true` or `false` |
| supportingFiles | Allows the user to define which supporting files will be generated. Prefer using the more robust `.openapi-generator-ignore`. | no value, or a colon-separated string of file names |
| models | Allows the user to define which models will be generated. Prefer using the more robust `.openapi-generator-ignore`. | no value, or a colon-separated string of model names |
| apis | Allows the user to define which apis will be generated. Prefer using the more robust `.openapi-generator-ignore`. | no value, or a colon-separated string of api names |
| supportingFiles | Allows the user to define which supporting files will be generated. Prefer using the more robust `.openapi-generator-ignore`. | no value, or a comma-separated string of file names |
| models | Allows the user to define which models will be generated. Prefer using the more robust `.openapi-generator-ignore`. | no value, or a comma-separated string of model names |
| apis | Allows the user to define which apis will be generated. Prefer using the more robust `.openapi-generator-ignore`. | no value, or a comma-separated string of api names |
| apiDocs | Allows the user to define if api docs will be generated. Prefer using the more robust `.openapi-generator-ignore`. | `true` or `false` |
| modelDocs | Allows the user to define if model docs will be generated. Prefer using the more robust `.openapi-generator-ignore`. | `true` or `false` |
| apiTests | Allows the user to define if api tests will be generated. Prefer using the more robust `.openapi-generator-ignore`. | `true` or `false` |
@@ -40,4 +40,4 @@ and
java {jar} generate {opts} --global-property=models
```
Why the two differing ways to provide the same properties? We previously accepted a `-D` tooling option which resembled Java System Property declaration. In older versions of OpenAPI Generator, the option modified the SystemProperties collection directly and was truly a "system property". This option changed during the 4.x release in an effort to make OpenAPI Generator thread-safe and isolate its configuration via thread locals. We no longer mutate System Properties. In the 4.x release and earlier, specifying the tooling `-D` option with system properties intended for other tools like swagger-parser rather than passing them as true Java System Properties would lead to unexpected behavior for the user; if our tool set the system property _after_ invoking certain code, it would seem to the user like Java System Properties weren't working!
Why the two differing ways to provide the same properties? We previously accepted a `-D` tooling option which resembled Java System Property declaration. In older versions of OpenAPI Generator, the option modified the SystemProperties collection directly and was truly a "system property". This option changed during the 4.x release in an effort to make OpenAPI Generator thread-safe and isolate its configuration via thread locals. We no longer mutate System Properties. In the 4.x release and earlier, specifying the tooling `-D` option with system properties intended for other tools like swagger-parser rather than passing them as true Java System Properties would lead to unexpected behavior for the user; if our tool set the system property _after_ invoking certain code, it would seem to the user like Java System Properties weren't working!

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -6,7 +6,7 @@
<artifactId>openapi-generator-project</artifactId>
<groupId>org.openapitools</groupId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -1,5 +1,5 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.0.1
openApiGeneratorVersion=7.0.1-SNAPSHOT
# /RELEASE_VERSION
# BEGIN placeholders

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>
@@ -93,11 +93,11 @@
<gradleVersion>${gradleVersion}</gradleVersion>
<args>
<arg>-P openApiGeneratorVersion=${project.version}</arg>
<!--
<arg>-Psigning.keyId=${env.SIGNING_KEY}</arg>
<arg>-Psigning.password=${env.SIGNING_PASSPHRASE}</arg>
<arg>-Psigning.secretKeyRingFile=${env.TRAVIS_BUILD_DIR}/sec.gpg</arg>
-->
</args>
</configuration>
<executions>

View File

@@ -1,3 +1,3 @@
# RELEASE_VERSION
openApiGeneratorVersion=7.0.1
openApiGeneratorVersion=7.0.1-SNAPSHOT
# /RELEASE_VERSION

View File

@@ -33,5 +33,12 @@ open class OpenApiGeneratorValidateExtension(project: Project) {
/**
* Whether to offer recommendations related to the validated specification document.
*/
val recommend = project.objects.property<Boolean>().convention(true)
val recommend = project.objects.property<Boolean?>()
init {
applyDefaults()
}
@Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults() = recommend.set(true)
}

View File

@@ -58,7 +58,7 @@ open class ValidateTask : DefaultTask() {
@Optional
@Input
val recommend = project.objects.property<Boolean>().convention(true)
val recommend = project.objects.property<Boolean?>()
@get:Internal
@set:Option(option = "input", description = "The input specification.")

View File

@@ -144,161 +144,4 @@ class ValidateTaskDslTest : TestBase() {
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
fun `validateGoodSpec as defined task should succeed on valid spec`(gradleVersion: String?) {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
|
| task validateGoodSpec(type: org.openapitools.generator.gradle.plugin.tasks.ValidateTask) {
| inputSpec.set(file("spec.yaml").absolutePath)
| }
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
.withProjectDir(temp)
.withArguments("validateGoodSpec")
.withPluginClasspath()
.build()
// Assert
assertTrue(
result.output.contains("Spec is valid."),
"Unexpected/no message presented to the user for a valid spec."
)
assertEquals(
SUCCESS, result.task(":validateGoodSpec")?.outcome,
"Expected a successful run, but found ${result.task(":validateGoodSpec")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
fun `validateBadSpec as defined task should fail on invalid spec`(gradleVersion: String?) {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
)
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
|
| task validateBadSpec(type: org.openapitools.generator.gradle.plugin.tasks.ValidateTask) {
| inputSpec.set(file("spec.yaml").absolutePath)
| }
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
.withProjectDir(temp)
.withArguments("validateBadSpec")
.withPluginClasspath()
.buildAndFail()
// Assert
assertTrue(
result.output.contains("Spec is invalid."),
"Unexpected/no message presented to the user for an invalid spec."
)
assertEquals(
FAILED, result.task(":validateBadSpec")?.outcome,
"Expected a failed run, but found ${result.task(":validateBadSpec")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
fun `openApiValidate should succeed with recommendations on valid spec`(gradleVersion: String?) {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-recommend.yaml")
)
// recommend = true is the default
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file("spec.yaml").absolutePath
| }
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.build()
// Assert
assertTrue(
result.output.contains("Spec is valid."),
"Unexpected/no message presented to the user for a valid spec."
)
assertTrue(
result.output.contains("Spec has issues or recommendations."),
"Unexpected/no recommendations message presented to the user for a valid spec."
)
assertEquals(
SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
fun `openApiValidate should succeed without recommendations on valid spec`(gradleVersion: String?) {
// Arrange
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-recommend.yaml")
)
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
|
| openApiValidate {
| inputSpec = file("spec.yaml").absolutePath
| recommend = false
| }
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
.withProjectDir(temp)
.withArguments("openApiValidate")
.withPluginClasspath()
.build()
// Assert
assertTrue(
result.output.contains("Spec is valid."),
"Unexpected/no message presented to the user for a valid spec."
)
assertTrue(
result.output.contains("Spec has issues or recommendations.").not(),
"Unexpected/recommendations message presented to the user for a valid spec"
)
assertEquals(
SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
}

View File

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

View File

@@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -15,7 +15,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -19,7 +19,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<dependencies>
<dependency>

View File

@@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -13,7 +13,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -20,7 +20,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -5,7 +5,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -520,6 +520,15 @@ public class CodeGenMojo extends AbstractMojo {
"generated-test-sources/openapi" : "generated-sources/openapi");
}
if (cleanupOutput) {
try {
FileUtils.deleteDirectory(output);
LOGGER.info("Previous run output is removed from {}", output);
} catch (IOException e) {
LOGGER.warn("Failed to clean-up output directory {}", output, e);
}
}
addCompileSourceRootIfConfigured();
try {
@@ -557,19 +566,10 @@ public class CodeGenMojo extends AbstractMojo {
}
}
if (cleanupOutput) {
try {
FileUtils.deleteDirectory(output);
LOGGER.info("Previous run output is removed from {}", output);
} catch (IOException e) {
LOGGER.warn("Failed to clean up output directory {}", output, e);
}
}
// attempt to read from config file
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile);
// if a config file wasn't specified, or we were unable to read it
// if a config file wasn't specified or we were unable to read it
if (configurator == null) {
configurator = new CodegenConfigurator();
}
@@ -938,8 +938,8 @@ public class CodeGenMojo extends AbstractMojo {
/**
* Calculate openapi specification file hash. If specification is hosted on remote resource it is downloaded first
*
* @param inputSpecFile - Openapi specification input file to calculate its hash.
* Does not take into account if input spec is hosted on remote resource
* @param inputSpecFile - Openapi specification input file to calculate it's hash.
* Does not taken into account if input spec is hosted on remote resource
* @return openapi specification file hash
* @throws IOException
*/
@@ -991,8 +991,8 @@ public class CodeGenMojo extends AbstractMojo {
/**
* Get specification hash file
* @param inputSpecFile - Openapi specification input file to calculate its hash.
* Does not take into account if input spec is hosted on remote resource
* @param inputSpecFile - Openapi specification input file to calculate it's hash.
* Does not taken into account if input spec is hosted on remote resource
* @return a file with previously calculated hash
*/
private File getHashFile(File inputSpecFile) {

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION -->
<version>7.0.1</version>
<version>7.0.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<relativePath>../..</relativePath>
</parent>

View File

@@ -30,7 +30,7 @@ public class CodegenOperation {
hasVersionHeaders = false, hasVersionQueryParams = false,
isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false, defaultReturnType = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false, hasConstantParams = false,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false,
hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined
public CodegenProperty returnProperty;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
@@ -45,7 +45,6 @@ public class CodegenOperation {
public List<CodegenParameter> queryParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> implicitHeadersParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> constantParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> cookieParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> requiredParams = new ArrayList<CodegenParameter>();
@@ -393,7 +392,6 @@ public class CodegenOperation {
sb.append(", operationIdLowerCase='").append(operationIdLowerCase).append('\'');
sb.append(", operationIdCamelCase='").append(operationIdCamelCase).append('\'');
sb.append(", operationIdSnakeCase='").append(operationIdSnakeCase).append('\'');
sb.append(", constantParams='").append(constantParams).append('\'');
sb.append('}');
return sb.toString();
}
@@ -474,8 +472,7 @@ public class CodegenOperation {
Objects.equals(operationIdOriginal, that.operationIdOriginal) &&
Objects.equals(operationIdLowerCase, that.operationIdLowerCase) &&
Objects.equals(operationIdCamelCase, that.operationIdCamelCase) &&
Objects.equals(operationIdSnakeCase, that.operationIdSnakeCase) &&
Objects.equals(constantParams, that.constantParams);
Objects.equals(operationIdSnakeCase, that.operationIdSnakeCase);
}
@Override
@@ -491,6 +488,6 @@ public class CodegenOperation {
pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, returnProperty, optionalParams,
authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs,
vendorExtensions, nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase,
operationIdSnakeCase, hasErrorResponseObject, requiredAndNotNullableParams, notNullableParams, constantParams);
operationIdSnakeCase, hasErrorResponseObject, requiredAndNotNullableParams, notNullableParams);
}
}

View File

@@ -17,7 +17,6 @@
package org.openapitools.codegen;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Ticker;
@@ -447,14 +446,10 @@ public class DefaultCodegen implements CodegenConfig {
.put("titlecase", new TitlecaseLambda())
.put("camelcase", new CamelCaseLambda(true).generator(this))
.put("pascalcase", new CamelCaseLambda(false).generator(this))
.put("forwardslash", new ForwardSlashLambda())
.put("backslash", new BackSlashLambda())
.put("doublequote", new DoubleQuoteLambda())
.put("indented", new IndentedLambda())
.put("indented_8", new IndentedLambda(8, " ", false))
.put("indented_12", new IndentedLambda(12, " ", false))
.put("indented_16", new IndentedLambda(16, " ", false));
}
private void registerMustacheLambdas() {
@@ -478,11 +473,6 @@ public class DefaultCodegen implements CodegenConfig {
for (Map.Entry<String, ModelsMap> entry : objs.entrySet()) {
CodegenModel model = ModelUtils.getModelByName(entry.getKey(), objs);
if (model == null) {
LOGGER.warn("Null model found in postProcessAllModels: {}", entry.getKey());
continue;
}
// add the model to the discriminator's mapping so templates have access to more than just the string to string mapping
if (model.discriminator != null && model.discriminator.getMappedModels() != null) {
for (CodegenDiscriminator.MappedModel mappedModel : model.discriminator.getMappedModels()) {
@@ -801,7 +791,6 @@ public class DefaultCodegen implements CodegenConfig {
Map<String, Object> allowableValues = cm.allowableValues;
List<Object> values = (List<Object>) allowableValues.get("values");
List<Map<String, Object>> enumVars = buildEnumVars(values, cm.dataType);
postProcessEnumVars(enumVars);
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
updateEnumVarsWithExtensions(enumVars, cm.getVendorExtensions(), cm.dataType);
cm.allowableValues.put("enumVars", enumVars);
@@ -1042,23 +1031,23 @@ public class DefaultCodegen implements CodegenConfig {
if (ModelUtils.isComposedSchema(s)) {
if (e.getKey().contains("/")) {
// if this is property schema, we also need to generate the oneOf interface model
addOneOfNameExtension(s, nOneOf);
addOneOfInterfaceModel(s, nOneOf);
addOneOfNameExtension((ComposedSchema) s, nOneOf);
addOneOfInterfaceModel((ComposedSchema) s, nOneOf);
} else {
// else this is a component schema, so we will just use that as the oneOf interface model
addOneOfNameExtension(s, n);
addOneOfNameExtension((ComposedSchema) s, n);
}
} else if (ModelUtils.isArraySchema(s)) {
Schema items = ((ArraySchema) s).getItems();
if (ModelUtils.isComposedSchema(items)) {
addOneOfNameExtension(items, nOneOf);
addOneOfInterfaceModel(items, nOneOf);
addOneOfNameExtension((ComposedSchema) items, nOneOf);
addOneOfInterfaceModel((ComposedSchema) items, nOneOf);
}
} else if (ModelUtils.isMapSchema(s)) {
Schema addProps = ModelUtils.getAdditionalProperties(s);
if (addProps != null && ModelUtils.isComposedSchema(addProps)) {
addOneOfNameExtension(addProps, nOneOf);
addOneOfInterfaceModel(addProps, nOneOf);
addOneOfNameExtension((ComposedSchema) addProps, nOneOf);
addOneOfInterfaceModel((ComposedSchema) addProps, nOneOf);
}
}
}
@@ -2280,9 +2269,10 @@ public class DefaultCodegen implements CodegenConfig {
**/
@SuppressWarnings("static-method")
public String getSchemaType(Schema schema) {
if (ModelUtils.isComposedSchema(schema)) { // composed schema
if (schema instanceof ComposedSchema) { // composed schema
ComposedSchema cs = (ComposedSchema) schema;
// Get the interfaces, i.e. the set of elements under 'allOf', 'anyOf' or 'oneOf'.
List<Schema> schemas = ModelUtils.getInterfaces(schema);
List<Schema> schemas = ModelUtils.getInterfaces(cs);
List<String> names = new ArrayList<>();
// Build a list of the schema types under each interface.
@@ -2292,12 +2282,12 @@ public class DefaultCodegen implements CodegenConfig {
names.add(getSingleSchemaType(s));
}
if (schema.getAllOf() != null) {
return toAllOfName(names, schema);
} else if (schema.getAnyOf() != null) { // anyOf
return toAnyOfName(names, schema);
} else if (schema.getOneOf() != null) { // oneOf
return toOneOfName(names, schema);
if (cs.getAllOf() != null) {
return toAllOfName(names, cs);
} else if (cs.getAnyOf() != null) { // anyOf
return toAnyOfName(names, cs);
} else if (cs.getOneOf() != null) { // oneOf
return toOneOfName(names, cs);
}
}
@@ -2333,7 +2323,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return name of the allOf schema
*/
@SuppressWarnings("static-method")
public String toAllOfName(List<String> names, Schema composedSchema) {
public String toAllOfName(List<String> names, ComposedSchema composedSchema) {
Map<String, Object> exts = composedSchema.getExtensions();
if (exts != null && exts.containsKey("x-all-of-name")) {
return (String) exts.get("x-all-of-name");
@@ -2357,7 +2347,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return name of the anyOf schema
*/
@SuppressWarnings("static-method")
public String toAnyOfName(List<String> names, Schema composedSchema) {
public String toAnyOfName(List<String> names, ComposedSchema composedSchema) {
return "anyOf<" + String.join(",", names) + ">";
}
@@ -2375,7 +2365,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return name of the oneOf schema
*/
@SuppressWarnings("static-method")
public String toOneOfName(List<String> names, Schema composedSchema) {
public String toOneOfName(List<String> names, ComposedSchema composedSchema) {
Map<String, Object> exts = composedSchema.getExtensions();
if (exts != null && exts.containsKey("x-one-of-name")) {
return (String) exts.get("x-one-of-name");
@@ -2680,7 +2670,7 @@ public class DefaultCodegen implements CodegenConfig {
Map<NamedSchema, CodegenProperty> schemaCodegenPropertyCache = new HashMap<>();
protected void updateModelForComposedSchema(CodegenModel m, Schema schema, Map<String, Schema> allDefinitions) {
final Schema composed = schema;
final ComposedSchema composed = (ComposedSchema) schema;
Map<String, Schema> properties = new LinkedHashMap<>();
List<String> required = new ArrayList<>();
Map<String, Schema> allProperties = new LinkedHashMap<>();
@@ -2706,17 +2696,17 @@ public class DefaultCodegen implements CodegenConfig {
if (composed.getAllOf() != null) {
int modelImplCnt = 0; // only one inline object allowed in a ComposedModel
int modelDiscriminators = 0; // only one discriminator allowed in a ComposedModel
for (Object innerSchema : composed.getAllOf()) { // TODO need to work with anyOf, oneOf as well
if (m.discriminator == null && ((Schema) innerSchema).getDiscriminator() != null) {
for (Schema innerSchema : composed.getAllOf()) { // TODO need to work with anyOf, oneOf as well
if (m.discriminator == null && innerSchema.getDiscriminator() != null) {
LOGGER.debug("discriminator is set to null (not correctly set earlier): {}", m.name);
m.setDiscriminator(createDiscriminator(m.name, (Schema) innerSchema));
m.setDiscriminator(createDiscriminator(m.name, innerSchema));
modelDiscriminators++;
}
if (((Schema) innerSchema).getXml() != null) {
m.xmlPrefix = ((Schema) innerSchema).getXml().getPrefix();
m.xmlNamespace = ((Schema) innerSchema).getXml().getNamespace();
m.xmlName = ((Schema) innerSchema).getXml().getName();
if (innerSchema.getXml() != null) {
m.xmlPrefix = innerSchema.getXml().getPrefix();
m.xmlNamespace = innerSchema.getXml().getNamespace();
m.xmlName = innerSchema.getXml().getName();
}
if (modelDiscriminators > 1) {
LOGGER.error("Allof composed schema is inheriting >1 discriminator. Only use one discriminator: {}", composed);
@@ -2753,14 +2743,14 @@ public class DefaultCodegen implements CodegenConfig {
if (composed.getAnyOf() != null) {
if (m.anyOf.contains(languageType)) {
LOGGER.debug("{} (anyOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType);
LOGGER.warn("{} (anyOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType);
} else {
m.anyOf.add(languageType);
}
} else if (composed.getOneOf() != null) {
if (m.oneOf.contains(languageType)) {
LOGGER.debug("{} (oneOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType);
LOGGER.warn("{} (oneOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType);
} else {
m.oneOf.add(languageType);
}
@@ -2894,7 +2884,7 @@ public class DefaultCodegen implements CodegenConfig {
}
protected void updateModelForObject(CodegenModel m, Schema schema) {
if (schema.getProperties() != null || schema.getRequired() != null && !(ModelUtils.isComposedSchema(schema))) {
if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) {
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null);
}
@@ -2923,7 +2913,7 @@ public class DefaultCodegen implements CodegenConfig {
addAdditionPropertiesToCodeGenModel(m, schema);
m.isMap = true;
}
if (schema.getProperties() != null || schema.getRequired() != null && !(ModelUtils.isComposedSchema(schema))) {
if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) {
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null);
}
@@ -3128,7 +3118,7 @@ public class DefaultCodegen implements CodegenConfig {
m.setRef(schema.get$ref());
}
if (ModelUtils.isComposedSchema(schema)) {
if (schema instanceof ComposedSchema) {
updateModelForComposedSchema(m, schema, allDefinitions);
}
@@ -3262,11 +3252,11 @@ public class DefaultCodegen implements CodegenConfig {
return cp;
}
if (ModelUtils.isComposedSchema(refSchema)) {
Schema composedSchema = refSchema;
ComposedSchema composedSchema = (ComposedSchema) refSchema;
if (composedSchema.getAllOf() != null) {
// If our discriminator is in one of the allOf schemas break when we find it
for (Object allOf : composedSchema.getAllOf()) {
CodegenProperty cp = discriminatorFound(composedSchemaName, (Schema) allOf, discPropName, visitedSchemas);
for (Schema allOf : composedSchema.getAllOf()) {
CodegenProperty cp = discriminatorFound(composedSchemaName, allOf, discPropName, visitedSchemas);
if (cp != null) {
return cp;
}
@@ -3275,9 +3265,9 @@ public class DefaultCodegen implements CodegenConfig {
if (composedSchema.getOneOf() != null && composedSchema.getOneOf().size() != 0) {
// All oneOf definitions must contain the discriminator
CodegenProperty cp = new CodegenProperty();
for (Object oneOf : composedSchema.getOneOf()) {
String modelName = ModelUtils.getSimpleRef(((Schema) oneOf).get$ref());
CodegenProperty thisCp = discriminatorFound(composedSchemaName, (Schema) oneOf, discPropName, visitedSchemas);
for (Schema oneOf : composedSchema.getOneOf()) {
String modelName = ModelUtils.getSimpleRef(oneOf.get$ref());
CodegenProperty thisCp = discriminatorFound(composedSchemaName, oneOf, discPropName, visitedSchemas);
if (thisCp == null) {
LOGGER.warn(
"'{}' defines discriminator '{}', but the referenced OneOf schema '{}' is missing {}",
@@ -3298,9 +3288,9 @@ public class DefaultCodegen implements CodegenConfig {
if (composedSchema.getAnyOf() != null && composedSchema.getAnyOf().size() != 0) {
// All anyOf definitions must contain the discriminator because a min of one must be selected
CodegenProperty cp = new CodegenProperty();
for (Object anyOf : composedSchema.getAnyOf()) {
String modelName = ModelUtils.getSimpleRef(((Schema) anyOf).get$ref());
CodegenProperty thisCp = discriminatorFound(composedSchemaName, (Schema) anyOf, discPropName, visitedSchemas);
for (Schema anyOf : composedSchema.getAnyOf()) {
String modelName = ModelUtils.getSimpleRef(anyOf.get$ref());
CodegenProperty thisCp = discriminatorFound(composedSchemaName, anyOf, discPropName, visitedSchemas);
if (thisCp == null) {
LOGGER.warn(
"'{}' defines discriminator '{}', but the referenced AnyOf schema '{}' is missing {}",
@@ -3349,11 +3339,11 @@ public class DefaultCodegen implements CodegenConfig {
Discriminator disc = new Discriminator();
if (ModelUtils.isComposedSchema(refSchema)) {
Schema composedSchema = refSchema;
ComposedSchema composedSchema = (ComposedSchema) refSchema;
if (composedSchema.getAllOf() != null) {
// If our discriminator is in one of the allOf schemas break when we find it
for (Object allOf : composedSchema.getAllOf()) {
foundDisc = recursiveGetDiscriminator((Schema) allOf, visitedSchemas);
for (Schema allOf : composedSchema.getAllOf()) {
foundDisc = recursiveGetDiscriminator(allOf, visitedSchemas);
if (foundDisc != null) {
disc.setPropertyName(foundDisc.getPropertyName());
disc.setMapping(foundDisc.getMapping());
@@ -3366,13 +3356,13 @@ public class DefaultCodegen implements CodegenConfig {
Integer hasDiscriminatorCnt = 0;
Integer hasNullTypeCnt = 0;
Set<String> discriminatorsPropNames = new HashSet<>();
for (Object oneOf : composedSchema.getOneOf()) {
if (ModelUtils.isNullType((Schema) oneOf)) {
for (Schema oneOf : composedSchema.getOneOf()) {
if (ModelUtils.isNullType(oneOf)) {
// The null type does not have a discriminator. Skip.
hasNullTypeCnt++;
continue;
}
foundDisc = recursiveGetDiscriminator((Schema) oneOf, visitedSchemas);
foundDisc = recursiveGetDiscriminator(oneOf, visitedSchemas);
if (foundDisc != null) {
discriminatorsPropNames.add(foundDisc.getPropertyName());
hasDiscriminatorCnt++;
@@ -3395,13 +3385,13 @@ public class DefaultCodegen implements CodegenConfig {
Integer hasDiscriminatorCnt = 0;
Integer hasNullTypeCnt = 0;
Set<String> discriminatorsPropNames = new HashSet<>();
for (Object anyOf : composedSchema.getAnyOf()) {
if (ModelUtils.isNullType((Schema) anyOf)) {
for (Schema anyOf : composedSchema.getAnyOf()) {
if (ModelUtils.isNullType(anyOf)) {
// The null type does not have a discriminator. Skip.
hasNullTypeCnt++;
continue;
}
foundDisc = recursiveGetDiscriminator((Schema) anyOf, visitedSchemas);
foundDisc = recursiveGetDiscriminator(anyOf, visitedSchemas);
if (foundDisc != null) {
discriminatorsPropNames.add(foundDisc.getPropertyName());
hasDiscriminatorCnt++;
@@ -3436,7 +3426,7 @@ public class DefaultCodegen implements CodegenConfig {
* @param c The ComposedSchema that contains the discriminator and oneOf/anyOf schemas
* @return the list of oneOf and anyOf MappedModel that need to be added to the discriminator map
*/
protected List<MappedModel> getOneOfAnyOfDescendants(String composedSchemaName, String discPropName, Schema c) {
protected List<MappedModel> getOneOfAnyOfDescendants(String composedSchemaName, String discPropName, ComposedSchema c) {
ArrayList<List<Schema>> listOLists = new ArrayList<>();
listOLists.add(c.getOneOf());
listOLists.add(c.getAnyOf());
@@ -3516,7 +3506,8 @@ public class DefaultCodegen implements CodegenConfig {
}
Schema child = schemas.get(childName);
if (ModelUtils.isComposedSchema(child)) {
List<Schema> parents = child.getAllOf();
ComposedSchema composedChild = (ComposedSchema) child;
List<Schema> parents = composedChild.getAllOf();
if (parents != null) {
for (Schema parent : parents) {
String ref = parent.get$ref();
@@ -3629,7 +3620,7 @@ public class DefaultCodegen implements CodegenConfig {
}
// if there are composed oneOf/anyOf schemas, add them to this discriminator
if (ModelUtils.isComposedSchema(schema) && !this.getLegacyDiscriminatorBehavior()) {
List<MappedModel> otherDescendants = getOneOfAnyOfDescendants(schemaName, discriminatorPropertyName, schema);
List<MappedModel> otherDescendants = getOneOfAnyOfDescendants(schemaName, discriminatorPropertyName, (ComposedSchema) schema);
for (MappedModel otherDescendant : otherDescendants) {
if (!uniqueDescendants.contains(otherDescendant)) {
uniqueDescendants.add(otherDescendant);
@@ -3663,18 +3654,15 @@ public class DefaultCodegen implements CodegenConfig {
* @param visitedSchemas circuit-breaker - the schemas with which the method was called before for recursive structures
*/
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema schema, Set<Schema> visitedSchemas) {
if (schema == null) {
return;
}
if (!visitedSchemas.add(schema)) {
return;
}
if (ModelUtils.isComposedSchema(schema)) {
if (schema instanceof ComposedSchema) {
ComposedSchema composedSchema = (ComposedSchema) schema;
if (schema.getAllOf() != null) {
for (Object component : schema.getAllOf()) {
addProperties(properties, required, (Schema) component, visitedSchemas);
if (composedSchema.getAllOf() != null) {
for (Schema component : composedSchema.getAllOf()) {
addProperties(properties, required, component, visitedSchemas);
}
}
@@ -3682,15 +3670,15 @@ public class DefaultCodegen implements CodegenConfig {
required.addAll(schema.getRequired());
}
if (schema.getOneOf() != null) {
for (Object component : schema.getOneOf()) {
addProperties(properties, required, (Schema) component, visitedSchemas);
if (composedSchema.getOneOf() != null) {
for (Schema component : composedSchema.getOneOf()) {
addProperties(properties, required, component, visitedSchemas);
}
}
if (schema.getAnyOf() != null) {
for (Object component : schema.getAnyOf()) {
addProperties(properties, required, (Schema) component, visitedSchemas);
if (composedSchema.getAnyOf() != null) {
for (Schema component : composedSchema.getAnyOf()) {
addProperties(properties, required, component, visitedSchemas);
}
}
@@ -3774,11 +3762,10 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.FALSE.equals(p.getNullable())) {
LOGGER.warn("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", p.getName());
}
property.isNullable = property.isNullable ||
!(ModelUtils.isComposedSchema(p)) ||
p.getAllOf() == null ||
p.getAllOf().size() == 0;
ComposedSchema composedSchema = p instanceof ComposedSchema
? (ComposedSchema) p
: null;
property.isNullable = property.isNullable || composedSchema == null || composedSchema.getAllOf() == null || composedSchema.getAllOf().size() == 0;
if (languageSpecificPrimitives.contains(property.dataType)) {
property.isPrimitiveType = true;
}
@@ -5755,7 +5742,7 @@ public class DefaultCodegen implements CodegenConfig {
* @param model codegen model
* @param modelName model name
*/
protected void addImport(Schema composed, Schema childSchema, CodegenModel model, String modelName ) {
protected void addImport(ComposedSchema composed, Schema childSchema, CodegenModel model, String modelName ) {
if (composed == null || childSchema == null) {
return;
}
@@ -5982,10 +5969,6 @@ public class DefaultCodegen implements CodegenConfig {
}
private static Boolean isAliasOfSimpleTypes(Schema schema) {
if (schema == null) {
return false;
}
return (!ModelUtils.isObjectSchema(schema)
&& !ModelUtils.isArraySchema(schema)
&& !ModelUtils.isMapSchema(schema)
@@ -6541,7 +6524,6 @@ public class DefaultCodegen implements CodegenConfig {
.findFirst();
String dataType = (referencedSchema.isPresent()) ? getTypeDeclaration(referencedSchema.get()) : varDataType;
List<Map<String, Object>> enumVars = buildEnumVars(values, dataType);
postProcessEnumVars(enumVars);
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
Map<String, Object> extensions = var.mostInnerItems != null ? var.mostInnerItems.getVendorExtensions() : var.getVendorExtensions();
@@ -6580,23 +6562,26 @@ public class DefaultCodegen implements CodegenConfig {
protected List<Map<String, Object>> buildEnumVars(List<Object> values, String dataType) {
List<Map<String, Object>> enumVars = new ArrayList<>();
int truncateIdx = isRemoveEnumValuePrefix()
? findCommonPrefixOfVars(values).length()
: 0;
int truncateIdx = 0;
if (isRemoveEnumValuePrefix()) {
String commonPrefix = findCommonPrefixOfVars(values);
truncateIdx = commonPrefix.length();
}
for (Object value : values) {
Map<String, Object> enumVar = new HashMap<>();
String enumName = truncateIdx == 0
? String.valueOf(value)
: value.toString().substring(truncateIdx);
if (enumName.isEmpty()) {
enumName = value.toString();
String enumName;
if (truncateIdx == 0) {
enumName = String.valueOf(value);
} else {
enumName = value.toString().substring(truncateIdx);
if (enumName.isEmpty()) {
enumName = value.toString();
}
}
final String finalEnumName = toEnumVarName(enumName, dataType);
enumVar.put("name", finalEnumName);
enumVar.put("name", toEnumVarName(enumName, dataType));
enumVar.put("value", toEnumValue(String.valueOf(value), dataType));
enumVar.put("isString", isDataTypeString(dataType));
enumVars.add(enumVar);
@@ -6608,15 +6593,18 @@ public class DefaultCodegen implements CodegenConfig {
Map<String, Object> enumVar = new HashMap<>();
String enumName = enumUnknownDefaultCaseName;
String enumValue = isDataTypeString(dataType)
? enumUnknownDefaultCaseName
: // This is a dummy value that attempts to avoid collisions with previously specified cases.
// Int.max / 192
// The number 192 that is used to calculate this random value, is the Swift Evolution proposal for frozen/non-frozen enums.
// [SE-0192](https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md)
// Since this functionality was born in the Swift 5 generator and latter on broth to all generators
// https://github.com/OpenAPITools/openapi-generator/pull/11013
String.valueOf(11184809);
String enumValue;
if (isDataTypeString(dataType)) {
enumValue = enumUnknownDefaultCaseName;
} else {
// This is a dummy value that attempts to avoid collisions with previously specified cases.
// Int.max / 192
// The number 192 that is used to calculate this random value, is the Swift Evolution proposal for frozen/non-frozen enums.
// [SE-0192](https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md)
// Since this functionality was born in the Swift 5 generator and latter on broth to all generators
// https://github.com/OpenAPITools/openapi-generator/pull/11013
enumValue = String.valueOf(11184809);
}
enumVar.put("name", toEnumVarName(enumName, dataType));
enumVar.put("value", toEnumValue(enumValue, dataType));
@@ -6627,27 +6615,6 @@ public class DefaultCodegen implements CodegenConfig {
return enumVars;
}
protected void postProcessEnumVars(List<Map<String, Object>> enumVars) {
Collections.reverse(enumVars);
enumVars.forEach(v -> {
String name = (String) v.get("name");
long count = enumVars.stream().filter(v1 -> v1.get("name").equals(name)).count();
if (count > 1) {
String uniqueEnumName = getUniqueEnumName(name, enumVars);
LOGGER.debug("Changing duplicate enumeration name from " + v.get("name") + " to " + uniqueEnumName);
v.put("name", uniqueEnumName);
}
});
Collections.reverse(enumVars);
}
private String getUniqueEnumName(String name, List<Map<String, Object>> enumVars) {
long count = enumVars.stream().filter(v -> v.get("name").equals(name)).count();
return count > 1
? getUniqueEnumName(name + count, enumVars)
: name;
}
protected void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions, String dataType) {
if (vendorExtensions != null) {
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-varnames", "name");
@@ -6938,13 +6905,6 @@ public class DefaultCodegen implements CodegenConfig {
LOGGER.debug("debugging fromRequestBodyToFormParameters= {}", body);
Schema schema = ModelUtils.getSchemaFromRequestBody(body);
schema = ModelUtils.getReferencedSchema(this.openAPI, schema);
if(ModelUtils.isMapSchema(schema)) {
LOGGER.error("Form parameters with additionalProperties are not supported by OpenAPI Generator. Please report the issue to https://github.com/openapitools/openapi-generator if you need help.");
}
if(ModelUtils.isArraySchema(schema)) {
LOGGER.error("Array form parameters are not supported by OpenAPI Generator. Please report the issue to https://github.com/openapitools/openapi-generator if you need help.");
}
List<String> allRequired = new ArrayList<>();
Map<String, Schema> properties = new LinkedHashMap<>();
// this traverses a composed schema and extracts all properties in each schema into properties
@@ -6953,8 +6913,6 @@ public class DefaultCodegen implements CodegenConfig {
// https://github.com/OpenAPITools/openapi-generator/issues/10415
addProperties(properties, allRequired, schema, new HashSet<>());
boolean isOneOfOrAnyOf = ModelUtils.isOneOf(schema) || ModelUtils.isAnyOf(schema);
if (!properties.isEmpty()) {
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
CodegenParameter codegenParameter;
@@ -6962,14 +6920,14 @@ public class DefaultCodegen implements CodegenConfig {
// value => property schema
String propertyName = entry.getKey();
Schema propertySchema = entry.getValue();
if (ModelUtils.isMapSchema(propertySchema)) {
LOGGER.error("Map of form parameters not supported. Please report the issue to https://github.com/openapitools/openapi-generator if you need help.");
continue;
}
codegenParameter = fromFormProperty(propertyName, propertySchema, imports);
if (isOneOfOrAnyOf) {
// for oneOf/anyOf, mark all the properties collected from the sub-schemas as optional
// so that users can choose which property to include in the form parameters
codegenParameter.required = false;
} else if (!codegenParameter.required && schema.getRequired() != null) {
// Set 'required' flag defined in the schema element
// Set 'required' flag defined in the schema element
if (!codegenParameter.required && schema.getRequired() != null) {
codegenParameter.required = schema.getRequired().contains(entry.getKey());
} else if (!codegenParameter.required) {
// Set 'required' flag for properties declared inside the allOf
@@ -7942,12 +7900,12 @@ public class DefaultCodegen implements CodegenConfig {
/**
* Add "x-one-of-name" extension to a given oneOf schema (assuming it has at least 1 oneOf elements)
*
* @param schema schema to add the extension to
* @param name name of the parent oneOf schema
* @param s schema to add the extension to
* @param name name of the parent oneOf schema
*/
public void addOneOfNameExtension(Schema schema, String name) {
if (schema.getOneOf() != null && schema.getOneOf().size() > 0) {
schema.addExtension("x-one-of-name", name);
public void addOneOfNameExtension(ComposedSchema s, String name) {
if (s.getOneOf() != null && s.getOneOf().size() > 0) {
s.addExtension("x-one-of-name", name);
}
}
@@ -7957,7 +7915,7 @@ public class DefaultCodegen implements CodegenConfig {
* @param cs ComposedSchema object to create as interface model
* @param type name to use for the generated interface model
*/
public void addOneOfInterfaceModel(Schema cs, String type) {
public void addOneOfInterfaceModel(ComposedSchema cs, String type) {
if (cs.getOneOf() == null) {
return;
}
@@ -7966,9 +7924,9 @@ public class DefaultCodegen implements CodegenConfig {
cm.setDiscriminator(createDiscriminator("", cs));
for (Object o : Optional.ofNullable(cs.getOneOf()).orElse(Collections.emptyList())) {
if (((Schema) o).get$ref() == null) {
if (cm.discriminator != null && ((Schema) o).get$ref() == null) {
for (Schema o : Optional.ofNullable(cs.getOneOf()).orElse(Collections.emptyList())) {
if (o.get$ref() == null) {
if (cm.discriminator != null && o.get$ref() == null) {
// OpenAPI spec states that inline objects should not be considered when discriminator is used
// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminatorObject
LOGGER.warn("Ignoring inline object in oneOf definition of {}, since discriminator is used", type);
@@ -7977,7 +7935,7 @@ public class DefaultCodegen implements CodegenConfig {
}
continue;
}
cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(((Schema) o).get$ref())));
cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref())));
}
cm.name = type;
cm.classname = type;
@@ -8148,7 +8106,7 @@ public class DefaultCodegen implements CodegenConfig {
}
private CodegenComposedSchemas getComposedSchemas(Schema schema) {
if (!(ModelUtils.isComposedSchema(schema)) && schema.getNot() == null) {
if (!(schema instanceof ComposedSchema) && schema.getNot() == null) {
return null;
}
Schema notSchema = schema.getNot();
@@ -8159,10 +8117,11 @@ public class DefaultCodegen implements CodegenConfig {
List<CodegenProperty> allOf = new ArrayList<>();
List<CodegenProperty> oneOf = new ArrayList<>();
List<CodegenProperty> anyOf = new ArrayList<>();
if (ModelUtils.isComposedSchema(schema)) {
allOf = getComposedProperties(schema.getAllOf(), "all_of");
oneOf = getComposedProperties(schema.getOneOf(), "one_of");
anyOf = getComposedProperties(schema.getAnyOf(), "any_of");
if (schema instanceof ComposedSchema) {
ComposedSchema cs = (ComposedSchema) schema;
allOf = getComposedProperties(cs.getAllOf(), "all_of");
oneOf = getComposedProperties(cs.getOneOf(), "one_of");
anyOf = getComposedProperties(cs.getAnyOf(), "any_of");
}
return new CodegenComposedSchemas(
allOf,

View File

@@ -58,7 +58,6 @@ import org.openapitools.codegen.utils.ImplementationVersion;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.ProcessUtils;
import org.openapitools.codegen.utils.URLPathUtils;
import org.openapitools.codegen.utils.SemVer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -263,10 +262,6 @@ public class DefaultGenerator implements Generator {
// normalize the spec
try {
if (config.getUseOpenAPINormalizer()) {
SemVer version = new SemVer(openAPI.getOpenapi());
if (version.atLeast("3.1.0")) {
config.openapiNormalizer().put("NORMALIZE_31SPEC", "true");
}
OpenAPINormalizer openapiNormalizer = new OpenAPINormalizer(openAPI, config.openapiNormalizer());
openapiNormalizer.normalize();
}
@@ -1334,10 +1329,8 @@ public class DefaultGenerator implements Generator {
for (Map.Entry<String, Schema> definitionsEntry : definitions.entrySet()) {
String key = definitionsEntry.getKey();
Schema schema = definitionsEntry.getValue();
if (schema == null) {
LOGGER.warn("Schema {} cannot be null in processModels", key);
continue;
}
if (schema == null)
throw new RuntimeException("schema cannot be null in processModels");
CodegenModel cm = config.fromModel(key, schema);
ModelMap mo = new ModelMap();
mo.setModel(cm);

View File

@@ -216,30 +216,32 @@ public class InlineModelResolver {
return true;
}
}
if (ModelUtils.isComposedSchema(schema)) {
if (schema instanceof ComposedSchema) {
// allOf, anyOf, oneOf
boolean isSingleAllOf = schema.getAllOf() != null && schema.getAllOf().size() == 1;
boolean isReadOnly = schema.getReadOnly() != null && schema.getReadOnly();
boolean isNullable = schema.getNullable() != null && schema.getNullable();
ComposedSchema m = (ComposedSchema) schema;
boolean isSingleAllOf = m.getAllOf() != null && m.getAllOf().size() == 1;
boolean isReadOnly = m.getReadOnly() != null && m.getReadOnly();
boolean isNullable = m.getNullable() != null && m.getNullable();
if (isSingleAllOf && (isReadOnly || isNullable)) {
// Check if this composed schema only contains an allOf and a readOnly or nullable.
ComposedSchema c = new ComposedSchema();
c.setAllOf(schema.getAllOf());
c.setReadOnly(schema.getReadOnly());
c.setNullable(schema.getNullable());
if (schema.equals(c)) {
return isModelNeeded((Schema) schema.getAllOf().get(0), visitedSchemas);
c.setAllOf(m.getAllOf());
c.setReadOnly(m.getReadOnly());
c.setNullable(m.getNullable());
if (m.equals(c)) {
return isModelNeeded(m.getAllOf().get(0), visitedSchemas);
}
} else if (isSingleAllOf && StringUtils.isNotEmpty(((Schema) schema.getAllOf().get(0)).get$ref())) {
} else if (isSingleAllOf && StringUtils.isNotEmpty(m.getAllOf().get(0).get$ref())) {
// single allOf and it's a ref
return isModelNeeded((Schema) schema.getAllOf().get(0), visitedSchemas);
return isModelNeeded(m.getAllOf().get(0), visitedSchemas);
}
if (schema.getAllOf() != null && !schema.getAllOf().isEmpty()) {
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
// check to ensure at least one of the allOf item is model
for (Object inner : schema.getAllOf()) {
if (isModelNeeded(ModelUtils.getReferencedSchema(openAPI, (Schema) inner), visitedSchemas)) {
for (Schema inner : m.getAllOf()) {
if (isModelNeeded(ModelUtils.getReferencedSchema(openAPI, inner), visitedSchemas)) {
return true;
}
}
@@ -247,10 +249,10 @@ public class InlineModelResolver {
return false;
}
if (schema.getAnyOf() != null && !schema.getAnyOf().isEmpty()) {
if (m.getAnyOf() != null && !m.getAnyOf().isEmpty()) {
return true;
}
if (schema.getOneOf() != null && !schema.getOneOf().isEmpty()) {
if (m.getOneOf() != null && !m.getOneOf().isEmpty()) {
return true;
}
}
@@ -271,7 +273,7 @@ public class InlineModelResolver {
// any to catch OpenAPI violations
if (isModelNeeded(schema) || "object".equals(schema.getType()) ||
schema.getProperties() != null || schema.getAdditionalProperties() != null ||
ModelUtils.isComposedSchema(schema)) {
schema instanceof ComposedSchema) {
LOGGER.error("Illegal schema found with $ref combined with other properties," +
" no properties should be defined alongside a $ref:\n " + schema.toString());
}
@@ -286,11 +288,6 @@ public class InlineModelResolver {
if (props != null) {
for (String propName : props.keySet()) {
Schema prop = props.get(propName);
if (prop == null) {
continue;
}
String schemaName = resolveModelName(prop.getTitle(), modelPrefix + "_" + propName);
// Recurse to create $refs for inner models
gatherInlineModels(prop, schemaName);
@@ -298,13 +295,13 @@ public class InlineModelResolver {
// If this schema should be split into its own model, do so
Schema refSchema = this.makeSchemaInComponents(schemaName, prop);
props.put(propName, refSchema);
} else if (ModelUtils.isComposedSchema(prop)) {
if (prop.getAllOf() != null && prop.getAllOf().size() == 1 &&
!(((Schema) prop.getAllOf().get(0)).getType() == null ||
"object".equals(((Schema) prop.getAllOf().get(0)).getType()))) {
} else if (prop instanceof ComposedSchema) {
ComposedSchema m = (ComposedSchema) prop;
if (m.getAllOf() != null && m.getAllOf().size() == 1 &&
!(m.getAllOf().get(0).getType() == null || "object".equals(m.getAllOf().get(0).getType()))) {
// allOf with only 1 type (non-model)
LOGGER.info("allOf schema used by the property `{}` replaced by its only item (a type)", propName);
props.put(propName, (Schema) prop.getAllOf().get(0));
props.put(propName, m.getAllOf().get(0));
}
}
}
@@ -313,15 +310,13 @@ public class InlineModelResolver {
if (schema.getAdditionalProperties() != null) {
if (schema.getAdditionalProperties() instanceof Schema) {
Schema inner = (Schema) schema.getAdditionalProperties();
if (inner != null) {
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + this.inlineSchemaOptions.get("MAP_ITEM_SUFFIX"));
// Recurse to create $refs for inner models
gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) {
// If this schema should be split into its own model, do so
Schema refSchema = this.makeSchemaInComponents(schemaName, inner);
schema.setAdditionalProperties(refSchema);
}
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + this.inlineSchemaOptions.get("MAP_ITEM_SUFFIX"));
// Recurse to create $refs for inner models
gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) {
// If this schema should be split into its own model, do so
Schema refSchema = this.makeSchemaInComponents(schemaName, inner);
schema.setAdditionalProperties(refSchema);
}
}
}
@@ -341,6 +336,10 @@ public class InlineModelResolver {
if (schema instanceof ArraySchema) {
ArraySchema array = (ArraySchema) schema;
Schema items = array.getItems();
/*if (items.getTitle() != null) {
LOGGER.info("schema title {}", items);
throw new RuntimeException("getTitle for array item is not null");
}*/
if (items == null) {
LOGGER.error("Illegal schema found with array type but no items," +
" items must be defined for array schemas:\n " + schema.toString());
@@ -358,91 +357,82 @@ public class InlineModelResolver {
}
}
// Check allOf, anyOf, oneOf for inline models
if (ModelUtils.isComposedSchema(schema)) {
if (schema.getAllOf() != null) {
if (schema instanceof ComposedSchema) {
ComposedSchema m = (ComposedSchema) schema;
if (m.getAllOf() != null) {
List<Schema> newAllOf = new ArrayList<Schema>();
boolean atLeastOneModel = false;
for (Object inner : schema.getAllOf()) {
if (inner == null) {
continue;
}
String schemaName = resolveModelName(((Schema) inner).getTitle(), modelPrefix + "_allOf");
for (Schema inner : m.getAllOf()) {
String schemaName = resolveModelName(inner.getTitle(), modelPrefix + "_allOf");
// Recurse to create $refs for inner models
gatherInlineModels((Schema) inner, schemaName);
if (isModelNeeded((Schema) inner)) {
gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) {
if (Boolean.TRUE.equals(this.refactorAllOfInlineSchemas)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, (Schema) inner);
Schema refSchema = this.makeSchemaInComponents(schemaName, inner);
newAllOf.add(refSchema); // replace with ref
atLeastOneModel = true;
} else { // do not refactor allOf inline schemas
newAllOf.add((Schema) inner);
newAllOf.add(inner);
atLeastOneModel = true;
}
} else {
newAllOf.add((Schema) inner);
newAllOf.add(inner);
}
}
if (atLeastOneModel) {
schema.setAllOf(newAllOf);
m.setAllOf(newAllOf);
} else {
// allOf is just one or more types only so do not generate the inline allOf model
if (schema.getAllOf().size() == 1) {
if (m.getAllOf().size() == 1) {
// handle earlier in this function when looping through properties
} else if (schema.getAllOf().size() > 1) {
} else if (m.getAllOf().size() > 1) {
LOGGER.warn("allOf schema `{}` containing multiple types (not model) is not supported at the moment.", schema.getName());
} else {
LOGGER.error("allOf schema `{}` contains no items.", schema.getName());
}
}
}
if (schema.getAnyOf() != null) {
if (m.getAnyOf() != null) {
List<Schema> newAnyOf = new ArrayList<Schema>();
for (Object inner : schema.getAnyOf()) {
if (inner == null) {
continue;
}
String schemaName = resolveModelName(((Schema) inner).getTitle(), modelPrefix + "_anyOf");
for (Schema inner : m.getAnyOf()) {
String schemaName = resolveModelName(inner.getTitle(), modelPrefix + "_anyOf");
// Recurse to create $refs for inner models
gatherInlineModels((Schema) inner, schemaName);
if (isModelNeeded((Schema) inner)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, (Schema) inner);
gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, inner);
newAnyOf.add(refSchema); // replace with ref
} else {
newAnyOf.add((Schema) inner);
newAnyOf.add(inner);
}
}
schema.setAnyOf(newAnyOf);
m.setAnyOf(newAnyOf);
}
if (schema.getOneOf() != null) {
if (m.getOneOf() != null) {
List<Schema> newOneOf = new ArrayList<Schema>();
for (Object inner : schema.getOneOf()) {
if (inner == null) {
continue;
}
String schemaName = resolveModelName(((Schema) inner).getTitle(), modelPrefix + "_oneOf");
for (Schema inner : m.getOneOf()) {
String schemaName = resolveModelName(inner.getTitle(), modelPrefix + "_oneOf");
// Recurse to create $refs for inner models
gatherInlineModels((Schema) inner, schemaName);
if (isModelNeeded((Schema) inner)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, (Schema) inner);
gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, inner);
newOneOf.add(refSchema); // replace with ref
} else {
newOneOf.add((Schema) inner);
newOneOf.add(inner);
}
}
schema.setOneOf(newOneOf);
m.setOneOf(newOneOf);
}
}
// Check not schema
if (schema.getNot() != null) {
Schema not = schema.getNot();
if (not != null) {
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + "_not");
// Recurse to create $refs for inner models
gatherInlineModels(not, schemaName);
if (isModelNeeded(not)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, not);
schema.setNot(refSchema);
}
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + "_not");
// Recurse to create $refs for inner models
gatherInlineModels(not, schemaName);
if (isModelNeeded(not)) {
Schema refSchema = this.makeSchemaInComponents(schemaName, not);
schema.setNot(refSchema);
}
}
}
@@ -643,18 +633,16 @@ public class InlineModelResolver {
List<String> modelNames = new ArrayList<String>(models.keySet());
for (String modelName : modelNames) {
Schema model = models.get(modelName);
if (model == null) {
continue;
}
if (ModelUtils.isAnyOf(model)) { // contains anyOf only
gatherInlineModels(model, modelName);
} else if (ModelUtils.isOneOf(model)) { // contains oneOf only
gatherInlineModels(model, modelName);
} else if (ModelUtils.isComposedSchema(model)) {
ComposedSchema m = (ComposedSchema) model;
// inline child schemas
flattenComposedChildren(modelName + "_allOf", model.getAllOf(), !Boolean.TRUE.equals(this.refactorAllOfInlineSchemas));
flattenComposedChildren(modelName + "_anyOf", model.getAnyOf(), false);
flattenComposedChildren(modelName + "_oneOf", model.getOneOf(), false);
flattenComposedChildren(modelName + "_allOf", m.getAllOf(), !Boolean.TRUE.equals(this.refactorAllOfInlineSchemas));
flattenComposedChildren(modelName + "_anyOf", m.getAnyOf(), false);
flattenComposedChildren(modelName + "_oneOf", m.getOneOf(), false);
} else {
gatherInlineModels(model, modelName);
}

View File

@@ -19,7 +19,6 @@ package org.openapitools.codegen;
import io.swagger.v3.oas.models.*;
import io.swagger.v3.oas.models.callbacks.Callback;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
@@ -88,9 +87,6 @@ public class OpenAPINormalizer {
// the allOf contains a new schema containing the properties in the top level
final String REFACTOR_ALLOF_WITH_PROPERTIES_ONLY = "REFACTOR_ALLOF_WITH_PROPERTIES_ONLY";
// when set to true, normalize OpenAPI 3.1 spec to make it work with the generator
final String NORMALIZE_31SPEC = "NORMALIZE_31SPEC";
// ============= end of rules =============
/**
@@ -119,7 +115,6 @@ public class OpenAPINormalizer {
ruleNames.add(SET_TAGS_FOR_ALL_OPERATIONS);
ruleNames.add(ADD_UNSIGNED_TO_INTEGER_WITH_INVALID_MAX_VALUE);
ruleNames.add(REFACTOR_ALLOF_WITH_PROPERTIES_ONLY);
ruleNames.add(NORMALIZE_31SPEC);
// rules that are default to true
rules.put(SIMPLIFY_ONEOF_ANYOF, true);
@@ -153,7 +148,7 @@ public class OpenAPINormalizer {
// loop through all the rules
for (Map.Entry<String, String> rule : inputRules.entrySet()) {
LOGGER.debug("processing rule {} => {}", rule.getKey(), rule.getValue());
LOGGER.info("processing rule {} => {}", rule.getKey(), rule.getValue());
if (!ruleNames.contains(rule.getKey())) { // invalid rule name
LOGGER.warn("Invalid openapi-normalizer rule name: ", rule.getKey());
} else if (enableAll) {
@@ -252,13 +247,11 @@ public class OpenAPINormalizer {
} else if (mediaType.getSchema() == null) {
continue;
} else {
Schema newSchema = normalizeSchema(mediaType.getSchema(), new HashSet<>());
mediaType.setSchema(newSchema);
normalizeSchema(mediaType.getSchema(), new HashSet<>());
}
}
}
/**
* Normalizes schemas in RequestBody
*
@@ -298,8 +291,7 @@ public class OpenAPINormalizer {
if (parameter.getSchema() == null) {
continue;
} else {
Schema newSchema = normalizeSchema(parameter.getSchema(), new HashSet<>());
parameter.setSchema(newSchema);
normalizeSchema(parameter.getSchema(), new HashSet<>());
}
}
}
@@ -320,29 +312,10 @@ public class OpenAPINormalizer {
continue;
} else {
normalizeContent(responsesEntry.getValue().getContent());
normalizeHeaders(responsesEntry.getValue().getHeaders());
}
}
}
/**
* Normalizes schemas in headers
*
* @param headers a map of headers
*/
private void normalizeHeaders(Map<String, Header> headers) {
if (headers == null || headers.isEmpty()) {
return;
}
for (String headerKey : headers.keySet()) {
Header h = headers.get(headerKey);
Schema updatedHeader = normalizeSchema(h.getSchema(), new HashSet<>());
h.setSchema(updatedHeader);
}
}
/**
* Normalizes schemas in components
*/
@@ -435,7 +408,7 @@ public class OpenAPINormalizer {
} else if (schema instanceof IntegerSchema) {
normalizeIntegerSchema(schema, visitedSchemas);
} else if (schema instanceof Schema) {
return normalizeSimpleSchema(schema, visitedSchemas);
normalizeSchemaWithOnlyProperties(schema, visitedSchemas);
} else {
throw new RuntimeException("Unknown schema type found in normalizer: " + schema);
}
@@ -443,10 +416,6 @@ public class OpenAPINormalizer {
return schema;
}
private Schema normalizeSimpleSchema(Schema schema, Set<Schema> visitedSchemas) {
return processNormalize31Spec(schema, visitedSchemas);
}
private void normalizeBooleanSchema(Schema schema, Set<Schema> visitedSchemas) {
processSimplifyBooleanEnum(schema);
}
@@ -455,6 +424,10 @@ public class OpenAPINormalizer {
processAddUnsignedToIntegerWithInvalidMaxValue(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;
@@ -697,9 +670,9 @@ public class OpenAPINormalizer {
/**
* Check if the schema is of type 'null'
* <p>
*
* Return true if the schema's type is 'null' or not specified
*
*
* @param schema Schema
*/
private boolean isNullTypeSchema(Schema schema) {
@@ -830,7 +803,7 @@ public class OpenAPINormalizer {
}
}
/**
/*
* When set to true, refactor schema with allOf and properties in the same level to a schema with allOf only and
* the allOf contains a new schema containing the properties in the top level.
*
@@ -871,75 +844,5 @@ public class OpenAPINormalizer {
return schema;
}
/**
* When set to true, normalize schema so that it works well with the generator.
*
* @param schema Schema
* @param visitedSchemas a set of visited schemas
* @return Schema
*/
private Schema processNormalize31Spec(Schema schema, Set<Schema> visitedSchemas) {
if (!getRule(NORMALIZE_31SPEC)) {
return schema;
}
if (schema == null || schema.getTypes() == null) {
return null;
}
// process null
if (schema.getTypes().contains("null")) {
schema.setNullable(true);
schema.getTypes().remove("null");
}
// only one item (type) left
if (schema.getTypes().size() == 1) {
String type = String.valueOf(schema.getTypes().iterator().next());
if ("array".equals(type)) {
ArraySchema as = new ArraySchema();
as.setXml(schema.getXml());
// `items` is also a json schema
if (StringUtils.isNotEmpty(schema.getItems().get$ref())) {
Schema ref = new Schema();
ref.set$ref(schema.getItems().get$ref());
as.setItems(ref);
} else { // inline schema (e.g. model, string, etc)
Schema updatedItems = normalizeSchema(schema.getItems(), visitedSchemas);
as.setItems(updatedItems);
}
return as;
} else { // other primitive type such as string
// set type (3.0 spec) directly
schema.setType(type);
}
} else { // more than 1 item
// convert to anyOf and keep all other attributes (e.g. nullable, description)
// the same. No need to handle null as it should have been removed at this point.
for (Object type : schema.getTypes()) {
switch (String.valueOf(type)) {
case "string":
schema.addAnyOfItem(new StringSchema());
break;
case "integer":
schema.addAnyOfItem(new IntegerSchema());
break;
case "number":
schema.addAnyOfItem(new NumberSchema());
break;
case "boolean":
schema.addAnyOfItem(new BooleanSchema());
break;
default:
LOGGER.error("Type {} not yet supported in openapi-normalizer to process OpenAPI 3.1 spec with multiple types.");
LOGGER.error("Please report the issue via https://github.com/OpenAPITools/openapi-generator/issues/new/.");
}
}
}
return schema;
}
// ===================== end of rules =====================
}

View File

@@ -287,8 +287,10 @@ public class ExampleGenerator {
return "https://openapi-generator.tech";
} else if (ModelUtils.isStringSchema(property)) {
LOGGER.debug("String property");
if (property.getDefault() != null) {
return String.valueOf(property.getDefault());
String defaultValue = (String) property.getDefault();
if (defaultValue != null && !defaultValue.isEmpty()) {
LOGGER.debug("Default value found: '{}'", defaultValue);
return defaultValue;
}
List<String> enumValues = property.getEnum();
if (enumValues != null && !enumValues.isEmpty()) {

View File

@@ -262,7 +262,7 @@ public abstract class AbstractApexCodegen extends DefaultCodegen implements Code
return "null";
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
String _default = String.valueOf(p.getDefault());
String _default = (String) p.getDefault();
if (p.getEnum() == null) {
return "\"" + escapeText(_default) + "\"";
} else {

View File

@@ -26,7 +26,6 @@ import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
@@ -59,7 +58,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
protected boolean returnICollection = false;
protected boolean netCoreProjectFileFlag = false;
protected boolean nullReferenceTypesFlag = false;
protected boolean useSourceGeneration = false;
protected String modelPropertyNaming = CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.PascalCase.name();
@@ -417,15 +415,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
.put("required", new RequiredParameterLambda())
.put("optional", new OptionalParameterLambda().generator(this))
.put("joinWithComma", new JoinWithCommaLambda())
.put("joinLinesWithComma", new JoinWithCommaLambda(false, "\n", ",\n"))
.put("trimLineBreaks", new TrimLineBreaksLambda())
.put("trimTrailingWithNewLine", new TrimTrailingWhiteSpaceLambda(true))
.put("trimTrailing", new TrimTrailingWhiteSpaceLambda(false))
.put("first", new FirstLambda(" "))
.put("firstDot", new FirstLambda("\\."))
.put("indent3", new IndentedLambda(12, " ", false))
.put("indent4", new IndentedLambda(16, " ", false))
.put("uniqueLinesWithNewLine", new UniqueLambda("\n", true));
.put("indent4", new IndentedLambda(16, " ", false));
}
@Override
@@ -527,7 +522,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
// GrandparentAnimal has a discriminator, but no oneOf nor anyOf
// modules\openapi-generator\src\test\resources\3_0\csharp\petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
model.setHasDiscriminatorWithNonEmptyMapping(
((model.anyOf != null && model.anyOf.size() > 0) || (model.oneOf != null && model.oneOf.size() > 0)) &&
((model.anyOf != null && model.anyOf.size() > 0) || (model.anyOf != null && model.oneOf.size() > 0)) &&
model.discriminator != null &&
model.discriminator.getMappedModels() != null &&
model.discriminator.getMappedModels().size() > 0);
@@ -1354,14 +1349,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return this.nullReferenceTypesFlag;
}
public void setUseSourceGeneration(final Boolean useSourceGeneration) {
this.useSourceGeneration = useSourceGeneration;
}
public boolean getUseSourceGeneration() {
return this.useSourceGeneration;
}
public void setInterfacePrefix(final String interfacePrefix) {
this.interfacePrefix = interfacePrefix;
}
@@ -1394,13 +1381,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return value;
}
final String partiallyEscaped = value
.replace("\n", "\\n")
.replace("\t", "\\t")
.replace("\r", "\\r")
.replaceAll("(?<!\\\\)\"", "\\\\\"");
return escapeUnsafeCharacters(partiallyEscaped);
return escapeText(value);
}
@Override

View File

@@ -795,7 +795,7 @@ public abstract class AbstractFSharpCodegen extends DefaultCodegen implements Co
}
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
String _default = String.valueOf(p.getDefault());
String _default = (String) p.getDefault();
if (p.getEnum() == null) {
return "\"" + _default + "\"";
} else {
@@ -1133,7 +1133,5 @@ public abstract class AbstractFSharpCodegen extends DefaultCodegen implements Co
}
@Override
public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.F_SHARP;
}
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.F_SHARP; }
}

View File

@@ -83,7 +83,6 @@ 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 AUTOSET_CONSTANTS = "autosetConstants";
public static final String JAVAX_PACKAGE = "javaxPackage";
public static final String USE_JAKARTA_EE = "useJakartaEe";
public static final String CONTAINER_DEFAULT_TO_NULL = "containerDefaultToNull";
@@ -138,7 +137,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
protected AnnotationLibrary annotationLibrary;
protected boolean implicitHeaders = false;
protected String implicitHeadersRegex = null;
protected boolean autosetConstants = false;
protected boolean camelCaseDollarSign = false;
protected boolean useJakartaEe = false;
protected boolean containerDefaultToNull = false;
@@ -565,10 +563,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.setImplicitHeadersRegex(additionalProperties.get(IMPLICIT_HEADERS_REGEX).toString());
}
if (additionalProperties.containsKey(AUTOSET_CONSTANTS)) {
this.setAutosetConstants(Boolean.parseBoolean(additionalProperties.get(AUTOSET_CONSTANTS).toString()));
}
if (additionalProperties.containsKey(CAMEL_CASE_DOLLAR_SIGN)) {
this.setCamelCaseDollarSign(Boolean.parseBoolean(additionalProperties.get(CAMEL_CASE_DOLLAR_SIGN).toString()));
}
@@ -1068,7 +1062,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
} else { // has default value
return toArrayDefaultValue(cp, schema);
}
} else if (ModelUtils.isMapSchema(schema) && !(ModelUtils.isComposedSchema(schema))) {
} else if (ModelUtils.isMapSchema(schema) && !(schema instanceof ComposedSchema)) {
if (schema.getProperties() != null && schema.getProperties().size() > 0) {
// object is complex object with free-form additional properties
if (schema.getDefault() != null) {
@@ -1355,7 +1349,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (example == null) {
example = "null";
} else if (Boolean.TRUE.equals(p.isArray)) {
if (p.items != null && p.items.defaultValue != null) {
if (p.items.defaultValue != null) {
String innerExample;
if ("String".equals(p.items.dataType)) {
innerExample = "\"" + p.items.defaultValue + "\"";
@@ -1584,7 +1579,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
op.vendorExtensions.put("x-java-import", operationImports);
handleImplicitHeaders(op);
handleConstantParams(op);
}
return objs;
@@ -1652,11 +1646,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
.map(Schema::getProperties))
.forEach(schemas -> schemas.replaceAll(
(name, s) -> Stream.of(s)
.filter(schema -> ModelUtils.isComposedSchema((Schema) schema))
//.map(schema -> (ComposedSchema) schema)
.filter(schema -> Objects.nonNull(((Schema) schema).getAnyOf()))
.flatMap(schema -> ((Schema) schema).getAnyOf().stream())
.filter(schema -> Objects.nonNull(((Schema) schema).getEnum()))
.filter(schema -> schema instanceof ComposedSchema)
.map(schema -> (ComposedSchema) schema)
.filter(schema -> Objects.nonNull(schema.getAnyOf()))
.flatMap(schema -> schema.getAnyOf().stream())
.filter(schema -> Objects.nonNull(schema.getEnum()))
.findFirst()
.orElse((Schema) s)));
}
@@ -2059,10 +2053,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.implicitHeadersRegex = implicitHeadersRegex;
}
public void setAutosetConstants(boolean autosetConstants) {
this.autosetConstants = autosetConstants;
}
public void setCamelCaseDollarSign(boolean camelCaseDollarSign) {
this.camelCaseDollarSign = camelCaseDollarSign;
}
@@ -2305,45 +2295,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
operation.hasParams = !operation.allParams.isEmpty();
}
/**
* This method removes all constant Query, Header and Cookie Params from allParams and sets them as constantParams in the CodegenOperation.
* The definition of constant is single valued required enum params.
* The constantParams in the the generated code should be hardcoded to the constantValue if autosetConstants feature is enabled.
*
* @param operation - operation to be processed
*/
protected void handleConstantParams(CodegenOperation operation) {
if (!autosetConstants || operation.allParams.isEmpty()) {
return;
}
final ArrayList<CodegenParameter> copy = new ArrayList<>(operation.allParams);
// Remove all params from Params, Non constant params will be added back later.
operation.allParams.clear();
// Finds all constant params, removes them from allParams and adds them to constant params.
// Also, adds back non constant params to allParams.
for (CodegenParameter p : copy) {
if (p.isEnum && p.required && p._enum != null && p._enum.size() == 1) {
// Add to constantParams for use in the code generation templates.
operation.constantParams.add(p);
if(p.isQueryParam) {
operation.queryParams.removeIf(param -> param.baseName.equals(p.baseName));
}
if(p.isHeaderParam) {
operation.headerParams.removeIf(param -> param.baseName.equals(p.baseName));
}
if(p.isCookieParam) {
operation.cookieParams.removeIf(param -> param.baseName.equals(p.baseName));
}
LOGGER.info("Update operation [{}]. Remove parameter [{}] because it can only have a fixed value of [{}]", operation.operationId, p.baseName, p._enum.get(0));
} else {
// Add back to allParams as the param is not a constant.
operation.allParams.add(p);
}
}
operation.hasParams = !operation.allParams.isEmpty();
}
private boolean shouldBeImplicitHeader(CodegenParameter parameter) {
return StringUtils.isNotBlank(implicitHeadersRegex) && parameter.baseName.matches(implicitHeadersRegex);
}

View File

@@ -1143,7 +1143,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
* ModelUtils.isMapSchema
* In other generators, isMap is true for all type object schemas
*/
if (schema.getProperties() != null || schema.getRequired() != null && !(ModelUtils.isComposedSchema(schema))) {
if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) {
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null);
}

View File

@@ -454,10 +454,6 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
this.srcBasePath = srcBasePath;
}
public void setTestBasePath(String testBasePath) {
this.testBasePath = testBasePath;
}
public void setParameterNamingConvention(String variableNamingConvention) {
this.variableNamingConvention = variableNamingConvention;
}

View File

@@ -353,7 +353,7 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
// correct "&#39;"s into "'"s after toString()
if (ModelUtils.isStringSchema(schema) && schema.getDefault() != null && !ModelUtils.isDateSchema(schema) && !ModelUtils.isDateTimeSchema(schema)) {
example = String.valueOf(schema.getDefault());
example = (String) schema.getDefault();
}
if (StringUtils.isNotBlank(example) && !"null".equals(example)) {
@@ -529,7 +529,7 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
}
example += ")";
} else {
LOGGER.debug("Type {} not handled properly in toExampleValue", schema.getType());
LOGGER.warn("Type {} not handled properly in toExampleValue", schema.getType());
}
if (ModelUtils.isStringSchema(schema)) {
@@ -591,7 +591,7 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
// type is a model class, e.g. User
example = this.packageName + "." + type + "()";
} else {
LOGGER.debug("Type {} not handled properly in setParameterExampleValue", type);
LOGGER.warn("Type {} not handled properly in setParameterExampleValue", type);
}
if (example == null) {
@@ -1747,7 +1747,6 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
hasModelsToImport = false;
boolean importAnnotated = false;
TreeSet<String> typingImports = new TreeSet<>();
TreeSet<String> pydanticImports = new TreeSet<>();
TreeSet<String> datetimeImports = new TreeSet<>();
@@ -1808,7 +1807,6 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
param.vendorExtensions.put("x-py-typing", typing);
} else {
param.vendorExtensions.put("x-py-typing", String.format(Locale.ROOT, "Annotated[%s, %s]", typing, fieldCustomization));
importAnnotated = true;
}
}
@@ -1840,12 +1838,6 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
List<Map<String, String>> newImports = new ArrayList<>();
if (importAnnotated) {
Map<String, String> item = new HashMap<>();
item.put("import", String.format(Locale.ROOT, String.format(Locale.ROOT, "from typing_extensions import Annotated")));
newImports.add(item);
}
// need datetime import
if (!datetimeImports.isEmpty()) {
Map<String, String> item = new HashMap<>();
@@ -1981,17 +1973,4 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
public String toEnumDefaultValue(String value, String datatype) {
return value;
}
/**
* checks if the data should be classified as "string" in enum
* e.g. double in C# needs to be double-quoted (e.g. "2.8") by treating it as a string
* In the future, we may rename this function to "isEnumString"
*
* @param dataType data type
* @return true if it's a enum string
*/
@Override
public boolean isDataTypeString(String dataType) {
return "str".equals(dataType);
}
}

View File

@@ -16,9 +16,17 @@
package org.openapitools.codegen.languages;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
@@ -61,8 +69,6 @@ import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.security.SecurityScheme;
import static org.openapitools.codegen.utils.StringUtils.*;
public abstract class AbstractPythonConnexionServerCodegen extends AbstractPythonCodegen implements CodegenConfig {
private static class PythonBooleanSerializer extends JsonSerializer<Boolean> {
@Override
@@ -172,7 +178,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
cliOptions.add(new CliOption(USE_PYTHON_SRC_ROOT_IN_IMPORTS, "include pythonSrcRoot in import namespaces.").
defaultValue("false"));
cliOptions.add(new CliOption(MOVE_TESTS_UNDER_PYTHON_SRC_ROOT, "generates test under the pythonSrcRoot folder.")
.defaultValue("false"));
.defaultValue("false"));
}
protected void addSupportingFiles() {
@@ -327,6 +333,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
}
@Override
public String toApiTestFilename(String name) {
return "test_" + toApiFilename(name);
@@ -629,6 +636,12 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
postProcessPattern(property.pattern, property.vendorExtensions);
}
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
// process enum in models
return postProcessModelsEnum(objs);
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> result = super.postProcessAllModels(objs);

View File

@@ -204,20 +204,6 @@ abstract public class AbstractRubyCodegen extends DefaultCodegen implements Code
return addRegularExpressionDelimiter(pattern);
}
@Override
public String addRegularExpressionDelimiter(String pattern) {
if (StringUtils.isEmpty(pattern)) {
return pattern;
}
if (!pattern.matches("^/.*")) {
// Perform a negative lookbehind on each `/` to ensure that it is escaped.
return "/" + pattern.replaceAll("(?<!\\\\)\\/", "\\\\/") + "/";
}
return pattern;
}
@Override
public String toParamName(String name) {
// obtain the name from parameterNameMapping directly if provided

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