Merge remote-tracking branch 'origin/master' into 7.0.x

This commit is contained in:
William Cheng
2022-07-19 11:54:20 +08:00
2800 changed files with 126318 additions and 33030 deletions

View File

@@ -16,5 +16,5 @@
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` (6.0.1) (patch release), `6.1.x` (breaking changes with fallbacks), `7.0.x` (breaking changes without fallbacks)
- [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (6.1.0) (minor release - breaking changes with fallbacks), `7.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

@@ -32,6 +32,7 @@ jobs:
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters
- samples/openapi3/client/petstore/java/jersey2-java8
- samples/client/petstore/java/okhttp-gson
- samples/client/petstore/java/okhttp-gson-group-parameter
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3

View File

@@ -5,10 +5,12 @@ on:
paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
pull_request:
paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
jobs:
build:
name: Build .Net projects
@@ -21,6 +23,7 @@ jobs:
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0-nrt
- samples/server/petstore/aspnetcore-6.0
- samples/server/petstore/aspnetcore-6.0-pocoModels
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v2

43
.github/workflows/samples-jdk17.yaml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Samples JDK17
on:
push:
paths:
# clients
- samples/openapi3/client/petstore/spring-cloud-3
# servers
- samples/openapi3/server/petstore/springboot-3
pull_request:
paths:
# clients
- samples/openapi3/client/petstore/spring-cloud-3
# servers
- samples/openapi3/server/petstore/springboot-3
jobs:
build:
name: Build with JDK17
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# clients
- samples/openapi3/client/petstore/spring-cloud-3
# servers
- samples/openapi3/server/petstore/springboot-3
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
- name: Cache maven dependencies
uses: actions/cache@v3
env:
cache-name: maven-repository
with:
path: |
~/.m2
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package

32
.github/workflows/samples-php7.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Samples PHP 7.x
on:
push:
paths:
- samples/server/petstore/php-laravel/lib/
pull_request:
paths:
- samples/server/petstore/php-laravel/lib/
jobs:
build:
name: Build PHP projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# servers
- samples/server/petstore/php-laravel/lib/
steps:
- uses: actions/checkout@v3
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
tools: php-cs-fixer, phpunit
- name: composer install
working-directory: ${{ matrix.sample }}
run: composer install
- name: phpunit
working-directory: ${{ matrix.sample }}
run: vendor/bin/phpunit

32
.github/workflows/samples-php8.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Samples PHP 8.x
on:
push:
paths:
- samples/server/petstore/php-symfony/SymfonyBundle-php/
pull_request:
paths:
- samples/server/petstore/php-symfony/SymfonyBundle-php/
jobs:
build:
name: Build PHP projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# servers
- samples/server/petstore/php-symfony/SymfonyBundle-php/
steps:
- uses: actions/checkout@v3
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: php-cs-fixer, phpunit
- name: composer install
working-directory: ${{ matrix.sample }}
run: composer install
- name: phpunit
working-directory: ${{ matrix.sample }}
run: vendor/bin/phpunit

View File

@@ -40,6 +40,7 @@ jobs:
- samples/server/petstore/spring-boot-nullable-set
- samples/server/petstore/spring-boot-defaultInterface-unhandledException
- samples/openapi3/server/petstore/spring-boot-oneof
- samples/server/petstore/springboot-virtualan
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3

5
.gitignore vendored
View File

@@ -222,6 +222,8 @@ samples/server/petstore/haskell-yesod/stack.yaml.lock
.Rproj.user
samples/client/petstore/R/**/petstore.Rcheck/
samples/client/petstore/R/**/*.tar.gz
samples/client/petstore/R/R.Rproj
samples/client/petstore/R/man/
# elixir
samples/client/petstore/elixir/_build/
@@ -266,3 +268,6 @@ samples/client/petstore/crystal/lib
# Go
samples/openapi3/client/petstore/go/privatekey.pem
## OCaml
samples/client/petstore/ocaml/_build/

137
.gitpod.yml Normal file
View File

@@ -0,0 +1,137 @@
## Learn more about this file at 'https://www.gitpod.io/docs/references/gitpod-yml'
##
## This '.gitpod.yml' file when placed at the root of a project instructs
## Gitpod how to prepare & build the project, start development environments
## and configure continuous prebuilds. Prebuilds when enabled builds a project
## like a CI server so you can start coding right away - no more waiting for
## dependencies to download and builds to finish when reviewing pull-requests
## or hacking on something new.
##
## With Gitpod you can develop software from any device (even iPads) via
## desktop or browser based versions of VS Code or any JetBrains IDE and
## customise it to your individual needs - from themes to extensions, you
## have full control.
##
## The easiest way to try out Gitpod is install the browser extenion:
## 'https://www.gitpod.io/docs/browser-extension' or by prefixing
## 'https://gitpod.io#' to the source control URL of any project.
##
## For example: 'https://gitpod.io#https://github.com/gitpod-io/gitpod'
## The 'image' section defines which Docker image Gitpod should use.
## By default, Gitpod uses a standard Docker Image called 'workspace-full'
## which can be found at 'https://github.com/gitpod-io/workspace-images'
##
## Workspaces started based on this default image come pre-installed with
## Docker, Go, Java, Node.js, C/C++, Python, Ruby, Rust, PHP as well as
## tools such as Homebrew, Tailscale, Nginx and several more.
##
## If this image does not include the tools needed for your project then
## a public Docker image or your own Docker file can be configured.
##
## Learn more about images at 'https://www.gitpod.io/docs/config-docker'
#image: node:buster # use 'https://hub.docker.com/_/node'
#
#image: # leave image undefined if using a Dockerfile
# file: .gitpod.Dockerfile # relative path to the Dockerfile from the
# # root of the project
## The 'tasks' section defines how Gitpod prepares and builds this project
## or how Gitpod can start development servers. With Gitpod, there are three
## types of tasks:
##
## - before: Use this for tasks that need to run before init and before command.
## - init: Use this to configure prebuilds of heavy-lifting tasks such as
## downloading dependencies or compiling source code.
## - command: Use this to start your database or application when the workspace starts.
##
## Learn more about these tasks at 'https://www.gitpod.io/docs/config-start-tasks'
#tasks:
# - before: |
# # commands to execute...
#
# - init: |
# # sudo apt-get install python3 # can be used to install operating system
# # dependencies but these are not kept after the
# # prebuild completes thus Gitpod recommends moving
# # operating system dependency installation steps
# # to a custom Dockerfile to make prebuilds faster
# # and to keep your codebase DRY.
# # 'https://www.gitpod.io/docs/config-docker'
#
# # pip install -r requirements.txt # install codebase dependencies
# # cmake # precompile codebase
#
# - name: Web Server
# openMode: split-left
# env:
# WEBSERVER_PORT: 8080
# command: |
# python3 -m http.server $WEBSERVER_PORT
#
# - name: Web Browser
# openMode: split-right
# env:
# WEBSERVER_PORT: 8080
# command: |
# gp await-port $WEBSERVER_PORT
# lynx `gp url`
tasks:
- init: ./mvnw package -DskipTests
## The 'ports' section defines various ports your may listen on are
## configured in Gitpod on an authenticated URL. By default, all ports
## are in private visibility state.
##
## Learn more about ports at 'https://www.gitpod.io/docs/config-ports'
#ports:
# - port: 8080 # alternatively configure entire ranges via '8080-8090'
# visibility: private # either 'public' or 'private' (default)
# onOpen: open-browser # either 'open-browser', 'open-preview' or 'ignore'
## The 'vscode' section defines a list of Visual Studio Code extensions from
## the OpenVSX.org registry to be installed upon workspace startup. OpenVSX
## is an open alternative to the proprietary Visual Studio Code Marketplace
## and extensions can be added by sending a pull-request with the extension
## identifier to https://github.com/open-vsx/publish-extensions
##
## The identifier of an extension is always ${publisher}.${name}.
##
## For example: 'vscodevim.vim'
##
## Learn more at 'https://www.gitpod.io/docs/ides-and-editors/vscode'
vscode:
extensions:
- redhat.java
- vscjava.vscode-java-pack
## The 'github' section defines configuration of continuous prebuilds
## for GitHub repositories when the GitHub application
## 'https://github.com/apps/gitpod-io' is installed in GitHub and granted
## permissions to access the repository.
##
## Learn more at 'https://www.gitpod.io/docs/prebuilds'
github:
prebuilds:
# enable for the default branch
master: true
# enable for all branches in this repo
branches: true
# enable for pull requests coming from this repo
pullRequests: true
# enable for pull requests coming from forks
pullRequestsFromForks: true
# add a check to pull requests
addCheck: true
# add a "Review in Gitpod" button as a comment to pull requests
addComment: true
# add a "Review in Gitpod" button to the pull request's description
addBadge: false

View File

@@ -111,11 +111,9 @@ before_install:
- cmake --version
# install Qt5
#- sudo apt install -y --no-install-recommends qt5-default
# -- skip perl test to shorten build time
# perl dep
#- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
#- cpanm --quiet --no-interactive Test::Exception Test::More Log::Any LWP::UserAgent URI::Query Module::Runtime DateTime Module::Find Moose::Role JSON || echo "Ignored failure from cpanm"
# -- skip perl test end
- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
- cpanm --quiet --no-interactive Test::Exception Test::More Log::Any LWP::UserAgent URI::Query Module::Runtime DateTime Module::Find Moose::Role JSON || echo "Ignored failure from cpanm"
# show host table to confirm petstore.swagger.io is mapped to localhost
- cat /etc/hosts
# show java version

View File

@@ -80,6 +80,7 @@ elif [ "$NODE_INDEX" = "4" ]; then
#mvn --no-snapshot-updates --quiet verify -Psamples.circleci.node4 -Dorg.slf4j.simpleLogger.defaultLogLevel=error
(cd samples/openapi3/client/petstore/python && make test)
(cd samples/openapi3/client/petstore/python-experimental && make test)
(cd samples/openapi3/client/3_0_3_unit_test/python-experimental && make test)
else
echo "Running node $NODE_INDEX to test 'samples.circleci.others' defined in pom.xml ..."

View File

@@ -3,25 +3,19 @@
<div align="center">
[![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22) [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE) [![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator) [![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g) [![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator)
[![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22) [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE) [![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator) [![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g) [![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator) [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/OpenAPITools/openapi-generator)
</div>
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.0.1`):
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.1.0`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![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)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/openapitools/openapi-generator/Check%20Supported%20Java%20Versions/master?label=Check%20Supported%20Java%20Versions&logo=github&logoColor=green)](https://github.com/OpenAPITools/openapi-generator/actions?query=workflow%3A%22Check+Supported+Java+Versions%22)
[6.1.x](https://github.com/OpenAPITools/openapi-generator/tree/6.1.x) (`6.1.x`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/6.1.x.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/6.1.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=6.1.x&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/6.1.x?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
[7.0.x](https://github.com/OpenAPITools/openapi-generator/tree/7.0.x) (`7.0.x`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/7.0.x.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/7.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
@@ -119,9 +113,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.0-SNAPSHOT/) | Feb/Mar 2023 | Major release with breaking changes (no fallback) |
| 6.1.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.1.0-SNAPSHOT/) | 26.07 2022 | Minor release with breaking changes (with fallbac) |
| 6.0.1 (upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.0.1-SNAPSHOT/) | 26.06 2022 | Patch release (enhancements, bug fixes, etc) |
| [6.0.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.0.0) (latest stable release) | 26.05.2022 | Major release with breaking changes (no fallback) |
| 6.1.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.1.0-SNAPSHOT/) | 03.08 2022 | Minor release with breaking changes (with fallback) |
| [6.0.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.0.1) (latest stable release) | 03.07.2022 | Patch release (enhancements, bug fixes, etc) |
| [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) |
@@ -179,16 +172,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 8 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar`
For **Mac/Linux** users:
```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.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/6.0.0/openapi-generator-cli-6.0.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -413,7 +406,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli"
```sh
openapi-generator-cli version-manager set 6.0.0
openapi-generator-cli version-manager set 6.0.1
```
Or install it as dev-dependency:
@@ -437,7 +430,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/6.0.0/openapi-generator-cli-6.0.0.jar)
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.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`
@@ -578,6 +571,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Aalborg University](https://www.aau.dk)
- [Adaptant Solutions AG](https://www.adaptant.io/)
- [adesso SE](https://www.adesso.de/)
- [Adyen](https://www.adyen.com/)
- [Agoda](https://www.agoda.com/)
- [Airthings](https://www.airthings.com/)
- [Allianz](https://www.allianz.com)
@@ -614,6 +608,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Element AI](https://www.elementai.com/)
- [Embotics](https://www.embotics.com/)
- [emineo](https://www.emineo.ch)
- [fastly](https://www.fastly.com/)
- [Fenergo](https://www.fenergo.com/)
- [freee](https://corp.freee.co.jp/en/)
- [FreshCells](https://www.freshcells.de/)
@@ -621,6 +616,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Gantner](https://www.gantner.com)
- [GenFlow](https://github.com/RepreZen/GenFlow)
- [GetYourGuide](https://www.getyourguide.com/)
- [Glovo](https://glovoapp.com/)
- [GMO Pepabo](https://pepabo.com/en/)
- [GoDaddy](https://godaddy.com)
- [Gumtree](https://gumtree.com)
@@ -868,6 +864,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2022-04-01 - [OpenAPI Generatorのコード生成とSpring Frameworkのカスタムデータバインディングを共存させる](https://techblog.zozo.com/entry/coexistence-of-openapi-and-spring) in [ZOZO Tech Blog](https://techblog.zozo.com/)
- 2022-04-06 - [Effective Software Development using OpenAPI Generator](https://apexlabs.ai/post/openapi-generator) by Ajil Oommen (Senior Flutter Developer)
- 2022-05-13 - [A Path From an API To Client Libraries](https://www.youtube.com/watch?v=XC8oVn_efTw) by [Filip Srnec](https://www.devoxx.co.uk/talk/?id=11211) at Infobip
- 2022-06-01 - [API First, using OpenAPI and Spring Boot](https://medium.com/xgeeks/api-first-using-openapi-and-spring-boot-2602c04bb0d3) by [Micael Estrázulas Vianna](https://estrazulas.medium.com/)
## [6 - About Us](#table-of-contents)

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-3.0
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-3.1
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-5.0
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -0,0 +1,9 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-6.0-pocoModels
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'
aspnetCoreVersion: "6.0"
userSecretsGuid: 'cb87e868-8646-48ef-9bb6-344b537d0d37'
pocoModels: true

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-6.0
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -0,0 +1,10 @@
generatorName: java
outputDir: samples/client/petstore/java/okhttp-gson-group-parameter
library: okhttp-gson
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/petstore-group-parameter.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-okhttp-gson-group-parameter
hideGenerationTimestamp: "true"
disallowAdditionalPropertiesIfNotPresent: false
useSingleRequestParameter: true

View File

@@ -0,0 +1,9 @@
generatorName: kotlin
outputDir: samples/client/petstore/kotlin-allOff-discriminator
inputSpec: modules/openapi-generator/src/test/resources/3_0/issue_10792.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
additionalProperties:
artifactId: kotlin-allOff-discriminator
serializableModel: "false"
dateLibrary: java8
enumUnknownDefaultCase: true

View File

@@ -1,6 +1,6 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v2/default
outputDir: samples/client/petstore/typescript-angular/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: "2"
ngVersion: 13.3.2

View File

@@ -1,10 +1,10 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v4.3/npm
outputDir: samples/client/petstore/typescript-angular/npm
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
npmVersion: 0.0.1
ngVersion: "4.3"
ngVersion: 13.3.2
npmName: '@openapitools/angular2-typescript-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,7 +1,7 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v2/with-interfaces
outputDir: samples/client/petstore/typescript-angular/with-interfaces
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
withInterfaces: "true"
ngVersion: "2"
ngVersion: 13.3.2

View File

@@ -2,3 +2,5 @@ generatorName: php-laravel
outputDir: samples/server/petstore/php-laravel
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/php-laravel
gitUserId: openapitools
gitRepoId: petstore

View File

@@ -2,3 +2,5 @@ generatorName: php-symfony
outputDir: samples/server/petstore/php-symfony/SymfonyBundle-php
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/php-symfony
gitUserId: openapitools
gitRepoId: petstore

View File

@@ -0,0 +1,6 @@
generatorName: python-experimental
outputDir: samples/openapi3/client/3_0_3_unit_test/python-experimental
inputSpec: modules/openapi-generator/src/test/resources/3_0/unit_test_spec/3_0_3_unit_test_spec.yaml
templateDir: modules/openapi-generator/src/main/resources/python-experimental
additionalProperties:
packageName: unit_test_api

View File

@@ -5,3 +5,7 @@ templateDir: modules/openapi-generator/src/main/resources/r
httpUserAgent: PetstoreAgent
additionalProperties:
packageName: petstore
exceptionPackage: rlang
useRlangExceptionHandling: true
returnExceptionOnFailure: true
errorObjectType: "ModelApiResponse"

View File

@@ -1,7 +1,7 @@
generatorName: rust
outputDir: samples/client/petstore/rust/hyper/petstore
library: hyper
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
supportAsync: "false"

View File

@@ -1,7 +1,7 @@
generatorName: rust
outputDir: samples/client/petstore/rust/reqwest/petstore
library: reqwest
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties:
supportAsync: false

View File

@@ -0,0 +1,12 @@
generatorName: spring
outputDir: samples/openapi3/server/petstore/springboot-3
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties:
groupId: org.openapitools.openapi3
documentationProvider: springdoc
artifactId: springboot
snapshotVersion: "true"
useSpringBoot3: true
useBeanValidation: true
hideGenerationTimestamp: "true"

View File

@@ -4,7 +4,7 @@ library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties:
documentationProvider: springfox
documentationProvider: springdoc
apiPackage: org.openapitools.virtualan.api
modelPackage: org.openapitools.virtualan.model
virtualService: true

View File

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

View File

@@ -1,10 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v10-provided-in-root/builds/with-npm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 10.0.0
npmVersion: 1.0.0
npmName: '@openapitools/typescript-angular-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,10 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v11-provided-in-root/builds/with-npm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 11.0.0
npmVersion: 1.0.0
npmName: '@openapitools/typescript-angular-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,6 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v11-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 11.0.0

View File

@@ -1,6 +1,6 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v11-oneOf/builds/default
outputDir: samples/client/petstore/typescript-angular-v12-oneOf/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 11.0.0
ngVersion: 12.2.0

View File

@@ -1,7 +1,7 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v9-provided-in-any/builds/default
outputDir: samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 9.0.0
ngVersion: 12.2.0
providedIn: any

View File

@@ -0,0 +1,6 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v13-oneOf/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 13.0.1

View File

@@ -1,6 +1,7 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v10-provided-in-root/builds/default
outputDir: samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 10.0.0
ngVersion: 13.0.1
providedIn: any

View File

@@ -1,10 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v9-provided-in-root/builds/with-npm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 9.0.0
npmVersion: 1.0.0
npmName: '@openapitools/typescript-angular-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,6 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v9-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 9.0.0

View File

@@ -53,9 +53,7 @@ if [[ ${#files[@]} -eq 1 && "${files[0]}" != *'*'* ]]; then
java ${JAVA_OPTS} -jar "$executable" generate -c ${files[0]} ${args[@]}
else
echo "Please press CTRL+C to stop or the script will continue in 5 seconds."
sleep 5
if [ ${#files[@]} -eq 0 ]; then
files=("${root}"/bin/configs/*.yaml)
fi

View File

@@ -394,3 +394,51 @@ or
```
--import-mappings Pet=my.models.MyPet --import-mappings Order=my.models.MyOrder
```
## Schema Mapping
One can map the schema to someting else (e.g. external objects/models outside of the package) using the `schemaMappings` option, e.g. in CLI
```sh
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/type-alias.yaml -o /tmp/java2/ --schema-mapping TypeAlias=foo.bar.TypeAlias
```
Another example (in conjunction with --type-mappings):
```sh
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i /tmp/alias.yaml -o /tmp/alias/ --schema-mappings stream=org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody --type-mappings string+binary=stream
```
while /tmp/alias.yaml is as follows:
```yaml
openapi: 3.0.3
info:
title: Demo app
version: 1.0.0
servers:
- url: /api/v1
paths:
/demo:
get:
summary: Demo
operationId: demo
responses:
'200':
description: Demo response
content:
text/csv:
schema:
type: string
format: binary
```
## Inline Schema Naming
Inline schemas are created as separate schemas automatically and the auto-generated schema name may not look good to everyone. One can customize the name using the `title` field or the `inlineSchemaNameMapping` option, e.g. in CLI
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/inline_model_resolver.yaml -o /tmp/java3/ --skip-validate-spec --inline-schema-name-mappings inline_object_2=SomethingMapped,inline_object_4=nothing_new
```
Another useful option is `inlineSchemaNameDefaults`, which allows you to customize the suffix of the auto-generated inline schema name, e.g. in CLI
```
--inline-schema-name-defaults arrayItemSuffix=_array_item
```
Note: Only arrayItemSuffix, mapItemSuffix are supported at the moment.

View File

@@ -41,6 +41,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|packageName|C# package name (convention: Title.Case).| |Org.OpenAPITools|
|packageTitle|Specifies an AssemblyTitle for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |OpenAPI Library|
|packageVersion|C# package version.| |1.0.0|
|pocoModels|Build POCO Models| |false|
|returnICollection|Return ICollection&lt;T&gt; instead of the concrete type.| |false|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src|

View File

@@ -38,6 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Imports |
| ---------- | ------- |
|OAIHttpFileElement|#include &quot;OAIHttpFileElement.h&quot;|
|QJsonValue|#include &lt;QJsonValue&gt;|
## INSTANTIATION TYPES

View File

@@ -54,6 +54,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>TArray</li>
<li>TArray&lt;uint8&gt;</li>
<li>TMap</li>
<li>TSet</li>
<li>TSharedPtr&lt;FJsonObject&gt;</li>
<li>TSharedPtr&lt;FJsonValue&gt;</li>
<li>bool</li>

View File

@@ -29,6 +29,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|serveStatic|serve will serve files from the directory 'static'.| |true|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|useCustomMonad|use a custom monad instead of the default Handler| |false|
## IMPORT MAPPING
@@ -195,7 +196,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|BasicAuth|✓|OAS2,OAS3
|ApiKey|✓|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken||OAS3
|BearerToken||OAS3
|OAuth2_Implicit|✓|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3

View File

@@ -80,7 +80,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false|
|singleContentTypes|Whether to select only one produces/consumes content-type by operation.| |false|
|skipDefaultInterface|Whether to generate default implementations for java8 interfaces| |false|
|skipDefaultInterface|Whether to skip generation of default implementations for java8 interfaces| |false|
|snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
@@ -91,6 +91,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useOptional|Use Optional container for optional parameters| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).| |true|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false|

View File

@@ -85,6 +85,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson support this option.| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS

View File

@@ -26,10 +26,12 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|generateRoomModels|Generate Android Room database models in addition to API models (JVM Volley library only)| |false|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|idea|Add IntellJ Idea plugin and mark Kotlin main and test folders as source folders.| |false|
|library|Library template (sub-template) to use|<dl><dt>**jvm-ktor**</dt><dd>Platform: Java Virtual Machine. HTTP client: Ktor 1.6.7. JSON processing: Gson, Jackson (default).</dd><dt>**jvm-okhttp4**</dt><dd>[DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0.</dd><dt>**jvm-okhttp3**</dt><dd>Platform: Java Virtual Machine. HTTP client: OkHttp 3.12.4 (Android 2.3+ and Java 7+). JSON processing: Moshi 1.8.0.</dd><dt>**jvm-retrofit2**</dt><dd>Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2.</dd><dt>**multiplatform**</dt><dd>Platform: Kotlin multiplatform. HTTP client: Ktor 1.6.7. JSON processing: Kotlinx Serialization: 1.2.1.</dd><dt>**jvm-volley**</dt><dd>Platform: JVM for Android. HTTP client: Volley 1.2.1. JSON processing: gson 2.8.9</dd></dl>|jvm-okhttp4|
|modelMutable|Create mutable models| |false|
|moshiCodeGen|Whether to enable codegen with the Moshi library. Refer to the [official Moshi doc](https://github.com/square/moshi#codegen) for more info.| |false|
|omitGradlePluginVersions|Whether to declare Gradle plugin versions in build files.| |false|
|omitGradleWrapper|Whether to omit Gradle wrapper for creating a sub project.| |false|
|packageName|Generated artifact package name.| |org.openapitools.client|
|parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null|
|requestDateConverter|JVM-Option. Defines in how to handle date-time objects that are used for a request (as query or parameter)|<dl><dt>**toJson**</dt><dd>[DEFAULT] Date formatter option using a json converter.</dd><dt>**toString**</dt><dd>Use the 'toString'-method of the date-time object to retrieve the related string representation.</dd></dl>|toJson|

View File

@@ -41,7 +41,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<ul class="column-ul">
<li>ARRAY</li>
<li>DateTime</li>
<li>DATE</li>
<li>DATE_TIME</li>
<li>HASH</li>
<li>boolean</li>
<li>double</li>

View File

@@ -18,6 +18,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|errorObjectType|Error object type.| |null|
|exceptionPackage|Specify the exception handling package|<dl><dt>**default**</dt><dd>Use stop() for raising exceptions.</dd><dt>**rlang**</dt><dd>Use rlang package for exceptions.</dd></dl>|default|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|packageName|R package name (convention: lowercase).| |openapi|

View File

@@ -18,11 +18,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|bestFitInt|Use best fitting integer type where minimum or maximum is set| |false|
|enumNameSuffix|Suffix that will be appended to all enum names.| ||
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|library|library template (sub-template) to use.|<dl><dt>**hyper**</dt><dd>HTTP client: Hyper.</dd><dt>**reqwest**</dt><dd>HTTP client: Reqwest.</dd></dl>|reqwest|
|packageName|Rust package name (convention: lowercase).| |openapi|
|packageVersion|Rust package version.| |1.0.0|
|preferUnsignedInt|Prefer unsigned integers where minimum value is &gt;= 0| |false|
|supportAsync|If set, generate async function call instead. This option is for 'reqwest' library only| |true|
|supportMultipleResponses|If set, return type wraps an enum of all possible 2xx schemas. This option is for 'reqwest' library only| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|

View File

@@ -73,7 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false|
|singleContentTypes|Whether to select only one produces/consumes content-type by operation.| |false|
|skipDefaultInterface|Whether to generate default implementations for java8 interfaces| |false|
|skipDefaultInterface|Whether to skip generation of default implementations for java8 interfaces| |false|
|snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
@@ -84,6 +84,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useOptional|Use Optional container for optional parameters| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).| |true|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false|

View File

@@ -53,6 +53,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null|
|useBacktickEscapes|Escape reserved words using backticks (default: false)| |false|
|useClasses|Use final classes for models instead of structs (default: false)| |false|
|useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true|
|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null|
## IMPORT MAPPING

View File

@@ -103,18 +103,18 @@ docker run --rm \
<!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.3.0/openapi-generator-cli-5.3.0.jar`
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar`
For **Mac/Linux** users:
```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.3.0/openapi-generator-cli-5.3.0.jar -O openapi-generator-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.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.
```powershell
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.3.0/openapi-generator-cli-5.3.0.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar
```
<!-- /RELEASE_VERSION -->

View File

@@ -16,7 +16,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.1.0</version>
<version>6.0.0</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>

View File

@@ -71,9 +71,15 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
@Option(name = {"--import-mappings"}, title = "import mappings", description = "displays the default import mappings (types and aliases, and what imports they will pull into the template)")
private Boolean importMappings;
@Option(name = {"--schema-mappings"}, title = "schema mappings", description = "display the schema mappings (none)")
private Boolean schemaMappings;
@Option(name = {"--inline-schema-name-mappings"}, title = "inline schema name mappings", description = "displays the inline schema name mappings (none)")
private Boolean inlineSchemaNameMappings;
@Option(name = {"--inline-schema-name-defaults"}, title = "inline schema name defaults", description = "default values used when naming inline schema name")
private Boolean inlineSchemaNameDefaults;
@Option(name = {"--metadata"}, title = "metadata", description = "displays the generator metadata like the help txt for the generator and generator type etc")
private Boolean metadata;
@@ -452,6 +458,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
sb.append(newline);
}
if (Boolean.TRUE.equals(schemaMappings)) {
sb.append(newline).append("SCHEMA MAPPING").append(newline).append(newline);
Map<String, String> map = config.schemaMapping()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b));
}, TreeMap::new));
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Scheme", "Mapped to");
sb.append(newline);
}
if (Boolean.TRUE.equals(inlineSchemaNameMappings)) {
sb.append(newline).append("INLINE SCHEMA NAME MAPPING").append(newline).append(newline);
Map<String, String> map = config.inlineSchemaNameMapping()
@@ -464,6 +482,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
sb.append(newline);
}
if (Boolean.TRUE.equals(inlineSchemaNameDefaults)) {
sb.append(newline).append("INLINE SCHEMA NAME DEFAULTS").append(newline).append(newline);
Map<String, String> map = config.inlineSchemaNameDefault()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b));
}, TreeMap::new));
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Inline scheme naming convention", "Defaulted to");
sb.append(newline);
}
if (Boolean.TRUE.equals(instantiationTypes)) {
sb.append(newline).append("INSTANTIATION TYPES").append(newline).append(newline);
Map<String, String> map = config.instantiationTypes()

View File

@@ -159,6 +159,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " You can also have multiple occurrences of this option.")
private List<String> importMappings = new ArrayList<>();
@Option(
name = {"--schema-mappings"},
title = "schema mappings",
description = "specifies mappings between the schema and the new name in the format of schema_a=Cat,schema_b=Bird."
+ " You can also have multiple occurrences of this option.")
private List<String> schemaMappings = new ArrayList<>();
@Option(
name = {"--inline-schema-name-mappings"},
title = "inline schema name mappings",
@@ -166,6 +173,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " You can also have multiple occurrences of this option.")
private List<String> inlineSchemaNameMappings = new ArrayList<>();
@Option(
name = {"--inline-schema-name-defaults"},
title = "inline schema name defaults",
description = "specifies the default values used when naming inline schema as such array items in the format of arrayItemSuffix=_inner,mapItemSuffix=_value. "
+ " ONLY arrayItemSuffix, mapItemSuffix at the moment.")
private List<String> inlineSchemaNameDefaults = new ArrayList<>();
@Option(
name = {"--server-variables"},
title = "server variables",
@@ -430,7 +444,9 @@ public class Generate extends OpenApiGeneratorCommand {
}
applyInstantiationTypesKvpList(instantiationTypes, configurator);
applyImportMappingsKvpList(importMappings, configurator);
applySchemaMappingsKvpList(schemaMappings, configurator);
applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator);
applyInlineSchemaNameDefaultsKvpList(inlineSchemaNameDefaults, configurator);
applyTypeMappingsKvpList(typeMappings, configurator);
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);

View File

@@ -50,7 +50,9 @@ public final class GeneratorSettings implements Serializable {
private final Map<String, String> typeMappings;
private final Map<String, Object> additionalProperties;
private final Map<String, String> importMappings;
private final Map<String, String> schemaMappings;
private final Map<String, String> inlineSchemaNameMappings;
private final Map<String, String> inlineSchemaNameDefaults;
private final Set<String> languageSpecificPrimitives;
private final Map<String, String> reservedWordsMappings;
private final Map<String, String> serverVariables;
@@ -235,6 +237,15 @@ public final class GeneratorSettings implements Serializable {
return importMappings;
}
/**
* Gets schema mappings between a schema and the new name.
*
* @return the schema mappings
*/
public Map<String, String> getSchemaMappings() {
return schemaMappings;
}
/**
* Gets inline schema name mappings between an inline schema name and the new name.
*
@@ -244,6 +255,15 @@ public final class GeneratorSettings implements Serializable {
return inlineSchemaNameMappings;
}
/**
* Gets inline schema name defaults between an inline schema naming convention and the default values.
*
* @return the inline schema name defaults
*/
public Map<String, String> getInlineSchemaNameDefaults() {
return inlineSchemaNameDefaults;
}
/**
* Gets language specific primitives. These are in addition to the "base" primitives defined in a generator.
* <p>
@@ -359,7 +379,9 @@ public final class GeneratorSettings implements Serializable {
instantiationTypes = Collections.unmodifiableMap(builder.instantiationTypes);
typeMappings = Collections.unmodifiableMap(builder.typeMappings);
importMappings = Collections.unmodifiableMap(builder.importMappings);
schemaMappings = Collections.unmodifiableMap(builder.schemaMappings);
inlineSchemaNameMappings = Collections.unmodifiableMap(builder.inlineSchemaNameMappings);
inlineSchemaNameDefaults = Collections.unmodifiableMap(builder.inlineSchemaNameDefaults);
languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives);
reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings);
serverVariables = Collections.unmodifiableMap(builder.serverVariables);
@@ -430,7 +452,9 @@ public final class GeneratorSettings implements Serializable {
typeMappings = Collections.unmodifiableMap(new HashMap<>(0));
additionalProperties = Collections.unmodifiableMap(new HashMap<>(0));
importMappings = Collections.unmodifiableMap(new HashMap<>(0));
schemaMappings = Collections.unmodifiableMap(new HashMap<>(0));
inlineSchemaNameMappings = Collections.unmodifiableMap(new HashMap<>(0));
inlineSchemaNameDefaults = Collections.unmodifiableMap(new HashMap<>(0));
languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0));
reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0));
serverVariables = Collections.unmodifiableMap(new HashMap<>(0));
@@ -482,9 +506,15 @@ public final class GeneratorSettings implements Serializable {
if (copy.getImportMappings() != null) {
builder.importMappings.putAll(copy.getImportMappings());
}
if (copy.getSchemaMappings() != null) {
builder.schemaMappings.putAll(copy.getSchemaMappings());
}
if (copy.getInlineSchemaNameMappings() != null) {
builder.inlineSchemaNameMappings.putAll(copy.getInlineSchemaNameMappings());
}
if (copy.getInlineSchemaNameDefaults() != null) {
builder.inlineSchemaNameDefaults.putAll(copy.getInlineSchemaNameDefaults());
}
if (copy.getLanguageSpecificPrimitives() != null) {
builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives());
}
@@ -524,7 +554,9 @@ public final class GeneratorSettings implements Serializable {
private Map<String, String> typeMappings;
private Map<String, Object> additionalProperties;
private Map<String, String> importMappings;
private Map<String, String> schemaMappings;
private Map<String, String> inlineSchemaNameMappings;
private Map<String, String> inlineSchemaNameDefaults;
private Set<String> languageSpecificPrimitives;
private Map<String, String> reservedWordsMappings;
private Map<String, String> serverVariables;
@@ -542,7 +574,9 @@ public final class GeneratorSettings implements Serializable {
typeMappings = new HashMap<>();
additionalProperties = new HashMap<>();
importMappings = new HashMap<>();
schemaMappings = new HashMap<>();
inlineSchemaNameMappings = new HashMap<>();
inlineSchemaNameDefaults = new HashMap<>();
languageSpecificPrimitives = new HashSet<>();
reservedWordsMappings = new HashMap<>();
serverVariables = new HashMap<>();
@@ -759,6 +793,32 @@ public final class GeneratorSettings implements Serializable {
return this;
}
/**
* Sets the {@code schemaMappings} and returns a reference to this Builder so that the methods can be chained together.
*
* @param schemaMappings the {@code schemaMappings} to set
* @return a reference to this Builder
*/
public Builder withSchemaMappings(Map<String, String> schemaMappings) {
this.schemaMappings = schemaMappings;
return this;
}
/**
* Sets a single {@code schemaMappings} and returns a reference to this Builder so that the methods can be chained together.
*
* @param key A key for some schema mapping
* @param value The value of some schema mapping
* @return a reference to this Builder
*/
public Builder withSchemaMapping(String key, String value) {
if (this.schemaMappings == null) {
this.schemaMappings = new HashMap<>();
}
this.schemaMappings.put(key, value);
return this;
}
/**
* Sets the {@code importMappings} and returns a reference to this Builder so that the methods can be chained together.
*
@@ -785,6 +845,32 @@ public final class GeneratorSettings implements Serializable {
return this;
}
/**
* Sets the {@code inlineSchemaNameDefaults} and returns a reference to this Builder so that the methods can be chained together.
*
* @param inlineSchemaNameDefaults the {@code inlineSchemaNameDefaults} to set
* @return a reference to this Builder
*/
public Builder withInlineSchemaNameDefaults(Map<String, String> inlineSchemaNameDefaults) {
this.inlineSchemaNameDefaults = inlineSchemaNameDefaults;
return this;
}
/**
* Sets a single {@code inlineSchemaNameDefaults} and returns a reference to this Builder so that the methods can be chained together.
*
* @param key Default naming convention
* @param value The value
* @return a reference to this Builder
*/
public Builder withInlineSchemaNameDefault(String key, String value) {
if (this.inlineSchemaNameDefaults == null) {
this.inlineSchemaNameDefaults = new HashMap<>();
}
this.inlineSchemaNameDefaults.put(key, value);
return this;
}
/**
* Sets the {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together.
*
@@ -799,8 +885,8 @@ public final class GeneratorSettings implements Serializable {
/**
* Sets a single {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together.
*
* @param key A key for some import mapping
* @param value The value of some import mapping
* @param key A key for the inline schema mapping
* @param value The value of inline schema mapping
* @return a reference to this Builder
*/
public Builder withInlineSchemaNameMapping(String key, String value) {
@@ -996,7 +1082,9 @@ public final class GeneratorSettings implements Serializable {
Objects.equals(getTypeMappings(), that.getTypeMappings()) &&
Objects.equals(getAdditionalProperties(), that.getAdditionalProperties()) &&
Objects.equals(getImportMappings(), that.getImportMappings()) &&
Objects.equals(getSchemaMappings(), that.getSchemaMappings()) &&
Objects.equals(getInlineSchemaNameMappings(), that.getInlineSchemaNameMappings()) &&
Objects.equals(getInlineSchemaNameDefaults(), that.getInlineSchemaNameDefaults()) &&
Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) &&
Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) &&
Objects.equals(getGitHost(), that.getGitHost()) &&
@@ -1025,7 +1113,9 @@ public final class GeneratorSettings implements Serializable {
getTypeMappings(),
getAdditionalProperties(),
getImportMappings(),
getSchemaMappings(),
getInlineSchemaNameMappings(),
getInlineSchemaNameDefaults(),
getLanguageSpecificPrimitives(),
getReservedWordsMappings(),
getGitHost(),

View File

@@ -71,6 +71,7 @@ public class WorkflowSettings {
this.outputDir = builder.outputDir;
this.verbose = builder.verbose;
this.skipOverwrite = builder.skipOverwrite;
this.skipOperationExample = builder.skipOperationExample;
this.removeOperationIdPrefix = builder.removeOperationIdPrefix;
this.logToStderr = builder.logToStderr;
this.validateSpec = builder.validateSpec;

View File

@@ -97,7 +97,7 @@ task validateGoodSpec(type: org.openapitools.generator.gradle.plugin.tasks.Valid
[source,group]
----
plugins {
id "org.openapi.generator" version "6.0.0"
id "org.openapi.generator" version "6.0.1"
}
----
@@ -113,7 +113,7 @@ buildscript {
// url "https://plugins.gradle.org/m2/"
}
dependencies {
classpath "org.openapitools:openapi-generator-gradle-plugin:6.0.0"
classpath "org.openapitools:openapi-generator-gradle-plugin:6.0.1"
}
}
@@ -695,7 +695,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath('org.openapitools:openapi-generator-gradle-plugin:6.0.0') {
classpath('org.openapitools:openapi-generator-gradle-plugin:6.0.1') {
exclude group: 'com.google.guava'
}
}

View File

@@ -18,5 +18,5 @@ gradle generateGoWithInvalidSpec # expected outcome: BUILD FAILED
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
```bash
gradle -PopenApiGeneratorVersion=5.3.0 openApiValidate
gradle -PopenApiGeneratorVersion=6.0.1 openApiValidate
```

View File

@@ -89,7 +89,8 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
register("openApiGenerate", GenerateTask::class.java).configure {
group = pluginGroup
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
description =
"Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
verbose.set(generate.verbose)
validateSpec.set(generate.validateSpec)
@@ -113,7 +114,9 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
serverVariables.set(generate.serverVariables)
languageSpecificPrimitives.set(generate.languageSpecificPrimitives)
importMappings.set(generate.importMappings)
schemaMappings.set(generate.schemaMappings)
inlineSchemaNameMappings.set(generate.inlineSchemaNameMappings)
inlineSchemaNameDefaults.set(generate.inlineSchemaNameDefaults)
invokerPackage.set(generate.invokerPackage)
groupId.set(generate.groupId)
id.set(generate.id)

View File

@@ -22,19 +22,18 @@ import org.gradle.kotlin.dsl.mapProperty
import org.gradle.kotlin.dsl.property
/**
* Gradle project level extension object definition for the generate task
* Gradle project level extension object definition for the `generate` task
*
* @author Jim Schubert
*/
open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* The verbosity of generation
*/
val verbose = project.objects.property<Boolean>()
/**
* Whether or not an input specification should be validated upon generation.
* Whether an input specification should be validated upon generation.
*/
val validateSpec = project.objects.property<Boolean>()
@@ -141,28 +140,38 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
*/
val importMappings = project.objects.mapProperty<String, String>()
/**
* Specifies mappings between a given schema and the new one
*/
val schemaMappings = project.objects.mapProperty<String, String>()
/**
* Specifies mappings between an inline schema name and the new name
*/
val inlineSchemaNameMappings = project.objects.mapProperty<String, String>()
/**
* Specifies default values for inline schema naming convention
*/
val inlineSchemaNameDefaults = project.objects.mapProperty<String, String>()
/**
* Root package for generated code.
*/
val invokerPackage = project.objects.property<String>()
/**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
* GroupId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/
val groupId = project.objects.property<String>()
/**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
* ArtifactId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/
val id = project.objects.property<String>()
/**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
* Artifact version in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/
val version = project.objects.property<String>()
@@ -237,7 +246,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
*
* Supporting files are those related to projects/frameworks which may be modified
* Supporting files are those related to `projects/frameworks` which may be modified
* by consumers.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
@@ -247,7 +256,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines whether or not model-related _test_ files should be generated.
* Defines whether model-related _test_ files should be generated.
*
* This option enables/disables generation of ALL model-related _test_ files.
*
@@ -257,7 +266,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val generateModelTests = project.objects.property<Boolean>()
/**
* Defines whether or not model-related _documentation_ files should be generated.
* Defines whether model-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL model-related _documentation_ files.
*
@@ -267,7 +276,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val generateModelDocumentation = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _test_ files should be generated.
* Defines whether api-related _test_ files should be generated.
*
* This option enables/disables generation of ALL api-related _test_ files.
*
@@ -277,7 +286,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val generateApiTests = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _documentation_ files should be generated.
* Defines whether api-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL api-related _documentation_ files.
*

View File

@@ -17,7 +17,6 @@
package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project
import org.gradle.api.tasks.Internal
import org.gradle.kotlin.dsl.listProperty
import org.openapitools.codegen.meta.Stability
@@ -37,7 +36,6 @@ open class OpenApiGeneratorGeneratorsExtension(project: Project) {
}
@Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){
include.set(Stability.values().map { s -> s.value() }.filterNot { it == Stability.DEPRECATED.value() })
}
fun applyDefaults() =
include.set(Stability.values().map { it.value() }.filterNot { it == Stability.DEPRECATED.value() })
}

View File

@@ -31,7 +31,7 @@ open class OpenApiGeneratorValidateExtension(project: Project) {
val inputSpec = project.objects.property<String>()
/**
* Whether or not to offer recommendations related to the validated specification document.
* Whether to offer recommendations related to the validated specification document.
*/
val recommend = project.objects.property<Boolean?>()
@@ -40,7 +40,5 @@ open class OpenApiGeneratorValidateExtension(project: Project) {
}
@Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){
recommend.set(true)
}
fun applyDefaults() = recommend.set(true)
}

View File

@@ -51,7 +51,6 @@ import org.openapitools.codegen.config.GlobalSettings
@Suppress("UnstableApiUsage")
@CacheableTask
open class GenerateTask : DefaultTask() {
/**
* The verbosity of generation
*/
@@ -60,7 +59,7 @@ open class GenerateTask : DefaultTask() {
val verbose = project.objects.property<Boolean>()
/**
* Whether or not an input specification should be validated upon generation.
* Whether an input specification should be validated upon generation.
*/
@Optional
@Input
@@ -219,6 +218,13 @@ open class GenerateTask : DefaultTask() {
@Input
val importMappings = project.objects.mapProperty<String, String>()
/**
* Specifies mappings between a given schema and the new one.
*/
@Optional
@Input
val schemaMappings = project.objects.mapProperty<String, String>()
/**
* Specifies mappings between the inline scheme name and the new name
*/
@@ -226,6 +232,13 @@ open class GenerateTask : DefaultTask() {
@Input
val inlineSchemaNameMappings = project.objects.mapProperty<String, String>()
/**
* Specifies default values for inline schema naming convention
*/
@Optional
@Input
val inlineSchemaNameDefaults = project.objects.mapProperty<String, String>()
/**
* Root package for generated code.
*/
@@ -234,21 +247,21 @@ open class GenerateTask : DefaultTask() {
val invokerPackage = project.objects.property<String>()
/**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
* GroupId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/
@Optional
@Input
val groupId = project.objects.property<String>()
/**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
* ArtifactId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/
@Optional
@Input
val id = project.objects.property<String>()
/**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.
* Artifact version in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/
@Optional
@Input
@@ -351,7 +364,7 @@ open class GenerateTask : DefaultTask() {
/**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
*
* Supporting files are those related to projects/frameworks which may be modified
* Supporting files are those related to `projects/frameworks` which may be modified
* by consumers.
*
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
@@ -363,7 +376,7 @@ open class GenerateTask : DefaultTask() {
val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/**
* Defines whether or not model-related _test_ files should be generated.
* Defines whether model-related _test_ files should be generated.
*
* This option enables/disables generation of ALL model-related _test_ files.
*
@@ -375,7 +388,7 @@ open class GenerateTask : DefaultTask() {
val generateModelTests = project.objects.property<Boolean>()
/**
* Defines whether or not model-related _documentation_ files should be generated.
* Defines whether model-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL model-related _documentation_ files.
*
@@ -387,7 +400,7 @@ open class GenerateTask : DefaultTask() {
val generateModelDocumentation = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _test_ files should be generated.
* Defines whether api-related _test_ files should be generated.
*
* This option enables/disables generation of ALL api-related _test_ files.
*
@@ -399,7 +412,7 @@ open class GenerateTask : DefaultTask() {
val generateApiTests = project.objects.property<Boolean>()
/**
* Defines whether or not api-related _documentation_ files should be generated.
* Defines whether api-related _documentation_ files should be generated.
*
* This option enables/disables generation of ALL api-related _documentation_ files.
*
@@ -497,7 +510,10 @@ open class GenerateTask : DefaultTask() {
}
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
GlobalSettings.setProperty(
CodegenConstants.SUPPORTING_FILES,
supportingFilesConstrainedTo.get().joinToString(",")
)
} else {
GlobalSettings.clearProperty(CodegenConstants.SUPPORTING_FILES)
}
@@ -685,12 +701,24 @@ open class GenerateTask : DefaultTask() {
}
}
if (schemaMappings.isPresent) {
schemaMappings.get().forEach { entry ->
configurator.addSchemaMapping(entry.key, entry.value)
}
}
if (inlineSchemaNameMappings.isPresent) {
inlineSchemaNameMappings.get().forEach { entry ->
configurator.addInlineSchemaNameMapping(entry.key, entry.value)
}
}
if (inlineSchemaNameDefaults.isPresent) {
inlineSchemaNameDefaults.get().forEach { entry ->
configurator.addInlineSchemaNameDefault(entry.key, entry.value)
}
}
if (typeMappings.isPresent) {
typeMappings.get().forEach { entry ->
configurator.addTypeMapping(entry.key, entry.value)
@@ -722,11 +750,11 @@ open class GenerateTask : DefaultTask() {
}
val clientOptInput = configurator.toClientOptInput()
val codgenConfig = clientOptInput.config
val codegenConfig = clientOptInput.config
if (configOptions.isPresent) {
val userSpecifiedConfigOptions = configOptions.get()
codgenConfig.cliOptions().forEach {
codegenConfig.cliOptions().forEach {
if (userSpecifiedConfigOptions.containsKey(it.opt)) {
clientOptInput.config.additionalProperties()[it.opt] = userSpecifiedConfigOptions[it.opt]
}

View File

@@ -43,7 +43,6 @@ open class GeneratorsTask : DefaultTask() {
@get:Internal
val include = project.objects.listProperty<String>()
@Suppress("unused")
@TaskAction
fun doWork() {
val generators = CodegenConfigLoader.getAll()

View File

@@ -44,7 +44,6 @@ import java.nio.charset.Charset
*/
@CacheableTask
open class MetaTask : DefaultTask() {
@get:Input
val generatorName = project.objects.property<String>()
@@ -54,10 +53,8 @@ open class MetaTask : DefaultTask() {
@get:OutputDirectory
val outputFolder = project.objects.property<String>()
@Suppress("unused")
@TaskAction
fun doWork() {
val packageToPath = packageName.get().replace(".", File.separator)
val dir = File(outputFolder.get())
val klass = "${generatorName.get().titleCasedTextOnly()}Generator"
@@ -79,15 +76,22 @@ open class MetaTask : DefaultTask() {
SupportingFile("api.template", dir("src", "main", "resources", templateResourceDir), "api.mustache"),
SupportingFile("model.template", dir("src", "main", "resources", templateResourceDir), "model.mustache"),
SupportingFile("myFile.template", dir("src", "main", "resources", templateResourceDir), "myFile.mustache"),
SupportingFile("services.mustache", dir("src", "main", "resources", "META-INF", "services"), CodegenConfig::class.java.canonicalName))
SupportingFile(
"services.mustache",
dir("src", "main", "resources", "META-INF", "services"),
CodegenConfig::class.java.canonicalName
)
)
val currentVersion = CodegenConstants::class.java.`package`.implementationVersion
val data = mapOf("generatorPackage" to packageToPath,
val data = mapOf(
"generatorPackage" to packageToPath,
"generatorClass" to klass,
"name" to templateResourceDir,
"fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass",
"openapiGeneratorVersion" to currentVersion)
"openapiGeneratorVersion" to currentVersion
)
supportingFiles.map {
try {
@@ -131,11 +135,10 @@ open class MetaTask : DefaultTask() {
}
private fun String.titleCasedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)
split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)
private fun String.hyphenatedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase)
split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase)
private fun dir(vararg parts: String): String =
parts.joinToString(separator = File.separator)
private fun dir(vararg parts: String): String = parts.joinToString(separator = File.separator)
}

View File

@@ -14,8 +14,6 @@
* limitations under the License.
*/
@file:Suppress("UnstableApiUsage")
package org.openapitools.generator.gradle.plugin.tasks
import io.swagger.parser.OpenAPIParser
@@ -45,7 +43,7 @@ import org.openapitools.codegen.validations.oas.RuleConfiguration
*
* ./gradlew openApiValidate --input=/path/to/file
*
* build.gradle:
* build.gradle.kts:
*
* openApiMeta {
* inputSpec = "path/to/spec.yaml"
@@ -62,7 +60,6 @@ open class ValidateTask : DefaultTask() {
@Input
val recommend = project.objects.property<Boolean?>()
@Suppress("unused")
@get:Internal
@set:Option(option = "input", description = "The input specification.")
var input: String? = null
@@ -70,7 +67,6 @@ open class ValidateTask : DefaultTask() {
inputSpec.set(value)
}
@Suppress("unused")
@TaskAction
fun doWork() {
val logger = Logging.getLogger(javaClass)
@@ -105,7 +101,6 @@ open class ValidateTask : DefaultTask() {
}
if (messages.isNotEmpty() || validationResult.errors.isNotEmpty()) {
out.withStyle(StyledTextOutput.Style.Error)
out.println("\nSpec is invalid.\nIssues:\n")

View File

@@ -4,12 +4,13 @@ import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test
import java.io.File
import java.nio.file.Files.createTempDirectory
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class GenerateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
override var temp: File = createTempDirectory(javaClass.simpleName).toFile()
private val defaultBuildGradle = """
plugins {
@@ -61,7 +62,7 @@ class GenerateTaskDslTest : TestBase() {
"build/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt"
).map {
val f = File(temp, it)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation.")
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation: $f")
}
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,
@@ -110,7 +111,7 @@ class GenerateTaskDslTest : TestBase() {
"build/java/src/main/java/org/openapitools/example/api/PetsApiClassSuffix.java"
).map {
val f = File(temp, it)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation. - " + f)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation. - $f")
}
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,

View File

@@ -27,7 +27,7 @@ class GeneratorsTaskDslTest : TestBase() {
.build()
// Assert
assertTrue(result.output.contains("The following generators are available:"), "User friendly generator notice is missing.")
assertTrue(result.output.contains("The following generators are available:"), "User-friendly generator notice is missing.")
assertTrue(result.output.contains("CLIENT generators:"), "Expected client generator header is missing.")
assertTrue(result.output.contains("android"), "Spot-checking listed client generators is missing a client generator.")
assertTrue(result.output.contains("SERVER generators:"), "Expected server generator header is missing.")

View File

@@ -34,7 +34,7 @@ class MetaTaskDslTest : TestBase() {
.build()
// Assert
assertTrue(result.output.contains("Wrote file to"), "User friendly write notice is missing.")
assertTrue(result.output.contains("Wrote file to"), "User-friendly write notice is missing.")
// To avoid any OS-specific output causing issues with our stdout comparisons, only compare on expected filenames.
listOf(

View File

@@ -4,27 +4,24 @@ import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod
import java.io.File
import java.io.InputStream
import java.nio.file.Files.createTempDirectory
abstract class TestBase {
protected open lateinit var temp: File
@BeforeMethod
protected fun before() {
temp = createTempDir(javaClass.simpleName)
temp = createTempDirectory(javaClass.simpleName).toFile()
temp.deleteOnExit()
}
@AfterMethod
protected fun after(){
protected fun after() {
temp.deleteRecursively()
}
protected fun withProject(
buildContents: String,
projectFiles: Map<String, InputStream> = mapOf()
) {
val buildFile = File(temp,"build.gradle")
buildFile.writeText(buildContents)
protected fun withProject(buildContents: String, projectFiles: Map<String, InputStream> = mapOf()) {
File(temp, "build.gradle").writeText(buildContents)
projectFiles.forEach { entry ->
val target = File(temp, entry.key)

View File

@@ -7,18 +7,20 @@ import org.gradle.util.GradleVersion
import org.testng.annotations.DataProvider
import org.testng.annotations.Test
import java.io.File
import java.nio.file.Files.createTempDirectory
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ValidateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName)
override var temp: File = createTempDirectory(javaClass.simpleName).toFile()
@DataProvider(name = "gradle_version_provider")
fun gradleVersionProvider(): Array<Array<String?>> = arrayOf(
arrayOf(null), // uses the version of Gradle used to build the plugin itself
arrayOf("5.6.4"),
arrayOf("6.9"),
arrayOf("7.0"))
arrayOf("7.0")
)
private fun getGradleRunner(gradleVersion: String?): GradleRunner {
val gradleRunner = GradleRunner.create()
@@ -33,7 +35,8 @@ class ValidateTaskDslTest : TestBase() {
@Test(dataProvider = "gradle_version_provider")
fun `openApiValidate should fail on non-file spec`(gradleVersion: String?) {
// Arrange
withProject("""
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
@@ -41,7 +44,8 @@ class ValidateTaskDslTest : TestBase() {
| openApiValidate {
| inputSpec = "some_location"
| }
""".trimMargin())
""".trimMargin()
)
// Act
val result = getGradleRunner(gradleVersion)
@@ -59,9 +63,14 @@ class ValidateTaskDslTest : TestBase() {
} else {
"An input file was expected to be present but it doesn't exist."
}
assertTrue(result.output.contains(expectedMessage), "Unexpected/no message presented to the user for a spec pointing to an invalid URI.")
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
assertTrue(
result.output.contains(expectedMessage),
"Unexpected/no message presented to the user for a spec pointing to an invalid URI."
)
assertEquals(
FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
@@ -71,7 +80,8 @@ class ValidateTaskDslTest : TestBase() {
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
)
withProject("""
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
@@ -79,7 +89,8 @@ class ValidateTaskDslTest : TestBase() {
| openApiValidate {
| inputSpec = file("spec.yaml").absolutePath
| }
""".trimMargin(), projectFiles)
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
@@ -89,9 +100,14 @@ class ValidateTaskDslTest : TestBase() {
.build()
// Assert
assertTrue(result.output.contains("Spec is valid."), "Unexpected/no message presented to the user for a valid spec.")
assertEquals(SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}")
assertTrue(
result.output.contains("Spec is valid."),
"Unexpected/no message presented to the user for a valid spec."
)
assertEquals(
SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
@Test(dataProvider = "gradle_version_provider")
@@ -100,7 +116,8 @@ class ValidateTaskDslTest : TestBase() {
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
)
withProject("""
withProject(
"""
| plugins {
| id 'org.openapi.generator'
| }
@@ -108,7 +125,8 @@ class ValidateTaskDslTest : TestBase() {
| openApiValidate {
| inputSpec = file('spec.yaml').absolutePath
| }
""".trimMargin(), projectFiles)
""".trimMargin(), projectFiles
)
// Act
val result = getGradleRunner(gradleVersion)
@@ -118,9 +136,13 @@ class ValidateTaskDslTest : TestBase() {
.buildAndFail()
// Assert
assertTrue(result.output.contains("Spec is invalid."), "Unexpected/no message presented to the user for an invalid spec.")
assertEquals(FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}")
assertTrue(
result.output.contains("Spec is invalid."),
"Unexpected/no message presented to the user for an invalid spec."
)
assertEquals(
FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}"
)
}
}

View File

@@ -12,7 +12,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.0.0</version>
<version>6.0.1</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
@@ -55,7 +55,7 @@ mvn clean compile
| `templateResourcePath` | `openapi.generator.maven.plugin.templateResourcePath` | directory with mustache templates via resource path. This option will overwrite any option defined in `templateDirectory`.
| `engine` | `openapi.generator.maven.plugin.engine` | The name of templating engine to use, "mustache" (default) or "handlebars" (beta)
| `auth` | `openapi.generator.maven.plugin.auth` | adds authorization headers when fetching the OpenAPI definitions remotely. Pass in a URL-encoded string of `name:header` with a comma separating multiple values
| `configurationFile` | `openapi.generator.maven.plugin.configurationFile` | Path to separate json configuration file. File content should be in a json format {"optionKey":"optionValue", "optionKey1":"optionValue1"...} Supported options can be different for each language. Run `config-help -g {generator name}` command for language specific config options
| `configurationFile` | `openapi.generator.maven.plugin.configurationFile` | Path to separate json configuration file. File content should be in a json format {"optionKey":"optionValue", "optionKey1":"optionValue1"...} Supported options can be different for each generator. Run `config-help -g {generator name}` command for generator-specific config options
| `skipOverwrite` | `openapi.generator.maven.plugin.skipOverwrite` | Specifies if the existing files should be overwritten during the generation. (`false` by default)
| `apiPackage` | `openapi.generator.maven.plugin.apiPackage` | the package to use for generated api objects/classes
| `modelPackage` | `openapi.generator.maven.plugin.modelPackage` | the package to use for generated model objects/classes
@@ -72,12 +72,12 @@ mvn clean compile
| `httpUserAgent` | `openapi.generator.maven.plugin.httpUserAgent` | Sets custom User-Agent header value
| `removeOperationIdPrefix` | `openapi.generator.maven.plugin.removeOperationIdPrefix` | remove operationId prefix (e.g. user_getName => getName)
| `skipOperationExample` | `openapi.generator.maven.plugin.skipOperationExample` | skip examples defined in the operation
| `logToStderr` | `openapi.generator.maven.plugin.logToStderr` | write all log messages (not just errors) to STDOUT
| `logToStderr` | `openapi.generator.maven.plugin.logToStderr` | write all log messages (not just errors) to STDERR
| `enablePostProcessFile` | `openapi.generator.maven.plugin.` | enable file post-processing hook
| `skipValidateSpec` | `openapi.generator.maven.plugin.skipValidateSpec` | Whether or not to skip validating the input spec prior to generation. By default, invalid specifications will result in an error.
| `strictSpec` | `openapi.generator.maven.plugin.strictSpec` | Whether or not to treat an input document strictly against the spec. 'MUST' and 'SHALL' wording in OpenAPI spec is strictly adhered to. e.g. when false, no fixes will be applied to documents which pass validation but don't follow the spec.
| `generateAliasAsModel` | `openapi.generator.maven.plugin.generateAliasAsModel` | generate alias (array, map) as model
| `configOptions` | N/A | a **map** of language-specific parameters. To show a full list of generator-specified parameters (options), please use `configHelp` (explained below)
| `configOptions` | N/A | a **map** of generator-specific parameters. To show a full list of generator-specified parameters (options), please use `configHelp` (explained below)
| `instantiationTypes` | `openapi.generator.maven.plugin.instantiationTypes` | sets instantiation type mappings in the format of type=instantiatedType,type=instantiatedType. For example (in Java): `array=ArrayList,map=HashMap`. In other words array types will get instantiated as ArrayList in generated code. You can also have multiple occurrences of this option
| `importMappings` | `openapi.generator.maven.plugin.importMappings` | specifies mappings between a given class and the import that should be used for that class in the format of type=import,type=import. You can also have multiple occurrences of this option
| `typeMappings` | `openapi.generator.maven.plugin.typeMappings` | sets mappings between OpenAPI spec types and generated code types in the format of OpenAPIType=generatedType,OpenAPIType=generatedType. For example: `array=List,map=Map,string=String`. You can also have multiple occurrences of this option. To map a specified format, use type+format, e.g. string+password=EncryptedString will map `type: string, format: password` to `EncryptedString`.
@@ -127,7 +127,7 @@ The `key` and `value` text are any values you'd like to provide for that option.
</configuration>
```
Not that some of these environment variable options may overwrite or conflict with other options available to the maven plugin. For example, the above `globalProperties` example is equivalent to the following:
Notice that some of these environment variable options may overwrite or conflict with other options available to the maven plugin. For example, the above `globalProperties` example is equivalent to the following:
```xml
<configuration>

View File

@@ -27,11 +27,11 @@
<!-- specify the swagger yaml -->
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code -->
<!-- target to generate kotlin client code -->
<generatorName>kotlin</generatorName>
<!-- hint: if you want to generate java server code, e.g. based on Spring Boot,
you can use the following target: <generatorName>spring</generatorName> -->
<!-- hint: if you want to generate kotlin server code, e.g. based on Spring Boot,
you can use the following generator: <generatorName>kotlin-spring</generatorName> -->
<!-- pass any necessary config options -->
<configOptions>

View File

@@ -32,11 +32,11 @@
<!-- specify the swagger yaml -->
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code -->
<!-- target to generate java server code -->
<generatorName>spring</generatorName>
<!-- hint: if you want to generate java server code, e.g. based on Spring Boot,
you can use the following target: <generatorName>spring</generatorName> -->
<!-- hint: if you want to generate java client code
you can use the following generator: <generatorName>java</generatorName> -->
<!-- pass any necessary config options -->
<configOptions>

View File

@@ -298,12 +298,24 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "importMappings", property = "openapi.generator.maven.plugin.importMappings")
private List<String> importMappings;
/**
* A map of scheme and the new one
*/
@Parameter(name = "schemaMappings", property = "openapi.generator.maven.plugin.schemaMappings")
private List<String> schemaMappings;
/**
* A map of inline scheme names and the new names
*/
@Parameter(name = "inlineSchemaNameMappings", property = "openapi.generator.maven.plugin.inlineSchemaNameMappings")
private List<String> inlineSchemaNameMappings;
/**
* A map of inline scheme naming convention and the value
*/
@Parameter(name = "inlineSchemaNameDefaults", property = "openapi.generator.maven.plugin.inlineSchemaNameDefaults")
private List<String> inlineSchemaNameDefaults;
/**
* A map of swagger spec types and the generated code types to use for them
*/
@@ -665,12 +677,24 @@ public class CodeGenMojo extends AbstractMojo {
configurator);
}
// Retained for backwards-compatibility with configOptions -> schema-mappings
if (schemaMappings == null && configOptions.containsKey("schema-mappings")) {
applySchemaMappingsKvp(configOptions.get("schema-mappings").toString(),
configurator);
}
// Retained for backwards-compatibility with configOptions -> inline-schema-name-mappings
if (importMappings == null && configOptions.containsKey("inline-schema-name-mappings")) {
if (inlineSchemaNameMappings == null && configOptions.containsKey("inline-schema-name-mappings")) {
applyInlineSchemaNameMappingsKvp(configOptions.get("inline-schema-name-mappings").toString(),
configurator);
}
// Retained for backwards-compatibility with configOptions -> inline-schema-name-defaults
if (inlineSchemaNameDefaults == null && configOptions.containsKey("inline-schema-name-defaults")) {
applyInlineSchemaNameDefaultsKvp(configOptions.get("inline-schema-name-defaults").toString(),
configurator);
}
// Retained for backwards-compatibility with configOptions -> type-mappings
if (typeMappings == null && configOptions.containsKey("type-mappings")) {
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
@@ -709,11 +733,21 @@ public class CodeGenMojo extends AbstractMojo {
applyImportMappingsKvpList(importMappings, configurator);
}
// Apply Schema Mappings
if (schemaMappings != null && (configOptions == null || !configOptions.containsKey("schema-mappings"))) {
applySchemaMappingsKvpList(schemaMappings, configurator);
}
// Apply Inline Schema Name Mappings
if (inlineSchemaNameMappings != null && (configOptions == null || !configOptions.containsKey("inline-schema-name-mappings"))) {
applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator);
}
// Apply Inline Schema Name Defaults
if (inlineSchemaNameDefaults != null && (configOptions == null || !configOptions.containsKey("inline-schema-name-defaults"))) {
applyInlineSchemaNameDefaultsKvpList(inlineSchemaNameDefaults, configurator);
}
// Apply Type Mappings
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
applyTypeMappingsKvpList(typeMappings, configurator);

View File

@@ -141,8 +141,12 @@ public interface CodegenConfig {
Map<String, String> importMapping();
Map<String, String> schemaMapping();
Map<String, String> inlineSchemaNameMapping();
Map<String, String> inlineSchemaNameDefault();
Map<String, String> apiTemplateFiles();
Map<String, String> modelTemplateFiles();
@@ -309,7 +313,7 @@ public interface CodegenConfig {
void setRemoveEnumValuePrefix(boolean removeEnumValuePrefix);
Schema unaliasSchema(Schema schema, Map<String, String> usedImportMappings);
Schema unaliasSchema(Schema schema);
String defaultTemplatingEngine();

View File

@@ -398,4 +398,7 @@ public class CodegenConstants {
public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC = "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.";
public static final String INIT_REQUIRED_VARS = "initRequiredVars";
public static final String INIT_REQUIRED_VARS_DESC = "If set to true then the required variables are included as positional arguments in __init__ and _from_openapi_data methods. Note: this can break some composition use cases. To learn more read PR #8802.";
public static final String ERROR_OBJECT_TYPE = "errorObjectType";
}

View File

@@ -75,6 +75,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
public List<CodegenProperty> readOnlyVars = new ArrayList<>(); // a list of read-only properties
public List<CodegenProperty> readWriteVars = new ArrayList<>(); // a list of properties for read, write
public List<CodegenProperty> parentVars = new ArrayList<>();
public List<CodegenProperty> nonNullableVars = new ArrayList<>(); // a list of non-nullable properties
public Map<String, Object> allowableValues;
// Sorted sets of required parameters.
@@ -109,6 +110,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
public Map<String, Object> vendorExtensions = new HashMap<>();
private CodegenComposedSchemas composedSchemas;
private boolean hasMultipleTypes = false;
public HashMap<String, SchemaTestCase> testCases = new HashMap<>();
/**
* The type of the value for the additionalProperties keyword in the OAS document.
@@ -195,6 +197,14 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
this.allVars = allVars;
}
public List<CodegenProperty> getNonNullableVars() {
return nonNullableVars;
}
public void setNonNullableVars(List<CodegenProperty> nonNullableVars) {
this.nonNullableVars = nonNullableVars;
}
public Map<String, Object> getAllowableValues() {
return allowableValues;
}
@@ -946,6 +956,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
Objects.equals(arrayModelType, that.arrayModelType) &&
Objects.equals(vars, that.vars) &&
Objects.equals(allVars, that.allVars) &&
Objects.equals(nonNullableVars, that.nonNullableVars) &&
Objects.equals(requiredVars, that.requiredVars) &&
Objects.equals(optionalVars, that.optionalVars) &&
Objects.equals(readOnlyVars, that.readOnlyVars) &&
@@ -981,7 +992,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
getXmlName(), getClassFilename(), getUnescapedDescription(), getDiscriminator(), getDefaultValue(),
getArrayModelType(), isAlias, isString, isInteger, isLong, isNumber, isNumeric, isFloat, isDouble,
isDate, isDateTime, isNull, hasValidation, isShort, isUnboundedInteger, isBoolean,
getVars(), getAllVars(), getRequiredVars(), getOptionalVars(), getReadOnlyVars(), getReadWriteVars(),
getVars(), getAllVars(), getNonNullableVars(), getRequiredVars(), getOptionalVars(), getReadOnlyVars(), getReadWriteVars(),
getParentVars(), getAllowableValues(), getMandatory(), getAllMandatory(), getImports(), hasVars,
isEmptyVars(), hasMoreModels, hasEnums, isEnum, isNullable, hasRequired, hasOptional, isArray,
hasChildren, isMap, isDeprecated, hasOnlyReadOnly, getExternalDocumentation(), getVendorExtensions(),
@@ -999,10 +1010,10 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
sb.append(", parent='").append(parent).append('\'');
sb.append(", parentSchema='").append(parentSchema).append('\'');
sb.append(", interfaces=").append(interfaces);
sb.append(", interfaceModels=").append(interfaceModels!=null?interfaceModels.size():"[]");
sb.append(", interfaceModels=").append(interfaceModels !=null ? interfaceModels.size() : "[]");
sb.append(", allParents=").append(allParents);
sb.append(", parentModel=").append(parentModel);
sb.append(", children=").append(children!=null?children.size():"[]");
sb.append(", children=").append(children != null ? children.size() : "[]");
sb.append(", anyOf=").append(anyOf);
sb.append(", oneOf=").append(oneOf);
sb.append(", allOf=").append(allOf);
@@ -1035,6 +1046,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
sb.append(", isDateTime=").append(isDateTime);
sb.append(", vars=").append(vars);
sb.append(", allVars=").append(allVars);
sb.append(", nonNullableVars=").append(nonNullableVars);
sb.append(", requiredVars=").append(requiredVars);
sb.append(", optionalVars=").append(optionalVars);
sb.append(", readOnlyVars=").append(readOnlyVars);
@@ -1122,6 +1134,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
requiredVars = removeDuplicatedProperty(requiredVars);
parentVars = removeDuplicatedProperty(parentVars);
allVars = removeDuplicatedProperty(allVars);
nonNullableVars = removeDuplicatedProperty(nonNullableVars);
readOnlyVars = removeDuplicatedProperty(readOnlyVars);
readWriteVars = removeDuplicatedProperty(readWriteVars);
}

View File

@@ -27,10 +27,11 @@ public class CodegenOperation {
public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, hasRequiredParams,
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart,
isResponseBinary = false, isResponseFile = false, hasReference = false,
isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
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,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public CodegenDiscriminator discriminator;
@@ -298,10 +299,12 @@ public class CodegenOperation {
sb.append(", returnSimpleType=").append(returnSimpleType);
sb.append(", subresourceOperation=").append(subresourceOperation);
sb.append(", isMap=").append(isMap);
sb.append(", returnProperty=").append(returnProperty);
sb.append(", isArray=").append(isArray);
sb.append(", isMultipart=").append(isMultipart);
sb.append(", isResponseBinary=").append(isResponseBinary);
sb.append(", isResponseFile=").append(isResponseFile);
sb.append(", isResponseFile=").append(isResponseOptional);
sb.append(", hasReference=").append(hasReference);
sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject);
@@ -377,6 +380,7 @@ public class CodegenOperation {
isMultipart == that.isMultipart &&
isResponseBinary == that.isResponseBinary &&
isResponseFile == that.isResponseFile &&
isResponseOptional == that.isResponseOptional &&
hasReference == that.hasReference &&
hasDefaultResponse == that.hasDefaultResponse &&
hasErrorResponseObject == that.hasErrorResponseObject &&
@@ -389,6 +393,7 @@ public class CodegenOperation {
isDeprecated == that.isDeprecated &&
isCallbackRequest == that.isCallbackRequest &&
uniqueItems == that.uniqueItems &&
Objects.equals(returnProperty, that.returnProperty) &&
Objects.equals(responseHeaders, that.responseHeaders) &&
Objects.equals(path, that.path) &&
Objects.equals(operationId, that.operationId) &&
@@ -437,14 +442,14 @@ public class CodegenOperation {
return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
hasRequiredParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isResponseBinary, isResponseFile, hasReference, hasDefaultResponse, isRestfulIndex,
isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful, isDeprecated,
isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse, discriminator, consumes,
produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams, pathParams, queryParams,
headerParams, formParams, cookieParams, requiredParams, optionalParams, authMethods, tags,
responses, callbacks, imports, examples, requestBodyExamples, externalDocs, vendorExtensions,
nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase, operationIdSnakeCase,
hasErrorResponseObject);
isArray, isMultipart, isResponseBinary, isResponseFile, isResponseOptional, hasReference,
hasDefaultResponse, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod,
returnBaseType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse,
discriminator, consumes, produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams,
pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, returnProperty, optionalParams,
authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs,
vendorExtensions, nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase,
operationIdSnakeCase, hasErrorResponseObject);
}
}

View File

@@ -153,8 +153,12 @@ public class DefaultCodegen implements CodegenConfig {
protected Set<String> reservedWords;
protected Set<String> languageSpecificPrimitives = new HashSet<>();
protected Map<String, String> importMapping = new HashMap<>();
// a map to store the mappping between a schema and the new one
protected Map<String, String> schemaMapping = new HashMap<>();
// a map to store the mappping between inline schema and the name provided by the user
protected Map<String, String> inlineSchemaNameMapping = new HashMap<>();
// a map to store the inline schema naming conventions
protected Map<String, String> inlineSchemaNameDefault = new HashMap<>();
protected String modelPackage = "", apiPackage = "", fileSuffix;
protected String modelNamePrefix = "", modelNameSuffix = "";
protected String apiNamePrefix = "", apiNameSuffix = "Api";
@@ -694,6 +698,10 @@ public class DefaultCodegen implements CodegenConfig {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.nonNullableVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.requiredVars) {
updateCodegenPropertyEnum(var);
}
@@ -1058,11 +1066,21 @@ public class DefaultCodegen implements CodegenConfig {
return importMapping;
}
@Override
public Map<String, String> schemaMapping() {
return schemaMapping;
}
@Override
public Map<String, String> inlineSchemaNameMapping() {
return inlineSchemaNameMapping;
}
@Override
public Map<String, String> inlineSchemaNameDefault() {
return inlineSchemaNameDefault;
}
@Override
public String testPackage() {
return testPackage;
@@ -1721,6 +1739,7 @@ public class DefaultCodegen implements CodegenConfig {
specialCharReplacements.put("<=", "Less_Than_Or_Equal_To");
specialCharReplacements.put(">=", "Greater_Than_Or_Equal_To");
specialCharReplacements.put("!=", "Not_Equal");
specialCharReplacements.put("<>", "Not_Equal");
specialCharReplacements.put("~=", "Tilde_Equal");
}
@@ -2184,8 +2203,8 @@ public class DefaultCodegen implements CodegenConfig {
}
@Override
public Schema unaliasSchema(Schema schema, Map<String, String> usedImportMappings) {
return ModelUtils.unaliasSchema(this.openAPI, schema, usedImportMappings);
public Schema unaliasSchema(Schema schema) {
return ModelUtils.unaliasSchema(this.openAPI, schema, schemaMapping);
}
/**
@@ -2195,13 +2214,13 @@ public class DefaultCodegen implements CodegenConfig {
* @return the string representation of the schema type.
*/
protected String getSingleSchemaType(Schema schema) {
Schema unaliasSchema = unaliasSchema(schema, importMapping);
Schema unaliasSchema = unaliasSchema(schema);
if (StringUtils.isNotBlank(unaliasSchema.get$ref())) { // reference to another definition/schema
// get the schema/model name from $ref
String schemaName = ModelUtils.getSimpleRef(unaliasSchema.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
if (importMapping.containsKey(schemaName)) {
if (schemaMapping.containsKey(schemaName)) {
return schemaName;
}
return getAlias(schemaName);
@@ -2297,8 +2316,8 @@ public class DefaultCodegen implements CodegenConfig {
} else if (ModelUtils.isAnyType(schema)) {
return "AnyType";
} else if (StringUtils.isNotEmpty(schema.getType())) {
if (!importMapping.containsKey(schema.getType())) {
LOGGER.warn("Unknown type found in the schema: {}", schema.getType());
if (!schemaMapping.containsKey(schema.getType())) {
LOGGER.warn("Unknown type found in the schema: {}. To map it, please use the schema mapping option (e.g. --schema-mappings in CLI)", schema.getType());
}
return schema.getType();
}
@@ -2437,26 +2456,29 @@ public class DefaultCodegen implements CodegenConfig {
}
private static class NamedSchema {
private NamedSchema(String name, Schema s) {
private NamedSchema(String name, Schema s, boolean required) {
this.name = name;
this.schema = s;
this.required = required;
}
private String name;
private Schema schema;
private boolean required;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NamedSchema that = (NamedSchema) o;
return Objects.equals(name, that.name) &&
return Objects.equals(required, that.required) &&
Objects.equals(name, that.name) &&
Objects.equals(schema, that.schema);
}
@Override
public int hashCode() {
return Objects.hash(name, schema);
return Objects.hash(name, schema, required);
}
}
@@ -2524,12 +2546,12 @@ public class DefaultCodegen implements CodegenConfig {
m.interfaces = new ArrayList<>();
for (Schema interfaceSchema : interfaces) {
interfaceSchema = unaliasSchema(interfaceSchema, importMapping);
interfaceSchema = unaliasSchema(interfaceSchema);
if (StringUtils.isBlank(interfaceSchema.get$ref())) {
// primitive type
String languageType = getTypeDeclaration(interfaceSchema);
CodegenProperty interfaceProperty = fromProperty(languageType, interfaceSchema);
CodegenProperty interfaceProperty = fromProperty(languageType, interfaceSchema, false);
if (ModelUtils.isArraySchema(interfaceSchema) || ModelUtils.isMapSchema(interfaceSchema)) {
while (interfaceProperty != null) {
addImport(m, interfaceProperty.complexType);
@@ -2565,9 +2587,10 @@ public class DefaultCodegen implements CodegenConfig {
refSchema = allDefinitions.get(ref);
}
final String modelName = toModelName(ref);
CodegenProperty interfaceProperty = fromProperty(modelName, interfaceSchema);
CodegenProperty interfaceProperty = fromProperty(modelName, interfaceSchema, false);
m.interfaces.add(modelName);
addImport(m, modelName);
addImport(composed, refSchema, m, modelName);
if (allDefinitions != null && refSchema != null) {
if (allParents.contains(ref) && supportsMultipleInheritance) {
// multiple inheritance
@@ -2689,6 +2712,52 @@ public class DefaultCodegen implements CodegenConfig {
setAddProps(schema, m);
}
protected String toTestCaseName(String specTestCaseName) {
return specTestCaseName;
}
/**
* A method that allows generators to pre-process test example payloads
* This can be useful if one needs to change how values like null in string are represnted
* @param data the test data payload
* @return the updated test data payload
*/
protected Object processTestExampleData(Object data) {
return data;
}
/**
* Processes any test cases if they exist in the components.x-test-examples vendor extensions
* If they exist then cast them to java class instances and return them back in a map
* @param schemaName the component schema name that the test cases are for
* @param vendorExtensions the extensions that may or may not hold the data
*/
private HashMap<String, SchemaTestCase> extractSchemaTestCases(String schemaName, HashMap<String, Object> vendorExtensions) {
String testExamplesKey = "x-schema-test-examples";
// schemaName to a map of test case name to test case
if (vendorExtensions == null || !vendorExtensions.containsKey(testExamplesKey)) {
return null;
}
HashMap<String, SchemaTestCase> schemaTestCases = new HashMap<>();
LinkedHashMap<String, Object> schemaNameToTestCases = (LinkedHashMap<String, Object>) vendorExtensions.get(testExamplesKey);
if (!schemaNameToTestCases.containsKey(schemaName)) {
return null;
}
LinkedHashMap<String, LinkedHashMap<String, Object>> testNameToTesCase = (LinkedHashMap<String, LinkedHashMap<String, Object>>) schemaNameToTestCases.get(schemaName);
for (Entry<String, LinkedHashMap<String, Object>> entry: testNameToTesCase.entrySet()) {
LinkedHashMap<String, Object> testExample = (LinkedHashMap<String, Object>) entry.getValue();
String nameInSnakeCase = toTestCaseName(entry.getKey());
Object data = processTestExampleData(testExample.get("data"));
SchemaTestCase testCase = new SchemaTestCase(
(String) testExample.getOrDefault("description", ""),
new ObjectWithTypeBooleans(data),
(boolean) testExample.get("valid")
);
schemaTestCases.put(nameInSnakeCase, testCase);
}
return schemaTestCases;
}
/**
* Convert OAS Model object to Codegen Model object.
@@ -2706,7 +2775,7 @@ public class DefaultCodegen implements CodegenConfig {
}
// unalias schema
schema = unaliasSchema(schema, importMapping);
schema = unaliasSchema(schema);
if (schema == null) {
LOGGER.warn("Schema {} not found", name);
return null;
@@ -2714,6 +2783,11 @@ public class DefaultCodegen implements CodegenConfig {
CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
ModelUtils.syncValidationProperties(schema, m);
if (openAPI != null) {
HashMap<String, Object> vendorExtensions = (HashMap<String, Object>) openAPI.getComponents().getExtensions();
HashMap<String, SchemaTestCase> schemaTestCases = extractSchemaTestCases(name, vendorExtensions);
m.testCases = schemaTestCases;
}
if (reservedWords.contains(name)) {
m.name = escapeReservedWord(name);
@@ -2764,7 +2838,7 @@ public class DefaultCodegen implements CodegenConfig {
m.setTypeProperties(schema);
m.setComposedSchemas(getComposedSchemas(schema));
if (ModelUtils.isArraySchema(schema)) {
CodegenProperty arrayProperty = fromProperty(name, schema);
CodegenProperty arrayProperty = fromProperty(name, schema, false);
m.setItems(arrayProperty.items);
m.arrayModelType = arrayProperty.complexType;
addParentContainer(m, name, schema);
@@ -2884,17 +2958,17 @@ public class DefaultCodegen implements CodegenConfig {
if (schema.getAdditionalProperties() == null) {
if (!disallowAdditionalPropertiesIfNotPresent) {
isAdditionalPropertiesTrue = true;
addPropProp = fromProperty("", new Schema());
addPropProp = fromProperty("", new Schema(), false);
additionalPropertiesIsAnyType = true;
}
} else if (schema.getAdditionalProperties() instanceof Boolean) {
if (Boolean.TRUE.equals(schema.getAdditionalProperties())) {
isAdditionalPropertiesTrue = true;
addPropProp = fromProperty("", new Schema());
addPropProp = fromProperty("", new Schema(), false);
additionalPropertiesIsAnyType = true;
}
} else {
addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties());
addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties(), false);
if (ModelUtils.isAnyType((Schema) schema.getAdditionalProperties())) {
additionalPropertiesIsAnyType = true;
}
@@ -3374,13 +3448,13 @@ public class DefaultCodegen implements CodegenConfig {
property.maxItems = p.getMaxProperties();
// handle inner property
Schema innerSchema = unaliasSchema(getAdditionalProperties(p), importMapping);
Schema innerSchema = unaliasSchema(getAdditionalProperties(p));
if (innerSchema == null) {
LOGGER.error("Undefined map inner type for `{}`. Default to String.", p.getName());
innerSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to undefined type");
p.setAdditionalProperties(innerSchema);
}
CodegenProperty cp = fromProperty("inner", innerSchema);
CodegenProperty cp = fromProperty("inner", innerSchema, false);
updatePropertyForMap(property, cp);
}
@@ -3451,6 +3525,19 @@ public class DefaultCodegen implements CodegenConfig {
property.pattern = toRegularExpression(p.getPattern());
}
/**
* TODO remove this in 7.0.0 as a breaking change
* This method was kept when required was added to the fromProperty signature
* to ensure that the change was non-breaking
*
* @param name name of the property
* @param p OAS property schema
* @return Codegen Property object
*/
public CodegenProperty fromProperty(String name, Schema p) {
return fromProperty(name, p, false);
}
/**
* Convert OAS Property object to Codegen Property object.
* <p>
@@ -3462,24 +3549,26 @@ public class DefaultCodegen implements CodegenConfig {
*
* @param name name of the property
* @param p OAS property schema
* @param required true if the property is required in the next higher object schema, false otherwise
* @return Codegen Property object
*/
public CodegenProperty fromProperty(String name, Schema p) {
public CodegenProperty fromProperty(String name, Schema p, boolean required) {
if (p == null) {
LOGGER.error("Undefined property/schema for `{}`. Default to type:string.", name);
return null;
}
LOGGER.debug("debugging fromProperty for {} : {}", name, p);
NamedSchema ns = new NamedSchema(name, p);
NamedSchema ns = new NamedSchema(name, p, required);
CodegenProperty cpc = schemaCodegenPropertyCache.get(ns);
if (cpc != null) {
LOGGER.debug("Cached fromProperty for {} : {}", name, p.getName());
LOGGER.debug("Cached fromProperty for {} : {} required={}", name, p.getName(), required);
return cpc;
}
// unalias schema
p = unaliasSchema(p, importMapping);
p = unaliasSchema(p);
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
property.required = required;
ModelUtils.syncValidationProperties(p, property);
property.name = toVarName(name);
@@ -3645,8 +3734,8 @@ public class DefaultCodegen implements CodegenConfig {
itemName = property.name;
}
ArraySchema arraySchema = (ArraySchema) p;
Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema), importMapping);
CodegenProperty cp = fromProperty(itemName, innerSchema);
Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema));
CodegenProperty cp = fromProperty(itemName, innerSchema, false);
updatePropertyForArray(property, cp);
} else if (ModelUtils.isTypeObjectSchema(p)) {
updatePropertyForObject(property, p);
@@ -3884,24 +3973,24 @@ public class DefaultCodegen implements CodegenConfig {
* @param schemas a map of the schemas in the openapi spec
* @param op endpoint CodegenOperation
* @param methodResponse the default ApiResponse for the endpoint
* @param importMappings mappings of external types to be omitted by unaliasing
* @param schemaMappings mappings of external types to be omitted by unaliasing
*/
protected void handleMethodResponse(Operation operation,
Map<String, Schema> schemas,
CodegenOperation op,
ApiResponse methodResponse,
Map<String, String> importMappings) {
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(methodResponse), importMapping);
Map<String, String> schemaMappings) {
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(methodResponse));
if (responseSchema != null) {
CodegenProperty cm = fromProperty("response", responseSchema);
CodegenProperty cm = fromProperty("response", responseSchema, false);
if (ModelUtils.isArraySchema(responseSchema)) {
ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty innerProperty = fromProperty("response", getSchemaItems(as));
CodegenProperty innerProperty = fromProperty("response", getSchemaItems(as), false);
op.returnBaseType = innerProperty.baseType;
} else if (ModelUtils.isMapSchema(responseSchema)) {
CodegenProperty innerProperty = fromProperty("response", getAdditionalProperties(responseSchema));
CodegenProperty innerProperty = fromProperty("response", getAdditionalProperties(responseSchema), false);
op.returnBaseType = innerProperty.baseType;
} else {
if (cm.complexType != null) {
@@ -3955,6 +4044,7 @@ public class DefaultCodegen implements CodegenConfig {
if (languageSpecificPrimitives().contains(op.returnBaseType) || op.returnBaseType == null) {
op.returnTypeIsPrimitive = true;
}
op.returnProperty = cm;
}
addHeaders(methodResponse, op.responseHeaders);
}
@@ -4078,6 +4168,13 @@ public class DefaultCodegen implements CodegenConfig {
op.hasErrorResponseObject = Boolean.TRUE;
}
}
// check if the operation can both return a 2xx response with a body and without
if (op.responses.stream().anyMatch(response -> response.is2xx && response.dataType != null) &&
op.responses.stream().anyMatch(response -> response.is2xx && response.dataType == null)) {
op.isResponseOptional = Boolean.TRUE;
}
op.responses.sort((a, b) -> {
int aScore = a.isWildcard() ? 2 : a.isRange() ? 1 : 0;
int bScore = b.isWildcard() ? 2 : b.isRange() ? 1 : 0;
@@ -4323,7 +4420,7 @@ public class DefaultCodegen implements CodegenConfig {
Schema responseSchema;
if (this.openAPI != null && this.openAPI.getComponents() != null) {
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(response), importMapping);
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(response));
} else { // no model/alias defined
responseSchema = ModelUtils.getSchemaFromResponse(response);
}
@@ -4351,7 +4448,7 @@ public class DefaultCodegen implements CodegenConfig {
r.setPattern(toRegularExpression(responseSchema.getPattern()));
}
CodegenProperty cp = fromProperty("response", responseSchema);
CodegenProperty cp = fromProperty("response", responseSchema, false);
r.dataType = getTypeDeclaration(responseSchema);
if (!ModelUtils.isArraySchema(responseSchema)) {
@@ -4374,7 +4471,7 @@ public class DefaultCodegen implements CodegenConfig {
r.isArray = true;
r.containerType = cp.containerType;
ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty items = fromProperty("response", getSchemaItems(as));
CodegenProperty items = fromProperty("response", getSchemaItems(as), false);
r.setItems(items);
CodegenProperty innerCp = items;
@@ -4533,7 +4630,7 @@ public class DefaultCodegen implements CodegenConfig {
private void updateParameterForMap(CodegenParameter codegenParameter, Schema parameterSchema, Set<String> imports) {
CodegenProperty codegenProperty = fromProperty("inner", getAdditionalProperties(parameterSchema));
CodegenProperty codegenProperty = fromProperty("inner", getAdditionalProperties(parameterSchema), false);
codegenParameter.items = codegenProperty;
codegenParameter.mostInnerItems = codegenProperty.mostInnerItems;
codegenParameter.baseType = codegenProperty.dataType;
@@ -4615,17 +4712,17 @@ public class DefaultCodegen implements CodegenConfig {
String parameterModelName = null;
if (parameter.getSchema() != null) {
parameterSchema = parameter.getSchema();
parameterSchema = unaliasSchema(parameter.getSchema());
parameterModelName = getParameterDataType(parameter, parameterSchema);
CodegenProperty prop;
if (this instanceof RustServerCodegen) {
// for rust server, we need to do somethings special as it uses
// $ref (e.g. #components/schemas/Pet) to determine whether it's a model
prop = fromProperty(parameter.getName(), parameterSchema);
prop = fromProperty(parameter.getName(), parameterSchema, false);
} else if (getUseInlineModelResolver()) {
prop = fromProperty(parameter.getName(), getReferencedSchemaWhenNotEnum(parameterSchema));
prop = fromProperty(parameter.getName(), getReferencedSchemaWhenNotEnum(parameterSchema), false);
} else {
prop = fromProperty(parameter.getName(), parameterSchema);
prop = fromProperty(parameter.getName(), parameterSchema, false);
}
codegenParameter.setSchema(prop);
} else if (parameter.getContent() != null) {
@@ -4661,7 +4758,8 @@ public class DefaultCodegen implements CodegenConfig {
return codegenParameter;
}
parameterSchema = unaliasSchema(parameterSchema, Collections.emptyMap());
// TODO need to reivew replacing empty map with schemaMapping instead
parameterSchema = unaliasSchema(parameterSchema);
if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \" {} \"", parameter.getName());
finishUpdatingParameter(codegenParameter, parameter);
@@ -4747,7 +4845,7 @@ public class DefaultCodegen implements CodegenConfig {
collectionFormat = getCollectionFormat(parameter);
// default to csv:
collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
CodegenProperty itemsProperty = fromProperty("inner", inner);
CodegenProperty itemsProperty = fromProperty("inner", inner, false);
codegenParameter.items = itemsProperty;
codegenParameter.mostInnerItems = itemsProperty.mostInnerItems;
codegenParameter.baseType = itemsProperty.dataType;
@@ -4763,15 +4861,10 @@ public class DefaultCodegen implements CodegenConfig {
;
}
CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema);
CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema, false);
if (Boolean.TRUE.equals(codegenProperty.isModel)) {
codegenParameter.isModel = true;
}
// TODO revise below which seems not working
//if (parameterSchema.getRequired() != null && !parameterSchema.getRequired().isEmpty() && parameterSchema.getRequired().contains(codegenProperty.baseName)) {
codegenProperty.required = Boolean.TRUE.equals(parameter.getRequired()) ? true : false;
//}
//codegenProperty.required = true;
if (parameterModelName != null) {
codegenParameter.dataType = parameterModelName;
@@ -4785,7 +4878,9 @@ public class DefaultCodegen implements CodegenConfig {
imports.add(codegenProperty.baseType);
}
codegenParameter.dataFormat = codegenProperty.dataFormat;
codegenParameter.required = codegenProperty.required;
if (parameter.getRequired() != null) {
codegenParameter.required = parameter.getRequired().booleanValue();
}
if (codegenProperty.isEnum) {
codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum;
@@ -4822,15 +4917,19 @@ public class DefaultCodegen implements CodegenConfig {
if (schema.get$ref() != null) {
schema = ModelUtils.getReferencedSchema(openAPI, schema);
}
codegenParameter.items = fromProperty(codegenParameter.paramName, schema);
codegenParameter.items = fromProperty(codegenParameter.paramName, schema, false);
// https://swagger.io/docs/specification/serialization/
if (schema != null) {
Map<String, Schema<?>> properties = schema.getProperties();
List<String> requiredVarNames = new ArrayList<>();
if (schema.getRequired() != null) {
requiredVarNames.addAll(schema.getRequired());
}
if (properties != null) {
codegenParameter.items.vars =
properties.entrySet().stream()
.map(entry -> {
CodegenProperty property = fromProperty(entry.getKey(), entry.getValue());
CodegenProperty property = fromProperty(entry.getKey(), entry.getValue(), requiredVarNames.contains(entry.getKey()));
property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]";
return property;
}).collect(Collectors.toList());
@@ -4865,7 +4964,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return data type
*/
protected String getParameterDataType(Parameter parameter, Schema schema) {
Schema unaliasSchema = ModelUtils.unaliasSchema(openAPI, schema);
Schema unaliasSchema = unaliasSchema(schema);
if (unaliasSchema.get$ref() != null) {
return toModelName(ModelUtils.getSimpleRef(unaliasSchema.get$ref()));
}
@@ -5109,7 +5208,7 @@ public class DefaultCodegen implements CodegenConfig {
} else {
schema = header.getSchema();
}
CodegenProperty cp = fromProperty(headerEntry.getKey(), schema);
CodegenProperty cp = fromProperty(headerEntry.getKey(), schema, false);
cp.setDescription(escapeText(description));
cp.setUnescapedDescription(description);
if (header.getRequired() != null) {
@@ -5177,7 +5276,7 @@ public class DefaultCodegen implements CodegenConfig {
* @param schema the input OAS schema.
*/
protected void addParentContainer(CodegenModel model, String name, Schema schema) {
final CodegenProperty property = fromProperty(name, schema);
final CodegenProperty property = fromProperty(name, schema, false);
addImport(model, property.complexType);
model.parent = toInstantiationType(schema);
final String containerType = property.containerType;
@@ -5230,13 +5329,30 @@ public class DefaultCodegen implements CodegenConfig {
addImport(m.imports, type);
}
private void addImport(Set<String> importsToBeAddedTo, String type) {
protected void addImport(Set<String> importsToBeAddedTo, String type) {
if (shouldAddImport(type)) {
importsToBeAddedTo.add(type);
}
}
private boolean shouldAddImport(String type) {
/**
* Add the model name of the child schema in a composed schema to the set of imports
*
* @param composed composed schema
* @param childSchema composed schema
* @param model codegen model
* @param modelName model name
*/
protected void addImport(ComposedSchema composed, Schema childSchema, CodegenModel model, String modelName ) {
// import only if it's not allOf composition schema (without discriminator)
if (!(composed.getAllOf() != null && childSchema.getDiscriminator() == null)) {
addImport(model, modelName);
} else {
LOGGER.debug("Skipped import for allOf composition schema {}", modelName);
}
}
protected boolean shouldAddImport(String type) {
return type != null && needToImport(type);
}
@@ -5249,7 +5365,7 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, Schema> unaliasPropertySchema(Map<String, Schema> properties) {
if (properties != null) {
for (String key : properties.keySet()) {
properties.put(key, unaliasSchema(properties.get(key), importMapping()));
properties.put(key, unaliasSchema(properties.get(key)));
}
}
@@ -5326,13 +5442,18 @@ public class DefaultCodegen implements CodegenConfig {
if (prop == null) {
LOGGER.warn("Please report the issue. There shouldn't be null property for {}", key);
} else {
final CodegenProperty cp = fromProperty(key, prop);
cp.required = mandatory.contains(key);
final CodegenProperty cp = fromProperty(key, prop, mandatory.contains(key));
vars.add(cp);
m.setHasVars(true);
if (cp.required) {
m.setHasRequired(true);
m.getRequiredVars().add(cp);
}
if (cm == null) {
continue;
}
cm.hasRequired = cm.hasRequired || cp.required;
cm.hasOptional = cm.hasOptional || !cp.required;
if (cp.isEnum) {
// FIXME: if supporting inheritance, when called a second time for allProperties it is possible for
@@ -5348,9 +5469,7 @@ public class DefaultCodegen implements CodegenConfig {
addImportsForPropertyType(cm, cp);
// if required, add to the list "requiredVars"
if (Boolean.TRUE.equals(cp.required)) {
cm.requiredVars.add(cp);
} else { // else add to the list "optionalVars" for optional property
if (Boolean.FALSE.equals(cp.required)) {
cm.optionalVars.add(cp);
}
@@ -5361,6 +5480,10 @@ public class DefaultCodegen implements CodegenConfig {
// duplicated properties will be removed by removeAllDuplicatedProperty later
cm.readWriteVars.add(cp);
}
if (Boolean.FALSE.equals(cp.isNullable)){
cm.nonNullableVars.add(cp);
}
}
}
return;
@@ -5375,9 +5498,18 @@ public class DefaultCodegen implements CodegenConfig {
* @param property The codegen representation of the OAS schema's property.
*/
protected void addImportsForPropertyType(CodegenModel model, CodegenProperty property) {
if (property.isContainer) {
if (property.isArray) {
if (property.getUniqueItems()) { // set
addImport(model.imports, typeMapping.get("set"));
} else { // array
addImport(model.imports, typeMapping.get("array"));
}
}
if (property.isMap) { // map
addImport(model.imports, typeMapping.get("map"));
}
addImports(model, property);
}
@@ -6180,7 +6312,7 @@ public class DefaultCodegen implements CodegenConfig {
// skip as it implies `consumes` in OAS2 is not defined
continue;
} else {
mediaType.put("mediaType", escapeText(escapeQuotationMark(key)));
mediaType.put("mediaType", escapeQuotationMark(key));
}
mediaTypeList.add(mediaType);
}
@@ -6246,7 +6378,7 @@ public class DefaultCodegen implements CodegenConfig {
for (String key : produces) {
// escape quotation to avoid code injection, "*/*" is a special case, do nothing
String encodedKey = "*/*".equals(key) ? key : escapeText(escapeQuotationMark(key));
String encodedKey = "*/*".equals(key) ? key : escapeQuotationMark(key);
//Only unique media types should be added to "produces"
if (!existingMediaTypes.contains(encodedKey)) {
Map<String, String> mediaType = new HashMap<>();
@@ -6357,9 +6489,9 @@ public class DefaultCodegen implements CodegenConfig {
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
LOGGER.debug("Debugging fromFormProperty {}: {}", name, propertySchema);
CodegenProperty codegenProperty = fromProperty(name, propertySchema);
CodegenProperty codegenProperty = fromProperty(name, propertySchema, false);
Schema ps = unaliasSchema(propertySchema, importMapping);
Schema ps = unaliasSchema(propertySchema);
ModelUtils.syncValidationProperties(ps, codegenParameter);
codegenParameter.setTypeProperties(ps);
codegenParameter.setComposedSchemas(getComposedSchemas(ps));
@@ -6443,7 +6575,7 @@ public class DefaultCodegen implements CodegenConfig {
;
} else if (ModelUtils.isArraySchema(ps)) {
Schema inner = getSchemaItems((ArraySchema) ps);
CodegenProperty arrayInnerProperty = fromProperty("inner", inner);
CodegenProperty arrayInnerProperty = fromProperty("inner", inner, false);
codegenParameter.items = arrayInnerProperty;
codegenParameter.mostInnerItems = arrayInnerProperty.mostInnerItems;
codegenParameter.isPrimitiveType = false;
@@ -6538,7 +6670,7 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.isNullable = codegenModel.isNullable;
imports.add(codegenParameter.baseType);
} else {
CodegenProperty codegenProperty = fromProperty("property", schema);
CodegenProperty codegenProperty = fromProperty("property", schema, false);
if (codegenProperty != null && codegenProperty.getComplexType() != null && codegenProperty.getComplexType().contains(" | ")) {
List<String> parts = Arrays.asList(codegenProperty.getComplexType().split(" \\| "));
@@ -6603,7 +6735,7 @@ public class DefaultCodegen implements CodegenConfig {
inner = new StringSchema().description("//TODO automatically added by openapi-generator");
schema.setAdditionalProperties(inner);
}
CodegenProperty codegenProperty = fromProperty("property", schema);
CodegenProperty codegenProperty = fromProperty("property", schema, false);
imports.add(codegenProperty.baseType);
@@ -6635,7 +6767,7 @@ public class DefaultCodegen implements CodegenConfig {
}
protected void updateRequestBodyForPrimitiveType(CodegenParameter codegenParameter, Schema schema, String bodyParameterName, Set<String> imports) {
CodegenProperty codegenProperty = fromProperty("PRIMITIVE_REQUEST_BODY", schema);
CodegenProperty codegenProperty = fromProperty("PRIMITIVE_REQUEST_BODY", schema, false);
if (codegenProperty != null) {
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "body"; // default to body
@@ -6669,7 +6801,7 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.isFreeFormObject = true;
// HTTP request body is free form object
CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema);
CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema, false);
if (codegenProperty != null) {
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "body"; // default to body
@@ -6698,7 +6830,7 @@ public class DefaultCodegen implements CodegenConfig {
} else {
final ArraySchema arraySchema = (ArraySchema) schema;
Schema inner = getSchemaItems(arraySchema);
CodegenProperty codegenProperty = fromProperty("property", arraySchema);
CodegenProperty codegenProperty = fromProperty("property", arraySchema, false);
imports.add(codegenProperty.baseType);
CodegenProperty innerCp = codegenProperty;
CodegenProperty mostInnerItem = innerCp;
@@ -6822,8 +6954,8 @@ public class DefaultCodegen implements CodegenConfig {
enc.getContentType(),
headers,
enc.getStyle().toString(),
enc.getExplode().booleanValue(),
enc.getAllowReserved().booleanValue()
enc.getExplode() == null ? false : enc.getExplode().booleanValue(),
enc.getAllowReserved() == null ? false : enc.getAllowReserved().booleanValue()
);
String propName = encodingEntry.getKey();
ceMap.put(propName, ce);
@@ -6832,7 +6964,7 @@ public class DefaultCodegen implements CodegenConfig {
String contentType = contentEntry.getKey();
CodegenProperty schemaProp = null;
if (mt.getSchema() != null) {
schemaProp = fromProperty(toMediaTypeSchemaName(contentType, mediaTypeSchemaSuffix), mt.getSchema());
schemaProp = fromProperty(toMediaTypeSchemaName(contentType, mediaTypeSchemaSuffix), mt.getSchema(), false);
}
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap);
cmtContent.put(contentType, codegenMt);
@@ -6870,7 +7002,7 @@ public class DefaultCodegen implements CodegenConfig {
name = ModelUtils.getSimpleRef(schema.get$ref());
}
Schema unaliasedSchema = unaliasSchema(schema, importMapping);
Schema unaliasedSchema = unaliasSchema(schema);
schema = ModelUtils.getReferencedSchema(this.openAPI, schema);
ModelUtils.syncValidationProperties(unaliasedSchema, codegenParameter);
@@ -6939,27 +7071,9 @@ public class DefaultCodegen implements CodegenConfig {
protected void addVarsRequiredVarsAdditionalProps(Schema schema, IJsonSchemaValidationProperties property) {
setAddProps(schema, property);
if (!"object".equals(schema.getType())) {
return;
}
if (schema instanceof ObjectSchema) {
ObjectSchema objSchema = (ObjectSchema) schema;
HashSet<String> requiredVars = new HashSet<>();
if (objSchema.getRequired() != null) {
requiredVars.addAll(objSchema.getRequired());
}
if (objSchema.getProperties() != null && objSchema.getProperties().size() > 0) {
property.setHasVars(true);
}
addVars(property, property.getVars(), objSchema.getProperties(), requiredVars);
List<CodegenProperty> requireCpVars = property.getVars()
.stream()
.filter(p -> Boolean.TRUE.equals(p.required)).collect(Collectors.toList());
property.setRequiredVars(requireCpVars);
if (property.getRequiredVars() != null && property.getRequiredVars().size() > 0) {
property.setHasRequired(true);
}
}
Set<String> mandatory = schema.getRequired() == null ? Collections.emptySet()
: new TreeSet<>(schema.getRequired());
addVars(property, property.getVars(), schema.getProperties(), mandatory);
}
private void addJsonSchemaForBodyRequestInCaseItsNotPresent(CodegenParameter codegenParameter, RequestBody body) {
@@ -7466,7 +7580,7 @@ public class DefaultCodegen implements CodegenConfig {
Schema notSchema = schema.getNot();
CodegenProperty notProperty = null;
if (notSchema != null) {
notProperty = fromProperty("NotSchema", notSchema);
notProperty = fromProperty("NotSchema", notSchema, false);
}
List<CodegenProperty> allOf = new ArrayList<>();
List<CodegenProperty> oneOf = new ArrayList<>();
@@ -7492,7 +7606,7 @@ public class DefaultCodegen implements CodegenConfig {
List<CodegenProperty> xOf = new ArrayList<>();
int i = 0;
for (Schema xOfSchema : xOfCollection) {
CodegenProperty cp = fromProperty(collectionName + "_" + i, xOfSchema);
CodegenProperty cp = fromProperty(collectionName + "_" + i, xOfSchema, false);
xOf.add(cp);
i += 1;
}

View File

@@ -441,6 +441,19 @@ public class DefaultGenerator implements Generator {
// process models only
for (String name : modelKeys) {
try {
//don't generate models that have an import mapping
if (config.schemaMapping().containsKey(name)) {
LOGGER.debug("Model {} not imported due to import mapping", name);
for (String templateName : config.modelTemplateFiles().keySet()) {
// HACK: Because this returns early, could lead to some invalid model reporting.
String filename = config.modelFilename(templateName, name);
Path path = java.nio.file.Paths.get(filename);
this.templateProcessor.skip(path,"Skipped prior to model processing due to schema mapping." );
}
continue;
}
// don't generate models that are not used as object (e.g. form parameters)
if (unusedModels.contains(name)) {
if (Boolean.FALSE.equals(skipFormModel)) {
@@ -464,7 +477,7 @@ public class DefaultGenerator implements Generator {
// generators may choose to make models for use case 2 + 3
Schema refSchema = new Schema();
refSchema.set$ref("#/components/schemas/" + name);
Schema unaliasedSchema = config.unaliasSchema(refSchema, config.importMapping());
Schema unaliasedSchema = config.unaliasSchema(refSchema);
if (unaliasedSchema.get$ref() == null) {
LOGGER.info("Model {} not generated since it's a free-form object", name);
continue;
@@ -508,6 +521,11 @@ public class DefaultGenerator implements Generator {
ModelsMap models = allProcessedModels.get(modelName);
models.put("modelPackage", config.modelPackage());
try {
//don't generate models that have a schema mapping
if (config.schemaMapping().containsKey(modelName)) {
continue;
}
// TODO revise below as we've already performed unaliasing so that the isAlias check may be removed
List<ModelMap> modelList = models.getModels();
if (modelList != null && !modelList.isEmpty()) {
@@ -875,6 +893,7 @@ public class DefaultGenerator implements Generator {
if (config.getUseInlineModelResolver()) {
InlineModelResolver inlineModelResolver = new InlineModelResolver();
inlineModelResolver.setInlineSchemaNameMapping(config.inlineSchemaNameMapping());
inlineModelResolver.setInlineSchemaNameDefaults(config.inlineSchemaNameDefault());
inlineModelResolver.flatten(openAPI);
}

View File

@@ -129,7 +129,7 @@ public interface IJsonSchemaValidationProperties {
boolean getHasVars();
void setHasVars(boolean hasRequiredVars);
void setHasVars(boolean hasVars);
boolean getHasRequired();

View File

@@ -42,6 +42,7 @@ public class InlineModelResolver {
private Map<String, Schema> addedModels = new HashMap<>();
private Map<String, String> generatedSignature = new HashMap<>();
private Map<String, String> inlineSchemaNameMapping = new HashMap<>();
private Map<String, String> inlineSchemaNameDefaults = new HashMap<>();
private Set<String> inlineSchemaNameMappingValues = new HashSet<>();
public boolean resolveInlineEnums = false;
@@ -60,11 +61,20 @@ public class InlineModelResolver {
final Logger LOGGER = LoggerFactory.getLogger(InlineModelResolver.class);
public InlineModelResolver() {
this.inlineSchemaNameDefaults.put("arrayItemSuffix", "_inner");
this.inlineSchemaNameDefaults.put("mapItemSuffix", "_value");
}
public void setInlineSchemaNameMapping(Map inlineSchemaNameMapping) {
this.inlineSchemaNameMapping = inlineSchemaNameMapping;
this.inlineSchemaNameMappingValues = new HashSet<>(inlineSchemaNameMapping.values());
}
public void setInlineSchemaNameDefaults(Map inlineSchemaNameDefaults) {
this.inlineSchemaNameDefaults.putAll(inlineSchemaNameDefaults);
}
void flatten(OpenAPI openAPI) {
this.openAPI = openAPI;
@@ -147,6 +157,26 @@ public class InlineModelResolver {
* @param schema target schema
*/
private boolean isModelNeeded(Schema schema) {
return isModelNeeded(schema, new HashSet<>());
}
/**
* Return false if model can be represented by primitives e.g. string, object
* without properties, array or map of other model (model contanier), etc.
* <p>
* Return true if a model should be generated e.g. object with properties,
* enum, oneOf, allOf, anyOf, etc.
*
* @param schema target schema
* @param visitedSchemas Visited schemas
*/
private boolean isModelNeeded(Schema schema, Set<Schema> visitedSchemas) {
if (visitedSchemas.contains(schema)) { // circular reference
return true;
} else {
visitedSchemas.add(schema);
}
if (resolveInlineEnums && schema.getEnum() != null && schema.getEnum().size() > 0) {
return true;
}
@@ -162,7 +192,7 @@ public class InlineModelResolver {
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
// check to ensure at least of the allOf item is model
for (Schema inner : m.getAllOf()) {
if (isModelNeeded(ModelUtils.getReferencedSchema(openAPI, inner))) {
if (isModelNeeded(ModelUtils.getReferencedSchema(openAPI, inner), visitedSchemas)) {
return true;
}
}
@@ -230,7 +260,7 @@ public class InlineModelResolver {
if (schema.getAdditionalProperties() != null) {
if (schema.getAdditionalProperties() instanceof Schema) {
Schema inner = (Schema) schema.getAdditionalProperties();
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + "_value");
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + this.inlineSchemaNameDefaults.get("mapItemSuffix"));
// Recurse to create $refs for inner models
gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) {
@@ -265,7 +295,7 @@ public class InlineModelResolver {
" items must be defined for array schemas:\n " + schema.toString());
return;
}
String schemaName = resolveModelName(items.getTitle(), modelPrefix + "_inner");
String schemaName = resolveModelName(items.getTitle(), modelPrefix + this.inlineSchemaNameDefaults.get("arrayItemSuffix"));
// Recurse to create $refs for inner models
gatherInlineModels(items, schemaName);

View File

@@ -0,0 +1,62 @@
package org.openapitools.codegen;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
public class ObjectWithTypeBooleans {
public boolean isUnboundedInteger;
public boolean isNumber;
public boolean isString;
public boolean isMap;
public boolean isArray;
public boolean isBoolean;
public boolean isNull;
public Object value;
/**
* A wrapper class that is used to store payloads to be ingested by schemas
* This class includes the payload value in the value property
* Other booleans: isUnboundedInteger/isNumber/isString/isMap/isArray/isBoolean/isNull
* allow generator templates to decide how to render each payload into code
* based upon what type it is. The booleans isX describe the value in value.
* @param value the input payload that is stored
*/
public ObjectWithTypeBooleans(Object value) {
Object usedValue = null;
if (value instanceof Integer){
this.isUnboundedInteger = true;
this.value = value;
} else if (value instanceof Double || value instanceof Float){
this.isNumber = true;
this.value = value;
} else if (value instanceof String) {
this.isString = true;
this.value = value;
} else if (value instanceof LinkedHashMap) {
LinkedHashMap<String, Object> castValue = (LinkedHashMap<String, Object>) value;
LinkedHashMap<ObjectWithTypeBooleans, ObjectWithTypeBooleans> castMap = new LinkedHashMap<>();
for (Map.Entry entry: castValue.entrySet()) {
ObjectWithTypeBooleans entryKey = new ObjectWithTypeBooleans(entry.getKey());
ObjectWithTypeBooleans entryValue = new ObjectWithTypeBooleans(entry.getValue());
castMap.put(entryKey, entryValue);
}
this.value = castMap;
this.isMap = true;
} else if (value instanceof ArrayList) {
ArrayList<ObjectWithTypeBooleans> castList = new ArrayList<>();
for (Object item: (ArrayList<Object>) value) {
castList.add(new ObjectWithTypeBooleans(item));
}
this.value = castList;
this.isArray = true;
} else if (value instanceof Boolean) {
this.isBoolean = true;
this.value = value;
} else if (value == null) {
this.isNull = true;
this.value = value;
}
}
}

View File

@@ -0,0 +1,14 @@
package org.openapitools.codegen;
public class SchemaTestCase {
public String description;
public ObjectWithTypeBooleans data;
// true means the test case should pass, false means it should fail
public boolean valid;
public SchemaTestCase(String description, ObjectWithTypeBooleans data, boolean valid) {
this.description = description;
this.data = data;
this.valid = valid;
}
}

View File

@@ -68,7 +68,9 @@ public class CodegenConfigurator {
private Map<String, String> typeMappings = new HashMap<>();
private Map<String, Object> additionalProperties = new HashMap<>();
private Map<String, String> importMappings = new HashMap<>();
private Map<String, String> schemaMappings = new HashMap<>();
private Map<String, String> inlineSchemaNameMappings = new HashMap<>();
private Map<String, String> inlineSchemaNameDefaults = new HashMap<>();
private Set<String> languageSpecificPrimitives = new HashSet<>();
private Map<String, String> reservedWordsMappings = new HashMap<>();
private Map<String, String> serverVariables = new HashMap<>();
@@ -112,9 +114,15 @@ public class CodegenConfigurator {
if(generatorSettings.getImportMappings() != null) {
configurator.importMappings.putAll(generatorSettings.getImportMappings());
}
if(generatorSettings.getSchemaMappings() != null) {
configurator.schemaMappings.putAll(generatorSettings.getSchemaMappings());
}
if(generatorSettings.getInlineSchemaNameMappings() != null) {
configurator.inlineSchemaNameMappings.putAll(generatorSettings.getInlineSchemaNameMappings());
}
if(generatorSettings.getInlineSchemaNameDefaults() != null) {
configurator.inlineSchemaNameDefaults.putAll(generatorSettings.getInlineSchemaNameDefaults());
}
if(generatorSettings.getLanguageSpecificPrimitives() != null) {
configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives());
}
@@ -184,12 +192,24 @@ public class CodegenConfigurator {
return this;
}
public CodegenConfigurator addSchemaMapping(String key, String value) {
this.schemaMappings.put(key, value);
generatorSettingsBuilder.withSchemaMapping(key, value);
return this;
}
public CodegenConfigurator addInlineSchemaNameMapping(String key, String value) {
this.inlineSchemaNameMappings.put(key, value);
generatorSettingsBuilder.withInlineSchemaNameMapping(key, value);
return this;
}
public CodegenConfigurator addInlineSchemaNameDefault(String key, String value) {
this.inlineSchemaNameDefaults.put(key, value);
generatorSettingsBuilder.withInlineSchemaNameDefault(key, value);
return this;
}
public CodegenConfigurator addInstantiationType(String key, String value) {
this.instantiationTypes.put(key, value);
generatorSettingsBuilder.withInstantiationType(key, value);
@@ -344,12 +364,24 @@ public class CodegenConfigurator {
return this;
}
public CodegenConfigurator setSchemaMappings(Map<String, String> schemaMappings) {
this.schemaMappings = schemaMappings;
generatorSettingsBuilder.withSchemaMappings(schemaMappings);
return this;
}
public CodegenConfigurator setInlineSchemaNameMappings(Map<String, String> inlineSchemaNameMappings) {
this.inlineSchemaNameMappings = inlineSchemaNameMappings;
generatorSettingsBuilder.withInlineSchemaNameMappings(inlineSchemaNameMappings);
return this;
}
public CodegenConfigurator setInlineSchemaNameDefaults(Map<String, String> inlineSchemaNameDefaults) {
this.inlineSchemaNameDefaults = inlineSchemaNameDefaults;
generatorSettingsBuilder.withInlineSchemaNameDefaults(inlineSchemaNameDefaults);
return this;
}
public CodegenConfigurator setInputSpec(String inputSpec) {
this.inputSpec = inputSpec;
workflowSettingsBuilder.withInputSpec(inputSpec);
@@ -626,7 +658,9 @@ public class CodegenConfigurator {
config.instantiationTypes().putAll(generatorSettings.getInstantiationTypes());
config.typeMapping().putAll(generatorSettings.getTypeMappings());
config.importMapping().putAll(generatorSettings.getImportMappings());
config.schemaMapping().putAll(generatorSettings.getSchemaMappings());
config.inlineSchemaNameMapping().putAll(generatorSettings.getInlineSchemaNameMappings());
config.inlineSchemaNameDefault().putAll(generatorSettings.getInlineSchemaNameDefaults());
config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives());
config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings());
config.additionalProperties().putAll(generatorSettings.getAdditionalProperties());

View File

@@ -81,6 +81,19 @@ public final class CodegenConfiguratorUtils {
}
}
public static void applySchemaMappingsKvpList(List<String> schemaMappings, CodegenConfigurator configurator) {
for (String propString : schemaMappings) {
applySchemaMappingsKvp(propString, configurator);
}
}
public static void applySchemaMappingsKvp(String schemaMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(schemaMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addSchemaMapping(entry.getKey().trim(), entry.getValue().trim());
}
}
public static void applyInlineSchemaNameMappingsKvpList(List<String> inlineSchemaNameMappings, CodegenConfigurator configurator) {
for (String propString : inlineSchemaNameMappings) {
applyInlineSchemaNameMappingsKvp(propString, configurator);
@@ -94,6 +107,19 @@ public final class CodegenConfiguratorUtils {
}
}
public static void applyInlineSchemaNameDefaultsKvpList(List<String> inlineSchemaNameDefaults, CodegenConfigurator configurator) {
for (String propString : inlineSchemaNameDefaults) {
applyInlineSchemaNameDefaultsKvp(propString, configurator);
}
}
public static void applyInlineSchemaNameDefaultsKvp(String inlineSchemaNameDefaults, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(inlineSchemaNameDefaults);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addInlineSchemaNameDefault(entry.getKey().trim(), entry.getValue().trim());
}
}
public static void applyTypeMappingsKvpList(List<String> typeMappings, CodegenConfigurator configurator) {
for (String propString : typeMappings) {
applyTypeMappingsKvp(propString, configurator);

View File

@@ -170,6 +170,9 @@ public class ExampleGenerator {
kv.put(EXAMPLE, example);
output.add(kv);
}
} else {
kv.put(EXAMPLE, "Custom MIME type example not yet supported: " + mediaType);
output.add(kv);
}
}
} else {

View File

@@ -385,8 +385,8 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
}
@Override
public CodegenProperty fromProperty(String name, Schema p) {
CodegenProperty property = super.fromProperty(name, p);
public CodegenProperty fromProperty(String name, Schema p, boolean required) {
CodegenProperty property = super.fromProperty(name, p, required);
if (property != null) {
String nameInCamelCase = property.nameInCamelCase;
nameInCamelCase = sanitizeName(nameInCamelCase);
@@ -566,7 +566,7 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
if (operation.getResponses() != null && !operation.getResponses().isEmpty()) {
ApiResponse methodResponse = findMethodResponse(operation.getResponses());
if (methodResponse != null && ModelUtils.getSchemaFromResponse(methodResponse) != null) {
CodegenProperty cm = fromProperty("response", ModelUtils.getSchemaFromResponse(methodResponse));
CodegenProperty cm = fromProperty("response", ModelUtils.getSchemaFromResponse(methodResponse), false);
op.vendorExtensions.put("x-codegen-response", cm);
op.vendorExtensions.put("x-is-model-type", isModelType(cm));
op.vendorExtensions.put("x-is-stream-type", isStreamType(cm));

View File

@@ -1070,10 +1070,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
@Override
public String toModelName(String name) {
// We need to check if import-mapping has a different model for this class, so we use it
// We need to check if schema-mapping has a different model for this class, so we use it
// instead of the auto-generated one.
if (importMapping.containsKey(name)) {
return importMapping.get(name);
if (schemaMapping.containsKey(name)) {
return schemaMapping.get(name);
}
// memoization and lookup in the cache
@@ -1410,8 +1410,15 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
} else {
example = "new List<" + p.items.dataType + ">()";
}
} else if (Boolean.TRUE.equals(p.isModel)) {
example = "new " + p.dataType + "()";
} else if (Boolean.TRUE.equals(p.isMap)) {
if (p.items != null) {
example = "new Dictionary<String, " + p.items.dataType + ">";
} else {
// default to String if item is not defined
example = "new Dictionary<String, String>";
}
}
p.example = example;

View File

@@ -251,8 +251,8 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
@SuppressWarnings("rawtypes")
@Override
public CodegenProperty fromProperty(String name, Schema p) {
CodegenProperty property = super.fromProperty(name, p);
public CodegenProperty fromProperty(String name, Schema p, boolean required) {
CodegenProperty property = super.fromProperty(name, p, required);
String nameInCamelCase = property.nameInCamelCase;
if (nameInCamelCase.length() > 1) {
nameInCamelCase = sanitizeName(Character.toLowerCase(nameInCamelCase.charAt(0)) + nameInCamelCase.substring(1));

View File

@@ -109,7 +109,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
apiTestTemplateFiles.put("api_test.mustache", ".dart");
final List<String> reservedWordsList = new ArrayList<>();
try(BufferedReader reader = new BufferedReader(
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(DartClientCodegen.class.getResourceAsStream("/dart/dart-keywords.txt"),
StandardCharsets.UTF_8))) {
while (reader.ready()) {
@@ -445,7 +445,8 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
return underscore(toModelName(name));
}
@Override public String toModelDocFilename(String name) {
@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}
@@ -488,7 +489,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
@Override
public String getTypeDeclaration(Schema p) {
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping);
Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema);
@@ -551,8 +552,8 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
}
@Override
public CodegenProperty fromProperty(String name, Schema p) {
final CodegenProperty property = super.fromProperty(name, p);
public CodegenProperty fromProperty(String name, Schema p, boolean required) {
final CodegenProperty property = super.fromProperty(name, p, required);
// Handle composed properties
if (ModelUtils.isComposedSchema(p)) {
@@ -819,5 +820,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
}
@Override
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.DART; }
public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.DART;
}
}

View File

@@ -177,10 +177,10 @@ public abstract class AbstractEiffelCodegen extends DefaultCodegen implements Co
@Override
public String toModelFilename(String name) {
// We need to check if import-mapping has a different model for this class, so we use it
// We need to check if schema-mapping has a different model for this class, so we use it
// instead of the auto-generated one.
if (importMapping.containsKey(name)) {
return importMapping.get(name);
if (schemaMapping.containsKey(name)) {
return schemaMapping.get(name);
}
if (!StringUtils.isEmpty(modelNamePrefix)) {

View File

@@ -346,7 +346,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// specification is aligned with the JSON schema specification.
// When "items" is not specified, the elements of the array may be anything at all.
if (inner != null) {
inner = ModelUtils.unaliasSchema(this.openAPI, inner);
inner = unaliasSchema(inner);
}
String typDecl;
if (inner != null) {
@@ -360,10 +360,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
return "[]" + typDecl;
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = getAdditionalProperties(p);
return getSchemaType(p) + "[string]" + getTypeDeclaration(ModelUtils.unaliasSchema(this.openAPI, inner));
return getSchemaType(p) + "[string]" + getTypeDeclaration(unaliasSchema(inner));
}
//return super.getTypeDeclaration(p);
//return super.getTypeDeclaration(p);
// Not using the supertype invocation, because we want to UpperCamelize
// the type.
String openAPIType = getSchemaType(p);
@@ -792,7 +792,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
public String toDefaultValue(Schema schema) {
schema = ModelUtils.unaliasSchema(this.openAPI, schema);
schema = unaliasSchema(schema);
if (schema.getDefault() != null) {
return schema.getDefault().toString();
} else {

View File

@@ -824,6 +824,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String toModelName(final String name) {
// We need to check if schema-mapping has a different model for this class, so we use it
// instead of the auto-generated one.
if (schemaMapping.containsKey(name)) {
return schemaMapping.get(name);
}
final String sanitizedName = sanitizeName(name);
String nameWithPrefixSuffix = sanitizedName;
@@ -867,7 +873,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String getTypeDeclaration(Schema p) {
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping);
Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema);
@@ -1330,6 +1336,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (property.isReadOnly) {
model.getVendorExtensions().put("x-has-readonly-properties", true);
}
// if data type happens to be the same as the property name and both are upper case
if (property.dataType != null && property.dataType.equals(property.name) && property.dataType.toUpperCase(Locale.ROOT).equals(property.name)) {
property.name = property.name.toLowerCase(Locale.ROOT);
}
}
@Override
@@ -2042,6 +2053,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
}
/**
* Search for property by {@link CodegenProperty#name}
* @param name - name to search for
* @param properties - list of properties
* @return either found property or {@link Optional#empty()} if nothing has been found
*/
protected Optional<CodegenProperty> findByName(String name, List<CodegenProperty> properties) {
if (properties == null || properties.isEmpty()) {
return Optional.empty();
}
return properties.stream()
.filter(p -> p.name.equals(name))
.findFirst();
}
/**
* This method removes all implicit header parameters from the list of parameters
*

View File

@@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.apache.commons.io.FilenameUtils;
@@ -364,7 +365,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
*/
@Override
public String getTypeDeclaration(Schema p) {
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping);
Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema);
@@ -673,6 +674,12 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
return name;
}
// If schemaMapping contains name, assume this is a legitimate model name.
if (schemaMapping.containsKey(name)) {
return schemaMapping.get(name);
}
// TODO review importMapping below as we've added schema mapping support
// If importMapping contains name, assume this is a legitimate model name.
if (importMapping.containsKey(name)) {
return importMapping.get(name);
@@ -1045,4 +1052,30 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.KOTLIN;
}
@Override
protected void updateModelForObject(CodegenModel m, Schema schema) {
/**
* we have a custom version of this function so we only set isMap to true if
* ModelUtils.isMapSchema
* In other generators, isMap is true for all type object schemas
*/
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);
}
if (ModelUtils.isMapSchema(schema)) {
// an object or anyType composed schema that has additionalProperties set
addAdditionPropertiesToCodeGenModel(m, schema);
} else {
m.setIsMap(false);
if (ModelUtils.isFreeFormObject(openAPI, schema)) {
// non-composed object type with no properties + additionalProperties
// additionalProperties must be null, ObjectSchema, or empty Schema
addAdditionPropertiesToCodeGenModel(m, schema);
}
}
// process 'additionalProperties'
setAddProps(schema, m);
}
}

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