forked from loafle/openapi-generator-original
Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2353d71d4b | ||
|
|
2f4dc9a049 | ||
|
|
54b5093381 | ||
|
|
cf2ddb8b8c | ||
|
|
8f8d3547f6 | ||
|
|
eae958f293 | ||
|
|
6930433def | ||
|
|
c537557a91 | ||
|
|
f7c857cc39 | ||
|
|
777bf1f3aa | ||
|
|
41185d3c6f | ||
|
|
1d4e24b203 | ||
|
|
c63f58f1ef | ||
|
|
9df70798b3 | ||
|
|
3efe56752e | ||
|
|
d8dde6855f | ||
|
|
ebf67e683c | ||
|
|
9b99b6b6bf | ||
|
|
33016f2790 | ||
|
|
963173b357 | ||
|
|
d31fa4f7c4 | ||
|
|
247bd68880 | ||
|
|
4eae430cca | ||
|
|
51a3a22928 | ||
|
|
46a4ffe64c | ||
|
|
ce0253892c | ||
|
|
bf2932d41c | ||
|
|
f8ada391c4 | ||
|
|
0ba9278308 | ||
|
|
e91d6d735d | ||
|
|
dd33434064 | ||
|
|
cf04ba30db | ||
|
|
5aa1da7c2e | ||
|
|
9be5b99266 | ||
|
|
792f95eb09 | ||
|
|
2b58f6737a | ||
|
|
363b095721 | ||
|
|
b9949e1a8e | ||
|
|
f58bd6d839 | ||
|
|
0e693cd9a8 | ||
|
|
7f8ff35245 | ||
|
|
2c418e1b71 | ||
|
|
941b3ea015 | ||
|
|
c656194f22 | ||
|
|
5b57eae5de | ||
|
|
edc05df774 | ||
|
|
6ab6896a13 | ||
|
|
32b8d7fee7 | ||
|
|
dc3a3dd15a | ||
|
|
8d9542207a | ||
|
|
31d9928734 | ||
|
|
e5c0d227ab | ||
|
|
653601bef2 | ||
|
|
7564d629e7 | ||
|
|
f647b2f24b | ||
|
|
0165b0fb33 | ||
|
|
df1819daa9 | ||
|
|
3c28946f1e | ||
|
|
22902e72a1 | ||
|
|
efde4a8eb8 | ||
|
|
c8837ea414 | ||
|
|
7c3a2a5c07 | ||
|
|
7e3149e675 | ||
|
|
9db62f459a | ||
|
|
c7349c7f88 | ||
|
|
69a766882d | ||
|
|
7ce38aae38 | ||
|
|
fd46b4e566 | ||
|
|
5711985ac3 | ||
|
|
7c6beb9692 | ||
|
|
f802e63f9f | ||
|
|
0ed02c8e91 | ||
|
|
93e2fc6355 | ||
|
|
60bc19e830 | ||
|
|
4742f0086b | ||
|
|
1522855915 | ||
|
|
3969afb2ff | ||
|
|
2ef499faf3 | ||
|
|
34945427d4 | ||
|
|
5849dbaaca | ||
|
|
73162cbcca | ||
|
|
0e2e1bf715 | ||
|
|
f21640f6a1 | ||
|
|
301208a785 | ||
|
|
4245cf42dd | ||
|
|
2184a8a9b4 | ||
|
|
30bfebfa16 | ||
|
|
303b469fae | ||
|
|
c95b1f4545 | ||
|
|
fbc3ff8766 | ||
|
|
63b1c233c9 | ||
|
|
eb5a8cc752 | ||
|
|
293d29ab3b | ||
|
|
078b04deac | ||
|
|
7eb9cda1e0 | ||
|
|
ac6fd3f79f | ||
|
|
f8f3a08282 | ||
|
|
36991a4e14 | ||
|
|
ecff8b5d00 | ||
|
|
521f5fafa3 | ||
|
|
02e85cc417 |
26
.travis.yml
26
.travis.yml
@@ -51,9 +51,9 @@ addons:
|
||||
|
||||
before_install:
|
||||
# install haskell
|
||||
- curl -sSL https://get.haskellstack.org/ | sh
|
||||
- stack upgrade
|
||||
- stack --version
|
||||
#- curl -sSL https://get.haskellstack.org/ | sh
|
||||
#- stack upgrade
|
||||
#- stack --version
|
||||
# install rust
|
||||
- curl https://sh.rustup.rs -sSf | sh -s -- -y -v
|
||||
# required when sudo: required for the Ruby petstore tests
|
||||
@@ -75,11 +75,11 @@ before_install:
|
||||
- sudo apt-get install -qq curl
|
||||
# install dart
|
||||
#- sudo apt-get update
|
||||
- sudo apt-get install apt-transport-https
|
||||
- sudo sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
|
||||
- sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install dart
|
||||
#- sudo apt-get install apt-transport-https
|
||||
#- sudo sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
|
||||
#- sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
|
||||
#- sudo apt-get update
|
||||
#- sudo apt-get install dart
|
||||
# install perl module
|
||||
#- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
|
||||
#- cpanm Test::Exception Test::More Log::Any LWP::UserAgent JSON URI:Query Module::Runtime DateTime Module::Find Moose::Role
|
||||
@@ -109,8 +109,8 @@ install:
|
||||
- gcc -v
|
||||
- echo $CC
|
||||
- echo $CXX
|
||||
- pub version
|
||||
- dart --version
|
||||
#- pub version
|
||||
#- dart --version
|
||||
|
||||
script:
|
||||
# fail fast
|
||||
@@ -122,8 +122,8 @@ script:
|
||||
# fail if generators contain tab '\t'
|
||||
- /bin/bash ./bin/utils/detect_tab_in_java_class.sh
|
||||
# run integration tests defined in maven pom.xml
|
||||
- mvn --quiet clean install
|
||||
- mvn --quiet verify -Psamples
|
||||
- ./run-in-docker.sh mvn --quiet --batch-mode clean install
|
||||
- mvn --quiet --batch-mode verify -Psamples
|
||||
after_success:
|
||||
# push to maven repo
|
||||
- if [ $SONATYPE_USERNAME ] && [ -z $TRAVIS_TAG ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
@@ -148,7 +148,7 @@ after_success:
|
||||
## docker: build and push openapi-generator-online to DockerHub
|
||||
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && docker build -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_GENERATOR_IMAGE_NAME:latest $DOCKER_GENERATOR_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_GENERATOR_IMAGE_NAME && echo "Pushed to $DOCKER_GENERATOR_IMAGE_NAME"; fi; fi
|
||||
## docker: build cli image and push to Docker Hub
|
||||
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && docker build -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME && echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME"; fi; fi
|
||||
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && cp docker-entrypoint.sh ./modules/openapi-generator-cli && docker build -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME && echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME"; fi; fi
|
||||
|
||||
env:
|
||||
- DOCKER_GENERATOR_IMAGE_NAME=openapitools/openapi-generator-online DOCKER_CODEGEN_CLI_IMAGE_NAME=openapitools/openapi-generator-cli NODE_ENV=test CC=gcc-5 CXX=g++-5
|
||||
|
||||
72
README.md
72
README.md
@@ -2,16 +2,11 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.2`): [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.4`): [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
||||
|
||||
[`3.4.x`](https://github.com/OpenAPITools/openapi-generator/tree/3.4.x) branch: [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
||||
|
||||
[`4.0.x`](https://github.com/OpenAPITools/openapi-generator/tree/4.0.x) branch: [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
||||
@@ -47,7 +42,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
|
||||
|
||||
| | Languages/Frameworks |
|
||||
|-|-|
|
||||
**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 7.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node)
|
||||
**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 7.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node)
|
||||
**Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **Go** (net/http, Gin), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples)), **Kotlin** (Spring Boot), **PHP** (Laravel, Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), Scalatra)
|
||||
**API documentation generators** | **HTML**, **Confluence Wiki**
|
||||
**Configuration files** | [**Apache2**](https://httpd.apache.org/)
|
||||
@@ -65,6 +60,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
|
||||
- [1.4 - Build Projects](#14---build-projects)
|
||||
- [1.5 - Homebrew](#15---homebrew)
|
||||
- [1.6 - Docker](#16---docker)
|
||||
- [1.7 - NPM](#17---npm)
|
||||
- [2 - Getting Started](#2---getting-started)
|
||||
- [3 - Usage](#3---usage)
|
||||
- [3.1 - Customization](#31---customization)
|
||||
@@ -87,10 +83,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
|
||||
|
||||
OpenAPI Generator Version | Release Date | Notes
|
||||
---------------------------- | ------------ | -----
|
||||
4.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/)| TBD | Major release with breaking changes (no fallback)
|
||||
3.4.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.4.0-SNAPSHOT/)| 01.11.2018 | Minor release (breaking changes with fallbacks)
|
||||
3.3.2 (current master, upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.3.2-SNAPSHOT/) | 31.10.2018 | Bugfix release
|
||||
[3.3.2](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.3.2) (latest stable release) | 31.10.2018 | Bugfix release
|
||||
4.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/)| 20.12.2018 | Major release with breaking changes (with or without fallback)
|
||||
[3.3.4](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.3.4) (latest stable release) | 30.11.2018 | Bugfix release
|
||||
|
||||
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
|
||||
|
||||
@@ -146,16 +140,16 @@ See the different versions of the [openapi-generator-cli](https://mvnrepository.
|
||||
|
||||
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: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar`
|
||||
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.4/openapi-generator-cli-3.3.4.jar`
|
||||
|
||||
For **Mac/Linux** users:
|
||||
```sh
|
||||
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar -O openapi-generator-cli.jar
|
||||
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.4/openapi-generator-cli-3.3.4.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 http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar
|
||||
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.4/openapi-generator-cli-3.3.4.jar
|
||||
```
|
||||
|
||||
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
|
||||
@@ -215,7 +209,7 @@ To build from source, you need the following installed and available in your `$P
|
||||
|
||||
* [Java 8](http://java.oracle.com)
|
||||
|
||||
* [Apache maven 3.3.3 or greater](http://maven.apache.org/)
|
||||
* [Apache maven 3.3.4 or greater](http://maven.apache.org/)
|
||||
|
||||
After cloning the project, you can build it from source with this command:
|
||||
```sh
|
||||
@@ -284,13 +278,13 @@ GEN_IP=$(docker inspect --format '{{.NetworkSettings.IPAddress}}' $CID)
|
||||
-d '{"openAPIUrl": "https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml"}' \
|
||||
'http://localhost:8888/api/gen/clients/ruby'
|
||||
|
||||
{"code":"c2d483d3-3672-40e9-91df-b9ffd18d22b8","link":"http://localhost:8888/api/gen/download/c2d483d3-3672-40e9-91df-b9ffd18d22b8"}
|
||||
{"code":"c2d483.3.4672-40e9-91df-b9ffd18d22b8","link":"http://localhost:8888/api/gen/download/c2d483.3.4672-40e9-91df-b9ffd18d22b8"}
|
||||
|
||||
# Download the generated zip file
|
||||
> wget http://localhost:8888/api/gen/download/c2d483d3-3672-40e9-91df-b9ffd18d22b8
|
||||
> wget http://localhost:8888/api/gen/download/c2d483.3.4672-40e9-91df-b9ffd18d22b8
|
||||
|
||||
# Unzip the file
|
||||
> unzip c2d483d3-3672-40e9-91df-b9ffd18d22b8
|
||||
> unzip c2d483.3.4672-40e9-91df-b9ffd18d22b8
|
||||
|
||||
# Shutdown the openapi generator image
|
||||
> docker stop $CID && docker rm $CID
|
||||
@@ -346,6 +340,30 @@ cd /vagrant
|
||||
./run-in-docker.sh mvn package
|
||||
```
|
||||
|
||||
### [1.7 - NPM](#table-of-contents)
|
||||
|
||||
There is also an [NPM package wrapper](https://www.npmjs.com/package/@openapitools/openapi-generator-cli) available for different platforms (e.g. Linux, Mac, Windows). (JVM is still required)
|
||||
Please see the [project's README](https://github.com/openapitools/openapi-generator-cli) there for more information.
|
||||
|
||||
Install it globally to get the CLI available on the command line:
|
||||
|
||||
```sh
|
||||
npm install @openapitools/openapi-generator-cli -g
|
||||
openapi-generator version
|
||||
```
|
||||
|
||||
Or install a particualar OpenAPI Generator version (e.g. v3.3.4):
|
||||
|
||||
```sh
|
||||
npm install @openapitools/openapi-generator-cli@cli-3.3.4 -g
|
||||
```
|
||||
|
||||
Or install it as dev-dependency:
|
||||
|
||||
```sh
|
||||
npm install @openapitools/openapi-generator-cli -D
|
||||
```
|
||||
|
||||
## [2 - Getting Started](#table-of-contents)
|
||||
|
||||
To generate a PHP client for [petstore.yaml](https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml), please run the following
|
||||
@@ -451,7 +469,7 @@ Other languages have petstore samples, too:
|
||||
./bin/objc-petstore.sh
|
||||
```
|
||||
|
||||
... and others. [Here is a list of all scripts.](wiki/Samples-folder#scripts)
|
||||
... and others. [Here is a list of all scripts.](https://github.com/OpenAPITools/openapi-generator/wiki/Samples-folder#scripts)
|
||||
|
||||
### [3.1 - Customization](#table-of-contents)
|
||||
|
||||
@@ -463,6 +481,15 @@ Please refer to [integration.md](docs/integration.md) on how to integrate OpenAP
|
||||
|
||||
### [3.3 - Online OpenAPI generator](#table-of-contents)
|
||||
|
||||
Here are the public online services:
|
||||
|
||||
- latest stable version: http://api.openapi-generator.tech
|
||||
- latest master: http://api-latest-master.openapi-generator.tech (updated with latest master every hour)
|
||||
|
||||
The server is sponsored by [Linode](https://www.linode.com/) [](https://www.linode.com/)
|
||||
|
||||
(These services are beta and do not have any guarantee on service level)
|
||||
|
||||
Please refer to [online-openapi-generator.md](docs/online-openapi-generator.md) on how to run and use the `openapi-generator-online` - a web service for `openapi-generator`.
|
||||
|
||||
### [3.4 - License information on Generated Code](#table-of-contents)
|
||||
@@ -478,6 +505,7 @@ When code is generated from this project, it shall be considered **AS IS** and o
|
||||
Here are some companies/projects (alphabetical order) using OpenAPI Generator in production. To add your company/project to the list, please visit [README.md](README.md) and click on the icon to edit the page.
|
||||
|
||||
- [Angular.Schule](https://angular.schule/)
|
||||
- [b<>com](https://b-com.com/en)
|
||||
- [Bithost GmbH](https://www.bithost.ch)
|
||||
- [Boxever](https://www.boxever.com/)
|
||||
- [GMO Pepabo](https://pepabo.com/en/)
|
||||
@@ -489,6 +517,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
|
||||
- [REST United](https://restunited.com)
|
||||
- [Suva](https://www.suva.ch/)
|
||||
- [Telstra](https://dev.telstra.com)
|
||||
- [TUI InfoTec GmbH](http://www.tui-infotec.com/)
|
||||
- [unblu inc.](https://www.unblu.com/)
|
||||
- [Zalando](https://www.zalando.com)
|
||||
|
||||
@@ -503,7 +532,8 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
|
||||
- 2018/07/19 - [OpenAPI Generator Contribution Quickstart - RingCentral Go SDK](https://medium.com/ringcentral-developers/openapi-generator-for-go-contribution-quickstart-8cc72bf37b53) by [John Wang](https://github.com/grokify)
|
||||
- 2018/08/22 - [OpenAPI Generatorのプロジェクト構成などのメモ](https://yinm.info/20180822/) by [Yusuke Iinuma](https://github.com/yinm)
|
||||
- 2018/10/31 - [A node package wrapper for openapi-generator](https://github.com/HarmoWatch/openapi-generator-cli)
|
||||
|
||||
- 2018/11/03 - [OpenAPI Generator + golang + Flutter でアプリ開発](http://ryuichi111std.hatenablog.com/entry/2018/11/03/214005) by [Ryuichi Daigo](https://github.com/ryuichi111)
|
||||
- 2018/11/19 - [OpenAPIs are everywhere](https://youtu.be/-lDot4Yn7Dg) by [Jeremie Bresson (Unblu)](https://github.com/jmini) at [EclipseCon Europe 2018](https://www.eclipsecon.org/europe2018)
|
||||
|
||||
## [6 - About Us](#table-of-contents)
|
||||
|
||||
@@ -527,6 +557,7 @@ Here is a list of template creators:
|
||||
* Akka-Scala: @cchafer
|
||||
* Apex: @asnelling
|
||||
* Bash: @bkryza
|
||||
* C: @PowerOfCreation @zhemant
|
||||
* C++ REST: @Danielku15
|
||||
* C# (.NET 2.0): @who
|
||||
* C# (.NET Standard 1.3 ): @Gronsak
|
||||
@@ -655,6 +686,7 @@ If you want to join the committee, please kindly apply by sending an email to te
|
||||
| Android | @jaz-ah (2017/09) |
|
||||
| Apex | |
|
||||
| Bash | @frol (2017/07) @bkryza (2017/08) @kenjones-cisco (2017/09) |
|
||||
| C | @zhemant (2018/11) |
|
||||
| C++ | @ravinikam (2017/07) @stkrwork (2017/07) @fvarose (2017/11) @etherealjoy (2018/02) @martindelille (2018/03) |
|
||||
| C# | @mandrean (2017/08) @jimschubert (2017/09) |
|
||||
| Clojure | |
|
||||
|
||||
32
bin/c-petstore.sh
Executable file
32
bin/c-petstore.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
echo "# START SCRIPT: $SCRIPT"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn -B clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/C-libcurl -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g c -o samples/client/petstore/c $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
17
bin/csharp-refactor-petstore-all.sh
Executable file
17
bin/csharp-refactor-petstore-all.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
# C# Petstore API client (.NET 3.5)
|
||||
./bin/csharp-refactor-petstore.sh
|
||||
|
||||
# C# Petstore API client with PropertyChanged
|
||||
./bin/csharp-refactor-property-changed-petstore.sh
|
||||
|
||||
# C# Petstore API client (v5.0 for .net standarnd 1.3+)
|
||||
./bin/csharp-refactor-petstore-net-standard.sh
|
||||
|
||||
# C# Petstore API client (.NET 4.0)
|
||||
./bin/csharp-refactor-petstore-net-40.sh
|
||||
|
||||
# C# Petstore API client (.NET 3.5)
|
||||
./bin/csharp-refactor-petstore-net-35.sh
|
||||
|
||||
37
bin/csharp-refactor-petstore.sh
Executable file
37
bin/csharp-refactor-petstore.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
echo "# START SCRIPT: $SCRIPT"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn -B clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp-refactor -o samples/client/petstore/csharp-refactor/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
# restore csproj file
|
||||
#echo "restore csproject file: CI/samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
|
||||
#cp ./CI/samples.ci/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/
|
||||
|
||||
@@ -27,6 +27,6 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g cwiki -o samples/documentation/cwiki $@"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/confluenceWikiDocs -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g cwiki -o samples/documentation/cwiki $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
@@ -27,6 +27,6 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g html -o samples/documentation/html $@"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/htmlDocs -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g html -o samples/documentation/html $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
0
bin/mysql-schema-petstore.sh
Normal file → Executable file
0
bin/mysql-schema-petstore.sh
Normal file → Executable file
@@ -25,8 +25,13 @@ then
|
||||
mvn clean package
|
||||
fi
|
||||
|
||||
# purge lib/doc folder
|
||||
echo "purge ruby petstore lib, docs folder"
|
||||
rm -Rf samples/openapi3/client/petstore/ruby/lib
|
||||
rm -Rf samples/openapi3/client/petstore/ruby/docs
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/ruby-client -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ruby -c bin/ruby-petstore.json -o samples/client/petstore/ruby -DskipFormModel=true $@"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/ruby-client -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ruby -c bin/ruby-petstore.json -o samples/openapi3/client/petstore/ruby -DskipFormModel=true $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
0
bin/springboot-virtualan-petstore-server.sh
Normal file → Executable file
0
bin/springboot-virtualan-petstore-server.sh
Normal file → Executable file
@@ -27,6 +27,6 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -i modules/openapi-generator/src/test\resources/2_0/petstore.yaml -g typescript-angular -c bin/typescript-angular-v6-petstore-not-provided-in-root-with-npm.json -o samples/client/petstore/typescript-angular-v6-not-provided-in-root/builds/with-npm -D providedInRoot=false --additional-properties ngVersion=6.0.0 $@"
|
||||
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g typescript-angular -c bin/typescript-angular-v6-petstore-not-provided-in-root-with-npm.json -o samples/client/petstore/typescript-angular-v6-not-provided-in-root/builds/with-npm -D providedInRoot=false --additional-properties ngVersion=6.0.0 $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
@@ -27,6 +27,6 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -i modules/openapi-generator/src/test\resources/2_0/petstore.yaml -g typescript-angular -o samples/client/petstore/typescript-angular-v6-not-provided-in-root/builds/default -D providedInRoot=false --additional-properties ngVersion=6.0.0 $@"
|
||||
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g typescript-angular -o samples/client/petstore/typescript-angular-v6-not-provided-in-root/builds/default -D providedInRoot=false --additional-properties ngVersion=6.0.0 $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
|
||||
@@ -10,34 +10,44 @@ echo "Please press CTRL+C to stop or the script will continue in 5 seconds."
|
||||
sleep 5
|
||||
|
||||
# LIST OF SCRIPTS:
|
||||
./bin/openapi3/ruby-client-petstore.sh > /dev/null 2>&1
|
||||
./bin/java-petstore-all.sh > /dev/null 2>&1
|
||||
./bin/java-jaxrs-petstore-server-all.sh > /dev/null 2>&1
|
||||
./bin/openapi3/jaxrs-jersey-petstore.sh > /dev/null 2>&1
|
||||
./bin/spring-all-pestore.sh > /dev/null 2>&1
|
||||
./bin/kotlin-client-petstore.sh > /dev/null 2>&1
|
||||
./bin/kotlin-client-string.sh > /dev/null 2>&1
|
||||
./bin/kotlin-client-threetenbp.sh > /dev/null 2>&1
|
||||
./bin/kotlin-server-petstore.sh > /dev/null 2>&1
|
||||
./bin/mysql-schema-petstore.sh > /dev/null 2>&1
|
||||
./bin/php-petstore.sh > /dev/null 2>&1
|
||||
./bin/php-silex-petstore-server.sh > /dev/null 2>&1
|
||||
./bin/php-symfony-petstore.sh > /dev/null 2>&1
|
||||
./bin/php-lumen-petstore-server.sh > /dev/null 2>&1
|
||||
./bin/php-slim-server-petstore.sh > /dev/null 2>&1
|
||||
./bin/php-ze-ph-petstore-server.sh > /dev/null 2>&1
|
||||
./bin/openapi3/php-petstore.sh > /dev/null 2>&1
|
||||
./bin/typescript-angular-petstore-all.sh > /dev/null 2>&1
|
||||
./bin/typescript-fetch-petstore-all.sh > /dev/null 2>&1
|
||||
./bin/typescript-node-petstore-all.sh > /dev/null 2>&1
|
||||
./bin/typescript-inversify-petstore.sh > /dev/null 2>&1
|
||||
./bin/rust-server-petstore.sh > /dev/null 2>&1
|
||||
./bin/haskell-http-client-petstore.sh > /dev/null 2>&1
|
||||
./bin/csharp-petstore.sh > /dev/null 2>&1
|
||||
./bin/meta-codegen.sh > /dev/null 2>&1
|
||||
./bin/utils/export_docs_generators.sh > /dev/null 2>&1
|
||||
./bin/go-petstore.sh > /dev/null 2>&1
|
||||
./bin/go-gin-petstore-server.sh > /dev/null 2>&1
|
||||
declare -a scripts=("./bin/openapi3/ruby-client-petstore.sh"
|
||||
"./bin/ruby-client-petstore.sh"
|
||||
"./bin/java-petstore-all.sh"
|
||||
"./bin/java-jaxrs-petstore-server-all.sh"
|
||||
"./bin/openapi3/jaxrs-jersey-petstore.sh"
|
||||
"./bin/spring-all-pestore.sh"
|
||||
"./bin/kotlin-client-petstore.sh"
|
||||
"./bin/kotlin-client-string.sh"
|
||||
"./bin/kotlin-client-threetenbp.sh"
|
||||
"./bin/kotlin-server-petstore.sh"
|
||||
"./bin/mysql-schema-petstore.sh"
|
||||
"./bin/php-petstore.sh"
|
||||
"./bin/php-silex-petstore-server.sh"
|
||||
"./bin/php-symfony-petstore.sh"
|
||||
"./bin/php-lumen-petstore-server.sh"
|
||||
"./bin/php-slim-server-petstore.sh"
|
||||
"./bin/php-ze-ph-petstore-server.sh"
|
||||
"./bin/openapi3/php-petstore.sh"
|
||||
"./bin/typescript-angular-petstore-all.sh"
|
||||
"./bin/typescript-fetch-petstore-all.sh"
|
||||
"./bin/typescript-node-petstore-all.sh"
|
||||
"./bin/typescript-inversify-petstore.sh"
|
||||
"./bin/rust-server-petstore.sh"
|
||||
"./bin/haskell-http-client-petstore.sh"
|
||||
"./bin/csharp-petstore.sh"
|
||||
"./bin/meta-codegen.sh"
|
||||
"./bin/utils/export_docs_generators.sh"
|
||||
"./bin/go-petstore.sh"
|
||||
"./bin/go-gin-petstore-server.sh")
|
||||
|
||||
for script in "${scripts[@]}"; do
|
||||
if eval $script > /dev/null 2>&1; then
|
||||
echo "Executed $script successfully!"
|
||||
else
|
||||
echo "ERROR: Failed to run $script"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check:
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
|
||||
28
bin/utils/test-fake-petstore-for-all.sh
Executable file
28
bin/utils/test-fake-petstore-for-all.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# A script to test all generators to ensure there's no Java exception when running it with OAS 2.0, 3.0 fake petstore spec
|
||||
#
|
||||
|
||||
SCRIPT="$0"
|
||||
echo "# START SCRIPT: ${SCRIPT}"
|
||||
|
||||
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||
|
||||
for GENERATOR in $(java -jar ${executable} list --short | sed -e 's/,/\'$'\n''/g')
|
||||
do
|
||||
if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR} > /dev/null 2>&1; then
|
||||
echo "[OAS 2.0] Executed ${GENERATOR} successfully!"
|
||||
else
|
||||
echo "ERROR: Failed to run ${GENERATOR}"
|
||||
echo "java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/3.0/${GENERATOR} > /dev/null 2>&1; then
|
||||
echo "[OAS 3.0] Executed ${GENERATOR} successfully!"
|
||||
else
|
||||
echo "ERROR: Failed to run ${GENERATOR}"
|
||||
echo "java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/3.0/${GENERATOR}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
10
bin/windows/c-petstore.bat
Executable file
10
bin/windows/c-petstore.bat
Executable file
@@ -0,0 +1,10 @@
|
||||
set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
|
||||
|
||||
If Not Exist %executable% (
|
||||
mvn clean package
|
||||
)
|
||||
|
||||
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
|
||||
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g c -o samples\client\petstore\c
|
||||
|
||||
java %JAVA_OPTS% -jar %executable% %ags%
|
||||
@@ -19,6 +19,9 @@ CONFIG OPTIONS for kotlin-server
|
||||
enumPropertyNaming
|
||||
Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original' (Default: camelCase)
|
||||
|
||||
parcelizeModels
|
||||
toggle "@Parcelize" for generated models
|
||||
|
||||
library
|
||||
library template (sub-template) to use (Default: ktor)
|
||||
ktor - ktor framework
|
||||
|
||||
@@ -19,6 +19,9 @@ CONFIG OPTIONS for kotlin-spring
|
||||
enumPropertyNaming
|
||||
Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original' (Default: camelCase)
|
||||
|
||||
parcelizeModels
|
||||
toggle "@Parcelize" for generated models
|
||||
|
||||
title
|
||||
server title name or client service name (Default: OpenAPI Kotlin Spring)
|
||||
|
||||
|
||||
@@ -19,10 +19,18 @@ CONFIG OPTIONS for kotlin
|
||||
enumPropertyNaming
|
||||
Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original' (Default: camelCase)
|
||||
|
||||
parcelizeModels
|
||||
toggle "@Parcelize" for generated models
|
||||
|
||||
dateLibrary
|
||||
Option. Date library to use
|
||||
string - String
|
||||
java8 - Java 8 native JSR310
|
||||
threetenbp - Threetenbp
|
||||
|
||||
collectionType
|
||||
Option. Collection type to use
|
||||
array - kotlin.Array
|
||||
list - kotlin.collections.List
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
|
||||
@@ -5,6 +5,6 @@ CONFIG OPTIONS for rust-server
|
||||
Rust crate name (convention: snake_case). (Default: openapi_client)
|
||||
|
||||
packageVersion
|
||||
Rust crate version. (Default: 1.0.0)
|
||||
Rust crate version.
|
||||
|
||||
Back to the [generators list](README.md)
|
||||
|
||||
@@ -170,6 +170,9 @@ CONFIG OPTIONS for spring
|
||||
hateoas
|
||||
Use Spring HATEOAS library to allow adding HATEOAS links (Default: false)
|
||||
|
||||
returnSuccessCode
|
||||
Generated server returns 2xx code (Default: false)
|
||||
|
||||
library
|
||||
library template (sub-template) to use (Default: spring-boot)
|
||||
spring-boot - Spring-boot Server application using the SpringFox integration.
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
## Online OpenAPI generator
|
||||
|
||||
One can also generate API client or server using the online openapi-generator.
|
||||
One can also generate API clients or server stubs using the online openapi-generator.
|
||||
|
||||
Here are the steps to run it locally:
|
||||
Here are the public online services:
|
||||
|
||||
- latest stable version: http://api.openapi-generator.tech
|
||||
- latest master: http://api-latest-master.openapi-generator.tech (updated with latest master every hour)
|
||||
|
||||
The server is sponsored by [Linode](https://www.linode.com/) [](https://www.linode.com/)
|
||||
|
||||
(These services are beta and do not have any guarantee on service level)
|
||||
|
||||
If you prefer to run the service locally, here are the steps:
|
||||
```
|
||||
mvn clean install
|
||||
cd modules/openapi-generator-online
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
:bulb: The online openapi-generator can be run via [Docker](https://github.com/OpenAPITools/openapi-generator#16---docker) as well.
|
||||
|
||||
For example, to generate Ruby API client, simply send the following HTTP request using curl:
|
||||
```sh
|
||||
curl -X POST -H "content-type:application/json" -d '{"openAPIUrl":"https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml"}' http://localhost:8080/api/gen/clients/ruby
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
FROM java:8-jre-alpine
|
||||
|
||||
ADD target/openapi-generator-cli.jar /opt/openapi-generator-cli/openapi-generator-cli.jar
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
ENTRYPOINT ["java", "-jar", "/opt/openapi-generator-cli/openapi-generator-cli.jar"]
|
||||
ADD target/openapi-generator-cli.jar /opt/openapi-generator/modules/openapi-generator-cli/target/openapi-generator-cli.jar
|
||||
|
||||
CMD ["help"]
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
|
||||
CMD ["help"]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
|
||||
import static org.openapitools.codegen.config.CodegenConfiguratorUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
@@ -246,6 +247,11 @@ public class Generate implements Runnable {
|
||||
}
|
||||
|
||||
if (isNotEmpty(spec)) {
|
||||
if (!spec.matches("^http(s)?://.*") && !new File(spec).exists()) {
|
||||
System.err.println("[error] The spec file is not found: " + spec);
|
||||
System.err.println("[error] Check the path of the OpenAPI spec and try again.");
|
||||
System.exit(1);
|
||||
}
|
||||
configurator.setInputSpec(spec);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public class GenerateTest {
|
||||
|
||||
@Test
|
||||
public void testRequiredArgs_ShortArgs() throws Exception {
|
||||
setupAndRunTest("-i", "swagger.yaml", "-g", "java", "-o", "src/main/java", false, null);
|
||||
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", false, null);
|
||||
new FullVerifications() {
|
||||
{
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public class GenerateTest {
|
||||
|
||||
@Test
|
||||
public void testRequiredArgs_LongArgs() throws Exception {
|
||||
setupAndRunTest("--input-spec", "swagger.yaml", "--generator-name", "java", "--output",
|
||||
setupAndRunTest("--input-spec", "src/test/resources/swagger.yaml", "--generator-name", "java", "--output",
|
||||
"src/main/java", false, null);
|
||||
new FullVerifications() {
|
||||
{
|
||||
@@ -220,7 +220,7 @@ public class GenerateTest {
|
||||
@Test
|
||||
public void testConfig() throws Exception {
|
||||
|
||||
setupAndRunTest("-i", "swagger.yaml", "-g", "java", "-o", "src/main/java", true,
|
||||
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
|
||||
"config.json", "-c", "config.json");
|
||||
|
||||
new FullVerifications() {
|
||||
@@ -228,7 +228,7 @@ public class GenerateTest {
|
||||
}
|
||||
};
|
||||
|
||||
setupAndRunTest("-i", "swagger.yaml", "-g", "java", "-o", "src/main/java", true,
|
||||
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
|
||||
"config.json", "--config", "config.json");
|
||||
|
||||
new FullVerifications() {
|
||||
@@ -570,7 +570,7 @@ public class GenerateTest {
|
||||
}
|
||||
|
||||
private void setupAndRunGenericTest(String... additionalParameters) {
|
||||
setupAndRunTest("-i", "swagger.yaml", "-g", "java", "-o", "src/main/java", false, null,
|
||||
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", false, null,
|
||||
additionalParameters);
|
||||
}
|
||||
}
|
||||
|
||||
109
modules/openapi-generator-cli/src/test/resources/swagger.yaml
Normal file
109
modules/openapi-generator-cli/src/test/resources/swagger.yaml
Normal file
@@ -0,0 +1,109 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
summary: Create a pet
|
||||
operationId: createPets
|
||||
tags:
|
||||
- pets
|
||||
responses:
|
||||
'201':
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
operationId: showPetById
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Expected response to a valid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
components:
|
||||
schemas:
|
||||
Pet:
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
@@ -48,7 +48,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.2"
|
||||
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +278,32 @@ in others being disabled. That is, OpenAPI Generator considers any one of these
|
||||
For more control over generation of individual files, configure an ignore file and refer to it via `ignoreFileOverride`.
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
When configuring `systemProperties` in order to perform selective generation you can disable generation of some parts by providing `"false"` value:
|
||||
[source,groovy]
|
||||
----
|
||||
openApiGenerate {
|
||||
// other settings omitted
|
||||
systemProperties = [
|
||||
modelDocs: "false",
|
||||
apis: "false"
|
||||
]
|
||||
}
|
||||
----
|
||||
When enabling generation of only specific parts you either have to provide CSV list of what you particularly are generating or provide an empty string `""` to generate everything. If you provide `"true"` it will be treated as a specific name of model or api you want to generate.
|
||||
[source,groovy]
|
||||
----
|
||||
openApiGenerate {
|
||||
// other settings omitted
|
||||
systemProperties = [
|
||||
apis: "",
|
||||
models: "User,Pet"
|
||||
]
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
=== openApiValidate
|
||||
|
||||
.Options
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
openApiGeneratorVersion=3.3.2
|
||||
openApiGeneratorVersion=3.3.4
|
||||
|
||||
# BEGIN placeholders
|
||||
# these are just placeholders to allow contributors to build directly
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -17,5 +17,5 @@ gradle generateGoWithInvalidSpec
|
||||
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
|
||||
|
||||
```bash
|
||||
gradle -PopenApiGeneratorVersion=3.3.2 openApiValidate
|
||||
gradle -PopenApiGeneratorVersion=3.3.4 openApiValidate
|
||||
```
|
||||
|
||||
@@ -1 +1 @@
|
||||
openApiGeneratorVersion=3.3.2
|
||||
openApiGeneratorVersion=3.3.4
|
||||
|
||||
@@ -11,7 +11,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
@@ -15,6 +15,11 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.sonatype.plexus</groupId>
|
||||
<artifactId>plexus-build-api</artifactId>
|
||||
<version>0.0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.Component;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import org.openapitools.codegen.CliOption;
|
||||
@@ -50,9 +51,15 @@ import org.openapitools.codegen.CodegenConfig;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.DefaultGenerator;
|
||||
import org.openapitools.codegen.config.CodegenConfigurator;
|
||||
import org.sonatype.plexus.build.incremental.BuildContext;
|
||||
import org.sonatype.plexus.build.incremental.DefaultBuildContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
/**
|
||||
* Goal which generates client/server code from a OpenAPI json/yaml definition.
|
||||
*/
|
||||
@@ -61,6 +68,13 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CodeGenMojo.class);
|
||||
|
||||
/**
|
||||
* The build context is only avail when running from within eclipse.
|
||||
* It is used to update the eclipse-m2e-layer when the plugin is executed inside the IDE.
|
||||
*/
|
||||
@Component
|
||||
private BuildContext buildContext = new DefaultBuildContext();
|
||||
|
||||
@Parameter(name="validateSpec", required = false, defaultValue = "true")
|
||||
private Boolean validateSpec;
|
||||
|
||||
@@ -307,6 +321,12 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(name = "skip", property = "codegen.skip", required = false, defaultValue = "false")
|
||||
private Boolean skip;
|
||||
|
||||
/**
|
||||
* Skip the execution if the source file is older than the output folder.
|
||||
*/
|
||||
@Parameter(name = "skipIfSpecIsUnchanged", property = "codegen.skipIfSpecIsUnchanged", required = false, defaultValue = "false")
|
||||
private Boolean skipIfSpecIsUnchanged;
|
||||
|
||||
/**
|
||||
* Add the output directory to the project as a source root, so that the generated java types
|
||||
* are compiled and included in the project artifact.
|
||||
@@ -329,274 +349,330 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(readonly = true, required = true, defaultValue = "${project}")
|
||||
private MavenProject project;
|
||||
|
||||
|
||||
public void setBuildContext(BuildContext buildContext) {
|
||||
this.buildContext = buildContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException {
|
||||
File inputSpecFile = new File(inputSpec);
|
||||
addCompileSourceRootIfConfigured();
|
||||
|
||||
if (skip) {
|
||||
getLog().info("Code generation is skipped.");
|
||||
// Even when no new sources are generated, the existing ones should
|
||||
// still be compiled if needed.
|
||||
addCompileSourceRootIfConfigured();
|
||||
return;
|
||||
}
|
||||
|
||||
// attempt to read from config file
|
||||
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile);
|
||||
|
||||
// if a config file wasn't specified or we were unable to read it
|
||||
if (configurator == null) {
|
||||
configurator = new CodegenConfigurator();
|
||||
}
|
||||
|
||||
configurator.setVerbose(verbose);
|
||||
|
||||
// now override with any specified parameters
|
||||
if (validateSpec != null) {
|
||||
configurator.setValidateSpec(validateSpec);
|
||||
}
|
||||
|
||||
if (skipOverwrite != null) {
|
||||
configurator.setSkipOverwrite(skipOverwrite);
|
||||
}
|
||||
|
||||
if (removeOperationIdPrefix != null) {
|
||||
configurator.setRemoveOperationIdPrefix(removeOperationIdPrefix);
|
||||
}
|
||||
|
||||
if (isNotEmpty(inputSpec)) {
|
||||
configurator.setInputSpec(inputSpec);
|
||||
}
|
||||
|
||||
if (isNotEmpty(gitUserId)) {
|
||||
configurator.setGitUserId(gitUserId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(gitRepoId)) {
|
||||
configurator.setGitRepoId(gitRepoId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(ignoreFileOverride)) {
|
||||
configurator.setIgnoreFileOverride(ignoreFileOverride);
|
||||
}
|
||||
|
||||
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
|
||||
if (isNotEmpty(generatorName)) {
|
||||
configurator.setGeneratorName(generatorName);
|
||||
|
||||
// check if generatorName & language are set together, inform user this needs to be updated to prevent future issues.
|
||||
if (isNotEmpty(language)) {
|
||||
LOGGER.warn("The 'language' option is deprecated and was replaced by 'generatorName'. Both can not be set together");
|
||||
throw new MojoExecutionException("Illegal configuration: 'language' and 'generatorName' can not be set both, remove 'language' from your configuration");
|
||||
}
|
||||
} else if (isNotEmpty(language)) {
|
||||
LOGGER.warn("The 'language' option is deprecated and may reference language names only in the next major release (4.0). Please use 'generatorName' instead.");
|
||||
configurator.setGeneratorName(language);
|
||||
} else {
|
||||
LOGGER.error("A generator name (generatorName) is required.");
|
||||
throw new MojoExecutionException("The generator requires 'generatorName'. Refer to documentation for a list of options.");
|
||||
}
|
||||
|
||||
|
||||
configurator.setOutputDir(output.getAbsolutePath());
|
||||
|
||||
if (isNotEmpty(auth)) {
|
||||
configurator.setAuth(auth);
|
||||
}
|
||||
|
||||
if (isNotEmpty(apiPackage)) {
|
||||
configurator.setApiPackage(apiPackage);
|
||||
}
|
||||
|
||||
if (isNotEmpty(modelPackage)) {
|
||||
configurator.setModelPackage(modelPackage);
|
||||
}
|
||||
|
||||
if (isNotEmpty(invokerPackage)) {
|
||||
configurator.setInvokerPackage(invokerPackage);
|
||||
}
|
||||
|
||||
if (isNotEmpty(groupId)) {
|
||||
configurator.setGroupId(groupId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(artifactId)) {
|
||||
configurator.setArtifactId(artifactId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(artifactVersion)) {
|
||||
configurator.setArtifactVersion(artifactVersion);
|
||||
}
|
||||
|
||||
if (isNotEmpty(library)) {
|
||||
configurator.setLibrary(library);
|
||||
}
|
||||
|
||||
if (isNotEmpty(modelNamePrefix)) {
|
||||
configurator.setModelNamePrefix(modelNamePrefix);
|
||||
}
|
||||
|
||||
if (isNotEmpty(modelNameSuffix)) {
|
||||
configurator.setModelNameSuffix(modelNameSuffix);
|
||||
}
|
||||
|
||||
if (null != templateDirectory) {
|
||||
configurator.setTemplateDir(templateDirectory.getAbsolutePath());
|
||||
}
|
||||
|
||||
// Set generation options
|
||||
if (null != generateApis && generateApis) {
|
||||
System.setProperty(CodegenConstants.APIS, "");
|
||||
} else {
|
||||
System.clearProperty(CodegenConstants.APIS);
|
||||
}
|
||||
|
||||
if (null != generateModels && generateModels) {
|
||||
System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
|
||||
} else {
|
||||
System.clearProperty(CodegenConstants.MODELS);
|
||||
}
|
||||
|
||||
if (null != generateSupportingFiles && generateSupportingFiles) {
|
||||
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
|
||||
} else {
|
||||
System.clearProperty(CodegenConstants.SUPPORTING_FILES);
|
||||
}
|
||||
|
||||
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
|
||||
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
|
||||
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
|
||||
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
|
||||
System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
|
||||
|
||||
if (configOptions != null) {
|
||||
// Retained for backwards-compataibility with configOptions -> instantiation-types
|
||||
if (instantiationTypes == null && configOptions.containsKey("instantiation-types")) {
|
||||
applyInstantiationTypesKvp(configOptions.get("instantiation-types").toString(),
|
||||
configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> import-mappings
|
||||
if (importMappings == null && configOptions.containsKey("import-mappings")) {
|
||||
applyImportMappingsKvp(configOptions.get("import-mappings").toString(),
|
||||
configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> type-mappings
|
||||
if (typeMappings == null && configOptions.containsKey("type-mappings")) {
|
||||
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> language-specific-primitives
|
||||
if (languageSpecificPrimitives == null && configOptions.containsKey("language-specific-primitives")) {
|
||||
applyLanguageSpecificPrimitivesCsv(configOptions
|
||||
.get("language-specific-primitives").toString(), configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> additional-properties
|
||||
if (additionalProperties == null && configOptions.containsKey("additional-properties")) {
|
||||
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(),
|
||||
configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> reserved-words-mappings
|
||||
if (reservedWordsMappings == null && configOptions.containsKey("reserved-words-mappings")) {
|
||||
applyReservedWordsMappingsKvp(configOptions.get("reserved-words-mappings")
|
||||
.toString(), configurator);
|
||||
}
|
||||
}
|
||||
|
||||
//Apply Instantiation Types
|
||||
if (instantiationTypes != null && (configOptions == null || !configOptions.containsKey("instantiation-types"))) {
|
||||
applyInstantiationTypesKvpList(instantiationTypes, configurator);
|
||||
}
|
||||
|
||||
//Apply Import Mappings
|
||||
if (importMappings != null && (configOptions == null || !configOptions.containsKey("import-mappings"))) {
|
||||
applyImportMappingsKvpList(importMappings, configurator);
|
||||
}
|
||||
|
||||
//Apply Type Mappings
|
||||
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
|
||||
applyTypeMappingsKvpList(typeMappings, configurator);
|
||||
}
|
||||
|
||||
//Apply Language Specific Primitives
|
||||
if (languageSpecificPrimitives != null && (configOptions == null || !configOptions.containsKey("language-specific-primitives"))) {
|
||||
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
|
||||
}
|
||||
|
||||
//Apply Additional Properties
|
||||
if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) {
|
||||
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
|
||||
}
|
||||
|
||||
//Apply Reserved Words Mappings
|
||||
if (reservedWordsMappings != null && (configOptions == null || !configOptions.containsKey("reserved-words-mappings"))) {
|
||||
applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator);
|
||||
}
|
||||
|
||||
if (environmentVariables != null) {
|
||||
|
||||
for (String key : environmentVariables.keySet()) {
|
||||
originalEnvironmentVariables.put(key, System.getProperty(key));
|
||||
String value = environmentVariables.get(key);
|
||||
if (value == null) {
|
||||
// don't put null values
|
||||
value = "";
|
||||
}
|
||||
System.setProperty(key, value);
|
||||
configurator.addSystemProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
final ClientOptInput input = configurator.toClientOptInput();
|
||||
final CodegenConfig config = input.getConfig();
|
||||
|
||||
if (configOptions != null) {
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
if (configOptions.containsKey(langCliOption.getOpt())) {
|
||||
input.getConfig().additionalProperties()
|
||||
.put(langCliOption.getOpt(), configOptions.get(langCliOption.getOpt()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (configHelp) {
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
System.out.println("\t" + langCliOption.getOpt());
|
||||
System.out.println("\t "
|
||||
+ langCliOption.getOptionHelp().replaceAll("\n", "\n\t "));
|
||||
System.out.println();
|
||||
}
|
||||
return;
|
||||
}
|
||||
adjustAdditionalProperties(config);
|
||||
try {
|
||||
if (skip) {
|
||||
getLog().info("Code generation is skipped.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (buildContext != null) {
|
||||
if (buildContext.isIncremental()) {
|
||||
if (inputSpec != null) {
|
||||
if (inputSpecFile.exists()) {
|
||||
if (!buildContext.hasDelta(inputSpecFile)) {
|
||||
getLog().info(
|
||||
"Code generation is skipped in delta-build because source-json was not modified.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skipIfSpecIsUnchanged) {
|
||||
if (inputSpecFile.exists()) {
|
||||
File storedInputSpecHashFile = getHashFile(inputSpecFile);
|
||||
if(storedInputSpecHashFile.exists()) {
|
||||
String inputSpecHash = Files.asByteSource(inputSpecFile).hash(Hashing.sha256()).toString();
|
||||
String storedInputSpecHash = Files.asCharSource(storedInputSpecHashFile, Charsets.UTF_8).read();
|
||||
if (inputSpecHash.equals(storedInputSpecHash)) {
|
||||
getLog().info(
|
||||
"Code generation is skipped because input was unchanged");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to read from config file
|
||||
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile);
|
||||
|
||||
// if a config file wasn't specified or we were unable to read it
|
||||
if (configurator == null) {
|
||||
configurator = new CodegenConfigurator();
|
||||
}
|
||||
|
||||
configurator.setVerbose(verbose);
|
||||
|
||||
// now override with any specified parameters
|
||||
if (validateSpec != null) {
|
||||
configurator.setValidateSpec(validateSpec);
|
||||
}
|
||||
|
||||
if (skipOverwrite != null) {
|
||||
configurator.setSkipOverwrite(skipOverwrite);
|
||||
}
|
||||
|
||||
if (removeOperationIdPrefix != null) {
|
||||
configurator.setRemoveOperationIdPrefix(removeOperationIdPrefix);
|
||||
}
|
||||
|
||||
if (isNotEmpty(inputSpec)) {
|
||||
configurator.setInputSpec(inputSpec);
|
||||
}
|
||||
|
||||
if (isNotEmpty(gitUserId)) {
|
||||
configurator.setGitUserId(gitUserId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(gitRepoId)) {
|
||||
configurator.setGitRepoId(gitRepoId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(ignoreFileOverride)) {
|
||||
configurator.setIgnoreFileOverride(ignoreFileOverride);
|
||||
}
|
||||
|
||||
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
|
||||
if (isNotEmpty(generatorName)) {
|
||||
configurator.setGeneratorName(generatorName);
|
||||
|
||||
// check if generatorName & language are set together, inform user this needs to be updated to prevent future issues.
|
||||
if (isNotEmpty(language)) {
|
||||
LOGGER.warn("The 'language' option is deprecated and was replaced by 'generatorName'. Both can not be set together");
|
||||
throw new MojoExecutionException(
|
||||
"Illegal configuration: 'language' and 'generatorName' can not be set both, remove 'language' from your configuration");
|
||||
}
|
||||
} else if (isNotEmpty(language)) {
|
||||
LOGGER.warn(
|
||||
"The 'language' option is deprecated and may reference language names only in the next major release (4.0). Please use 'generatorName' instead.");
|
||||
configurator.setGeneratorName(language);
|
||||
} else {
|
||||
LOGGER.error("A generator name (generatorName) is required.");
|
||||
throw new MojoExecutionException("The generator requires 'generatorName'. Refer to documentation for a list of options.");
|
||||
}
|
||||
|
||||
configurator.setOutputDir(output.getAbsolutePath());
|
||||
|
||||
if (isNotEmpty(auth)) {
|
||||
configurator.setAuth(auth);
|
||||
}
|
||||
|
||||
if (isNotEmpty(apiPackage)) {
|
||||
configurator.setApiPackage(apiPackage);
|
||||
}
|
||||
|
||||
if (isNotEmpty(modelPackage)) {
|
||||
configurator.setModelPackage(modelPackage);
|
||||
}
|
||||
|
||||
if (isNotEmpty(invokerPackage)) {
|
||||
configurator.setInvokerPackage(invokerPackage);
|
||||
}
|
||||
|
||||
if (isNotEmpty(groupId)) {
|
||||
configurator.setGroupId(groupId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(artifactId)) {
|
||||
configurator.setArtifactId(artifactId);
|
||||
}
|
||||
|
||||
if (isNotEmpty(artifactVersion)) {
|
||||
configurator.setArtifactVersion(artifactVersion);
|
||||
}
|
||||
|
||||
if (isNotEmpty(library)) {
|
||||
configurator.setLibrary(library);
|
||||
}
|
||||
|
||||
if (isNotEmpty(modelNamePrefix)) {
|
||||
configurator.setModelNamePrefix(modelNamePrefix);
|
||||
}
|
||||
|
||||
if (isNotEmpty(modelNameSuffix)) {
|
||||
configurator.setModelNameSuffix(modelNameSuffix);
|
||||
}
|
||||
|
||||
if (null != templateDirectory) {
|
||||
configurator.setTemplateDir(templateDirectory.getAbsolutePath());
|
||||
}
|
||||
|
||||
// Set generation options
|
||||
if (null != generateApis && generateApis) {
|
||||
System.setProperty(CodegenConstants.APIS, "");
|
||||
} else {
|
||||
System.clearProperty(CodegenConstants.APIS);
|
||||
}
|
||||
|
||||
if (null != generateModels && generateModels) {
|
||||
System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
|
||||
} else {
|
||||
System.clearProperty(CodegenConstants.MODELS);
|
||||
}
|
||||
|
||||
if (null != generateSupportingFiles && generateSupportingFiles) {
|
||||
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
|
||||
} else {
|
||||
System.clearProperty(CodegenConstants.SUPPORTING_FILES);
|
||||
}
|
||||
|
||||
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
|
||||
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
|
||||
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
|
||||
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
|
||||
System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
|
||||
|
||||
if (configOptions != null) {
|
||||
// Retained for backwards-compataibility with configOptions -> instantiation-types
|
||||
if (instantiationTypes == null && configOptions.containsKey("instantiation-types")) {
|
||||
applyInstantiationTypesKvp(configOptions.get("instantiation-types").toString(),
|
||||
configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> import-mappings
|
||||
if (importMappings == null && configOptions.containsKey("import-mappings")) {
|
||||
applyImportMappingsKvp(configOptions.get("import-mappings").toString(),
|
||||
configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> type-mappings
|
||||
if (typeMappings == null && configOptions.containsKey("type-mappings")) {
|
||||
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> language-specific-primitives
|
||||
if (languageSpecificPrimitives == null && configOptions.containsKey("language-specific-primitives")) {
|
||||
applyLanguageSpecificPrimitivesCsv(configOptions
|
||||
.get("language-specific-primitives").toString(), configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> additional-properties
|
||||
if (additionalProperties == null && configOptions.containsKey("additional-properties")) {
|
||||
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(),
|
||||
configurator);
|
||||
}
|
||||
|
||||
// Retained for backwards-compataibility with configOptions -> reserved-words-mappings
|
||||
if (reservedWordsMappings == null && configOptions.containsKey("reserved-words-mappings")) {
|
||||
applyReservedWordsMappingsKvp(configOptions.get("reserved-words-mappings")
|
||||
.toString(), configurator);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Instantiation Types
|
||||
if (instantiationTypes != null && (configOptions == null || !configOptions.containsKey("instantiation-types"))) {
|
||||
applyInstantiationTypesKvpList(instantiationTypes, configurator);
|
||||
}
|
||||
|
||||
// Apply Import Mappings
|
||||
if (importMappings != null && (configOptions == null || !configOptions.containsKey("import-mappings"))) {
|
||||
applyImportMappingsKvpList(importMappings, configurator);
|
||||
}
|
||||
|
||||
// Apply Type Mappings
|
||||
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
|
||||
applyTypeMappingsKvpList(typeMappings, configurator);
|
||||
}
|
||||
|
||||
// Apply Language Specific Primitives
|
||||
if (languageSpecificPrimitives != null
|
||||
&& (configOptions == null || !configOptions.containsKey("language-specific-primitives"))) {
|
||||
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
|
||||
}
|
||||
|
||||
// Apply Additional Properties
|
||||
if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) {
|
||||
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
|
||||
}
|
||||
|
||||
// Apply Reserved Words Mappings
|
||||
if (reservedWordsMappings != null && (configOptions == null || !configOptions.containsKey("reserved-words-mappings"))) {
|
||||
applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator);
|
||||
}
|
||||
|
||||
if (environmentVariables != null) {
|
||||
|
||||
for (String key : environmentVariables.keySet()) {
|
||||
originalEnvironmentVariables.put(key, System.getProperty(key));
|
||||
String value = environmentVariables.get(key);
|
||||
if (value == null) {
|
||||
// don't put null values
|
||||
value = "";
|
||||
}
|
||||
System.setProperty(key, value);
|
||||
configurator.addSystemProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
final ClientOptInput input = configurator.toClientOptInput();
|
||||
final CodegenConfig config = input.getConfig();
|
||||
|
||||
if (configOptions != null) {
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
if (configOptions.containsKey(langCliOption.getOpt())) {
|
||||
input.getConfig().additionalProperties()
|
||||
.put(langCliOption.getOpt(), configOptions.get(langCliOption.getOpt()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (configHelp) {
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
System.out.println("\t" + langCliOption.getOpt());
|
||||
System.out.println("\t "
|
||||
+ langCliOption.getOptionHelp().replaceAll("\n", "\n\t "));
|
||||
System.out.println();
|
||||
}
|
||||
return;
|
||||
}
|
||||
adjustAdditionalProperties(config);
|
||||
new DefaultGenerator().opts(input).generate();
|
||||
|
||||
if (buildContext != null) {
|
||||
buildContext.refresh(new File(getCompileSourceRoot()));
|
||||
}
|
||||
|
||||
// Store a checksum of the input spec
|
||||
File storedInputSpecHashFile = getHashFile(inputSpecFile);
|
||||
String inputSpecHash = Files.asByteSource(inputSpecFile).hash(Hashing.sha256()).toString();
|
||||
|
||||
if (storedInputSpecHashFile.getParent() != null && !new File(storedInputSpecHashFile.getParent()).exists()) {
|
||||
File parent = new File(storedInputSpecHashFile.getParent());
|
||||
parent.mkdirs();
|
||||
}
|
||||
Files.asCharSink(storedInputSpecHashFile, Charsets.UTF_8).write(inputSpecHash);
|
||||
|
||||
} catch (Exception e) {
|
||||
// Maven logs exceptions thrown by plugins only if invoked with -e
|
||||
// I find it annoying to jump through hoops to get basic diagnostic information,
|
||||
// so let's log it in any case:
|
||||
if (buildContext != null) {
|
||||
buildContext.addError(inputSpecFile, 0, 0, "unexpected error in Open-API generation", e);
|
||||
}
|
||||
getLog().error(e);
|
||||
throw new MojoExecutionException(
|
||||
"Code generation failed. See above for the full exception.");
|
||||
}
|
||||
}
|
||||
|
||||
addCompileSourceRootIfConfigured();
|
||||
private File getHashFile(File inputSpecFile) {
|
||||
return new File(output.getPath() + File.separator + ".openapi-generator" + File.separator + inputSpecFile.getName() + ".sha256");
|
||||
}
|
||||
|
||||
private String getCompileSourceRoot() {
|
||||
final Object sourceFolderObject =
|
||||
configOptions == null ? null : configOptions
|
||||
.get(CodegenConstants.SOURCE_FOLDER);
|
||||
final String sourceFolder =
|
||||
sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString();
|
||||
|
||||
String sourceJavaFolder = output.toString() + "/" + sourceFolder;
|
||||
return sourceJavaFolder;
|
||||
}
|
||||
|
||||
private void addCompileSourceRootIfConfigured() {
|
||||
if (addCompileSourceRoot) {
|
||||
final Object sourceFolderObject =
|
||||
configOptions == null ? null : configOptions
|
||||
.get(CodegenConstants.SOURCE_FOLDER);
|
||||
final String sourceFolder =
|
||||
sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString();
|
||||
|
||||
String sourceJavaFolder = output.toString() + "/" + sourceFolder;
|
||||
project.addCompileSourceRoot(sourceJavaFolder);
|
||||
project.addCompileSourceRoot(getCompileSourceRoot());
|
||||
}
|
||||
|
||||
// Reset all environment variables to their original value. This prevents unexpected
|
||||
@@ -611,10 +687,10 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This method enables conversion of true/false strings in
|
||||
* This method enables conversion of true/false strings in
|
||||
* config.additionalProperties (configuration/configOptions) to proper booleans.
|
||||
* This enables mustache files to handle the properties better.
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
private void adjustAdditionalProperties(final CodegenConfig config) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<execute>
|
||||
<runOnIncremental>true</runOnIncremental>
|
||||
<runOnConfiguration>true</runOnConfiguration>
|
||||
</execute>
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>openapi-generator-online</artifactId>
|
||||
|
||||
@@ -19,11 +19,11 @@ package org.openapitools.codegen.online.service;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.online.api.GenApiDelegate;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
import org.openapitools.codegen.CodegenConfigLoader;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.online.api.GenApiDelegate;
|
||||
import org.openapitools.codegen.online.model.Generated;
|
||||
import org.openapitools.codegen.online.model.GeneratorInput;
|
||||
import org.openapitools.codegen.online.model.ResponseCode;
|
||||
@@ -36,8 +36,9 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@@ -114,33 +115,7 @@ public class GenApiService implements GenApiDelegate {
|
||||
@Override
|
||||
public ResponseEntity<ResponseCode> generateClient(String language, GeneratorInput generatorInput) {
|
||||
String filename = Generator.generateClient(language, generatorInput);
|
||||
String host = System.getenv("GENERATOR_HOST");
|
||||
HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);
|
||||
|
||||
if (StringUtils.isBlank(host)) {
|
||||
String scheme = servletRequest.getHeader("X-SSL");
|
||||
String port = "";
|
||||
if ("1".equals(scheme)) {
|
||||
scheme = "https";
|
||||
} else {
|
||||
scheme = servletRequest.getScheme();
|
||||
port = ":" + servletRequest.getServerPort();
|
||||
}
|
||||
host = scheme + "://" + servletRequest.getServerName() + port;
|
||||
}
|
||||
|
||||
if (filename != null) {
|
||||
String code = String.valueOf(UUID.randomUUID().toString());
|
||||
Generated g = new Generated();
|
||||
g.setFilename(filename);
|
||||
g.setFriendlyName(language + "-client");
|
||||
fileMap.put(code, g);
|
||||
System.out.println(code + ", " + filename);
|
||||
String link = host + "/api/gen/download/" + code;
|
||||
return ResponseEntity.ok().body(new ResponseCode(code, link));
|
||||
} else {
|
||||
return ResponseEntity.status(500).build();
|
||||
}
|
||||
return getResponse(filename, language + "-client");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,20 +158,27 @@ public class GenApiService implements GenApiDelegate {
|
||||
String filename = Generator.generateServer(framework, generatorInput);
|
||||
System.out.println("generated name: " + filename);
|
||||
|
||||
HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);
|
||||
return getResponse(filename, framework + "-server");
|
||||
}
|
||||
|
||||
String host =
|
||||
servletRequest.getScheme() + "://" + servletRequest.getServerName() + ":"
|
||||
+ servletRequest.getServerPort();
|
||||
private ResponseEntity<ResponseCode> getResponse(String filename, String friendlyName) {
|
||||
String host = System.getenv("GENERATOR_HOST");
|
||||
|
||||
UriComponentsBuilder uriBuilder;
|
||||
if (!StringUtils.isBlank(host)) {
|
||||
uriBuilder = UriComponentsBuilder.fromUriString(host);
|
||||
} else {
|
||||
uriBuilder = ServletUriComponentsBuilder.fromCurrentContextPath();
|
||||
}
|
||||
|
||||
if (filename != null) {
|
||||
String code = String.valueOf(UUID.randomUUID().toString());
|
||||
String code = UUID.randomUUID().toString();
|
||||
Generated g = new Generated();
|
||||
g.setFilename(filename);
|
||||
g.setFriendlyName(framework + "-server");
|
||||
g.setFriendlyName(friendlyName);
|
||||
fileMap.put(code, g);
|
||||
System.out.println(code + ", " + filename);
|
||||
String link = host + "/api/gen/download/" + code;
|
||||
String link = uriBuilder.path("/api/gen/download/").path(code).toUriString();
|
||||
return ResponseEntity.ok().body(new ResponseCode(code, link));
|
||||
} else {
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.3.4</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.swagger.v3.oas.models.servers.Server;
|
||||
import io.swagger.v3.oas.models.servers.ServerVariable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -261,4 +262,9 @@ public interface CodegenConfig {
|
||||
|
||||
public void setEnablePostProcessFile(boolean isEnablePostProcessFile);
|
||||
|
||||
// set OpenAPI and schemas
|
||||
public void setGlobalOpenAPI(OpenAPI openAPI);
|
||||
|
||||
public void setGlobalSchemas(OpenAPI openAPI);
|
||||
|
||||
}
|
||||
|
||||
@@ -221,6 +221,10 @@ public class CodegenConstants {
|
||||
public static final String SOURCECODEONLY_GENERATION = "generateSourceCodeOnly";
|
||||
public static final String SOURCECODEONLY_GENERATION_DESC = "Specifies that only a library source code is to be generated.";
|
||||
|
||||
public static final String PARCELIZE_MODELS = "parcelizeModels";
|
||||
public static final String PARCELIZE_MODELS_DESC = "toggle \"@Parcelize\" for generated models";
|
||||
|
||||
|
||||
// Not user-configurable. System provided for use in templates.
|
||||
|
||||
public static final String GENERATE_APIS = "generateApis";
|
||||
|
||||
@@ -27,11 +27,12 @@ public class CodegenParameter {
|
||||
isCookieParam, isBodyParam, hasMore, isContainer,
|
||||
secondaryParam, isCollectionFormatMulti, isPrimitiveType, isModel;
|
||||
public String baseName, paramName, dataType, datatypeWithEnum, dataFormat,
|
||||
collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName;
|
||||
collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName;
|
||||
|
||||
public String example; // example value (x-example)
|
||||
public String jsonSchema;
|
||||
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isEmail;
|
||||
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary,
|
||||
isBoolean, isDate, isDateTime, isUuid, isEmail, isFreeFormObject;
|
||||
public boolean isListContainer, isMapContainer;
|
||||
public boolean isFile;
|
||||
public boolean isEnum;
|
||||
@@ -94,7 +95,7 @@ public class CodegenParameter {
|
||||
* See http://json-schema.org/latest/json-schema-validation.html#anchor14
|
||||
*/
|
||||
public Number multipleOf;
|
||||
|
||||
|
||||
public CodegenParameter copy() {
|
||||
CodegenParameter output = new CodegenParameter();
|
||||
output.isFile = this.isFile;
|
||||
@@ -148,7 +149,7 @@ public class CodegenParameter {
|
||||
if (this.mostInnerItems != null) {
|
||||
output.mostInnerItems = this.mostInnerItems;
|
||||
}
|
||||
if(this.vendorExtensions != null){
|
||||
if (this.vendorExtensions != null) {
|
||||
output.vendorExtensions = new HashMap<String, Object>(this.vendorExtensions);
|
||||
}
|
||||
output.hasValidation = this.hasValidation;
|
||||
@@ -167,6 +168,7 @@ public class CodegenParameter {
|
||||
output.isDateTime = this.isDateTime;
|
||||
output.isUuid = this.isUuid;
|
||||
output.isEmail = this.isEmail;
|
||||
output.isFreeFormObject = this.isFreeFormObject;
|
||||
output.isListContainer = this.isListContainer;
|
||||
output.isMapContainer = this.isMapContainer;
|
||||
|
||||
@@ -259,6 +261,8 @@ public class CodegenParameter {
|
||||
return false;
|
||||
if (isEmail != that.isEmail)
|
||||
return false;
|
||||
if (isFreeFormObject != that.isFreeFormObject)
|
||||
return false;
|
||||
if (isListContainer != that.isListContainer)
|
||||
return false;
|
||||
if (isMapContainer != that.isMapContainer)
|
||||
@@ -307,18 +311,18 @@ public class CodegenParameter {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = isFormParam ? 13:31;
|
||||
result = 31 * result + (isQueryParam ? 13:31);
|
||||
result = 31 * result + (isPathParam ? 13:31);
|
||||
result = 31 * result + (isHeaderParam ? 13:31);
|
||||
result = 31 * result + (isCookieParam ? 13:31);
|
||||
result = 31 * result + (isBodyParam ? 13:31);
|
||||
result = 31 * result + (hasMore ? 13:31);
|
||||
result = 31 * result + (isContainer ? 13:31);
|
||||
result = 31 * result + (secondaryParam ? 13:31);
|
||||
result = 31 * result + (isCollectionFormatMulti ? 13:31);
|
||||
result = 31 * result + (isPrimitiveType ? 13:31);
|
||||
result = 31 * result + (isModel ? 13:31);
|
||||
int result = isFormParam ? 13 : 31;
|
||||
result = 31 * result + (isQueryParam ? 13 : 31);
|
||||
result = 31 * result + (isPathParam ? 13 : 31);
|
||||
result = 31 * result + (isHeaderParam ? 13 : 31);
|
||||
result = 31 * result + (isCookieParam ? 13 : 31);
|
||||
result = 31 * result + (isBodyParam ? 13 : 31);
|
||||
result = 31 * result + (hasMore ? 13 : 31);
|
||||
result = 31 * result + (isContainer ? 13 : 31);
|
||||
result = 31 * result + (secondaryParam ? 13 : 31);
|
||||
result = 31 * result + (isCollectionFormatMulti ? 13 : 31);
|
||||
result = 31 * result + (isPrimitiveType ? 13 : 31);
|
||||
result = 31 * result + (isModel ? 13 : 31);
|
||||
result = 31 * result + (baseName != null ? baseName.hashCode() : 0);
|
||||
result = 31 * result + (paramName != null ? paramName.hashCode() : 0);
|
||||
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
|
||||
@@ -332,42 +336,43 @@ public class CodegenParameter {
|
||||
result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0);
|
||||
result = 31 * result + (example != null ? example.hashCode() : 0);
|
||||
result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0);
|
||||
result = 31 * result + (isString ? 13:31);
|
||||
result = 31 * result + (isNumeric ? 13:31);
|
||||
result = 31 * result + (isInteger ? 13:31);
|
||||
result = 31 * result + (isLong ? 13:31);
|
||||
result = 31 * result + (isFloat ? 13:31);
|
||||
result = 31 * result + (isNumber ? 13:31);
|
||||
result = 31 * result + (isDouble ? 13:31);
|
||||
result = 31 * result + (isByteArray ? 13:31);
|
||||
result = 31 * result + (isBinary ? 13:31);
|
||||
result = 31 * result + (isBoolean ? 13:31);
|
||||
result = 31 * result + (isDate ? 13:31);
|
||||
result = 31 * result + (isDateTime ? 13:31);
|
||||
result = 31 * result + (isUuid ? 13:31);
|
||||
result = 31 * result + (isEmail ? 13:31);
|
||||
result = 31 * result + (isListContainer ? 13:31);
|
||||
result = 31 * result + (isMapContainer ? 13:31);
|
||||
result = 31 * result + (isFile ? 13:31);
|
||||
result = 31 * result + (isString ? 13 : 31);
|
||||
result = 31 * result + (isNumeric ? 13 : 31);
|
||||
result = 31 * result + (isInteger ? 13 : 31);
|
||||
result = 31 * result + (isLong ? 13 : 31);
|
||||
result = 31 * result + (isFloat ? 13 : 31);
|
||||
result = 31 * result + (isNumber ? 13 : 31);
|
||||
result = 31 * result + (isDouble ? 13 : 31);
|
||||
result = 31 * result + (isByteArray ? 13 : 31);
|
||||
result = 31 * result + (isBinary ? 13 : 31);
|
||||
result = 31 * result + (isBoolean ? 13 : 31);
|
||||
result = 31 * result + (isDate ? 13 : 31);
|
||||
result = 31 * result + (isDateTime ? 13 : 31);
|
||||
result = 31 * result + (isUuid ? 13 : 31);
|
||||
result = 31 * result + (isEmail ? 13 : 31);
|
||||
result = 31 * result + (isFreeFormObject ? 13 : 31);
|
||||
result = 31 * result + (isListContainer ? 13 : 31);
|
||||
result = 31 * result + (isMapContainer ? 13 : 31);
|
||||
result = 31 * result + (isFile ? 13 : 31);
|
||||
result = 31 * result + (isEnum ? 1 : 0);
|
||||
result = 31 * result + (_enum != null ? _enum.hashCode() : 0);
|
||||
result = 31 * result + (allowableValues != null ? allowableValues.hashCode() : 0);
|
||||
result = 31 * result + (items != null ? items.hashCode() : 0);
|
||||
result = 31 * result + (mostInnerItems != null ? mostInnerItems.hashCode() : 0);
|
||||
result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0);
|
||||
result = 31 * result + (hasValidation ? 13:31);
|
||||
result = 31 * result + (isNullable ? 13:31);
|
||||
result = 31 * result + (required ? 13:31);
|
||||
result = 31 * result + (hasValidation ? 13 : 31);
|
||||
result = 31 * result + (isNullable ? 13 : 31);
|
||||
result = 31 * result + (required ? 13 : 31);
|
||||
result = 31 * result + (maximum != null ? maximum.hashCode() : 0);
|
||||
result = 31 * result + (exclusiveMaximum ? 13:31);
|
||||
result = 31 * result + (exclusiveMaximum ? 13 : 31);
|
||||
result = 31 * result + (minimum != null ? minimum.hashCode() : 0);
|
||||
result = 31 * result + (exclusiveMinimum ? 13:31);
|
||||
result = 31 * result + (exclusiveMinimum ? 13 : 31);
|
||||
result = 31 * result + (maxLength != null ? maxLength.hashCode() : 0);
|
||||
result = 31 * result + (minLength != null ? minLength.hashCode() : 0);
|
||||
result = 31 * result + (pattern != null ? pattern.hashCode() : 0);
|
||||
result = 31 * result + (maxItems != null ? maxItems.hashCode() : 0);
|
||||
result = 31 * result + (minItems != null ? minItems.hashCode() : 0);
|
||||
result = 31 * result + (uniqueItems ? 13:31);
|
||||
result = 31 * result + (uniqueItems ? 13 : 31);
|
||||
result = 31 * result + (multipleOf != null ? multipleOf.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
@@ -414,6 +419,7 @@ public class CodegenParameter {
|
||||
", isDateTime=" + isDateTime +
|
||||
", isUuid=" + isUuid +
|
||||
", isEmail=" + isEmail +
|
||||
", isFreeFormObject=" + isFreeFormObject +
|
||||
", isListContainer=" + isListContainer +
|
||||
", isMapContainer=" + isMapContainer +
|
||||
", isFile=" + isFile +
|
||||
|
||||
@@ -25,10 +25,12 @@ import java.util.Objects;
|
||||
|
||||
public class CodegenProperty implements Cloneable {
|
||||
public String baseName, complexType, getter, setter, description, dataType,
|
||||
datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam,
|
||||
baseType, containerType, title;
|
||||
datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam,
|
||||
baseType, containerType, title;
|
||||
|
||||
/** The 'description' string without escape charcters needed by some programming languages/targets */
|
||||
/**
|
||||
* The 'description' string without escape charcters needed by some programming languages/targets
|
||||
*/
|
||||
public String unescapedDescription;
|
||||
|
||||
/**
|
||||
@@ -56,7 +58,8 @@ public class CodegenProperty implements Cloneable {
|
||||
public boolean hasMore, required, secondaryParam;
|
||||
public boolean hasMoreNonReadOnly; // for model constructor, true if next property is not readonly
|
||||
public boolean isPrimitiveType, isModel, isContainer, isNotContainer;
|
||||
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile, isBoolean, isDate, isDateTime, isUuid, isEmail;
|
||||
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile,
|
||||
isBoolean, isDate, isDateTime, isUuid, isEmail, isFreeFormObject;
|
||||
public boolean isListContainer, isMapContainer;
|
||||
public boolean isEnum;
|
||||
public boolean isReadOnly;
|
||||
@@ -84,7 +87,7 @@ public class CodegenProperty implements Cloneable {
|
||||
public String xmlNamespace;
|
||||
public boolean isXmlWrapped = false;
|
||||
|
||||
public String getBaseName() {
|
||||
public String getBaseName() {
|
||||
return baseName;
|
||||
}
|
||||
|
||||
@@ -125,9 +128,9 @@ public class CodegenProperty implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return dataType
|
||||
* @deprecated since version 3.0.0, use {@link #getDataType()} instead.<br>
|
||||
* May be removed with the next major release (4.0)
|
||||
* @return dataType
|
||||
*/
|
||||
@Deprecated
|
||||
public String getDatatype() {
|
||||
@@ -411,8 +414,7 @@ public class CodegenProperty implements Cloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((_enum == null) ? 0 : _enum.hashCode());
|
||||
@@ -429,19 +431,19 @@ public class CodegenProperty implements Cloneable {
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((title == null) ? 0 : title.hashCode());
|
||||
result = prime * result + ((example == null) ? 0 : example.hashCode());
|
||||
result = prime * result + (exclusiveMaximum ? 13:31);
|
||||
result = prime * result + (exclusiveMinimum ? 13:31);
|
||||
result = prime * result + (exclusiveMaximum ? 13 : 31);
|
||||
result = prime * result + (exclusiveMinimum ? 13 : 31);
|
||||
result = prime * result + ((getter == null) ? 0 : getter.hashCode());
|
||||
result = prime * result + (hasMore ? 13:31);
|
||||
result = prime * result + ((hasMoreNonReadOnly ? 13:31));
|
||||
result = prime * result + ((isContainer ? 13:31));
|
||||
result = prime * result + (hasMore ? 13 : 31);
|
||||
result = prime * result + ((hasMoreNonReadOnly ? 13 : 31));
|
||||
result = prime * result + ((isContainer ? 13 : 31));
|
||||
result = prime * result + (isEnum ? 1231 : 1237);
|
||||
result = prime * result + ((isNotContainer ? 13:31));
|
||||
result = prime * result + ((isPrimitiveType ? 13:31));
|
||||
result = prime * result + ((isModel ? 13:31));
|
||||
result = prime * result + ((isReadOnly ? 13:31));
|
||||
result = prime * result + ((isWriteOnly ? 13:31));
|
||||
result = prime * result + ((isNullable ? 13:31));
|
||||
result = prime * result + ((isNotContainer ? 13 : 31));
|
||||
result = prime * result + ((isPrimitiveType ? 13 : 31));
|
||||
result = prime * result + ((isModel ? 13 : 31));
|
||||
result = prime * result + ((isReadOnly ? 13 : 31));
|
||||
result = prime * result + ((isWriteOnly ? 13 : 31));
|
||||
result = prime * result + ((isNullable ? 13 : 31));
|
||||
result = prime * result + ((items == null) ? 0 : items.hashCode());
|
||||
result = prime * result + ((mostInnerItems == null) ? 0 : mostInnerItems.hashCode());
|
||||
result = prime * result + ((jsonSchema == null) ? 0 : jsonSchema.hashCode());
|
||||
@@ -453,29 +455,30 @@ public class CodegenProperty implements Cloneable {
|
||||
result = prime * result + ((minimum == null) ? 0 : minimum.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
|
||||
result = prime * result + ((required ? 13:31));
|
||||
result = prime * result + ((secondaryParam ? 13:31));
|
||||
result = prime * result + ((required ? 13 : 31));
|
||||
result = prime * result + ((secondaryParam ? 13 : 31));
|
||||
result = prime * result + ((setter == null) ? 0 : setter.hashCode());
|
||||
result = prime * result + ((unescapedDescription == null) ? 0 : unescapedDescription.hashCode());
|
||||
result = prime * result + ((vendorExtensions == null) ? 0 : vendorExtensions.hashCode());
|
||||
result = prime * result + ((hasValidation ? 13:31));
|
||||
result = prime * result + ((isString ? 13:31));
|
||||
result = prime * result + ((isNumeric ? 13:31));
|
||||
result = prime * result + ((isInteger ? 13:31));
|
||||
result = prime * result + ((isLong ?13:31));
|
||||
result = prime * result + ((isNumber ? 13:31));
|
||||
result = prime * result + ((isFloat ? 13:31));
|
||||
result = prime * result + ((isDouble ? 13:31));
|
||||
result = prime * result + ((isByteArray ? 13:31));
|
||||
result = prime * result + ((isBinary ? 13:31));
|
||||
result = prime * result + ((isFile ? 13:31));
|
||||
result = prime * result + ((isBoolean ? 13:31));
|
||||
result = prime * result + ((isDate ? 13:31));
|
||||
result = prime * result + ((isDateTime ? 13:31));
|
||||
result = prime * result + ((isUuid ? 13:31));
|
||||
result = prime * result + ((isEmail ? 13:31));
|
||||
result = prime * result + ((isMapContainer ? 13:31));
|
||||
result = prime * result + ((isListContainer ? 13:31));
|
||||
result = prime * result + ((hasValidation ? 13 : 31));
|
||||
result = prime * result + ((isString ? 13 : 31));
|
||||
result = prime * result + ((isNumeric ? 13 : 31));
|
||||
result = prime * result + ((isInteger ? 13 : 31));
|
||||
result = prime * result + ((isLong ? 13 : 31));
|
||||
result = prime * result + ((isNumber ? 13 : 31));
|
||||
result = prime * result + ((isFloat ? 13 : 31));
|
||||
result = prime * result + ((isDouble ? 13 : 31));
|
||||
result = prime * result + ((isByteArray ? 13 : 31));
|
||||
result = prime * result + ((isBinary ? 13 : 31));
|
||||
result = prime * result + ((isFile ? 13 : 31));
|
||||
result = prime * result + ((isBoolean ? 13 : 31));
|
||||
result = prime * result + ((isDate ? 13 : 31));
|
||||
result = prime * result + ((isDateTime ? 13 : 31));
|
||||
result = prime * result + ((isUuid ? 13 : 31));
|
||||
result = prime * result + ((isEmail ? 13 : 31));
|
||||
result = prime * result + ((isFreeFormObject ? 13 : 31));
|
||||
result = prime * result + ((isMapContainer ? 13 : 31));
|
||||
result = prime * result + ((isListContainer ? 13 : 31));
|
||||
result = prime * result + Objects.hashCode(isInherited);
|
||||
result = prime * result + Objects.hashCode(discriminatorValue);
|
||||
result = prime * result + Objects.hashCode(nameInCamelCase);
|
||||
@@ -483,11 +486,11 @@ public class CodegenProperty implements Cloneable {
|
||||
result = prime * result + Objects.hashCode(enumName);
|
||||
result = prime * result + ((maxItems == null) ? 0 : maxItems.hashCode());
|
||||
result = prime * result + ((minItems == null) ? 0 : minItems.hashCode());
|
||||
result = prime * result + ((isXmlAttribute ? 13:31));
|
||||
result = prime * result + ((isXmlAttribute ? 13 : 31));
|
||||
result = prime * result + ((xmlPrefix == null) ? 0 : xmlPrefix.hashCode());
|
||||
result = prime * result + ((xmlName == null) ? 0 : xmlName.hashCode());
|
||||
result = prime * result + ((xmlNamespace == null) ? 0 : xmlNamespace.hashCode());
|
||||
result = prime * result + ((isXmlWrapped ? 13:31));
|
||||
result = prime * result + ((isXmlWrapped ? 13 : 31));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -657,6 +660,9 @@ public class CodegenProperty implements Cloneable {
|
||||
if (this.isEmail != other.isEmail) {
|
||||
return false;
|
||||
}
|
||||
if (this.isFreeFormObject != other.isFreeFormObject) {
|
||||
return false;
|
||||
}
|
||||
if (this.isBinary != other.isBinary) {
|
||||
return false;
|
||||
}
|
||||
@@ -724,7 +730,7 @@ public class CodegenProperty implements Cloneable {
|
||||
if (this.mostInnerItems != null) {
|
||||
cp.mostInnerItems = this.mostInnerItems;
|
||||
}
|
||||
if(this.vendorExtensions != null){
|
||||
if (this.vendorExtensions != null) {
|
||||
cp.vendorExtensions = new HashMap<String, Object>(this.vendorExtensions);
|
||||
}
|
||||
return cp;
|
||||
@@ -785,11 +791,12 @@ public class CodegenProperty implements Cloneable {
|
||||
", isDateTime=" + isDateTime +
|
||||
", isUuid=" + isUuid +
|
||||
", isEmail=" + isEmail +
|
||||
", isFreeFormObject=" + isFreeFormObject +
|
||||
", isListContainer=" + isListContainer +
|
||||
", isMapContainer=" + isMapContainer +
|
||||
", isEnum=" + isEnum +
|
||||
", isReadOnly=" + isReadOnly +
|
||||
", isWriteOnly=" + isWriteOnly+
|
||||
", isWriteOnly=" + isWriteOnly +
|
||||
", isNullable=" + isNullable +
|
||||
", _enum=" + _enum +
|
||||
", allowableValues=" + allowableValues +
|
||||
|
||||
@@ -17,11 +17,7 @@
|
||||
|
||||
package org.openapitools.codegen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class CodegenResponse {
|
||||
public final List<CodegenProperty> headers = new ArrayList<CodegenProperty>();
|
||||
@@ -30,7 +26,8 @@ public class CodegenResponse {
|
||||
public List<Map<String, Object>> examples;
|
||||
public String dataType, baseType, containerType;
|
||||
public boolean hasHeaders;
|
||||
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail;
|
||||
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate,
|
||||
isDateTime, isUuid, isEmail, isModel, isFreeFormObject;
|
||||
public boolean isDefault;
|
||||
public boolean simpleType;
|
||||
public boolean primitiveType;
|
||||
@@ -48,76 +45,90 @@ public class CodegenResponse {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(Locale.ROOT, "%s(%s)", code, containerType);
|
||||
return "CodegenResponse{" +
|
||||
"headers=" + headers +
|
||||
", code='" + code + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
", hasMore=" + hasMore +
|
||||
", examples=" + examples +
|
||||
", dataType='" + dataType + '\'' +
|
||||
", baseType='" + baseType + '\'' +
|
||||
", containerType='" + containerType + '\'' +
|
||||
", hasHeaders=" + hasHeaders +
|
||||
", isString=" + isString +
|
||||
", isNumeric=" + isNumeric +
|
||||
", isInteger=" + isInteger +
|
||||
", isLong=" + isLong +
|
||||
", isNumber=" + isNumber +
|
||||
", isFloat=" + isFloat +
|
||||
", isDouble=" + isDouble +
|
||||
", isByteArray=" + isByteArray +
|
||||
", isBoolean=" + isBoolean +
|
||||
", isDate=" + isDate +
|
||||
", isDateTime=" + isDateTime +
|
||||
", isUuid=" + isUuid +
|
||||
", isEmail=" + isEmail +
|
||||
", isFreeFormObject=" + isFreeFormObject +
|
||||
", isModel=" + isModel +
|
||||
", isDefault=" + isDefault +
|
||||
", simpleType=" + simpleType +
|
||||
", primitiveType=" + primitiveType +
|
||||
", isMapContainer=" + isMapContainer +
|
||||
", isListContainer=" + isListContainer +
|
||||
", isBinary=" + isBinary +
|
||||
", isFile=" + isFile +
|
||||
", schema=" + schema +
|
||||
", jsonSchema='" + jsonSchema + '\'' +
|
||||
", vendorExtensions=" + vendorExtensions +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
CodegenResponse that = (CodegenResponse) o;
|
||||
|
||||
if (!headers.equals(that.headers))
|
||||
return false;
|
||||
if (code != null ? !code.equals(that.code) : that.code != null)
|
||||
return false;
|
||||
if (message != null ? !message.equals(that.message) : that.message != null)
|
||||
return false;
|
||||
if (hasMore != that.hasMore)
|
||||
return false;
|
||||
if (examples != null ? !examples.equals(that.examples) : that.examples != null)
|
||||
return false;
|
||||
if (dataType != null ? !dataType.equals(that.dataType) : that.dataType != null)
|
||||
return false;
|
||||
if (baseType != null ? !baseType.equals(that.baseType) : that.baseType != null)
|
||||
return false;
|
||||
if (containerType != null ? !containerType.equals(that.containerType) : that.containerType != null)
|
||||
return false;
|
||||
if (isDefault != that.isDefault)
|
||||
return false;
|
||||
if (simpleType != that.simpleType)
|
||||
return false;
|
||||
if (primitiveType != that.primitiveType)
|
||||
return false;
|
||||
if (isMapContainer != that.isMapContainer)
|
||||
return false;
|
||||
if (isListContainer != that.isListContainer)
|
||||
return false;
|
||||
if (isBinary != that.isBinary)
|
||||
return false;
|
||||
if (isFile != that.isFile)
|
||||
return false;
|
||||
if (isNumeric != that.isNumeric)
|
||||
return false;
|
||||
if (schema != null ? !schema.equals(that.schema) : that.schema != null)
|
||||
return false;
|
||||
if (vendorExtensions != null ? !vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions != null)
|
||||
return false;
|
||||
return jsonSchema != null ? jsonSchema.equals(that.jsonSchema) : that.jsonSchema == null;
|
||||
return hasMore == that.hasMore &&
|
||||
hasHeaders == that.hasHeaders &&
|
||||
isString == that.isString &&
|
||||
isNumeric == that.isNumeric &&
|
||||
isInteger == that.isInteger &&
|
||||
isLong == that.isLong &&
|
||||
isNumber == that.isNumber &&
|
||||
isFloat == that.isFloat &&
|
||||
isDouble == that.isDouble &&
|
||||
isByteArray == that.isByteArray &&
|
||||
isBoolean == that.isBoolean &&
|
||||
isDate == that.isDate &&
|
||||
isDateTime == that.isDateTime &&
|
||||
isUuid == that.isUuid &&
|
||||
isEmail == that.isEmail &&
|
||||
isFreeFormObject == that.isFreeFormObject &&
|
||||
isModel == that.isModel &&
|
||||
isDefault == that.isDefault &&
|
||||
simpleType == that.simpleType &&
|
||||
primitiveType == that.primitiveType &&
|
||||
isMapContainer == that.isMapContainer &&
|
||||
isListContainer == that.isListContainer &&
|
||||
isBinary == that.isBinary &&
|
||||
isFile == that.isFile &&
|
||||
Objects.equals(headers, that.headers) &&
|
||||
Objects.equals(code, that.code) &&
|
||||
Objects.equals(message, that.message) &&
|
||||
Objects.equals(examples, that.examples) &&
|
||||
Objects.equals(dataType, that.dataType) &&
|
||||
Objects.equals(baseType, that.baseType) &&
|
||||
Objects.equals(containerType, that.containerType) &&
|
||||
Objects.equals(schema, that.schema) &&
|
||||
Objects.equals(jsonSchema, that.jsonSchema) &&
|
||||
Objects.equals(vendorExtensions, that.vendorExtensions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = headers.hashCode();
|
||||
result = 31 * result + (code != null ? code.hashCode() : 0);
|
||||
result = 31 * result + (message != null ? message.hashCode() : 0);
|
||||
result = 31 * result + (hasMore ? 13:31);
|
||||
result = 31 * result + (examples != null ? examples.hashCode() : 0);
|
||||
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
|
||||
result = 31 * result + (baseType != null ? baseType.hashCode() : 0);
|
||||
result = 31 * result + (containerType != null ? containerType.hashCode() : 0);
|
||||
result = 31 * result + (isDefault ? 13:31);
|
||||
result = 31 * result + (isNumeric ? 13:31);
|
||||
result = 31 * result + (simpleType ? 13:31);
|
||||
result = 31 * result + (primitiveType ? 13:31);
|
||||
result = 31 * result + (isMapContainer ? 13:31);
|
||||
result = 31 * result + (isListContainer ? 13:31);
|
||||
result = 31 * result + (isBinary ? 13:31);
|
||||
result = 31 * result + (isFile ? 13:31);
|
||||
result = 31 * result + (schema != null ? schema.hashCode() : 0);
|
||||
result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0);
|
||||
result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0);
|
||||
return result;
|
||||
return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, hasHeaders,
|
||||
isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate,
|
||||
isDateTime, isUuid, isEmail, isFreeFormObject, isModel, isDefault, simpleType, primitiveType, isMapContainer,
|
||||
isListContainer, isBinary, isFile, schema, jsonSchema, vendorExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,9 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
// flag to indicate whether to use environment variable to post process file
|
||||
protected boolean enablePostProcessFile = false;
|
||||
|
||||
// make openapi and schemas available to all methods
|
||||
protected OpenAPI globalOpenAPI;
|
||||
protected Map<String, Schema> globalSchemas;
|
||||
|
||||
public List<CliOption> cliOptions() {
|
||||
return cliOptions;
|
||||
@@ -383,6 +386,32 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set global OpenAPI based on OpenAPI object
|
||||
*
|
||||
* @param openAPI OpenAPI object
|
||||
*/
|
||||
public void setGlobalOpenAPI(OpenAPI openAPI) {
|
||||
this.globalOpenAPI = openAPI;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set global schema based on OpenAPI object
|
||||
*
|
||||
* @param openAPI OpenAPI object
|
||||
*/
|
||||
public void setGlobalSchemas(OpenAPI openAPI) {
|
||||
if (openAPI != null && openAPI.getComponents() != null) {
|
||||
this.globalSchemas = openAPI.getComponents().getSchemas();
|
||||
}
|
||||
|
||||
if (this.globalSchemas == null) { // initalize with empty map if it's null
|
||||
this.globalSchemas = new HashMap<String, Schema>();
|
||||
}
|
||||
}
|
||||
|
||||
// override with any special post-processing
|
||||
@SuppressWarnings("static-method")
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
@@ -1152,6 +1181,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
codegenParameter.example = "38400000-8cf0-11bd-b23e-10b96e4ef00d";
|
||||
} else if (Boolean.TRUE.equals(codegenParameter.isString)) {
|
||||
codegenParameter.example = codegenParameter.paramName + "_example";
|
||||
} else if (Boolean.TRUE.equals(codegenParameter.isFreeFormObject)) {
|
||||
codegenParameter.example = "Object";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1375,6 +1406,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return "UUID";
|
||||
} else if (ModelUtils.isStringSchema(schema)) {
|
||||
return "string";
|
||||
} else if (ModelUtils.isFreeFormObject(schema)) {
|
||||
return "object";
|
||||
} else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) { // having property implies it's a model
|
||||
return "object";
|
||||
} else if (StringUtils.isNotEmpty(schema.getType())) {
|
||||
@@ -1685,7 +1718,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return m;
|
||||
}
|
||||
|
||||
private CodegenDiscriminator createDiscriminator(String schemaName, Schema schema, Map<String, Schema> allDefinitions) {
|
||||
private CodegenDiscriminator createDiscriminator(String schemaName, Schema
|
||||
schema, Map<String, Schema> allDefinitions) {
|
||||
if (schema.getDiscriminator() == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -1717,7 +1751,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
addParentContainer(codegenModel, codegenModel.name, schema);
|
||||
}
|
||||
|
||||
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema schema, Map<String, Schema> allSchemas) {
|
||||
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema
|
||||
schema, Map<String, Schema> allSchemas) {
|
||||
if (schema instanceof ComposedSchema) {
|
||||
ComposedSchema composedSchema = (ComposedSchema) schema;
|
||||
if (composedSchema.getAllOf() == null) {
|
||||
@@ -1756,6 +1791,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return org.openapitools.codegen.utils.StringUtils.camelize(toVarName(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert OAS Property object to Codegen Property object
|
||||
*
|
||||
@@ -1769,6 +1805,10 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return null;
|
||||
}
|
||||
LOGGER.debug("debugging fromProperty for " + name + " : " + p);
|
||||
|
||||
// unalias schema
|
||||
p = ModelUtils.unaliasSchema(globalSchemas, p);
|
||||
|
||||
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
|
||||
property.name = toVarName(name);
|
||||
property.baseName = name;
|
||||
@@ -1997,7 +2037,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
if (itemName == null) {
|
||||
itemName = property.name;
|
||||
}
|
||||
CodegenProperty cp = fromProperty(itemName, ((ArraySchema) p).getItems());
|
||||
Schema innerSchema = ModelUtils.unaliasSchema(globalSchemas, ((ArraySchema) p).getItems());
|
||||
CodegenProperty cp = fromProperty(itemName, innerSchema);
|
||||
updatePropertyForArray(property, cp);
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
property.isContainer = true;
|
||||
@@ -2008,8 +2049,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
property.maxItems = p.getMaxProperties();
|
||||
|
||||
// handle inner property
|
||||
CodegenProperty cp = fromProperty("inner", ModelUtils.getAdditionalProperties(p));
|
||||
Schema innerSchema = ModelUtils.unaliasSchema(globalSchemas, ModelUtils.getAdditionalProperties(p));
|
||||
CodegenProperty cp = fromProperty("inner", innerSchema);
|
||||
updatePropertyForMap(property, cp);
|
||||
} else if (ModelUtils.isFreeFormObject(p)) {
|
||||
property.isFreeFormObject = true;
|
||||
property.baseType = getSchemaType(p);
|
||||
} else { // model
|
||||
// TODO revise the logic below
|
||||
//if (StringUtils.isNotBlank(p.get$ref())) {
|
||||
@@ -2212,7 +2257,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
* @param schemas a map of OAS models
|
||||
* @return Codegen Operation object
|
||||
*/
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Schema> schemas) {
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation
|
||||
operation, Map<String, Schema> schemas) {
|
||||
return fromOperation(path, httpMethod, operation, schemas, null);
|
||||
}
|
||||
|
||||
@@ -2298,10 +2344,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
op.responses.get(op.responses.size() - 1).hasMore = false;
|
||||
|
||||
if (methodResponse != null) {
|
||||
Schema responseSchema = ModelUtils.getSchemaFromResponse(methodResponse);
|
||||
if (openAPI != null && openAPI.getComponents() != null) { // has models/aliases defined
|
||||
responseSchema = ModelUtils.unaliasSchema(openAPI.getComponents().getSchemas(), responseSchema);
|
||||
}
|
||||
Schema responseSchema = ModelUtils.unaliasSchema(globalSchemas, ModelUtils.getSchemaFromResponse(methodResponse));
|
||||
|
||||
if (responseSchema != null) {
|
||||
CodegenProperty cm = fromProperty("response", responseSchema);
|
||||
|
||||
@@ -2321,7 +2365,13 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
// generate examples
|
||||
op.examples = new ExampleGenerator(schemas, openAPI).generateFromResponseSchema(responseSchema, getProducesInfo(openAPI, operation));
|
||||
String exampleStatusCode = "200";
|
||||
for (String key : operation.getResponses().keySet()) {
|
||||
if (operation.getResponses().get(key) == methodResponse && !key.equals("default")) {
|
||||
exampleStatusCode = key;
|
||||
}
|
||||
}
|
||||
op.examples = new ExampleGenerator(schemas, openAPI).generateFromResponseSchema(exampleStatusCode, responseSchema, getProducesInfo(openAPI, operation));
|
||||
op.defaultResponse = toDefaultValue(responseSchema);
|
||||
op.returnType = cm.dataType;
|
||||
op.hasReference = schemas != null && schemas.containsKey(op.returnBaseType);
|
||||
@@ -2549,7 +2599,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
} else {
|
||||
r.code = responseCode;
|
||||
}
|
||||
final Schema responseSchema = ModelUtils.getSchemaFromResponse(response);
|
||||
Schema responseSchema;
|
||||
if (openAPI != null && openAPI.getComponents() != null) {
|
||||
responseSchema = ModelUtils.unaliasSchema(openAPI.getComponents().getSchemas(), ModelUtils.getSchemaFromResponse(response));
|
||||
} else { // no model/alias defined
|
||||
responseSchema = ModelUtils.getSchemaFromResponse(response);
|
||||
}
|
||||
r.schema = responseSchema;
|
||||
r.message = escapeText(response.getDescription());
|
||||
// TODO need to revise and test examples in responses
|
||||
@@ -2563,6 +2618,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
r.hasHeaders = !r.headers.isEmpty();
|
||||
|
||||
if (r.schema != null) {
|
||||
Map<String, Schema> allSchemas = null;
|
||||
CodegenProperty cp = fromProperty("response", responseSchema);
|
||||
|
||||
if (ModelUtils.isArraySchema(responseSchema)) {
|
||||
@@ -2576,6 +2632,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
} else {
|
||||
if (cp.complexType != null) {
|
||||
r.baseType = cp.complexType;
|
||||
r.isModel = true;
|
||||
} else {
|
||||
r.baseType = cp.baseType;
|
||||
}
|
||||
@@ -2616,6 +2673,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
r.isDate = true;
|
||||
} else if (Boolean.TRUE.equals(cp.isDateTime)) {
|
||||
r.isDateTime = true;
|
||||
} else if (Boolean.TRUE.equals(cp.isFreeFormObject)) {
|
||||
r.isFreeFormObject = true;
|
||||
} else {
|
||||
LOGGER.debug("Property type is not primitive: " + cp.dataType);
|
||||
}
|
||||
@@ -2651,7 +2710,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
* @param openAPI a OAS object representing the spec
|
||||
* @return Codegen Response object
|
||||
*/
|
||||
public CodegenCallback fromCallback(String name, Callback callback, Map<String, Schema> schemas, OpenAPI openAPI) {
|
||||
public CodegenCallback fromCallback(String name, Callback callback, Map<String, Schema> schemas, OpenAPI
|
||||
openAPI) {
|
||||
CodegenCallback c = new CodegenCallback();
|
||||
c.name = name;
|
||||
|
||||
@@ -2985,6 +3045,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
LOGGER.warn("Unknown parameter type: " + parameter.getName());
|
||||
}
|
||||
|
||||
// default to UNKNOWN_PARAMETER_NAME if paramName is null
|
||||
if (codegenParameter.paramName == null) {
|
||||
LOGGER.warn("Parameter name not defined properly. Default to UNKNOWN_PARAMETER_NAME");
|
||||
codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME";
|
||||
}
|
||||
|
||||
// set the parameter excample value
|
||||
// should be overridden by lang codegen
|
||||
setParameterExampleValue(codegenParameter, parameter);
|
||||
@@ -3189,6 +3255,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
String description = headers.getValue().getDescription();
|
||||
// follow the $ref
|
||||
Header header = ModelUtils.getReferencedHeader(openAPI, headers.getValue());
|
||||
|
||||
CodegenProperty cp = fromProperty(headers.getKey(), header.getSchema());
|
||||
cp.setDescription(escapeText(description));
|
||||
cp.setUnescapedDescription(description);
|
||||
@@ -3221,7 +3288,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
* @param operations map of Codegen operations
|
||||
*/
|
||||
@SuppressWarnings("static-method")
|
||||
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
|
||||
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation
|
||||
co, Map<String, List<CodegenOperation>> operations) {
|
||||
List<CodegenOperation> opList = operations.get(tag);
|
||||
if (opList == null) {
|
||||
opList = new ArrayList<CodegenOperation>();
|
||||
@@ -3328,7 +3396,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
* @param properties model properties (schemas)
|
||||
* @return model properties with direct reference to schemas
|
||||
*/
|
||||
private Map<String, Schema> unaliasPropertySchema(Map<String, Schema> allSchemas, Map<String, Schema> properties) {
|
||||
private Map<String, Schema> unaliasPropertySchema
|
||||
(Map<String, Schema> allSchemas, Map<String, Schema> properties) {
|
||||
if (properties != null) {
|
||||
for (String key : properties.keySet()) {
|
||||
properties.put(key, ModelUtils.unaliasSchema(allSchemas, properties.get(key)));
|
||||
@@ -3369,7 +3438,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private void addVars(CodegenModel m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
|
||||
private void addVars(CodegenModel
|
||||
m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
|
||||
// convert set to list so that we can access the next entry in the loop
|
||||
List<Map.Entry<String, Schema>> propertyList = new ArrayList<Map.Entry<String, Schema>>(properties.entrySet());
|
||||
final int totalCount = propertyList.size();
|
||||
@@ -3882,6 +3952,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
} else if (Boolean.TRUE.equals(property.isDateTime)) {
|
||||
parameter.isDateTime = true;
|
||||
parameter.isPrimitiveType = true;
|
||||
} else if (Boolean.TRUE.equals(property.isFreeFormObject)) {
|
||||
parameter.isFreeFormObject = true;
|
||||
} else {
|
||||
LOGGER.debug("Property type is not primitive: " + property.dataType);
|
||||
}
|
||||
@@ -3955,7 +4027,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
|
||||
private void updateEnumVarsWithExtensions
|
||||
(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
|
||||
if (vendorExtensions != null && vendorExtensions.containsKey("x-enum-varnames")) {
|
||||
List<String> alias = (List<String>) vendorExtensions.get("x-enum-varnames");
|
||||
int size = Math.min(enumVars.size(), alias.size());
|
||||
@@ -4266,7 +4339,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<CodegenParameter> fromRequestBodyToFormParameters(RequestBody body, Map<String, Schema> schemas, Set<String> imports) {
|
||||
public List<CodegenParameter> fromRequestBodyToFormParameters(RequestBody
|
||||
body, Map<String, Schema> schemas, Set<String> imports) {
|
||||
List<CodegenParameter> parameters = new ArrayList<CodegenParameter>();
|
||||
LOGGER.debug("debugging fromRequestBodyToFormParameters= " + body);
|
||||
Schema schema = ModelUtils.getSchemaFromRequestBody(body);
|
||||
@@ -4422,7 +4496,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return codegenParameter;
|
||||
}
|
||||
|
||||
public CodegenParameter fromRequestBody(RequestBody body, Map<String, Schema> schemas, Set<String> imports, String bodyParameterName) {
|
||||
public CodegenParameter fromRequestBody(RequestBody
|
||||
body, Map<String, Schema> schemas, Set<String> imports, String bodyParameterName) {
|
||||
if (body == null) {
|
||||
LOGGER.error("body in fromRequestBody cannot be null!");
|
||||
}
|
||||
@@ -4729,7 +4804,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
/**
|
||||
* Set the boolean value indicating the state of the option for post-processing file using envirionment variables.
|
||||
*
|
||||
* @param enablePostProcessFile true to enable post-processing file
|
||||
* @param enablePostProcessFile true to enable post-processing file
|
||||
*/
|
||||
public void setEnablePostProcessFile(boolean enablePostProcessFile) {
|
||||
this.enablePostProcessFile = enablePostProcessFile;
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.ignore.CodegenIgnoreProcessor;
|
||||
//import org.openapitools.codegen.languages.AbstractJavaCodegen;
|
||||
import org.openapitools.codegen.utils.ImplementationVersion;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.openapitools.codegen.utils.URLPathUtils;
|
||||
@@ -170,7 +169,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
|
||||
}
|
||||
|
||||
|
||||
if (System.getProperty("debugOpenAPI") != null) {
|
||||
Json.prettyPrint(openAPI);
|
||||
} else if (System.getProperty("debugSwagger") != null) {
|
||||
@@ -182,6 +180,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
|
||||
config.processOpts();
|
||||
config.preprocessOpenAPI(openAPI);
|
||||
|
||||
// set OpenAPI and schemas to make these available to all methods
|
||||
config.setGlobalOpenAPI(openAPI);
|
||||
config.setGlobalSchemas(openAPI);
|
||||
|
||||
config.additionalProperties().put("generatorVersion", ImplementationVersion.read());
|
||||
config.additionalProperties().put("generatedDate", ZonedDateTime.now().toString());
|
||||
config.additionalProperties().put("generatedYear", String.valueOf(ZonedDateTime.now().getYear()));
|
||||
@@ -425,6 +428,25 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
|
||||
Schema schema = schemas.get(name);
|
||||
|
||||
// check to see if it's a "map" model
|
||||
if (ModelUtils.isMapSchema(schema)) {
|
||||
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
|
||||
// schema without property, i.e. alias to map
|
||||
LOGGER.info("Model " + name + " not generated since it's an alias to map (without property)");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check to see if it's an "array" model
|
||||
if (ModelUtils.isArraySchema(schema)) {
|
||||
if (schema.getProperties() == null || schema.getProperties().isEmpty()) {
|
||||
// schema without property, i.e. alias to array
|
||||
LOGGER.info("Model " + name + " not generated since it's an alias to array (without property)");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Schema> schemaMap = new HashMap<>();
|
||||
schemaMap.put(name, schema);
|
||||
Map<String, Object> models = processModels(config, schemaMap, schemas);
|
||||
@@ -524,10 +546,31 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
operation.put("importPath", config.toApiImport(tag));
|
||||
operation.put("classFilename", config.toApiFilename(tag));
|
||||
|
||||
if (allModels == null || allModels.isEmpty()) {
|
||||
operation.put("hasModel", false);
|
||||
} else {
|
||||
operation.put("hasModel", true);
|
||||
}
|
||||
|
||||
if (!config.vendorExtensions().isEmpty()) {
|
||||
operation.put("vendorExtensions", config.vendorExtensions());
|
||||
}
|
||||
|
||||
// process top-level x-group-parameters
|
||||
if (config.vendorExtensions().containsKey("x-group-parameters")) {
|
||||
Boolean isGroupParameters = Boolean.valueOf(config.vendorExtensions().get("x-group-parameters").toString());
|
||||
|
||||
Map<String, Object> objectMap = (Map<String, Object>) operation.get("operations");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
|
||||
for (CodegenOperation op : operations) {
|
||||
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
|
||||
if (!op.vendorExtensions.containsKey("x-group-parameters")) {
|
||||
op.vendorExtensions.put("x-group-parameters", Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pass sortParamsByRequiredFlag through to the Mustache template...
|
||||
boolean sortParamsByRequiredFlag = true;
|
||||
if (this.config.additionalProperties().containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
|
||||
@@ -1032,13 +1075,16 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
|
||||
List<Map<String, String>> imports = new ArrayList<Map<String, String>>();
|
||||
Set<String> mappingSet = new TreeSet<>();
|
||||
for (String nextImport : allImports) {
|
||||
Map<String, String> im = new LinkedHashMap<String, String>();
|
||||
String mapping = config.importMapping().get(nextImport);
|
||||
if (mapping == null) {
|
||||
mapping = config.toModelImport(nextImport);
|
||||
}
|
||||
if (mapping != null) {
|
||||
|
||||
if (mapping != null && !mappingSet.contains(mapping)) { // ensure import (mapping) is unique
|
||||
mappingSet.add(mapping);
|
||||
im.put("import", mapping);
|
||||
im.put("classname", nextImport);
|
||||
if (!imports.contains(im)) { // avoid duplicates
|
||||
@@ -1053,6 +1099,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
if (imports.size() > 0) {
|
||||
operations.put("hasImport", true);
|
||||
}
|
||||
|
||||
config.postProcessOperations(operations);
|
||||
config.postProcessOperationsWithModels(operations, allModels);
|
||||
if (objs.size() > 0) {
|
||||
|
||||
@@ -42,6 +42,7 @@ public class ExampleGenerator {
|
||||
private static final String NONE = "none";
|
||||
private static final String URL = "url";
|
||||
private static final String URI = "uri";
|
||||
private static final String STATUS_CODE = "statusCode";
|
||||
|
||||
protected Map<String, Schema> examples;
|
||||
private OpenAPI openAPI;
|
||||
@@ -54,7 +55,20 @@ public class ExampleGenerator {
|
||||
this.random = new Random("ExampleGenerator".hashCode());
|
||||
}
|
||||
|
||||
public List<Map<String, String>> generateFromResponseSchema(Schema responseSchema, Set<String> producesInfo) {
|
||||
public List<Map<String, String>> generateFromResponseSchema(String statusCode, Schema responseSchema, Set<String> producesInfo) {
|
||||
List<Map<String, String>> examples = generateFromResponseSchema(responseSchema, producesInfo);
|
||||
if (examples == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Map<String, String> example : examples) {
|
||||
example.put(STATUS_CODE, statusCode);
|
||||
}
|
||||
|
||||
return examples;
|
||||
}
|
||||
|
||||
private List<Map<String, String>> generateFromResponseSchema(Schema responseSchema, Set<String> producesInfo) {
|
||||
if (responseSchema.getExample() == null && StringUtils.isEmpty(responseSchema.get$ref()) && !ModelUtils.isArraySchema(responseSchema)) {
|
||||
// no example provided
|
||||
return null;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
@@ -35,8 +36,6 @@ import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
|
||||
public abstract class AbstractApexCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractApexCodegen.class);
|
||||
|
||||
@@ -325,7 +324,7 @@ public abstract class AbstractApexCodegen extends DefaultCodegen implements Code
|
||||
if (example.isEmpty()) {
|
||||
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
|
||||
}
|
||||
((ByteArraySchema) p).setExample(example);
|
||||
p.setExample(example);
|
||||
example = "EncodingUtil.base64Decode('" + example + "')";
|
||||
} else if (ModelUtils.isDateSchema(p)) {
|
||||
if (example.matches("^\\d{4}(-\\d{2}){2}")) {
|
||||
|
||||
@@ -160,21 +160,21 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("string", "string");
|
||||
typeMapping.put("binary", "byte[]");
|
||||
typeMapping.put("bytearray", "byte[]");
|
||||
typeMapping.put("ByteArray", "byte[]");
|
||||
typeMapping.put("boolean", "bool?");
|
||||
typeMapping.put("integer", "int?");
|
||||
typeMapping.put("float", "float?");
|
||||
typeMapping.put("long", "long?");
|
||||
typeMapping.put("double", "double?");
|
||||
typeMapping.put("number", "decimal?");
|
||||
typeMapping.put("datetime", "DateTime?");
|
||||
typeMapping.put("DateTime", "DateTime?");
|
||||
typeMapping.put("date", "DateTime?");
|
||||
typeMapping.put("file", "System.IO.Stream");
|
||||
typeMapping.put("array", "List");
|
||||
typeMapping.put("list", "List");
|
||||
typeMapping.put("map", "Dictionary");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("uuid", "Guid?");
|
||||
typeMapping.put("UUID", "Guid?");
|
||||
}
|
||||
|
||||
public void setReturnICollection(boolean returnICollection) {
|
||||
@@ -216,6 +216,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("CSHARP_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable CSHARP_POST_PROCESS_FILE not defined so the C# code may not be properly formatted by uncrustify (0.66 or later) or other code formatter. To define it, try `export CSHARP_POST_PROCESS_FILE=\"/usr/local/bin/uncrustify --no-backup\" && export UNCRUSTIFY_CONFIG=/path/to/uncrustify-rules.cfg` (Linux/Mac). Note: replace /path/to with the location of uncrustify-rules.cfg");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
// {{packageVersion}}
|
||||
@@ -766,20 +767,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
String type;
|
||||
|
||||
if (openAPIType == null) {
|
||||
openAPIType = ""; // set swagger type to empty string if null
|
||||
LOGGER.error("OpenAPI Type for {} is null. Default to UNKNOWN_OPENAPI_TYPE instead.", p.getName());
|
||||
openAPIType = "UNKNOWN_OPENAPI_TYPE";
|
||||
}
|
||||
|
||||
// NOTE: typeMapping here supports things like string/String, long/Long, datetime/DateTime as lowercase keys.
|
||||
// Should we require explicit casing here (values are not insensitive).
|
||||
// TODO avoid using toLowerCase as typeMapping should be case-sensitive
|
||||
if (typeMapping.containsKey(openAPIType.toLowerCase(Locale.ROOT))) {
|
||||
type = typeMapping.get(openAPIType.toLowerCase(Locale.ROOT));
|
||||
if (typeMapping.containsKey(openAPIType)) {
|
||||
type = typeMapping.get(openAPIType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
type = openAPIType;
|
||||
}
|
||||
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.openapitools.codegen.languages;
|
||||
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
@@ -28,6 +30,7 @@ import org.openapitools.codegen.mustache.IndentedLambda;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -226,8 +229,8 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
|
||||
nameInCamelCase = sanitizeName(nameInCamelCase);
|
||||
}
|
||||
if (isReservedWord(nameInCamelCase) || nameInCamelCase.matches("^\\d.*")) {
|
||||
nameInCamelCase = escapeReservedWord(nameInCamelCase);
|
||||
}
|
||||
nameInCamelCase = escapeReservedWord(nameInCamelCase);
|
||||
}
|
||||
property.nameInCamelCase = nameInCamelCase;
|
||||
return property;
|
||||
}
|
||||
@@ -249,6 +252,12 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
|
||||
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("CPP_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable CPP_POST_PROCESS_FILE not defined so the C++ code may not be properly formatted. To define it, try 'export CPP_POST_PROCESS_FILE=\"/usr/local/bin/clang-format -i\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
addMustacheLambdas(additionalProperties);
|
||||
}
|
||||
|
||||
@@ -265,4 +274,31 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
|
||||
objs.put("lambda", lambdas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessFile(File file, String fileType) {
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
String cppPostProcessFile = System.getenv("CPP_POST_PROCESS_FILE");
|
||||
if (StringUtils.isEmpty(cppPostProcessFile)) {
|
||||
return; // skip if CPP_POST_PROCESS_FILE env variable is not defined
|
||||
}
|
||||
// only process files with cpp extension
|
||||
if ("cpp".equals(FilenameUtils.getExtension(file.toString())) || "h".equals(FilenameUtils.getExtension(file.toString()))) {
|
||||
String command = cppPostProcessFile + " " + file.toString();
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
p.waitFor();
|
||||
int exitValue = p.exitValue();
|
||||
if (exitValue != 0) {
|
||||
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
|
||||
} else {
|
||||
LOGGER.info("Successfully executed: " + command);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("GO_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable GO_POST_PROCESS_FILE not defined so Go code may not be properly formatted. To define it, try `export GO_POST_PROCESS_FILE=\"/usr/local/bin/gofmt -w\"` (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("JAVA_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable JAVA_POST_PROCESS_FILE not defined so the Java code may not be properly formatted. To define it, try 'export JAVA_POST_PROCESS_FILE=\"/usr/local/bin/clang-format -i\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(SUPPORT_JAVA6)) {
|
||||
@@ -1397,7 +1398,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
return; // skip if JAVA_POST_PROCESS_FILE env variable is not defined
|
||||
}
|
||||
|
||||
// only process files with hs extension
|
||||
// only process files with java extension
|
||||
if ("java".equals(FilenameUtils.getExtension(file.toString()))) {
|
||||
String command = javaPostProcessFile + " " + file.toString();
|
||||
try {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
|
||||
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
@@ -44,6 +45,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
||||
|
||||
protected String apiDocPath = "docs/";
|
||||
protected String modelDocPath = "docs/";
|
||||
protected boolean parcelizeModels = false;
|
||||
|
||||
protected CodegenConstants.ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase;
|
||||
|
||||
@@ -198,6 +200,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
||||
|
||||
CliOption enumPropertyNamingOpt = new CliOption(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_DESC);
|
||||
cliOptions.add(enumPropertyNamingOpt.defaultValue(enumPropertyNaming.name()));
|
||||
cliOptions.add(new CliOption(CodegenConstants.PARCELIZE_MODELS, CodegenConstants.PARCELIZE_MODELS_DESC));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,6 +311,11 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("KOTLIN_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable KOTLIN_POST_PROCESS_FILE not defined so the Kotlin code may not be properly formatted. To define it, try 'export KOTLIN_POST_PROCESS_FILE=\"/usr/local/bin/ktlint -F\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.ENUM_PROPERTY_NAMING)) {
|
||||
setEnumPropertyNaming((String) additionalProperties.get(CodegenConstants.ENUM_PROPERTY_NAMING));
|
||||
}
|
||||
@@ -350,6 +358,20 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
||||
LOGGER.warn(CodegenConstants.INVOKER_PACKAGE + " with " + this.getName() + " generator is ignored. Use " + CodegenConstants.PACKAGE_NAME + ".");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.PARCELIZE_MODELS)) {
|
||||
this.setParcelizeModels(Boolean.valueOf((String)additionalProperties.get(CodegenConstants.PARCELIZE_MODELS)));
|
||||
LOGGER.info(CodegenConstants.PARCELIZE_MODELS + " depends on the android framework and " +
|
||||
"experimental parcelize feature. Make sure your build applies the android plugin:\n" +
|
||||
"apply plugin: 'com.android.library' OR apply plugin: 'com.android.application'.\n" +
|
||||
"and enables the experimental features:\n" +
|
||||
"androidExtensions {\n" +
|
||||
" experimental = true\n" +
|
||||
"}"
|
||||
);
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.PARCELIZE_MODELS, parcelizeModels);
|
||||
}
|
||||
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage());
|
||||
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage());
|
||||
|
||||
@@ -377,6 +399,14 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
|
||||
public Boolean getParcelizeModels() {
|
||||
return parcelizeModels;
|
||||
}
|
||||
|
||||
public void setParcelizeModels(Boolean parcelizeModels) {
|
||||
this.parcelizeModels = parcelizeModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sanitized variable name for enum
|
||||
*
|
||||
@@ -684,4 +714,33 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
||||
}
|
||||
return startsWithTwoUppercaseLetters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessFile(File file, String fileType) {
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String kotlinPostProcessFile = System.getenv("KOTLIN_POST_PROCESS_FILE");
|
||||
if (StringUtils.isEmpty(kotlinPostProcessFile)) {
|
||||
return; // skip if KOTLIN_POST_PROCESS_FILE env variable is not defined
|
||||
}
|
||||
|
||||
// only process files with kt extension
|
||||
if ("kt".equals(FilenameUtils.getExtension(file.toString()))) {
|
||||
String command = kotlinPostProcessFile + " " + file.toString();
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
p.waitFor();
|
||||
int exitValue = p.exitValue();
|
||||
if (exitValue != 0) {
|
||||
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
|
||||
} else {
|
||||
LOGGER.info("Successfully executed: " + command);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.openapitools.codegen.languages;
|
||||
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
@@ -40,12 +41,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public abstract class AbstractPhpCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPhpCodegen.class);
|
||||
@@ -161,6 +156,11 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("PHP_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable PHP_POST_PROCESS_FILE not defined so the PHP code may not be properly formatted. To define it, try 'export PHP_POST_PROCESS_FILE=\"/usr/local/bin/prettier --write\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(PACKAGE_NAME)) {
|
||||
this.setPackageName((String) additionalProperties.get(PACKAGE_NAME));
|
||||
} else {
|
||||
@@ -773,4 +773,31 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
|
||||
final int lastBackslashIndex = phpClassName.lastIndexOf('\\');
|
||||
return phpClassName.substring(lastBackslashIndex + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessFile(File file, String fileType) {
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
String phpPostProcessFile = System.getenv("PHP_POST_PROCESS_FILE");
|
||||
if (StringUtils.isEmpty(phpPostProcessFile)) {
|
||||
return; // skip if PHP_POST_PROCESS_FILE env variable is not defined
|
||||
}
|
||||
// only process files with php extension
|
||||
if ("php".equals(FilenameUtils.getExtension(file.toString()))) {
|
||||
String command = phpPostProcessFile + " " + file.toString();
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
p.waitFor();
|
||||
int exitValue = p.exitValue();
|
||||
if (exitValue != 0) {
|
||||
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
|
||||
} else {
|
||||
LOGGER.info("Successfully executed: " + command);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,10 @@ abstract class AbstractRubyCodegen extends DefaultCodegen implements CodegenConf
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toRegularExpression(String pattern) {
|
||||
return addRegularExpressionDelimiter(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// should be the same as variable name
|
||||
|
||||
@@ -116,6 +116,7 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("SCALA_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable SCALA_POST_PROCESS_FILE not defined so the Scala code may not be properly formatted. To define it, try 'export SCALA_POST_PROCESS_FILE=/usr/local/bin/scalafmt' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import io.swagger.v3.oas.models.info.*;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
@@ -224,7 +225,7 @@ public class ApexClientCodegen extends AbstractApexCodegen {
|
||||
);
|
||||
} else if (ModelUtils.isBooleanSchema(p)) {
|
||||
// true => "true", false => "false", null => "null"
|
||||
out = String.valueOf(((BooleanSchema) p).getDefault());
|
||||
out = String.valueOf(p.getDefault());
|
||||
} else if (ModelUtils.isLongSchema(p)) {
|
||||
Long def = (Long) p.getDefault();
|
||||
out = def == null ? out : def.toString() + "L";
|
||||
|
||||
@@ -251,4 +251,9 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
|
||||
// To avoid unexpected behaviors when options are passed programmatically such as { "useCollection": "" }
|
||||
return super.processCompiler(compiler).emptyStringIsFalse(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toRegularExpression(String pattern) {
|
||||
return escapeText(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CLibcurlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CLibcurlClientCodegen.class);
|
||||
|
||||
protected String moduleName;
|
||||
protected String specFolder = "spec";
|
||||
protected String libFolder = "lib";
|
||||
protected String apiDocPath = "docs/";
|
||||
protected String modelDocPath = "docs/";
|
||||
|
||||
protected static int emptyMethodNameCounter = 0;
|
||||
|
||||
public CLibcurlClientCodegen() {
|
||||
super();
|
||||
|
||||
modelPackage = "models";
|
||||
apiPackage = "api";
|
||||
outputFolder = "generated-code" + File.separator + "C-libcurl";
|
||||
modelTemplateFiles.put("model-header.mustache", ".h");
|
||||
modelTemplateFiles.put("model-body.mustache", ".c");
|
||||
apiTemplateFiles.put("api-header.mustache", ".h");
|
||||
apiTemplateFiles.put("api-body.mustache", ".c");
|
||||
//modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||
//apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||
embeddedTemplateDir = templateDir = "C-libcurl";
|
||||
|
||||
// TODO add auto-generated test files
|
||||
//modelTestTemplateFiles.put("model_test.mustache", ".c");
|
||||
//apiTestTemplateFiles.put("api_test.mustache", ".c");
|
||||
|
||||
// default HIDE_GENERATION_TIMESTAMP to true
|
||||
hideGenerationTimestamp = Boolean.TRUE;
|
||||
|
||||
setReservedWordsLowerCase(
|
||||
Arrays.asList(
|
||||
// local variable names used in API methods (endpoints)
|
||||
|
||||
// c reserved keywords
|
||||
// ref: https://en.cppreference.com/w/c/keyword
|
||||
"auto",
|
||||
"break",
|
||||
"case",
|
||||
"char",
|
||||
"const",
|
||||
"continue",
|
||||
"default",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"enum",
|
||||
"extern",
|
||||
"float",
|
||||
"for",
|
||||
"goto",
|
||||
"if",
|
||||
"inline",
|
||||
"int",
|
||||
"long",
|
||||
"register",
|
||||
"restrict",
|
||||
"return",
|
||||
"short",
|
||||
"signed",
|
||||
"sizeof",
|
||||
"static",
|
||||
"struct",
|
||||
"switch",
|
||||
"typedef",
|
||||
"union",
|
||||
"unsigned",
|
||||
"void",
|
||||
"volatile",
|
||||
"while",
|
||||
"_Alignas",
|
||||
"_Alignof",
|
||||
"_Atomic",
|
||||
"_Bool",
|
||||
"_Complex",
|
||||
"_Generic",
|
||||
"_Imaginary",
|
||||
"_Noreturn",
|
||||
"_Static_assert",
|
||||
"_Thread_local")
|
||||
);
|
||||
|
||||
instantiationTypes.clear();
|
||||
typeMapping.clear();
|
||||
importMapping.clear();
|
||||
languageSpecificPrimitives.clear();
|
||||
|
||||
// primitives in C lang
|
||||
languageSpecificPrimitives.add("int");
|
||||
languageSpecificPrimitives.add("short");
|
||||
languageSpecificPrimitives.add("int");
|
||||
languageSpecificPrimitives.add("long");
|
||||
languageSpecificPrimitives.add("float");
|
||||
languageSpecificPrimitives.add("double");
|
||||
languageSpecificPrimitives.add("char");
|
||||
languageSpecificPrimitives.add("FILE");
|
||||
languageSpecificPrimitives.add("Object");
|
||||
languageSpecificPrimitives.add("list_t*");
|
||||
|
||||
typeMapping.put("string", "char");
|
||||
typeMapping.put("char", "char");
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("long", "long");
|
||||
typeMapping.put("float", "double");
|
||||
typeMapping.put("double", "float");
|
||||
typeMapping.put("number", "float");
|
||||
typeMapping.put("date", "char");
|
||||
typeMapping.put("DateTime", "char");
|
||||
typeMapping.put("boolean", "int");
|
||||
typeMapping.put("file", "FILE");
|
||||
typeMapping.put("binary", "char");
|
||||
typeMapping.put("ByteArray", "char");
|
||||
typeMapping.put("UUID", "char");
|
||||
typeMapping.put("array", "list");
|
||||
typeMapping.put("map", "list_t*");
|
||||
typeMapping.put("date-time", "char");
|
||||
|
||||
// remove modelPackage and apiPackage added by default
|
||||
Iterator<CliOption> itr = cliOptions.iterator();
|
||||
while (itr.hasNext()) {
|
||||
CliOption opt = itr.next();
|
||||
if (CodegenConstants.MODEL_PACKAGE.equals(opt.getOpt()) ||
|
||||
CodegenConstants.API_PACKAGE.equals(opt.getOpt())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
|
||||
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC).
|
||||
defaultValue(Boolean.TRUE.toString()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("C_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable C_POST_PROCESS_FILE not defined so the C code may not be properly formatted by uncrustify (0.66 or later) or other code formatter. To define it, try `export C_POST_PROCESS_FILE=\"/usr/local/bin/uncrustify --no-backup\" && export UNCRUSTIFY_CONFIG=/path/to/uncrustify-rules.cfg` (Linux/Mac). Note: replace /path/to with the location of uncrustify-rules.cfg");
|
||||
}
|
||||
|
||||
// make api and model doc path available in mustache template
|
||||
additionalProperties.put("apiDocPath", apiDocPath);
|
||||
additionalProperties.put("modelDocPath", modelDocPath);
|
||||
|
||||
// use constant model/api package (folder path)
|
||||
setModelPackage("models");
|
||||
setApiPackage("api");
|
||||
|
||||
// root folder
|
||||
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", "", "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("libcurl.licence.mustache", "", "libcurl.licence"));
|
||||
supportingFiles.add(new SupportingFile("uncrustify-rules.cfg.mustache", "", "uncrustify-rules.cfg"));
|
||||
supportingFiles.add(new SupportingFile("README.md.mustache", "", "README.md"));
|
||||
// src folder
|
||||
supportingFiles.add(new SupportingFile("apiClient.c.mustache", "src", "apiClient.c"));
|
||||
supportingFiles.add(new SupportingFile("apiKey.c.mustache", "src", "apiKey.c"));
|
||||
supportingFiles.add(new SupportingFile("list.c.mustache", "src", "list.c"));
|
||||
// include folder
|
||||
supportingFiles.add(new SupportingFile("apiClient.h.mustache", "include", "apiClient.h"));
|
||||
supportingFiles.add(new SupportingFile("keyValuePair.h.mustache", "include", "keyValuePair.h"));
|
||||
supportingFiles.add(new SupportingFile("list.h.mustache", "include", "list.h"));
|
||||
// external folder
|
||||
supportingFiles.add(new SupportingFile("cJSON.licence.mustache", "external", "cJSON.licence"));
|
||||
supportingFiles.add(new SupportingFile("cJSON.c.mustache", "external" + File.separator + "src", "cJSON.c"));
|
||||
supportingFiles.add(new SupportingFile("cJSON.h.mustache", "external" + File.separator + "include", "cJSON.h"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "c";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a C (libcurl) client library (beta).";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
if (this.reservedWordsMappings().containsKey(name)) {
|
||||
return this.reservedWordsMappings().get(name);
|
||||
}
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + File.separator + "api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + File.separator + "model";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiTestFileFolder() {
|
||||
return outputFolder + File.separator + "unit-test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelTestFileFolder() {
|
||||
return outputFolder + File.separator + "unit-test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiDocFileFolder() {
|
||||
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelDocFileFolder() {
|
||||
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Schema schema) {
|
||||
/* comment out below as we'll do it in the template instead
|
||||
if (ModelUtils.isArraySchema(schema)) {
|
||||
Schema inner = ((ArraySchema) schema).getItems();
|
||||
return getSchemaType(schema) + "<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (ModelUtils.isMapSchema(schema)) {
|
||||
Schema inner = (Schema) schema.getAdditionalProperties();
|
||||
return getSchemaType(schema) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
*/
|
||||
|
||||
return super.getTypeDeclaration(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDefaultValue(Schema p) {
|
||||
if (ModelUtils.isIntegerSchema(p) || ModelUtils.isNumberSchema(p) || ModelUtils.isBooleanSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
return p.getDefault().toString();
|
||||
}
|
||||
} else if (ModelUtils.isStringSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
return "'" + escapeText((String) p.getDefault()) + "'";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemaType(Schema schema) {
|
||||
String openAPIType = super.getSchemaType(schema);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(openAPIType)) {
|
||||
type = typeMapping.get(openAPIType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
type = openAPIType;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// sanitize name
|
||||
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
// if it's all uppper case, convert to lower case
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
name = underscore(name);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// should be the same as variable name
|
||||
name = name.replaceAll("-","_");
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
|
||||
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||
name = modelNamePrefix + "_" + name;
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||
name = name + "_" + modelNameSuffix;
|
||||
}
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(name)) {
|
||||
String modelName = camelize("Model" + name);
|
||||
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||
return modelName;
|
||||
}
|
||||
|
||||
// model name starts with number
|
||||
if (name.matches("^\\d.*")) {
|
||||
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
|
||||
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||
}
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return underscore(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return underscore(toModelName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelDocFilename(String name) {
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
|
||||
// e.g. PhoneNumberApi.rb => phone_number_api.rb
|
||||
return camelize(name) + "API";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiDocFilename(String name) {
|
||||
return toApiName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiTestFilename(String name) {
|
||||
return ("test_" + toApiFilename(name)).replaceAll("_", "-");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelTestFilename(String name) {
|
||||
return ("test_" + toModelFilename(name)).replaceAll("_", "-");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if (name.length() == 0) {
|
||||
return "DefaultApi";
|
||||
}
|
||||
// e.g. phone_number_api => PhoneNumberApi
|
||||
return camelize(name) + "API";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumValue(String value, String datatype) {
|
||||
if ("Integer".equals(datatype) || "Float".equals(datatype)) {
|
||||
return value;
|
||||
} else {
|
||||
if (value.matches("\\d.*")) { // starts with number
|
||||
return "N" + escapeText(value);
|
||||
} else {
|
||||
return escapeText(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumVarName(String name, String datatype) {
|
||||
if (name.length() == 0) {
|
||||
return "EMPTY";
|
||||
}
|
||||
|
||||
// number
|
||||
if ("Integer".equals(datatype) || "Float".equals(datatype)) {
|
||||
String varName = name;
|
||||
varName = varName.replaceAll("-", "MINUS_");
|
||||
varName = varName.replaceAll("\\+", "PLUS_");
|
||||
varName = varName.replaceAll("\\.", "_DOT_");
|
||||
return varName;
|
||||
}
|
||||
|
||||
// string
|
||||
String enumName = sanitizeName(camelize(name).toUpperCase(Locale.ROOT));
|
||||
enumName = enumName.replaceFirst("^_", "");
|
||||
enumName = enumName.replaceFirst("_$", "");
|
||||
|
||||
if (enumName.matches("\\d.*")) { // starts with number
|
||||
return "N" + enumName;
|
||||
} else {
|
||||
return enumName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumName(CodegenProperty property) {
|
||||
String enumName = camelize(toModelName(property.name)).toUpperCase(Locale.ROOT);
|
||||
enumName = enumName.replaceFirst("^_", "");
|
||||
enumName = enumName.replaceFirst("_$", "");
|
||||
|
||||
if (enumName.matches("\\d.*")) { // starts with number
|
||||
return "N" + enumName;
|
||||
} else {
|
||||
return enumName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
// process enum in models
|
||||
return postProcessModelsEnum(objs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// rename to empty_method_name_1 (e.g.) if method name is empty
|
||||
if (StringUtils.isEmpty(operationId)) {
|
||||
operationId = camelize("empty_method_name_" + emptyMethodNameCounter++);
|
||||
LOGGER.warn("Empty method name (operationId) found. Renamed to " + operationId);
|
||||
return operationId;
|
||||
}
|
||||
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(operationId)) {
|
||||
String newOperationId = camelize(sanitizeName("call_" + operationId), true);
|
||||
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||
return newOperationId;
|
||||
}
|
||||
|
||||
// operationId starts with a number
|
||||
if (operationId.matches("^\\d.*")) {
|
||||
String newOperationId = camelize(sanitizeName("call_" + operationId), true);
|
||||
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + newOperationId);
|
||||
return newOperationId;
|
||||
}
|
||||
|
||||
return camelize(sanitizeName(operationId), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiImport(String name) {
|
||||
return apiPackage() + "/" + toApiFilename(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
return "#include \"" + name + ".h\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterExampleValue(CodegenParameter p) {
|
||||
String example;
|
||||
|
||||
if (p.defaultValue == null) {
|
||||
example = p.example;
|
||||
} else {
|
||||
p.example = p.defaultValue;
|
||||
return;
|
||||
}
|
||||
|
||||
String type = p.baseType;
|
||||
if (type == null) {
|
||||
type = p.dataType;
|
||||
}
|
||||
|
||||
if ("String".equals(type)) {
|
||||
if (example == null) {
|
||||
example = p.paramName + "_example";
|
||||
}
|
||||
example = "'" + escapeText(example) + "'";
|
||||
} else if ("Integer".equals(type)) {
|
||||
if (example == null) {
|
||||
example = "56";
|
||||
}
|
||||
} else if ("Float".equals(type)) {
|
||||
if (example == null) {
|
||||
example = "3.4";
|
||||
}
|
||||
} else if ("BOOLEAN".equals(type)) {
|
||||
if (example == null) {
|
||||
example = "true";
|
||||
}
|
||||
} else if ("File".equals(type)) {
|
||||
if (example == null) {
|
||||
example = "/path/to/file";
|
||||
}
|
||||
example = "File.new('" + escapeText(example) + "')";
|
||||
} else if ("Date".equals(type)) {
|
||||
if (example == null) {
|
||||
example = "2013-10-20";
|
||||
}
|
||||
example = "Date.parse('" + escapeText(example) + "')";
|
||||
} else if ("DateTime".equals(type)) {
|
||||
if (example == null) {
|
||||
example = "2013-10-20T19:20:30+01:00";
|
||||
}
|
||||
example = "DateTime.parse('" + escapeText(example) + "')";
|
||||
} else if (!languageSpecificPrimitives.contains(type)) {
|
||||
// type is a model class, e.g. User
|
||||
example = moduleName + "::" + type + ".new";
|
||||
}
|
||||
|
||||
if (example == null) {
|
||||
example = "nil";
|
||||
} else if (Boolean.TRUE.equals(p.isListContainer)) {
|
||||
example = "[" + example + "]";
|
||||
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
|
||||
example = "{'key' => " + example + "}";
|
||||
}
|
||||
|
||||
p.example = example;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverwrite(String filename) {
|
||||
// skip spec file as the file might have been updated with new test cases
|
||||
return !(skipOverwrite && new File(filename).exists());
|
||||
//
|
||||
//return super.shouldOverwrite(filename) && !filename.endsWith("_spec.rb");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeQuotationMark(String input) {
|
||||
// remove ' to avoid code injection
|
||||
return input.replace("'", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeUnsafeCharacters(String input) {
|
||||
return input.replace("=end", "=_end").replace("=begin", "=_begin");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postProcessFile(File file, String fileType) {
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String cPostProcessFile = System.getenv("C_POST_PROCESS_FILE");
|
||||
if (StringUtils.isEmpty(cPostProcessFile)) {
|
||||
return; // skip if C_POST_PROCESS_FILE env variable is not defined
|
||||
}
|
||||
|
||||
// only procees the following type (or we can simply rely on the file extension to check if it's a .c or .h file)
|
||||
Set<String> supportedFileType = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"supporting-mustache",
|
||||
"model-test",
|
||||
"model",
|
||||
"api-test",
|
||||
"api"));
|
||||
if (!supportedFileType.contains(fileType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// only process files with .c or .h extension
|
||||
if ("c".equals(FilenameUtils.getExtension(file.toString())) ||
|
||||
"h".equals(FilenameUtils.getExtension(file.toString()))) {
|
||||
String command = cPostProcessFile + " " + file.toString();
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
int exitValue = p.waitFor();
|
||||
if (exitValue != 0) {
|
||||
LOGGER.error("Error running the command ({}). Exit code: {}", command, exitValue);
|
||||
} else {
|
||||
LOGGER.info("Successfully executed: " + command);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,10 +285,12 @@ public class CSharpNancyFXServerCodegen extends AbstractCSharpCodegen {
|
||||
LOGGER.debug("Processing parents: " + parentModels);
|
||||
for (final String parent : parentModels) {
|
||||
final CodegenModel parentModel = ModelUtils.getModelByName(parent, models);
|
||||
parentModel.hasChildren = true;
|
||||
final Collection<CodegenModel> childrenModels = childrenByParent.get(parent);
|
||||
for (final CodegenModel child : childrenModels) {
|
||||
processParentPropertiesInChildModel(parentModel, child);
|
||||
if (parentModel != null) {
|
||||
parentModel.hasChildren = true;
|
||||
final Collection<CodegenModel> childrenModels = childrenByParent.get(parent);
|
||||
for (final CodegenModel child : childrenModels) {
|
||||
processParentPropertiesInChildModel(parentModel, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
* Copyright 2018 SmartBear Software
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isEmpty;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.samskivert.mustache.Mustache;
|
||||
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenModel;
|
||||
import org.openapitools.codegen.CodegenOperation;
|
||||
import org.openapitools.codegen.CodegenParameter;
|
||||
import org.openapitools.codegen.CodegenProperty;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.SupportingFile;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
|
||||
@SuppressWarnings({"hiding"})
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
|
||||
private static final String NET45 = "v4.5";
|
||||
private static final String NET40 = "v4.0";
|
||||
private static final String NET35 = "v3.5";
|
||||
// TODO: v5.0 is PCL, not netstandard version 1.3, and not a specific .NET Framework. This needs to be updated,
|
||||
// especially because it will conflict with .NET Framework 5.0 when released, and PCL 5 refers to Framework 4.0.
|
||||
// We should support either NETSTANDARD, PCL, or Both… but the concepts shouldn't be mixed.
|
||||
private static final String NETSTANDARD = "v5.0";
|
||||
private static final String UWP = "uwp";
|
||||
|
||||
// Defines the sdk option for targeted frameworks, which differs from targetFramework and targetFrameworkNuget
|
||||
private static final String MCS_NET_VERSION_KEY = "x-mcs-sdk";
|
||||
|
||||
protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase(Locale.ROOT) + "}";
|
||||
protected String clientPackage = "Org.OpenAPITools.Client";
|
||||
protected String localVariablePrefix = "";
|
||||
protected String apiDocPath = "docs/";
|
||||
protected String modelDocPath = "docs/";
|
||||
|
||||
// Defines TargetFrameworkVersion in csproj files
|
||||
protected String targetFramework = NET45;
|
||||
|
||||
// Defines nuget identifiers for target framework
|
||||
protected String targetFrameworkNuget = "net45";
|
||||
protected boolean supportsAsync = Boolean.TRUE;
|
||||
protected boolean supportsUWP = Boolean.FALSE;
|
||||
protected boolean netStandard = Boolean.FALSE;
|
||||
protected boolean generatePropertyChanged = Boolean.FALSE;
|
||||
|
||||
protected boolean validatable = Boolean.TRUE;
|
||||
protected Map<Character, String> regexModifiers;
|
||||
protected final Map<String, String> frameworks;
|
||||
|
||||
// By default, generated code is considered public
|
||||
protected boolean nonPublicApi = Boolean.FALSE;
|
||||
|
||||
public CSharpRefactorClientCodegen() {
|
||||
super();
|
||||
supportsInheritance = true;
|
||||
modelTemplateFiles.put("model.mustache", ".cs");
|
||||
apiTemplateFiles.put("api.mustache", ".cs");
|
||||
|
||||
modelDocTemplateFiles.put("model_doc.mustache", ".md");
|
||||
apiDocTemplateFiles.put("api_doc.mustache", ".md");
|
||||
|
||||
embeddedTemplateDir = templateDir = "csharp-refactor";
|
||||
|
||||
hideGenerationTimestamp = Boolean.TRUE;
|
||||
|
||||
cliOptions.clear();
|
||||
|
||||
// CLI options
|
||||
addOption(CodegenConstants.PACKAGE_NAME,
|
||||
"C# package name (convention: Title.Case).",
|
||||
this.packageName);
|
||||
|
||||
addOption(CodegenConstants.PACKAGE_VERSION,
|
||||
"C# package version.",
|
||||
this.packageVersion);
|
||||
|
||||
addOption(CodegenConstants.SOURCE_FOLDER,
|
||||
CodegenConstants.SOURCE_FOLDER_DESC,
|
||||
sourceFolder);
|
||||
|
||||
addOption(CodegenConstants.OPTIONAL_PROJECT_GUID,
|
||||
CodegenConstants.OPTIONAL_PROJECT_GUID_DESC,
|
||||
null);
|
||||
|
||||
addOption(CodegenConstants.INTERFACE_PREFIX,
|
||||
CodegenConstants.INTERFACE_PREFIX_DESC,
|
||||
interfacePrefix);
|
||||
|
||||
CliOption framework = new CliOption(
|
||||
CodegenConstants.DOTNET_FRAMEWORK,
|
||||
CodegenConstants.DOTNET_FRAMEWORK_DESC
|
||||
);
|
||||
frameworks = new ImmutableMap.Builder<String, String>()
|
||||
.put(NET35, ".NET Framework 3.5 compatible")
|
||||
.put(NET40, ".NET Framework 4.0 compatible")
|
||||
.put(NET45, ".NET Framework 4.5+ compatible")
|
||||
.put(NETSTANDARD, ".NET Standard 1.3 compatible")
|
||||
.put(UWP, "Universal Windows Platform (IMPORTANT: this will be decommissioned and replaced by v5.0)")
|
||||
.build();
|
||||
framework.defaultValue(this.targetFramework);
|
||||
framework.setEnum(frameworks);
|
||||
cliOptions.add(framework);
|
||||
|
||||
CliOption modelPropertyNaming = new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC);
|
||||
cliOptions.add(modelPropertyNaming.defaultValue("PascalCase"));
|
||||
|
||||
// CLI Switches
|
||||
addSwitch(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||
CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC,
|
||||
this.hideGenerationTimestamp);
|
||||
|
||||
addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
|
||||
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC,
|
||||
this.sortParamsByRequiredFlag);
|
||||
|
||||
addSwitch(CodegenConstants.USE_DATETIME_OFFSET,
|
||||
CodegenConstants.USE_DATETIME_OFFSET_DESC,
|
||||
this.useDateTimeOffsetFlag);
|
||||
|
||||
addSwitch(CodegenConstants.USE_COLLECTION,
|
||||
CodegenConstants.USE_COLLECTION_DESC,
|
||||
this.useCollection);
|
||||
|
||||
addSwitch(CodegenConstants.RETURN_ICOLLECTION,
|
||||
CodegenConstants.RETURN_ICOLLECTION_DESC,
|
||||
this.returnICollection);
|
||||
|
||||
addSwitch(CodegenConstants.OPTIONAL_METHOD_ARGUMENT,
|
||||
"C# Optional method argument, e.g. void square(int x=10) (.net 4.0+ only).",
|
||||
this.optionalMethodArgumentFlag);
|
||||
|
||||
addSwitch(CodegenConstants.OPTIONAL_ASSEMBLY_INFO,
|
||||
CodegenConstants.OPTIONAL_ASSEMBLY_INFO_DESC,
|
||||
this.optionalAssemblyInfoFlag);
|
||||
|
||||
addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE,
|
||||
CodegenConstants.OPTIONAL_PROJECT_FILE_DESC,
|
||||
this.optionalProjectFileFlag);
|
||||
|
||||
addSwitch(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES,
|
||||
CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES_DESC,
|
||||
this.optionalEmitDefaultValue);
|
||||
|
||||
addSwitch(CodegenConstants.GENERATE_PROPERTY_CHANGED,
|
||||
CodegenConstants.PACKAGE_DESCRIPTION_DESC,
|
||||
this.generatePropertyChanged);
|
||||
|
||||
// NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo
|
||||
// https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx
|
||||
// to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen
|
||||
// should rely on default public visibility.
|
||||
addSwitch(CodegenConstants.NON_PUBLIC_API,
|
||||
CodegenConstants.NON_PUBLIC_API_DESC,
|
||||
this.nonPublicApi);
|
||||
|
||||
addSwitch(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS,
|
||||
CodegenConstants.ALLOW_UNICODE_IDENTIFIERS_DESC,
|
||||
this.allowUnicodeIdentifiers);
|
||||
|
||||
addSwitch(CodegenConstants.NETCORE_PROJECT_FILE,
|
||||
CodegenConstants.NETCORE_PROJECT_FILE_DESC,
|
||||
this.netCoreProjectFileFlag);
|
||||
|
||||
addSwitch(CodegenConstants.VALIDATABLE,
|
||||
CodegenConstants.VALIDATABLE_DESC,
|
||||
this.validatable);
|
||||
|
||||
regexModifiers = new HashMap<Character, String>();
|
||||
regexModifiers.put('i', "IgnoreCase");
|
||||
regexModifiers.put('m', "Multiline");
|
||||
regexModifiers.put('s', "Singleline");
|
||||
regexModifiers.put('x', "IgnorePatternWhitespace");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
/*
|
||||
* NOTE: When supporting boolean additionalProperties, you should read the value and write it back as a boolean.
|
||||
* This avoids oddities where additionalProperties contains "false" rather than false, which will cause the
|
||||
* templating engine to behave unexpectedly.
|
||||
*
|
||||
* Use the pattern:
|
||||
* if (additionalProperties.containsKey(prop)) convertPropertyToBooleanAndWriteBack(prop);
|
||||
*/
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
|
||||
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
|
||||
}
|
||||
|
||||
|
||||
if (isEmpty(apiPackage)) {
|
||||
setApiPackage("Api");
|
||||
}
|
||||
if (isEmpty(modelPackage)) {
|
||||
setModelPackage("Model");
|
||||
}
|
||||
clientPackage = "Client";
|
||||
|
||||
Boolean excludeTests = false;
|
||||
if (additionalProperties.containsKey(CodegenConstants.EXCLUDE_TESTS)) {
|
||||
excludeTests = convertPropertyToBooleanAndWriteBack(CodegenConstants.EXCLUDE_TESTS);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.VALIDATABLE)) {
|
||||
setValidatable(convertPropertyToBooleanAndWriteBack(CodegenConstants.VALIDATABLE));
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.VALIDATABLE, validatable);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.DOTNET_FRAMEWORK)) {
|
||||
setTargetFramework((String) additionalProperties.get(CodegenConstants.DOTNET_FRAMEWORK));
|
||||
} else {
|
||||
// Ensure default is set.
|
||||
setTargetFramework(NET45);
|
||||
additionalProperties.put(CodegenConstants.DOTNET_FRAMEWORK, this.targetFramework);
|
||||
}
|
||||
|
||||
if (NET35.equals(this.targetFramework)) {
|
||||
// This is correct, mono will require you build .NET 3.5 sources using 4.0 SDK
|
||||
additionalProperties.put(MCS_NET_VERSION_KEY, "4");
|
||||
additionalProperties.put("net35", true);
|
||||
if (additionalProperties.containsKey(CodegenConstants.SUPPORTS_ASYNC)) {
|
||||
LOGGER.warn(".NET 3.5 generator does not support async.");
|
||||
additionalProperties.remove(CodegenConstants.SUPPORTS_ASYNC);
|
||||
}
|
||||
|
||||
setTargetFrameworkNuget("net35");
|
||||
setValidatable(Boolean.FALSE);
|
||||
setSupportsAsync(Boolean.FALSE);
|
||||
} else if (NETSTANDARD.equals(this.targetFramework)) {
|
||||
// TODO: NETSTANDARD here is misrepresenting a PCL v5.0 which supports .NET Framework 4.6+, .NET Core 1.0, and Windows Universal 10.0
|
||||
additionalProperties.put(MCS_NET_VERSION_KEY, "4.6-api");
|
||||
if (additionalProperties.containsKey("supportsUWP")) {
|
||||
LOGGER.warn(".NET " + NETSTANDARD + " generator does not support UWP.");
|
||||
additionalProperties.remove("supportsUWP");
|
||||
}
|
||||
|
||||
// TODO: NETSTANDARD=v5.0 and targetFrameworkNuget=netstandard1.3. These need to sync.
|
||||
setTargetFrameworkNuget("netstandard1.3");
|
||||
setSupportsAsync(Boolean.TRUE);
|
||||
setSupportsUWP(Boolean.FALSE);
|
||||
setNetStandard(Boolean.TRUE);
|
||||
|
||||
//Tests not yet implemented for .NET Standard codegen
|
||||
//Todo implement it
|
||||
excludeTests = true;
|
||||
} else if (UWP.equals(this.targetFramework)) {
|
||||
setTargetFrameworkNuget("uwp");
|
||||
setSupportsAsync(Boolean.TRUE);
|
||||
setSupportsUWP(Boolean.TRUE);
|
||||
} else if (NET40.equals(this.targetFramework)) {
|
||||
additionalProperties.put(MCS_NET_VERSION_KEY, "4");
|
||||
additionalProperties.put("isNet40", true);
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.SUPPORTS_ASYNC)) {
|
||||
LOGGER.warn(".NET " + NET40 + " generator does not support async.");
|
||||
additionalProperties.remove(CodegenConstants.SUPPORTS_ASYNC);
|
||||
}
|
||||
|
||||
setTargetFrameworkNuget("net40");
|
||||
setSupportsAsync(Boolean.FALSE);
|
||||
} else {
|
||||
additionalProperties.put(MCS_NET_VERSION_KEY, "4.5.2-api");
|
||||
setTargetFrameworkNuget("net45");
|
||||
setSupportsAsync(Boolean.TRUE);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.GENERATE_PROPERTY_CHANGED)) {
|
||||
if (NET35.equals(targetFramework)) {
|
||||
LOGGER.warn(CodegenConstants.GENERATE_PROPERTY_CHANGED + " is only supported by generated code for .NET 4+.");
|
||||
additionalProperties.remove(CodegenConstants.GENERATE_PROPERTY_CHANGED);
|
||||
} else if (NETSTANDARD.equals(targetFramework)) {
|
||||
LOGGER.warn(CodegenConstants.GENERATE_PROPERTY_CHANGED + " is not supported in .NET Standard generated code.");
|
||||
additionalProperties.remove(CodegenConstants.GENERATE_PROPERTY_CHANGED);
|
||||
} else if (Boolean.TRUE.equals(netCoreProjectFileFlag)) {
|
||||
LOGGER.warn(CodegenConstants.GENERATE_PROPERTY_CHANGED + " is not supported in .NET Core csproj project format.");
|
||||
additionalProperties.remove(CodegenConstants.GENERATE_PROPERTY_CHANGED);
|
||||
} else {
|
||||
setGeneratePropertyChanged(convertPropertyToBooleanAndWriteBack(CodegenConstants.GENERATE_PROPERTY_CHANGED));
|
||||
}
|
||||
}
|
||||
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
additionalProperties.put("clientPackage", clientPackage);
|
||||
|
||||
additionalProperties.put(CodegenConstants.EXCLUDE_TESTS, excludeTests);
|
||||
additionalProperties.put(CodegenConstants.VALIDATABLE, this.validatable);
|
||||
additionalProperties.put(CodegenConstants.SUPPORTS_ASYNC, this.supportsAsync);
|
||||
additionalProperties.put("supportsUWP", this.supportsUWP);
|
||||
additionalProperties.put("netStandard", this.netStandard);
|
||||
additionalProperties.put("targetFrameworkNuget", this.targetFrameworkNuget);
|
||||
|
||||
// TODO: either remove this and update templates to match the "optionalEmitDefaultValues" property, or rename that property.
|
||||
additionalProperties.put("emitDefaultValue", optionalEmitDefaultValue);
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_FILE)) {
|
||||
setOptionalProjectFileFlag(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_PROJECT_FILE));
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.OPTIONAL_PROJECT_FILE, optionalProjectFileFlag);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) {
|
||||
setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID));
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.OPTIONAL_PROJECT_GUID, packageGuid);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_METHOD_ARGUMENT)) {
|
||||
setOptionalMethodArgumentFlag(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_METHOD_ARGUMENT));
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.OPTIONAL_METHOD_ARGUMENT, optionalMethodArgumentFlag);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_ASSEMBLY_INFO)) {
|
||||
setOptionalAssemblyInfoFlag(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_ASSEMBLY_INFO));
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.OPTIONAL_ASSEMBLY_INFO, optionalAssemblyInfoFlag);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) {
|
||||
setNonPublicApi(convertPropertyToBooleanAndWriteBack(CodegenConstants.NON_PUBLIC_API));
|
||||
} else {
|
||||
additionalProperties.put(CodegenConstants.NON_PUBLIC_API, isNonPublicApi());
|
||||
}
|
||||
|
||||
final String testPackageName = testPackageName();
|
||||
String packageFolder = sourceFolder + File.separator + packageName;
|
||||
String clientPackageDir = packageFolder + File.separator + clientPackage;
|
||||
String testPackageFolder = testFolder + File.separator + testPackageName;
|
||||
|
||||
additionalProperties.put("testPackageName", testPackageName);
|
||||
|
||||
//Compute the relative path to the bin directory where the external assemblies live
|
||||
//This is necessary to properly generate the project file
|
||||
int packageDepth = packageFolder.length() - packageFolder.replace(java.io.File.separator, "").length();
|
||||
String binRelativePath = "..\\";
|
||||
for (int i = 0; i < packageDepth; i = i + 1)
|
||||
binRelativePath += "..\\";
|
||||
binRelativePath += "vendor";
|
||||
additionalProperties.put("binRelativePath", binRelativePath);
|
||||
|
||||
supportingFiles.add(new SupportingFile("IApiAccessor.mustache",
|
||||
clientPackageDir, "IApiAccessor.cs"));
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache",
|
||||
clientPackageDir, "Configuration.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache",
|
||||
clientPackageDir, "ApiClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiException.mustache",
|
||||
clientPackageDir, "ApiException.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiResponse.mustache",
|
||||
clientPackageDir, "ApiResponse.cs"));
|
||||
supportingFiles.add(new SupportingFile("ExceptionFactory.mustache",
|
||||
clientPackageDir, "ExceptionFactory.cs"));
|
||||
supportingFiles.add(new SupportingFile("OpenAPIDateConverter.mustache",
|
||||
clientPackageDir, "OpenAPIDateConverter.cs"));
|
||||
|
||||
supportingFiles.add(new SupportingFile("ClientUtils.mustache",
|
||||
clientPackageDir, "ClientUtils.cs"));
|
||||
supportingFiles.add(new SupportingFile("HttpMethod.mustache",
|
||||
clientPackageDir, "HttpMethod.cs"));
|
||||
supportingFiles.add(new SupportingFile("IAsynchronousClient.mustache",
|
||||
clientPackageDir, "IAsynchronousClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("ISynchronousClient.mustache",
|
||||
clientPackageDir, "ISynchronousClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("RequestOptions.mustache",
|
||||
clientPackageDir, "RequestOptions.cs"));
|
||||
supportingFiles.add(new SupportingFile("Multimap.mustache",
|
||||
clientPackageDir, "Multimap.cs"));
|
||||
|
||||
if (Boolean.FALSE.equals(this.netStandard) && Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
|
||||
supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat"));
|
||||
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh"));
|
||||
|
||||
// copy package.config to nuget's standard location for project-level installs
|
||||
supportingFiles.add(new SupportingFile("packages.config.mustache", packageFolder + File.separator, "packages.config"));
|
||||
// .travis.yml for travis-ci.org CI
|
||||
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
|
||||
} else if (Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
|
||||
supportingFiles.add(new SupportingFile("project.json.mustache", packageFolder + File.separator, "project.json"));
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile("IReadableConfiguration.mustache",
|
||||
clientPackageDir, "IReadableConfiguration.cs"));
|
||||
supportingFiles.add(new SupportingFile("GlobalConfiguration.mustache",
|
||||
clientPackageDir, "GlobalConfiguration.cs"));
|
||||
|
||||
// Only write out test related files if excludeTests is unset or explicitly set to false (see start of this method)
|
||||
if (Boolean.FALSE.equals(excludeTests)) {
|
||||
// shell script to run the nunit test
|
||||
supportingFiles.add(new SupportingFile("mono_nunit_test.mustache", "", "mono_nunit_test.sh"));
|
||||
|
||||
modelTestTemplateFiles.put("model_test.mustache", ".cs");
|
||||
apiTestTemplateFiles.put("api_test.mustache", ".cs");
|
||||
|
||||
if (Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
|
||||
supportingFiles.add(new SupportingFile("packages_test.config.mustache", testPackageFolder + File.separator, "packages.config"));
|
||||
}
|
||||
|
||||
if (NET40.equals(this.targetFramework)) {
|
||||
// Include minimal tests for modifications made to JsonSubTypes, since code is quite different for .net 4.0 from original implementation
|
||||
supportingFiles.add(new SupportingFile("JsonSubTypesTests.mustache",
|
||||
testPackageFolder + File.separator + "Client",
|
||||
"JsonSubTypesTests.cs"));
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(generatePropertyChanged)) {
|
||||
supportingFiles.add(new SupportingFile("FodyWeavers.xml", packageFolder, "FodyWeavers.xml"));
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||
|
||||
if (optionalAssemblyInfoFlag && Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
|
||||
supportingFiles.add(new SupportingFile("AssemblyInfo.mustache", packageFolder + File.separator + "Properties", "AssemblyInfo.cs"));
|
||||
}
|
||||
if (optionalProjectFileFlag) {
|
||||
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
|
||||
|
||||
if (Boolean.TRUE.equals(this.netCoreProjectFileFlag)) {
|
||||
supportingFiles.add(new SupportingFile("netcore_project.mustache", packageFolder, packageName + ".csproj"));
|
||||
} else {
|
||||
supportingFiles.add(new SupportingFile("Project.mustache", packageFolder, packageName + ".csproj"));
|
||||
if (Boolean.FALSE.equals(this.netStandard)) {
|
||||
supportingFiles.add(new SupportingFile("nuspec.mustache", packageFolder, packageName + ".nuspec"));
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(excludeTests)) {
|
||||
// NOTE: This exists here rather than previous excludeTests block because the test project is considered an optional project file.
|
||||
if (Boolean.TRUE.equals(this.netCoreProjectFileFlag)) {
|
||||
supportingFiles.add(new SupportingFile("netcore_testproject.mustache", testPackageFolder, testPackageName + ".csproj"));
|
||||
} else {
|
||||
supportingFiles.add(new SupportingFile("TestProject.mustache", testPackageFolder, testPackageName + ".csproj"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
additionalProperties.put("apiDocPath", apiDocPath);
|
||||
additionalProperties.put("modelDocPath", modelDocPath);
|
||||
}
|
||||
|
||||
public void setModelPropertyNaming(String naming) {
|
||||
if ("original".equals(naming) || "camelCase".equals(naming) ||
|
||||
"PascalCase".equals(naming) || "snake_case".equals(naming)) {
|
||||
this.modelPropertyNaming = naming;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
naming + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
}
|
||||
}
|
||||
|
||||
public String getModelPropertyNaming() {
|
||||
return this.modelPropertyNaming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
||||
super.postProcessOperationsWithModels(objs, allModels);
|
||||
if (objs != null) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
if (operations != null) {
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation operation : ops) {
|
||||
if (operation.returnType != null) {
|
||||
operation.returnContainer = operation.returnType;
|
||||
if (this.returnICollection && (
|
||||
operation.returnType.startsWith("List") ||
|
||||
operation.returnType.startsWith("Collection"))) {
|
||||
// NOTE: ICollection works for both List<T> and Collection<T>
|
||||
int genericStart = operation.returnType.indexOf("<");
|
||||
if (genericStart > 0) {
|
||||
operation.returnType = "ICollection" + operation.returnType.substring(genericStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "csharp-refactor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a CSharp client library.";
|
||||
}
|
||||
|
||||
public void setOptionalAssemblyInfoFlag(boolean flag) {
|
||||
this.optionalAssemblyInfoFlag = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
|
||||
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
|
||||
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) {
|
||||
final Schema parentModel = allDefinitions.get(toModelName(codegenModel.parent));
|
||||
if (parentModel != null) {
|
||||
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel, allDefinitions);
|
||||
if (codegenModel.hasEnums) {
|
||||
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
|
||||
}
|
||||
|
||||
Map<String, CodegenProperty> propertyHash = new HashMap<>(codegenModel.vars.size());
|
||||
for (final CodegenProperty property : codegenModel.vars) {
|
||||
propertyHash.put(property.name, property);
|
||||
}
|
||||
|
||||
for (final CodegenProperty property : codegenModel.readWriteVars) {
|
||||
if (property.defaultValue == null && property.baseName.equals(parentCodegenModel.discriminator)) {
|
||||
property.defaultValue = "\"" + name + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
CodegenProperty last = null;
|
||||
for (final CodegenProperty property : parentCodegenModel.vars) {
|
||||
// helper list of parentVars simplifies templating
|
||||
if (!propertyHash.containsKey(property.name)) {
|
||||
final CodegenProperty parentVar = property.clone();
|
||||
parentVar.isInherited = true;
|
||||
parentVar.hasMore = true;
|
||||
last = parentVar;
|
||||
LOGGER.info("adding parent variable {}", property.name);
|
||||
codegenModel.parentVars.add(parentVar);
|
||||
}
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
last.hasMore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup possible duplicates. Currently, readWriteVars can contain the same property twice. May or may not be isolated to C#.
|
||||
if (codegenModel != null && codegenModel.readWriteVars != null && codegenModel.readWriteVars.size() > 1) {
|
||||
int length = codegenModel.readWriteVars.size() - 1;
|
||||
for (int i = length; i > (length / 2); i--) {
|
||||
final CodegenProperty codegenProperty = codegenModel.readWriteVars.get(i);
|
||||
// If the property at current index is found earlier in the list, remove this last instance.
|
||||
if (codegenModel.readWriteVars.indexOf(codegenProperty) < i) {
|
||||
codegenModel.readWriteVars.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
public void setOptionalProjectFileFlag(boolean flag) {
|
||||
this.optionalProjectFileFlag = flag;
|
||||
}
|
||||
|
||||
public void setPackageGuid(String packageGuid) {
|
||||
this.packageGuid = packageGuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessParameter(CodegenParameter parameter) {
|
||||
postProcessPattern(parameter.pattern, parameter.vendorExtensions);
|
||||
super.postProcessParameter(parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||
postProcessPattern(property.pattern, property.vendorExtensions);
|
||||
super.postProcessModelProperty(model, property);
|
||||
}
|
||||
|
||||
/*
|
||||
* The pattern spec follows the Perl convention and style of modifiers. .NET
|
||||
* does not support this syntax directly so we need to convert the pattern to a .NET compatible
|
||||
* format and apply modifiers in a compatible way.
|
||||
* See https://msdn.microsoft.com/en-us/library/yd1hzczs(v=vs.110).aspx for .NET options.
|
||||
*/
|
||||
public void postProcessPattern(String pattern, Map<String, Object> vendorExtensions) {
|
||||
if (pattern != null) {
|
||||
int i = pattern.lastIndexOf('/');
|
||||
|
||||
//Must follow Perl /pattern/modifiers convention
|
||||
if (pattern.charAt(0) != '/' || i < 2) {
|
||||
throw new IllegalArgumentException("Pattern must follow the Perl "
|
||||
+ "/pattern/modifiers convention. " + pattern + " is not valid.");
|
||||
}
|
||||
|
||||
String regex = pattern.substring(1, i).replace("'", "\'");
|
||||
List<String> modifiers = new ArrayList<String>();
|
||||
|
||||
// perl requires an explicit modifier to be culture specific and .NET is the reverse.
|
||||
modifiers.add("CultureInvariant");
|
||||
|
||||
for (char c : pattern.substring(i).toCharArray()) {
|
||||
if (regexModifiers.containsKey(c)) {
|
||||
String modifier = regexModifiers.get(c);
|
||||
modifiers.add(modifier);
|
||||
} else if (c == 'l') {
|
||||
modifiers.remove("CultureInvariant");
|
||||
}
|
||||
}
|
||||
|
||||
vendorExtensions.put("x-regex", regex);
|
||||
vendorExtensions.put("x-modifiers", modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTargetFramework(String dotnetFramework) {
|
||||
if (!frameworks.containsKey(dotnetFramework)) {
|
||||
LOGGER.warn("Invalid .NET framework version, defaulting to " + this.targetFramework);
|
||||
} else {
|
||||
this.targetFramework = dotnetFramework;
|
||||
}
|
||||
LOGGER.info("Generating code for .NET Framework " + this.targetFramework);
|
||||
}
|
||||
|
||||
private CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
|
||||
// This generator uses inline classes to define enums, which breaks when
|
||||
// dealing with models that have subTypes. To clean this up, we will analyze
|
||||
// the parent and child models, look for enums that match, and remove
|
||||
// them from the child models and leave them in the parent.
|
||||
// Because the child models extend the parents, the enums will be available via the parent.
|
||||
|
||||
// Only bother with reconciliation if the parent model has enums.
|
||||
if (parentCodegenModel.hasEnums) {
|
||||
|
||||
// Get the properties for the parent and child models
|
||||
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
|
||||
List<CodegenProperty> codegenProperties = codegenModel.vars;
|
||||
|
||||
// Iterate over all of the parent model properties
|
||||
boolean removedChildEnum = false;
|
||||
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
|
||||
// Look for enums
|
||||
if (parentModelCodegenPropery.isEnum) {
|
||||
// Now that we have found an enum in the parent class,
|
||||
// and search the child class for the same enum.
|
||||
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
CodegenProperty codegenProperty = iterator.next();
|
||||
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
|
||||
// We found an enum in the child class that is
|
||||
// a duplicate of the one in the parent, so remove it.
|
||||
iterator.remove();
|
||||
removedChildEnum = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (removedChildEnum) {
|
||||
// If we removed an entry from this model's vars, we need to ensure hasMore is updated
|
||||
int count = 0, numVars = codegenProperties.size();
|
||||
for (CodegenProperty codegenProperty : codegenProperties) {
|
||||
count += 1;
|
||||
codegenProperty.hasMore = count < numVars;
|
||||
}
|
||||
codegenModel.vars = codegenProperties;
|
||||
}
|
||||
}
|
||||
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumVarName(String value, String datatype) {
|
||||
if (value.length() == 0) {
|
||||
return "Empty";
|
||||
}
|
||||
|
||||
// for symbol, e.g. $, #
|
||||
if (getSymbolName(value) != null) {
|
||||
return camelize(getSymbolName(value));
|
||||
}
|
||||
|
||||
// number
|
||||
if (datatype.startsWith("int") || datatype.startsWith("long") ||
|
||||
datatype.startsWith("double") || datatype.startsWith("float")) {
|
||||
String varName = "NUMBER_" + value;
|
||||
varName = varName.replaceAll("-", "MINUS_");
|
||||
varName = varName.replaceAll("\\+", "PLUS_");
|
||||
varName = varName.replaceAll("\\.", "_DOT_");
|
||||
return varName;
|
||||
}
|
||||
|
||||
// string
|
||||
String var = value.replaceAll("_", " ");
|
||||
//var = WordUtils.capitalizeFully(var);
|
||||
var = camelize(var);
|
||||
var = var.replaceAll("\\W+", "");
|
||||
|
||||
if (var.matches("\\d.*")) {
|
||||
return "_" + var;
|
||||
} else {
|
||||
return var;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// sanitize name
|
||||
name = sanitizeName(name);
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$")) {
|
||||
return name;
|
||||
}
|
||||
|
||||
name = getNameUsingModelPropertyNaming(name);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameUsingModelPropertyNaming(String name) {
|
||||
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
|
||||
case original:
|
||||
return name;
|
||||
case camelCase:
|
||||
return camelize(name, true);
|
||||
case PascalCase:
|
||||
return camelize(name);
|
||||
case snake_case:
|
||||
return underscore(name);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
name + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public void setPackageVersion(String packageVersion) {
|
||||
this.packageVersion = packageVersion;
|
||||
}
|
||||
|
||||
public void setTargetFrameworkNuget(String targetFrameworkNuget) {
|
||||
this.targetFrameworkNuget = targetFrameworkNuget;
|
||||
}
|
||||
|
||||
public void setSupportsAsync(Boolean supportsAsync) {
|
||||
this.supportsAsync = supportsAsync;
|
||||
}
|
||||
|
||||
public void setSupportsUWP(Boolean supportsUWP) {
|
||||
this.supportsUWP = supportsUWP;
|
||||
}
|
||||
|
||||
public void setNetStandard(Boolean netStandard) {
|
||||
this.netStandard = netStandard;
|
||||
}
|
||||
|
||||
public void setGeneratePropertyChanged(final Boolean generatePropertyChanged) {
|
||||
this.generatePropertyChanged = generatePropertyChanged;
|
||||
}
|
||||
|
||||
public boolean isNonPublicApi() {
|
||||
return nonPublicApi;
|
||||
}
|
||||
|
||||
public void setNonPublicApi(final boolean nonPublicApi) {
|
||||
this.nonPublicApi = nonPublicApi;
|
||||
}
|
||||
|
||||
public void setValidatable(boolean validatable) {
|
||||
this.validatable = validatable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelDocFilename(String name) {
|
||||
return toModelFilename(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiDocFileFolder() {
|
||||
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelDocFileFolder() {
|
||||
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiTestFileFolder() {
|
||||
return outputFolder + File.separator + testFolder + File.separator + testPackageName() + File.separator + apiPackage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelTestFileFolder() {
|
||||
return outputFolder + File.separator + testFolder + File.separator + testPackageName() + File.separator + modelPackage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mustache.Compiler processCompiler(Mustache.Compiler compiler) {
|
||||
// To avoid unexpected behaviors when options are passed programmatically such as { "supportsAsync": "" }
|
||||
return super.processCompiler(compiler).emptyStringIsFalse(true);
|
||||
}
|
||||
}
|
||||
@@ -253,7 +253,7 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
|
||||
if (!folder.isEmpty())
|
||||
folder += File.separator;
|
||||
|
||||
return "#include \"" + folder + toModelName(name) + ".h\"";
|
||||
return "#include \"" + folder + sanitizeName(name) + ".h\"";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,12 +276,12 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return initialCaps(toModelName(name));
|
||||
return sanitizeName(initialCaps(toModelName(name)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return modelNamePrefix + initialCaps(name) + "Api";
|
||||
return modelNamePrefix + sanitizeName(initialCaps(name)) + "Api";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -306,7 +306,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return modelNamePrefix + initialCaps(name);
|
||||
return modelNamePrefix + sanitizeName(initialCaps(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -322,7 +322,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return modelNamePrefix + initialCaps(name) + "ApiHandler";
|
||||
return modelNamePrefix + sanitizeName(initialCaps(name)) + "ApiHandler";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -285,8 +285,8 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation op : operationList) {
|
||||
for(String hdr : op.imports) {
|
||||
if(importMapping.containsKey(hdr)) {
|
||||
for (String hdr : op.imports) {
|
||||
if (importMapping.containsKey(hdr)) {
|
||||
continue;
|
||||
}
|
||||
operations.put("hasModelImport", true);
|
||||
@@ -295,7 +295,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
|
||||
protected boolean isFileSchema(CodegenProperty property) {
|
||||
return property.baseType.equals("HttpContent");
|
||||
}
|
||||
@@ -411,7 +411,6 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessAllModels(final Map<String, Object> models) {
|
||||
|
||||
final Map<String, Object> processed = super.postProcessAllModels(models);
|
||||
postProcessParentModels(models);
|
||||
return processed;
|
||||
@@ -432,13 +431,18 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
|
||||
*/
|
||||
private void processParentPropertiesInChildModel(final CodegenModel parent, final CodegenModel child) {
|
||||
final Map<String, CodegenProperty> childPropertiesByName = new HashMap<>(child.vars.size());
|
||||
for (final CodegenProperty childSchema : child.vars) {
|
||||
childPropertiesByName.put(childSchema.name, childSchema);
|
||||
if (child != null && child.vars != null && !child.vars.isEmpty()) {
|
||||
for (final CodegenProperty childSchema : child.vars) {
|
||||
childPropertiesByName.put(childSchema.name, childSchema);
|
||||
}
|
||||
}
|
||||
for (final CodegenProperty parentSchema : parent.vars) {
|
||||
final CodegenProperty duplicatedByParent = childPropertiesByName.get(parentSchema.name);
|
||||
if (duplicatedByParent != null) {
|
||||
duplicatedByParent.isInherited = true;
|
||||
|
||||
if (parent != null && parent.vars != null && !parent.vars.isEmpty()) {
|
||||
for (final CodegenProperty parentSchema : parent.vars) {
|
||||
final CodegenProperty duplicatedByParent = childPropertiesByName.get(parentSchema.name);
|
||||
if (duplicatedByParent != null) {
|
||||
duplicatedByParent.isInherited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("DART_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable DART_POST_PROCESS_FILE not defined so the Dart code may not be properly formatted. To define it, try `export DART_POST_PROCESS_FILE=\"/usr/local/bin/dartfmt -w\"` (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(BROWSER_CLIENT)) {
|
||||
@@ -313,6 +314,9 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
if (schema.getDefault() != null) {
|
||||
if (ModelUtils.isStringSchema(schema)) {
|
||||
return "\"" + schema.getDefault().toString().replaceAll("\"", "\\\"") + "\"";
|
||||
}
|
||||
return schema.getDefault().toString();
|
||||
} else {
|
||||
return "null";
|
||||
|
||||
@@ -169,7 +169,7 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
typeMapping.put("map", "Map");
|
||||
typeMapping.put("array", "List");
|
||||
typeMapping.put("list", "List");
|
||||
// typeMapping.put("object", "Map");
|
||||
typeMapping.put("object", "Map");
|
||||
typeMapping.put("binary", "String");
|
||||
typeMapping.put("ByteArray", "String");
|
||||
typeMapping.put("UUID", "String");
|
||||
@@ -431,7 +431,19 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||
}
|
||||
|
||||
return org.openapitools.codegen.utils.StringUtils.camelize(sanitizeName(operationId));
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(operationId)) {
|
||||
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + org.openapitools.codegen.utils.StringUtils.underscore(sanitizeName("call_" + operationId)));
|
||||
return org.openapitools.codegen.utils.StringUtils.underscore(sanitizeName("call_" + operationId));
|
||||
}
|
||||
|
||||
// operationId starts with a number
|
||||
if (operationId.matches("^\\d.*")) {
|
||||
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + org.openapitools.codegen.utils.StringUtils.underscore(sanitizeName("call_" + operationId)));
|
||||
operationId = "call_" + operationId;
|
||||
}
|
||||
|
||||
return org.openapitools.codegen.utils.StringUtils.underscore(sanitizeName(operationId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -642,6 +654,9 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
sb.append(param.dataType);
|
||||
} else if (param.isFile || param.isBinary) {
|
||||
sb.append("String.t");
|
||||
} else if ("String.t".equals(param.dataType)) {
|
||||
// uuid, password, etc
|
||||
sb.append(param.dataType);
|
||||
} else {
|
||||
// <module>.Model.<type>.t
|
||||
sb.append(moduleName);
|
||||
@@ -681,6 +696,8 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
// Primitive return type, don't even try to decode
|
||||
if (returnBaseType == null || (returnSimpleType && returnTypeIsPrimitive)) {
|
||||
return "false";
|
||||
} else if (isListContainer && languageSpecificPrimitives().contains(returnBaseType)) {
|
||||
return "[]";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (isListContainer) {
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
private static final String ENCODER = "elmEncoder";
|
||||
private static final String DECODER = "elmDecoder";
|
||||
private static final String DISCRIMINATOR_NAME = "discriminatorName";
|
||||
private static final String UNION_TYPE = "elmUnionType";
|
||||
private static final String CUSTOM_TYPE = "elmCustomType";
|
||||
|
||||
protected String packageName = "openapi";
|
||||
protected String packageVersion = "1.0.0";
|
||||
@@ -123,6 +123,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
"Dict",
|
||||
"Float",
|
||||
"Int",
|
||||
"List",
|
||||
"String")
|
||||
);
|
||||
|
||||
@@ -191,6 +192,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
} else { // 0.19
|
||||
LOGGER.info("Environment variable ELM_POST_PROCESS_FILE not defined so the Elm code may not be properly formatted. To define it, try `export ELM_POST_PROCESS_FILE=\"/usr/local/bin/elm-format --elm-version={} --yes\"` (Linux/Mac)", "0.19");
|
||||
}
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
switch (elmVersion) {
|
||||
@@ -261,7 +263,13 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toEnumVarName(String value, String datatype) {
|
||||
final String camelized = org.openapitools.codegen.utils.StringUtils.camelize(value.replace(" ", "_").replace("(", "_").replace(")", "")); // TODO FIXME escape properly
|
||||
String camelized = org.openapitools.codegen.utils.StringUtils.camelize(value.replace(" ", "_").replace("(", "_").replace(")", "")); // TODO FIXME escape properly
|
||||
|
||||
if (camelized.length() == 0) {
|
||||
LOGGER.error("Unable to determine enum variable name (name: {}, datatype: {}) from empty string. Default to UnknownEnumVariableName", value, datatype);
|
||||
camelized = "UnknownEnumVariableName";
|
||||
}
|
||||
|
||||
if (!Character.isUpperCase(camelized.charAt(0))) {
|
||||
return "N" + camelized;
|
||||
}
|
||||
@@ -345,7 +353,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
if (cm.isEnum) {
|
||||
addEncoderAndDecoder(cm.vendorExtensions, cm.classname, DataTypeExposure.EXPOSED);
|
||||
cm.vendorExtensions.put(UNION_TYPE, cm.classname);
|
||||
cm.vendorExtensions.put(CUSTOM_TYPE, cm.classname);
|
||||
} else if (cm.isAlias) {
|
||||
addEncoderAndDecoder(cm.vendorExtensions, cm.dataType, DataTypeExposure.EXPOSED);
|
||||
}
|
||||
@@ -495,9 +503,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
} else if (ModelUtils.isDateTimeSchema(p)) {
|
||||
return toOptionalValue(null);
|
||||
} else if (ModelUtils.isNumberSchema(p)) {
|
||||
NumberSchema dp = (NumberSchema) p;
|
||||
if (dp.getDefault() != null) {
|
||||
return toOptionalValue(dp.getDefault().toString());
|
||||
if (p.getDefault() != null) {
|
||||
return toOptionalValue(p.getDefault().toString());
|
||||
}
|
||||
return toOptionalValue(null);
|
||||
} else if (ModelUtils.isIntegerSchema(p)) {
|
||||
@@ -572,7 +579,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
if (property.isEnum) {
|
||||
addEncoderAndDecoder(property.vendorExtensions, property.baseName, DataTypeExposure.INTERNAL);
|
||||
property.vendorExtensions.put(UNION_TYPE, property.datatypeWithEnum);
|
||||
property.vendorExtensions.put(CUSTOM_TYPE, property.datatypeWithEnum);
|
||||
} else {
|
||||
final boolean isPrimitiveType = property.isMapContainer ? isPrimitiveDataType(property.dataType) : property.isPrimitiveType;
|
||||
addEncoderAndDecoder(property.vendorExtensions, property.dataType, isPrimitiveType ? DataTypeExposure.PRIMITIVE : DataTypeExposure.EXTERNAL);
|
||||
|
||||
@@ -891,7 +891,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
|
||||
if (appendDataType
|
||||
&& uniqueParamNameTypes.containsKey(paramNameType)
|
||||
&& !isDuplicate(paramNameType, dataType)) {
|
||||
paramNameType = paramNameType + dataType;
|
||||
paramNameType = toTypeName("", paramNameType + dataType);
|
||||
}
|
||||
|
||||
while (typeNames.contains(paramNameType)) {
|
||||
|
||||
@@ -152,6 +152,7 @@ public class JavaResteasyServerCodegen extends AbstractJavaJAXRSServerCodegen im
|
||||
|
||||
@Override
|
||||
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||
super.postProcessModelProperty(model, property);
|
||||
//Add imports for Jackson
|
||||
if (!BooleanUtils.toBoolean(model.isEnum)) {
|
||||
model.imports.add("JsonProperty");
|
||||
|
||||
@@ -234,6 +234,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("JS_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable JS_POST_PROCESS_FILE not defined so the JS code may not be properly formatted. To define it, try 'export JS_POST_PROCESS_FILE=\"/usr/local/bin/js-beautify -r -f\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(PROJECT_NAME)) {
|
||||
@@ -296,7 +297,11 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
}
|
||||
if (projectDescription == null) {
|
||||
// when projectDescription is not specified, use info.description
|
||||
projectDescription = sanitizeName(info.getDescription());
|
||||
if (StringUtils.isEmpty(info.getDescription())) {
|
||||
projectDescription = "JS API client generated by OpenAPI Generator";
|
||||
} else {
|
||||
projectDescription = sanitizeName(info.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
// when licenceName is not specified, use info.license
|
||||
@@ -505,13 +510,18 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
|
||||
private String getNameUsingModelPropertyNaming(String name) {
|
||||
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
|
||||
case original: return name;
|
||||
case camelCase: return org.openapitools.codegen.utils.StringUtils.camelize(name, true);
|
||||
case PascalCase: return org.openapitools.codegen.utils.StringUtils.camelize(name);
|
||||
case snake_case: return org.openapitools.codegen.utils.StringUtils.underscore(name);
|
||||
default: throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
name + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
case original:
|
||||
return name;
|
||||
case camelCase:
|
||||
return org.openapitools.codegen.utils.StringUtils.camelize(name, true);
|
||||
case PascalCase:
|
||||
return org.openapitools.codegen.utils.StringUtils.camelize(name);
|
||||
case snake_case:
|
||||
return org.openapitools.codegen.utils.StringUtils.underscore(name);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
name + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,7 +880,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
codegenModel.getVendorExtensions().put("x-itemType", getSchemaType(ModelUtils.getAdditionalProperties(model)));
|
||||
} else {
|
||||
String type = model.getType();
|
||||
if (isPrimitiveType(type)){
|
||||
if (isPrimitiveType(type)) {
|
||||
codegenModel.vendorExtensions.put("x-isPrimitive", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,11 @@ import java.util.Map;
|
||||
public class KotlinClientCodegen extends AbstractKotlinCodegen {
|
||||
|
||||
public static final String DATE_LIBRARY = "dateLibrary";
|
||||
public static final String COLLECTION_TYPE = "collectionType";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(KotlinClientCodegen.class);
|
||||
|
||||
protected String dateLibrary = DateLibrary.JAVA8.value;
|
||||
protected String collectionType = CollectionType.ARRAY.value;
|
||||
|
||||
public enum DateLibrary {
|
||||
STRING("string"),
|
||||
@@ -47,6 +49,17 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
public enum CollectionType {
|
||||
ARRAY("array"),
|
||||
LIST("list");
|
||||
|
||||
public final String value;
|
||||
|
||||
CollectionType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of `KotlinClientCodegen`.
|
||||
*/
|
||||
@@ -74,6 +87,13 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
|
||||
dateOptions.put(DateLibrary.JAVA8.value, "Java 8 native JSR310");
|
||||
dateLibrary.setEnum(dateOptions);
|
||||
cliOptions.add(dateLibrary);
|
||||
|
||||
CliOption collectionType = new CliOption(COLLECTION_TYPE, "Option. Collection type to use");
|
||||
Map<String, String> collectionOptions = new HashMap<>();
|
||||
collectionOptions.put(CollectionType.ARRAY.value, "kotlin.Array");
|
||||
collectionOptions.put(CollectionType.LIST.value, "kotlin.collections.List");
|
||||
collectionType.setEnum(collectionOptions);
|
||||
cliOptions.add(collectionType);
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
@@ -92,6 +112,10 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
|
||||
this.dateLibrary = library;
|
||||
}
|
||||
|
||||
public void setCollectionType(String collectionType) {
|
||||
this.collectionType = collectionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
@@ -116,6 +140,15 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
|
||||
additionalProperties.put(DateLibrary.JAVA8.value, true);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(COLLECTION_TYPE)) {
|
||||
setCollectionType(additionalProperties.get(COLLECTION_TYPE).toString());
|
||||
}
|
||||
|
||||
if (CollectionType.LIST.value.equals(collectionType)) {
|
||||
typeMapping.put("array", "kotlin.collections.List");
|
||||
typeMapping.put("list", "kotlin.collections.List");
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle"));
|
||||
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||
|
||||
@@ -135,6 +135,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("PERL_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable PERL_POST_PROCESS_FILE not defined so the Perl code may not be properly formatted. To define it, try 'export PERL_POST_PROCESS_FILE=/usr/local/bin/perltidy -b -bext=\"/\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(MODULE_VERSION)) {
|
||||
|
||||
@@ -424,6 +424,10 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
|
||||
var.vendorExtensions.put("x-parameterType", typeHint);
|
||||
}
|
||||
|
||||
if (var.isContainer) {
|
||||
var.vendorExtensions.put("x-parameterType", getTypeHint(var.dataType + "[]"));
|
||||
}
|
||||
|
||||
// Create a variable to display the correct data type in comments for models
|
||||
var.vendorExtensions.put("x-commentType", var.dataType);
|
||||
if (var.isContainer) {
|
||||
|
||||
@@ -174,6 +174,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("PYTHON_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE=\"/usr/local/bin/yapf -i\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
Boolean excludeTests = false;
|
||||
|
||||
@@ -157,6 +157,7 @@ public class PythonFlaskConnexionServerCodegen extends DefaultCodegen implements
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("PYTHON_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE=\"/usr/local/bin/yapf -i\"' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
//apiTemplateFiles.clear();
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import io.swagger.v3.oas.models.examples.Example;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.slf4j.Logger;
|
||||
@@ -536,6 +538,34 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
|
||||
p.example = example;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the example value of the parameter. Overrides the
|
||||
* setParameterExampleValue(CodegenParameter, Parameter) method in
|
||||
* DefaultCodegen to always call setParameterExampleValue(CodegenParameter)
|
||||
* in this class, which adds single quotes around strings from the
|
||||
* x-example property.
|
||||
*
|
||||
* @param codegenParameter Codegen parameter
|
||||
* @param parameter Parameter
|
||||
*/
|
||||
public void setParameterExampleValue(CodegenParameter codegenParameter, Parameter parameter) {
|
||||
if (parameter.getExample() != null) {
|
||||
codegenParameter.example = parameter.getExample().toString();
|
||||
} else if (parameter.getExamples() != null && !parameter.getExamples().isEmpty()) {
|
||||
Example example = parameter.getExamples().values().iterator().next();
|
||||
if (example.getValue() != null) {
|
||||
codegenParameter.example = example.getValue().toString();
|
||||
}
|
||||
} else {
|
||||
Schema schema = parameter.getSchema();
|
||||
if (schema != null && schema.getExample() != null) {
|
||||
codegenParameter.example = schema.getExample().toString();
|
||||
}
|
||||
}
|
||||
|
||||
setParameterExampleValue(codegenParameter);
|
||||
}
|
||||
|
||||
public void setGemName(String gemName) {
|
||||
this.gemName = gemName;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.openapitools.codegen.languages;
|
||||
import com.google.common.base.Strings;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.media.StringSchema;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.openapitools.codegen.utils.StringUtils;
|
||||
@@ -310,9 +311,17 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
if (ModelUtils.isArraySchema(p)) {
|
||||
ArraySchema ap = (ArraySchema) p;
|
||||
Schema inner = ap.getItems();
|
||||
if (inner == null) {
|
||||
LOGGER.warn(ap.getName() + "(array property) does not have a proper inner type defined.Default to string");
|
||||
inner = new StringSchema().description("TODO default missing array inner type to string");
|
||||
}
|
||||
return "Vec<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
Schema inner = ModelUtils.getAdditionalProperties(p);
|
||||
if (inner == null) {
|
||||
LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined. Default to string");
|
||||
inner = new StringSchema().description("TODO default missing map inner type to string");
|
||||
}
|
||||
return "::std::collections::HashMap<String, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
|
||||
|
||||
@@ -177,8 +177,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
"Rust crate name (convention: snake_case).")
|
||||
.defaultValue("openapi_client"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION,
|
||||
"Rust crate version.")
|
||||
.defaultValue("1.0.0"));
|
||||
"Rust crate version."));
|
||||
|
||||
/*
|
||||
* Additional Properties. These values can be passed to the templates and
|
||||
@@ -224,8 +223,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
|
||||
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
|
||||
} else {
|
||||
setPackageVersion("1.0.0");
|
||||
}
|
||||
|
||||
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
|
||||
@@ -477,6 +474,10 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return mimetype.toLowerCase(Locale.ROOT).startsWith("text/plain");
|
||||
}
|
||||
|
||||
boolean isMimetypeHtmlText(String mimetype) {
|
||||
return mimetype.toLowerCase(Locale.ROOT).startsWith("text/html");
|
||||
}
|
||||
|
||||
boolean isMimetypeWwwFormUrlEncoded(String mimetype) {
|
||||
return mimetype.toLowerCase(Locale.ROOT).startsWith("application/x-www-form-urlencoded");
|
||||
}
|
||||
@@ -547,6 +548,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
consumesXml = true;
|
||||
} else if (isMimetypePlainText(mimeType)) {
|
||||
consumesPlainText = true;
|
||||
} else if (isMimetypeHtmlText(mimeType)) {
|
||||
consumesPlainText = true;
|
||||
} else if (isMimetypeWwwFormUrlEncoded(mimeType)) {
|
||||
additionalProperties.put("usesUrlEncodedForm", true);
|
||||
}
|
||||
@@ -573,6 +576,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
producesXml = true;
|
||||
} else if (isMimetypePlainText(mimeType)) {
|
||||
producesPlainText = true;
|
||||
} else if (isMimetypeHtmlText(mimeType)) {
|
||||
producesPlainText = true;
|
||||
}
|
||||
|
||||
mediaType.put("mediaType", mimeType);
|
||||
@@ -665,7 +670,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
if (isMimetypeXml(mediaType)) {
|
||||
additionalProperties.put("usesXml", true);
|
||||
consumesXml = true;
|
||||
} else if (isMimetypePlainText(mediaType)) {
|
||||
} else if (isMimetypePlainText(mediaType) || isMimetypeHtmlText(mediaType)) {
|
||||
consumesPlainText = true;
|
||||
} else if (isMimetypeWwwFormUrlEncoded(mediaType)) {
|
||||
additionalProperties.put("usesUrlEncodedForm", true);
|
||||
|
||||
@@ -239,6 +239,11 @@ public class ScalaGatlingCodegen extends AbstractScalaCodegen implements Codegen
|
||||
continue;
|
||||
}
|
||||
for (Operation operation : path.readOperations()) {
|
||||
|
||||
if (operation.getExtensions() == null) {
|
||||
operation.setExtensions(new HashMap());
|
||||
}
|
||||
|
||||
if (!operation.getExtensions().keySet().contains("x-gatling-path")) {
|
||||
if (pathname.contains("{")) {
|
||||
String gatlingPath = pathname.replaceAll("\\{", "\\$\\{");
|
||||
|
||||
@@ -77,6 +77,7 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
public static final String OPENAPI_DOCKET_CONFIG = "swaggerDocketConfig";
|
||||
public static final String API_FIRST = "apiFirst";
|
||||
public static final String HATEOAS = "hateoas";
|
||||
public static final String RETURN_SUCCESS_CODE = "returnSuccessCode";
|
||||
|
||||
protected String title = "OpenAPI Spring";
|
||||
protected String configPackage = "org.openapitools.configuration";
|
||||
@@ -98,6 +99,7 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
protected boolean useOptional = false;
|
||||
protected boolean virtualService = false;
|
||||
protected boolean hateoas = false;
|
||||
protected boolean returnSuccessCode = false;
|
||||
|
||||
public SpringCodegen() {
|
||||
super();
|
||||
@@ -131,6 +133,7 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
cliOptions.add(CliOption.newBoolean(API_FIRST, "Generate the API from the OAI spec at server compile time (API first approach)", apiFirst));
|
||||
cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,"Use Optional container for optional parameters", useOptional));
|
||||
cliOptions.add(CliOption.newBoolean(HATEOAS, "Use Spring HATEOAS library to allow adding HATEOAS links", hateoas));
|
||||
cliOptions.add(CliOption.newBoolean(RETURN_SUCCESS_CODE, "Generated server returns 2xx code", returnSuccessCode));
|
||||
|
||||
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application using the SpringFox integration.");
|
||||
supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration.");
|
||||
@@ -277,6 +280,10 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
this.setHateoas(Boolean.valueOf(additionalProperties.get(HATEOAS).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(RETURN_SUCCESS_CODE)) {
|
||||
this.setReturnSuccessCode(Boolean.valueOf(additionalProperties.get(RETURN_SUCCESS_CODE).toString()));
|
||||
}
|
||||
|
||||
typeMapping.put("file", "Resource");
|
||||
importMapping.put("Resource", "org.springframework.core.io.Resource");
|
||||
|
||||
@@ -721,6 +728,10 @@ public class SpringCodegen extends AbstractJavaCodegen
|
||||
this.hateoas = hateoas;
|
||||
}
|
||||
|
||||
public void setReturnSuccessCode(boolean returnSuccessCode) {
|
||||
this.returnSuccessCode = returnSuccessCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||
super.postProcessModelProperty(model, property);
|
||||
|
||||
@@ -245,6 +245,7 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("SWIFT_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable SWIFT_POST_PROCESS_FILE not defined so the Swift code may not be properly formatted. To define it, try 'export SWIFT_POST_PROCESS_FILE=/usr/local/bin/swiftformat' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
// Setup project name
|
||||
|
||||
@@ -300,6 +300,7 @@ public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("SWIFT_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Environment variable SWIFT_POST_PROCESS_FILE not defined so the Swift code may not be properly formatted. To define it, try 'export SWIFT_POST_PROCESS_FILE=/usr/local/bin/swiftformat' (Linux/Mac)");
|
||||
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
|
||||
}
|
||||
|
||||
// Setup project name
|
||||
|
||||
@@ -472,7 +472,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return this.sanitizeName(this.convertUsingFileNamingConvention(name) + modelFileSuffix);
|
||||
return this.convertUsingFileNamingConvention(this.sanitizeName(name) + modelFileSuffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -302,9 +302,13 @@ public class ModelUtils {
|
||||
if (schema instanceof ObjectSchema) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// must not be a map
|
||||
if (SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType()) && !(schema instanceof MapSchema)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// must have at least one property
|
||||
if (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
@@ -501,7 +505,70 @@ public class ModelUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Schema contains a reference to an other Schema with '$ref', returns the referenced Schema if it is found or the actual Schema in the other cases.
|
||||
* Check to see if the schema is a model with at least one properties
|
||||
*
|
||||
* @param schema potentially containing a '$ref'
|
||||
* @return true if it's a model with at least one properties
|
||||
*/
|
||||
public static boolean isModel(Schema schema) {
|
||||
if (schema == null) {
|
||||
LOGGER.error("Schema cannot be null in isModel check");
|
||||
return false;
|
||||
}
|
||||
|
||||
// has at least one property
|
||||
if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// composed schema is a model
|
||||
if (schema instanceof ComposedSchema) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the schema is a free form object
|
||||
*
|
||||
* @param schema potentially containing a '$ref'
|
||||
* @return true if it's a free-form object
|
||||
*/
|
||||
public static boolean isFreeFormObject(Schema schema) {
|
||||
if (schema == null) {
|
||||
LOGGER.error("Schema cannot be null in isFreeFormObject check");
|
||||
return false;
|
||||
}
|
||||
|
||||
// has at least one property
|
||||
if ("object".equals(schema.getType())) {
|
||||
// no properties
|
||||
if ((schema.getProperties() == null || schema.getProperties().isEmpty())) {
|
||||
if (schema.getAdditionalProperties() == null) {
|
||||
return true;
|
||||
} else {
|
||||
// additionalProperties set to true
|
||||
if (schema.getAdditionalProperties() instanceof Boolean
|
||||
&& (Boolean) schema.getAdditionalProperties()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// additionalProperties is set to {}
|
||||
if (schema.getAdditionalProperties() instanceof Schema && schema.getAdditionalProperties() != null
|
||||
&& schema.getAdditionalProperties() instanceof ObjectSchema
|
||||
&& ((Schema) schema.getAdditionalProperties()).getProperties().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Schema contains a reference to another Schema with '$ref', returns the referenced Schema if it is found or the actual Schema in the other cases.
|
||||
*
|
||||
* @param openAPI specification being checked
|
||||
* @param schema potentially containing a '$ref'
|
||||
@@ -623,7 +690,7 @@ public class ModelUtils {
|
||||
/**
|
||||
* If a Callback contains a reference to an other Callback with '$ref', returns the referenced Callback if it is found or the actual Callback in the other cases.
|
||||
*
|
||||
* @param openAPI specification being checked
|
||||
* @param openAPI specification being checked
|
||||
* @param callback potentially containing a '$ref'
|
||||
* @return callback without '$ref'
|
||||
*/
|
||||
@@ -642,7 +709,7 @@ public class ModelUtils {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (openAPI != null && openAPI.getComponents() != null && openAPI.getComponents().getCallbacks() != null) {
|
||||
return openAPI.getComponents().getCallbacks().get(name);
|
||||
}
|
||||
@@ -689,7 +756,8 @@ public class ModelUtils {
|
||||
*/
|
||||
public static Schema unaliasSchema(Map<String, Schema> allSchemas, Schema schema) {
|
||||
if (allSchemas == null || allSchemas.isEmpty()) {
|
||||
LOGGER.warn("allSchemas cann't be null/empty in unaliasSchema. Returned 'schema'");
|
||||
// skip the warning as the spec can have no model defined
|
||||
//LOGGER.warn("allSchemas cannot be null/empty in unaliasSchema. Returned 'schema'");
|
||||
return schema;
|
||||
}
|
||||
|
||||
@@ -701,22 +769,17 @@ public class ModelUtils {
|
||||
} else if (ref.getEnum() != null && !ref.getEnum().isEmpty()) {
|
||||
// top-level enum class
|
||||
return schema;
|
||||
} else if (isArraySchema(ref) || isComposedSchema(ref)) { // array def should be created as models
|
||||
} else if (isFreeFormObject(ref)) {
|
||||
return schema;
|
||||
} else if (isArraySchema(ref)) {
|
||||
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
|
||||
} else if (isComposedSchema(ref)) {
|
||||
return schema;
|
||||
} else if (isMapSchema(ref)) {
|
||||
if (ref.getProperties() != null && !ref.getProperties().isEmpty()) // has properties
|
||||
return schema; // treat it as model
|
||||
else {
|
||||
// treat it as a typical map
|
||||
/* TODO unalias the map item if it's an alias
|
||||
if (ref.getAdditionalProperties() != null) {
|
||||
|
||||
Schema innerSchema = (Schema) ref.getAdditionalProperties();
|
||||
if (StringUtils.isNotEmpty(innerSchema.get$ref())) { // map item is a ref to something else
|
||||
//Schema unaliasInnerSchema = unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(innerSchema.get$ref())));
|
||||
//ref.setAdditionalProperties(unaliasInnerSchema);
|
||||
}
|
||||
}*/
|
||||
return unaliasSchema(allSchemas, allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref())));
|
||||
}
|
||||
} else if (isObjectSchema(ref)) { // model
|
||||
|
||||
@@ -179,7 +179,7 @@ public class URLPathUtils {
|
||||
LOGGER.warn("'scheme' not defined in the spec (2.0). Default to [http] for server URL [{}]", url);
|
||||
} else if (url.startsWith("/")) {
|
||||
url = LOCAL_HOST + url;
|
||||
LOGGER.warn("'host' not defined in the spec (2.0). Default to [{}] for server URL [{}]", LOCAL_HOST, url);
|
||||
LOGGER.warn("'host' (OAS 2.0) or 'servers' (OAS 3.0) not defined in the spec. Default to [{}] for server URL [{}]", LOCAL_HOST, url);
|
||||
} else if (!url.matches("[a-zA-Z][0-9a-zA-Z.+\\-]+://.+")) {
|
||||
// Add http scheme for urls without a scheme.
|
||||
// 2.0 spec is restricted to the following schemes: "http", "https", "ws", "wss"
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (CGenerator)
|
||||
|
||||
file(GLOB SRC_C src/*.c)
|
||||
#file(GLOB UNIT_TESTS_C unit-tests/*.c)
|
||||
#file(GLOB UNIT_TEST_C unit-test/*.c)
|
||||
file(GLOB MODEL_C model/*.c)
|
||||
file(GLOB API_C api/*.c)
|
||||
file(GLOB EXTERNAL_SRC_C external/src/*.c)
|
||||
set(ALL_SRC_LIST ${SRC_C} ${UNIT_TESTS_C} ${UNIT_TEST_C} ${MODEL_C} ${API_C})
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
include(CTest)
|
||||
include_directories(include)
|
||||
include_directories(external/include)
|
||||
include_directories(model)
|
||||
include_directories(api)
|
||||
|
||||
find_program(VALGRIND valgrind)
|
||||
if(VALGRIND)
|
||||
set(CMAKE_MEMORYCHECK_COMMAND valgrind)
|
||||
set(CMAKE_MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --track-origins=yes --read-var-info=yes --show-leak-kinds=all --error-exitcode=1")
|
||||
set(VALGRIND_LIST "")
|
||||
endif()
|
||||
|
||||
find_package(CURL 7.61.1 REQUIRED)
|
||||
if(CURL_FOUND)
|
||||
include_directories(${CURL_INCLUDE_DIR})
|
||||
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${CURL_LIBRARIES} )
|
||||
else(CURL_FOUND)
|
||||
message(FATAL_ERROR "Could not find the CURL library and development files.")
|
||||
endif()
|
||||
|
||||
# comment out below as auto-generated test file is not supported at the moment
|
||||
#foreach(ELEMENT ${UNIT_TESTS_C})
|
||||
# get_filename_component(ELEMENT_NAME ${ELEMENT} NAME_WE)
|
||||
# string(REGEX REPLACE "\\.c$" "" ELEMENT_REPLACED ${ELEMENT_NAME})
|
||||
# set(EXE_NAME unit-${ELEMENT_REPLACED})
|
||||
# add_executable(${EXE_NAME} ${ELEMENT} ${SRC_C} ${MODEL_C} ${API_C} ${EXTERNAL_SRC_C})
|
||||
# target_link_libraries(${EXE_NAME} ${CURL_LIBRARIES})
|
||||
# add_test(NAME ${EXE_NAME} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME})
|
||||
#
|
||||
# if(VALGRIND)
|
||||
# set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}")
|
||||
# separate_arguments(memcheck_command)
|
||||
#
|
||||
# add_test(
|
||||
# NAME valgrind-test-${ELEMENT_REPLACED}
|
||||
# COMMAND ${memcheck_command} ${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME}
|
||||
# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
# )
|
||||
# endif()
|
||||
#endforeach()
|
||||
#
|
||||
#foreach(ELEMENT ${UNIT_TEST_C})
|
||||
#get_filename_component(ELEMENT_NAME ${ELEMENT} NAME_WE)
|
||||
#string(REGEX REPLACE "\\.c$" "" ELEMENT_REPLACED ${ELEMENT_NAME})
|
||||
#set(EXE_NAME unit-${ELEMENT_REPLACED})
|
||||
#add_executable(${EXE_NAME} ${ELEMENT} ${SRC_C} ${MODEL_C} ${API_C} ${EXTERNAL_SRC_C})
|
||||
#target_link_libraries(${EXE_NAME} ${CURL_LIBRARIES})
|
||||
#add_test(NAME ${EXE_NAME} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME})
|
||||
#
|
||||
#if(VALGRIND)
|
||||
#set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}")
|
||||
#separate_arguments(memcheck_command)
|
||||
#
|
||||
#add_test(
|
||||
#NAME valgrind-test-${ELEMENT_REPLACED}
|
||||
#COMMAND ${memcheck_command} ${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME}
|
||||
#WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
#)
|
||||
#endif()
|
||||
#endforeach()
|
||||
|
||||
#For common coding standard (code beautifier/pretty printing)
|
||||
find_program(UNCRUSTIFY uncrustify)
|
||||
if(UNCRUSTIFY)
|
||||
add_custom_target(
|
||||
uncrustify
|
||||
)
|
||||
|
||||
foreach(ELEMENT ${ALL_SRC_LIST})
|
||||
string(REGEX REPLACE "/" "_" ELEMENT_NAME ${ELEMENT})
|
||||
set(DEP_NAME "uncrustify-${ELEMENT_NAME}")
|
||||
add_custom_target(
|
||||
${DEP_NAME}
|
||||
uncrustify -c uncrustify-rules.cfg --no-backup ${ELEMENT}
|
||||
DEPENDS ${ELEMENT}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
VERBATIM
|
||||
)
|
||||
add_dependencies(uncrustify ${DEP_NAME})
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -0,0 +1,45 @@
|
||||
# C API client for {{{projectName}}}
|
||||
|
||||
## Overview
|
||||
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI spec](https://openapis.org) from a remote server, you can easily generate an API client.
|
||||
|
||||
- API version: {{appVersion}}
|
||||
- Package version: {{packageVersion}}
|
||||
{{^hideGenerationTimestamp}}
|
||||
- Build date: {{generatedDate}}
|
||||
{{/hideGenerationTimestamp}}
|
||||
- Build package: {{generatorClass}}
|
||||
{{#infoUrl}}
|
||||
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
||||
{{/infoUrl}}
|
||||
|
||||
## Installation
|
||||
You'll need the `curl 7.61.1` package in order to build the API. To have code formatted nicely you also need to have uncrustify version 0.67.
|
||||
|
||||
### Prerequisites
|
||||
Install the `curl 7.61.1` package with the following command on Linux.
|
||||
```bash
|
||||
sudo apt remove curl
|
||||
wget http://curl.haxx.se/download/curl-7.61.1.tar.gz
|
||||
tar -xvf curl-7.61.1.tar.gz
|
||||
cd curl-7.61.1/
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
Install the `uncrustify 0.67` package with the following command on Linux.
|
||||
```bash
|
||||
git clone https://github.com/uncrustify/uncrustify.git
|
||||
cd uncrustify
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
|
||||
{{/hasMore}}{{/apis}}{{/apiInfo}}
|
||||
@@ -0,0 +1,454 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "apiClient.h"
|
||||
#include "cJSON.h"
|
||||
#include "keyValuePair.h"
|
||||
{{#imports}}{{{import}}}
|
||||
{{/imports}}
|
||||
|
||||
#define MAX_BUFFER_LENGTH 4096
|
||||
#define intToStr(dst, src) \
|
||||
do {\
|
||||
char dst[256];\
|
||||
snprintf(dst, 256, "%ld", (long int)(src));\
|
||||
}while(0)
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#summary}}
|
||||
// {{{summary}}}
|
||||
//
|
||||
{{/summary}}
|
||||
{{#notes}}
|
||||
// {{{notes}}}
|
||||
//
|
||||
{{/notes}}
|
||||
{{#returnType}}{{#returnTypeIsPrimitive}}{{#returnSimpleType}}{{{.}}}*{{/returnSimpleType}}{{^returnSimpleType}}{{{.}}}{{/returnSimpleType}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{{.}}}_t*{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
{{{classname}}}_{{{operationId}}}(apiClient_t *apiClient{{#allParams}}, {{{dataType}}}{{#isPrimitiveType}}{{#isString}}*{{/isString}}{{#isFile}}*{{/isFile}}{{/isPrimitiveType}}{{^isPrimitiveType}}_t*{{/isPrimitiveType}} {{{paramName}}}{{/allParams}}) {
|
||||
list_t *localVarQueryParameters = {{#hasQueryParams}}list_create();{{/hasQueryParams}}{{^hasQueryParams}}NULL;{{/hasQueryParams}}
|
||||
list_t *localVarHeaderParameters = {{#hasHeaderParams}}list_create();{{/hasHeaderParams}}{{^hasHeaderParams}}NULL;{{/hasHeaderParams}}
|
||||
list_t *localVarFormParameters = {{#hasFormParams}}list_create();{{/hasFormParams}}{{^hasFormParams}}NULL;{{/hasFormParams}}
|
||||
list_t *localVarHeaderType = {{#hasProduces}}list_create();{{/hasProduces}}{{^hasProduces}}NULL;{{/hasProduces}}
|
||||
list_t *localVarContentType = {{#hasConsumes}}list_create();{{/hasConsumes}}{{^hasConsumes}}NULL;{{/hasConsumes}}
|
||||
char *localVarBodyParameters = NULL;
|
||||
|
||||
// create the path
|
||||
long sizeOfPath = strlen("{{{path}}}")+1;
|
||||
char *localVarPath = malloc(sizeOfPath);
|
||||
snprintf(localVarPath, sizeOfPath, "{{{path}}}");
|
||||
|
||||
{{#pathParams}}
|
||||
|
||||
// Path Params
|
||||
long sizeOfPathParams_{{{paramName}}} = {{#pathParams}}{{#isLong}}sizeof({{paramName}})+3{{/isLong}}{{#isString}}strlen({{paramName}})+3{{/isString}}{{/pathParams}} + strlen("{ {{paramName}} }");
|
||||
|
||||
{{#isLong}}
|
||||
if({{paramName}} == 0){
|
||||
goto end;
|
||||
}
|
||||
char* localVarToReplace_{{paramName}} = malloc(sizeOfPathParams_{{paramName}});
|
||||
snprintf(localVarToReplace_{{paramName}}, sizeOfPathParams_{{paramName}}, "%s%s%s", "{", "{{paramName}}", "}");
|
||||
|
||||
char localVarBuff_{{paramName}}[256];
|
||||
intToStr(localVarBuff_{{paramName}}, {{paramName}});
|
||||
|
||||
localVarPath = strReplace(localVarPath, localVarToReplace_{{paramName}}, localVarBuff_{{paramName}});
|
||||
|
||||
{{/isLong}}
|
||||
{{#isString}}
|
||||
if({{paramName}} == NULL) {
|
||||
goto end;
|
||||
}
|
||||
char* localVarToReplace_{{paramName}} = malloc(sizeOfPathParams_{{paramName}});
|
||||
sprintf(localVarToReplace_{{paramName}}, "%s%s%s", "{", "{{paramName}}", "}");
|
||||
|
||||
localVarPath = strReplace(localVarPath, localVarToReplace_{{paramName}}, {{paramName}});
|
||||
{{/isString}}
|
||||
{{/pathParams}}
|
||||
{{#headerParams}}
|
||||
|
||||
{{#isString}}
|
||||
// header parameters
|
||||
char *keyHeader_{{{paramName}}};
|
||||
char *valueHeader_{{{paramName}}};
|
||||
keyValuePair_t *keyPairHeader_{{paramName}} = 0;
|
||||
if ({{paramName}}) {
|
||||
keyHeader_{{{paramName}}} = strdup("{{{paramName}}}");
|
||||
valueHeader_{{{paramName}}} = strdup({{{paramName}}});
|
||||
keyPairHeader_{{paramName}} = keyValuePair_create(keyHeader_{{{paramName}}}, valueHeader_{{{paramName}}});
|
||||
list_addElement(localVarHeaderParameters,keyPairHeader_{{paramName}});
|
||||
}
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
// header parameters
|
||||
char *keyHeader_{{{paramName}}};
|
||||
{{dataType}} valueHeader_{{{paramName}}};
|
||||
keyValuePair_t *keyPairHeader_{{paramName}} = 0;
|
||||
if ({{paramName}}) {
|
||||
keyHeader_{{{paramName}}} = strdup("{{{paramName}}}");
|
||||
valueHeader_{{{paramName}}} = {{{paramName}}};
|
||||
keyPairHeader_{{paramName}} = keyValuePair_create(keyHeader_{{{paramName}}}, &valueHeader_{{{paramName}}});
|
||||
list_addElement(localVarHeaderParameters,keyPairHeader_{{paramName}});
|
||||
}
|
||||
{{/isString}}
|
||||
{{/headerParams}}
|
||||
{{#queryParams}}
|
||||
|
||||
// query parameters
|
||||
{{#isListContainer}}
|
||||
if ({{paramName}})
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{#isString}}
|
||||
char *keyQuery_{{{paramName}}};
|
||||
char *valueQuery_{{{paramName}}};
|
||||
keyValuePair_t *keyPairQuery_{{paramName}} = 0;
|
||||
if ({{paramName}})
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
char *keyQuery_{{{paramName}}};
|
||||
{{dataType}} valueQuery_{{{paramName}}};
|
||||
keyValuePair_t *keyPairQuery_{{paramName}} = 0;
|
||||
if ({{paramName}})
|
||||
{{/isString}}
|
||||
{{/isListContainer}}
|
||||
{
|
||||
{{#isListContainer}}
|
||||
//listContainer
|
||||
localVarQueryParameters = {{{paramName}}};
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{#isString}}
|
||||
//string
|
||||
keyQuery_{{{paramName}}} = strdup("{{{paramName}}}");
|
||||
valueQuery_{{{paramName}}} = strdup({{{paramName}}});
|
||||
keyPairQuery_{{paramName}} = keyValuePair_create(keyQuery_{{{paramName}}}, valueQuery_{{{paramName}}});
|
||||
list_addElement(localVarQueryParameters,keyPairQuery_{{paramName}});
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
//not string
|
||||
keyQuery_{{{paramName}}} = strdup("{{{paramName}}}");
|
||||
valueQuery_{{{paramName}}} = {{{paramName}}};
|
||||
keyPairQuery_{{paramName}} = keyValuePair_create(keyQuery_{{{paramName}}}, &valueQuery_{{{paramName}}});
|
||||
list_addElement(localVarQueryParameters,keyPairQuery_{{paramName}});
|
||||
{{/isString}}
|
||||
{{/isListContainer}}
|
||||
}
|
||||
{{/queryParams}}
|
||||
{{#formParams}}
|
||||
|
||||
// form parameters
|
||||
{{#isFile}}
|
||||
|
||||
char *keyForm_{{paramName}};
|
||||
FileStruct *fileVar_{{paramName}};
|
||||
keyValuePair_t *keyPairForm_{{paramName}} = 0;
|
||||
if ({{paramName}} != NULL)
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
{{#isString}}
|
||||
char *keyForm_{{paramName}};
|
||||
char *valueForm_{{paramName}};
|
||||
keyValuePair_t *keyPairForm_{{paramName}} = 0;
|
||||
if ({{paramName}})
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
char *keyForm_{{paramName}};
|
||||
{{dataType}} valueForm_{{paramName}};
|
||||
keyValuePair_t *keyPairForm_{{paramName}} = 0;
|
||||
if ({{paramName}})
|
||||
{{/isString}}
|
||||
{{/isFile}}
|
||||
{
|
||||
{{#isFile}}
|
||||
fseek({{paramName}}, 0, SEEK_END);
|
||||
long f_size = ftell({{paramName}});
|
||||
fseek({{paramName}}, 0, SEEK_SET);
|
||||
fileVar_{{paramName}} = malloc(sizeof(FileStruct));
|
||||
keyForm_{{paramName}} = strdup("{{{paramName}}}");
|
||||
fileVar_{{paramName}}->fileData = malloc((f_size)* sizeof(char*));
|
||||
|
||||
fread(fileVar_{{paramName}}->fileData, f_size, 1, file);
|
||||
fileVar_{{paramName}}->fileData[f_size] = '\0';
|
||||
|
||||
fileVar_{{paramName}}->fileSize = f_size;
|
||||
char valueFile_{{paramName}}[sizeof(fileVar_{{paramName}})];
|
||||
|
||||
memcpy(valueFile_{{paramName}},&fileVar_{{paramName}}, sizeof(fileVar_{{paramName}}));
|
||||
|
||||
keyPairForm_{{paramName}} = keyValuePair_create(keyForm_{{paramName}},valueFile_{{paramName}});
|
||||
list_addElement(localVarFormParameters,keyPairForm_{{paramName}}); //file adding
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
{{#isString}}
|
||||
keyForm_{{paramName}} = strdup("{{{paramName}}}");
|
||||
valueForm_{{paramName}} = strdup({{paramName}});
|
||||
keyPairForm_{{paramName}} = keyValuePair_create(keyForm_{{paramName}},valueForm_{{paramName}});
|
||||
list_addElement(localVarFormParameters,keyPairForm_{{paramName}}); //String
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
keyForm_{{paramName}} = strdup("{{{paramName}}}");
|
||||
valueForm_{{paramName}} = {{paramName}};
|
||||
keyPairForm_{{paramName}} = keyValuePair_create(keyForm_{{paramName}},&valueForm_{{paramName}});
|
||||
list_addElement(localVarFormParameters,keyPairForm_{{paramName}}); // not String
|
||||
{{/isString}}
|
||||
{{/isFile}}
|
||||
}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}
|
||||
|
||||
// Body Param
|
||||
{{#isListContainer}}
|
||||
//notstring
|
||||
cJSON *localVar_{{paramName}};
|
||||
cJSON *localVarItemJSON_{{paramName}};
|
||||
cJSON *localVarSingleItemJSON_{{paramName}};
|
||||
if ({{paramName}} != NULL) {
|
||||
localVarItemJSON_{{paramName}} = cJSON_CreateObject();
|
||||
localVarSingleItemJSON_{{paramName}} = cJSON_AddArrayToObject(localVarItemJSON_{{paramName}}, "{{paramName}}");
|
||||
if (localVarSingleItemJSON_{{paramName}} == NULL) {
|
||||
// nonprimitive container
|
||||
const char *error_ptr = cJSON_GetErrorPtr();
|
||||
if(error_ptr != NULL) {
|
||||
fprintf(stderr, "Error Before: %s\n", error_ptr);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
listEntry_t *{{paramName}}BodyListEntry;
|
||||
|
||||
list_ForEach({{paramName}}BodyListEntry, {{paramName}}) {
|
||||
localVar_{{paramName}} = {{paramName}}_convertToJSON({{paramName}}BodyListEntry->data);
|
||||
if(localVar_{{paramName}} == NULL) {
|
||||
const char *error_ptr = cJSON_GetErrorPtr();
|
||||
if(error_ptr != NULL) {
|
||||
fprintf(stderr, "Error Before: %s\n", error_ptr);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
cJSON_AddItemToArray(localVarSingleItemJSON_{{paramName}}, localVar_{{paramName}});
|
||||
}
|
||||
|
||||
localVarBodyParameters = cJSON_Print(localVarItemJSON_{{paramName}});
|
||||
}
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
cJSON *localVarSingleItemJSON_{{paramName}};
|
||||
if ({{paramName}} != NULL) {
|
||||
//string
|
||||
localVarSingleItemJSON_{{paramName}} = {{paramName}}_convertToJSON({{paramName}});
|
||||
localVarBodyParameters = cJSON_Print(localVarSingleItemJSON_{{paramName}});
|
||||
}
|
||||
{{/isListContainer}}
|
||||
{{/bodyParam}}
|
||||
{{#produces}}
|
||||
list_addElement(localVarHeaderType,"{{{mediaType}}}"); //produces
|
||||
{{/produces}}
|
||||
{{#consumes}}
|
||||
list_addElement(localVarContentType,"{{{mediaType}}}"); //consumes
|
||||
{{/consumes}}
|
||||
apiClient_invoke(apiClient,
|
||||
localVarPath,
|
||||
localVarQueryParameters,
|
||||
localVarHeaderParameters,
|
||||
localVarFormParameters,
|
||||
localVarHeaderType,
|
||||
localVarContentType,
|
||||
localVarBodyParameters,
|
||||
"{{{httpMethod}}}");
|
||||
|
||||
{{#responses}}
|
||||
if (apiClient->response_code == {{code}}) {
|
||||
printf("%s\n","{{message}}");
|
||||
}
|
||||
{{/responses}}
|
||||
{{#returnType}}
|
||||
{{#returnTypeIsPrimitive}}
|
||||
{{#returnSimpleType}}
|
||||
//primitive reutrn type simple
|
||||
{{returnType}}* elementToReturn = strdup(({{returnType}}*)apiClient->dataReceived);
|
||||
|
||||
{{/returnSimpleType}}
|
||||
{{^returnSimpleType}}
|
||||
//primitive reutrn type not simple
|
||||
cJSON *{{paramName}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
|
||||
cJSON *{{{paramName}}}VarJSON;
|
||||
list_t *elementToReturn = list_create();
|
||||
cJSON_ArrayForEach({{{paramName}}}VarJSON, {{paramName}}localVarJSON){
|
||||
keyValuePair_t *keyPair = keyValuePair_create(strdup({{{paramName}}}VarJSON->string), cJSON_Print({{{paramName}}}VarJSON));
|
||||
list_addElement(elementToReturn, keyPair);
|
||||
}
|
||||
cJSON_Delete({{paramName}}localVarJSON);
|
||||
|
||||
{{/returnSimpleType}}
|
||||
{{/returnTypeIsPrimitive}}
|
||||
{{^returnTypeIsPrimitive}}
|
||||
{{#returnContainer}}
|
||||
cJSON *{{classname}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
|
||||
if(!cJSON_IsArray({{classname}}localVarJSON)) {
|
||||
return 0;//nonprimitive container
|
||||
}
|
||||
list_t *elementToReturn = list_create();
|
||||
cJSON *{{{paramName}}}VarJSON;
|
||||
cJSON_ArrayForEach({{{paramName}}}VarJSON, {{classname}}localVarJSON)
|
||||
{
|
||||
if(!cJSON_IsObject({{{paramName}}}VarJSON))
|
||||
{
|
||||
// return 0;
|
||||
}
|
||||
char *localVarJSONToChar = cJSON_Print({{{paramName}}}VarJSON);
|
||||
list_addElement(elementToReturn , localVarJSONToChar);
|
||||
}
|
||||
|
||||
cJSON_Delete( {{classname}}localVarJSON);
|
||||
cJSON_Delete( {{{paramName}}}VarJSON);
|
||||
{{/returnContainer}}
|
||||
{{^returnContainer}}
|
||||
//nonprimitive not container
|
||||
{{{returnBaseType}}}_t *elementToReturn = {{{returnBaseType}}}_parseFromJSON(apiClient->dataReceived);
|
||||
if(elementToReturn == NULL) {
|
||||
// return 0;
|
||||
}
|
||||
|
||||
{{/returnContainer}}
|
||||
//return type
|
||||
{{/returnTypeIsPrimitive}}
|
||||
apiClient_free(apiClient);
|
||||
{{#hasQueryParams}}list_free(localVarQueryParameters);{{/hasQueryParams}}
|
||||
{{#hasHeaderParams}}list_free(localVarHeaderParameters);{{/hasHeaderParams}}
|
||||
{{#hasFormParams}}list_free(localVarFormParameters);{{/hasFormParams}}
|
||||
{{#hasProduces}}list_free(localVarHeaderType);{{/hasProduces}}
|
||||
{{#hasConsumes}}list_free(localVarContentType);{{/hasConsumes}}
|
||||
free(localVarPath);
|
||||
{{#pathParams}}
|
||||
free(localVarToReplace_{{paramName}});
|
||||
{{/pathParams}}
|
||||
{{#headerParams}}
|
||||
{{#isString}}
|
||||
free(keyHeader_{{{paramName}}});
|
||||
free(valueHeader_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
free(keyHeader_{{{paramName}}});
|
||||
{{/isString}}
|
||||
free(keyPairHeader_{{paramName}});
|
||||
{{/headerParams}}
|
||||
{{#bodyParams}}
|
||||
{{#isListContainer}}
|
||||
cJSON_Delete(localVarItemJSON_{{paramName}});
|
||||
cJSON_Delete(localVarSingleItemJSON_{{paramName}});
|
||||
cJSON_Delete(localVar_{{paramName}});
|
||||
free(localVarBodyParameters);
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
cJSON_Delete(localVarSingleItemJSON_{{paramName}});
|
||||
free(localVarBodyParameters);
|
||||
{{/isListContainer}}
|
||||
{{/bodyParams}}
|
||||
{{#queryParams}}
|
||||
{{^isListContainer}}
|
||||
{{#isString}}
|
||||
free(keyQuery_{{{paramName}}});
|
||||
free(valueQuery_{{{paramName}}});
|
||||
keyValuePair_free(keyPairQuery_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
free(keyQuery_{{{paramName}}});
|
||||
keyValuePair_free(keyPairQuery_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{/isListContainer}}
|
||||
{{/queryParams}}
|
||||
{{#formParams}}
|
||||
{{#isFile}}
|
||||
free(keyForm_{{{paramName}}});
|
||||
free(fileVar_{{paramName}}->fileData);
|
||||
free(fileVar_{{paramName}});
|
||||
free(keyPairForm_{{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
{{#isString}}
|
||||
free(keyForm_{{{paramName}}});
|
||||
free(valueForm_{{{paramName}}});
|
||||
free(keyPairForm_{{paramName}});
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
free(keyForm_{{{paramName}}});
|
||||
free(keyPairForm_{{paramName}});
|
||||
{{/isString}}
|
||||
{{/isFile}}
|
||||
{{/formParams}}
|
||||
return elementToReturn;
|
||||
end:
|
||||
return NULL;
|
||||
{{/returnType}}
|
||||
{{^returnType}}
|
||||
//No return type
|
||||
end: apiClient_free(apiClient);
|
||||
{{#hasQueryParams}}list_free(localVarQueryParameters);{{/hasQueryParams}}
|
||||
{{#hasHeaderParams}}list_free(localVarHeaderParameters);{{/hasHeaderParams}}
|
||||
{{#hasFormParams}}list_free(localVarFormParameters);{{/hasFormParams}}
|
||||
{{#hasProduces}}list_free(localVarHeaderType);{{/hasProduces}}
|
||||
{{#hasConsumes}}list_free(localVarContentType);{{/hasConsumes}}
|
||||
free(localVarPath);
|
||||
{{#pathParams}}
|
||||
free(localVarToReplace_{{paramName}});
|
||||
{{/pathParams}}
|
||||
{{#headerParams}}
|
||||
{{#isString}}
|
||||
free(keyHeader_{{{paramName}}});
|
||||
free(valueHeader_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
free(keyHeader_{{{paramName}}});
|
||||
{{/isString}}
|
||||
free(keyPairHeader_{{paramName}});
|
||||
{{/headerParams}}
|
||||
{{#bodyParams}}
|
||||
{{#isListContainer}}
|
||||
cJSON_Delete(localVarItemJSON_{{paramName}});
|
||||
cJSON_Delete(localVarSingleItemJSON_{{paramName}});
|
||||
cJSON_Delete(localVar_{{paramName}});
|
||||
free(localVarBodyParameters);
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
cJSON_Delete(localVarSingleItemJSON_{{paramName}});
|
||||
free(localVarBodyParameters);
|
||||
{{/isListContainer}}
|
||||
{{/bodyParams}}
|
||||
{{#queryParams}}
|
||||
{{^isListContainer}}
|
||||
{{#isString}}
|
||||
free(keyQuery_{{{paramName}}});
|
||||
free(valueQuery_{{{paramName}}});
|
||||
keyValuePair_free(keyPairQuery_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{#isString}}
|
||||
free(keyQuery_{{{paramName}}});
|
||||
keyValuePair_free(keyPairQuery_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{/isListContainer}}
|
||||
{{/queryParams}}
|
||||
{{#formParams}}
|
||||
{{#isFile}}
|
||||
free(keyForm_{{{paramName}}});
|
||||
free(fileVar_{{paramName}}->fileData);
|
||||
free(fileVar_{{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
{{#isString}}
|
||||
free(keyForm_{{{paramName}}});
|
||||
free(valueForm_{{{paramName}}});
|
||||
keyValuePair_free(keyPairForm_{{{paramName}}});
|
||||
{{/isString}}
|
||||
{{^isString}}
|
||||
free(keyForm_{{{paramName}}});
|
||||
free(keyPairForm_{{paramName}});
|
||||
{{/isString}}
|
||||
{{/isFile}}
|
||||
{{/formParams}}
|
||||
{{/returnType}}
|
||||
|
||||
}
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "apiClient.h"
|
||||
#include "cJSON.h"
|
||||
{{#imports}}{{{import}}}
|
||||
{{/imports}}
|
||||
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#summary}}
|
||||
// {{{summary}}}
|
||||
//
|
||||
{{/summary}}
|
||||
{{#notes}}
|
||||
// {{{notes}}}
|
||||
//
|
||||
{{/notes}}
|
||||
{{#returnType}}{{#returnTypeIsPrimitive}}{{#returnSimpleType}}{{{.}}}*{{/returnSimpleType}}{{^returnSimpleType}}{{{.}}}{{/returnSimpleType}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{{.}}}_t*{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
{{{classname}}}_{{{operationId}}}(apiClient_t *apiClient{{#allParams}},{{{dataType}}}{{#isPrimitiveType}}{{#isString}}*{{/isString}}{{#isFile}}*{{/isFile}}{{/isPrimitiveType}}{{^isPrimitiveType}}_t*{{/isPrimitiveType}} {{{paramName}}} {{/allParams}});
|
||||
|
||||
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,449 @@
|
||||
#include <curl/curl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "apiClient.h"
|
||||
#include "keyValuePair.h"
|
||||
|
||||
size_t writeDataCallback(void *buffer, size_t size, size_t nmemb, void *userp);
|
||||
|
||||
apiClient_t *apiClient_create() {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
apiClient_t *apiClient = malloc(sizeof(apiClient_t));
|
||||
apiClient->basePath = "{{{basePath}}}";
|
||||
apiClient->dataReceived = NULL;
|
||||
apiClient->response_code = 0;
|
||||
#ifdef BASIC_AUTH
|
||||
apiClient->username = NULL;
|
||||
apiClient->password = NULL;
|
||||
#endif // BASIC_AUTH
|
||||
#ifdef OAUTH2
|
||||
apiClient->accessToken = NULL;
|
||||
#endif // OAUTH2
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
void apiClient_free(apiClient_t *apiClient) {
|
||||
if(apiClient->dataReceived) {
|
||||
free(apiClient->dataReceived);
|
||||
}
|
||||
free(apiClient);
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
void replaceSpaceWithPlus(char *stringToProcess) {
|
||||
for(int i = 0; i < strlen(stringToProcess); i++) {
|
||||
if(stringToProcess[i] == ' ') {
|
||||
stringToProcess[i] = '+';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *assembleTargetUrl(char *basePath,
|
||||
char *operationParameter,
|
||||
list_t *queryParameters) {
|
||||
int neededBufferSizeForQueryParameters = 0;
|
||||
listEntry_t *listEntry;
|
||||
|
||||
if(queryParameters != NULL) {
|
||||
list_ForEach(listEntry, queryParameters) {
|
||||
keyValuePair_t *pair = listEntry->data;
|
||||
neededBufferSizeForQueryParameters +=
|
||||
strlen(pair->key) + strlen(pair->value);
|
||||
}
|
||||
|
||||
neededBufferSizeForQueryParameters +=
|
||||
(queryParameters->count * 2); // each keyValuePair is separated by a = and a & except the last, but this makes up for the ? at the beginning
|
||||
}
|
||||
|
||||
int operationParameterLength = 0;
|
||||
int basePathLength = strlen(basePath);
|
||||
bool slashNeedsToBeAppendedToBasePath = false;
|
||||
|
||||
if(operationParameter != NULL) {
|
||||
operationParameterLength = (1 + strlen(operationParameter));
|
||||
}
|
||||
if(basePath[strlen(basePath) - 1] != '/') {
|
||||
slashNeedsToBeAppendedToBasePath = true;
|
||||
basePathLength++;
|
||||
}
|
||||
|
||||
char *targetUrl =
|
||||
malloc(
|
||||
neededBufferSizeForQueryParameters + basePathLength + operationParameterLength +
|
||||
1);
|
||||
|
||||
strcpy(targetUrl, basePath);
|
||||
|
||||
if(operationParameter != NULL) {
|
||||
strcat(targetUrl, operationParameter);
|
||||
}
|
||||
|
||||
if(queryParameters != NULL) {
|
||||
strcat(targetUrl, "?");
|
||||
list_ForEach(listEntry, queryParameters) {
|
||||
keyValuePair_t *pair = listEntry->data;
|
||||
replaceSpaceWithPlus(pair->key);
|
||||
strcat(targetUrl, pair->key);
|
||||
strcat(targetUrl, "=");
|
||||
replaceSpaceWithPlus(pair->value);
|
||||
strcat(targetUrl, pair->value);
|
||||
if(listEntry->nextListEntry != NULL) {
|
||||
strcat(targetUrl, "&");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetUrl;
|
||||
}
|
||||
|
||||
char *assembleHeaderField(char *key, char *value) {
|
||||
char *header = malloc(strlen(key) + strlen(value) + 3);
|
||||
|
||||
strcpy(header, key),
|
||||
strcat(header, ": ");
|
||||
strcat(header, value);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
void postData(CURL *handle, char *bodyParameters) {
|
||||
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, bodyParameters);
|
||||
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE_LARGE,
|
||||
strlen(bodyParameters));
|
||||
}
|
||||
|
||||
int lengthOfKeyPair(keyValuePair_t *keyPair) {
|
||||
long length = 0;
|
||||
if((keyPair->key != NULL) &&
|
||||
(keyPair->value != NULL) )
|
||||
{
|
||||
length = strlen(keyPair->key) + strlen(keyPair->value);
|
||||
return length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void apiClient_invoke(apiClient_t *apiClient,
|
||||
char *operationParameter,
|
||||
list_t *queryParameters,
|
||||
list_t *headerParameters,
|
||||
list_t *formParameters,
|
||||
list_t *headerType,
|
||||
list_t *contentType,
|
||||
char *bodyParameters,
|
||||
char *requestType) {
|
||||
CURL *handle = curl_easy_init();
|
||||
CURLcode res;
|
||||
|
||||
if(handle) {
|
||||
listEntry_t *listEntry;
|
||||
curl_mime *mime = NULL;
|
||||
struct curl_slist *headers = NULL;
|
||||
char *buffContent = NULL;
|
||||
char *buffHeader = NULL;
|
||||
FileStruct *fileVar = NULL;
|
||||
char *formString = NULL;
|
||||
|
||||
if(headerType != NULL) {
|
||||
list_ForEach(listEntry, headerType) {
|
||||
if(strstr((char *) listEntry->data,
|
||||
"xml") == NULL)
|
||||
{
|
||||
buffHeader = malloc(strlen(
|
||||
"Accept: ") +
|
||||
strlen((char *)
|
||||
listEntry->
|
||||
data) + 1);
|
||||
sprintf(buffHeader, "%s%s", "Accept: ",
|
||||
(char *) listEntry->data);
|
||||
headers = curl_slist_append(headers,
|
||||
buffHeader);
|
||||
free(buffHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(contentType != NULL) {
|
||||
list_ForEach(listEntry, contentType) {
|
||||
if(strstr((char *) listEntry->data,
|
||||
"xml") == NULL)
|
||||
{
|
||||
buffContent =
|
||||
malloc(strlen(
|
||||
"Content-Type: ") + strlen(
|
||||
(char *)
|
||||
listEntry->data) +
|
||||
1);
|
||||
sprintf(buffContent, "%s%s",
|
||||
"Content-Type: ",
|
||||
(char *) listEntry->data);
|
||||
headers = curl_slist_append(headers,
|
||||
buffContent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
headers = curl_slist_append(headers,
|
||||
"Content-Type: application/json");
|
||||
}
|
||||
|
||||
if(requestType != NULL) {
|
||||
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST,
|
||||
requestType);
|
||||
}
|
||||
|
||||
if(formParameters != NULL) {
|
||||
if(strstr(buffContent,
|
||||
"application/x-www-form-urlencoded") != NULL)
|
||||
{
|
||||
long parameterLength = 0;
|
||||
long keyPairLength = 0;
|
||||
list_ForEach(listEntry, formParameters) {
|
||||
keyValuePair_t *keyPair =
|
||||
listEntry->data;
|
||||
|
||||
keyPairLength =
|
||||
lengthOfKeyPair(keyPair) + 1;
|
||||
|
||||
if(listEntry->nextListEntry != NULL) {
|
||||
parameterLength++;
|
||||
}
|
||||
parameterLength = parameterLength +
|
||||
keyPairLength;
|
||||
}
|
||||
|
||||
formString = malloc(parameterLength + 1);
|
||||
memset(formString, 0, parameterLength + 1);
|
||||
|
||||
list_ForEach(listEntry, formParameters) {
|
||||
keyValuePair_t *keyPair =
|
||||
listEntry->data;
|
||||
if((keyPair->key != NULL) &&
|
||||
(keyPair->value != NULL) )
|
||||
{
|
||||
strcat(formString,
|
||||
keyPair->key);
|
||||
strcat(formString, "=");
|
||||
strcat(formString,
|
||||
keyPair->value);
|
||||
if(listEntry->nextListEntry !=
|
||||
NULL)
|
||||
{
|
||||
strcat(formString, "&");
|
||||
}
|
||||
}
|
||||
}
|
||||
curl_easy_setopt(handle, CURLOPT_POSTFIELDS,
|
||||
formString);
|
||||
}
|
||||
if(strstr(buffContent, "multipart/form-data") != NULL) {
|
||||
mime = curl_mime_init(handle);
|
||||
list_ForEach(listEntry, formParameters) {
|
||||
keyValuePair_t *keyValuePair =
|
||||
listEntry->data;
|
||||
|
||||
if((keyValuePair->key != NULL) &&
|
||||
(keyValuePair->value != NULL) )
|
||||
{
|
||||
curl_mimepart *part =
|
||||
curl_mime_addpart(mime);
|
||||
|
||||
curl_mime_name(part,
|
||||
keyValuePair->key);
|
||||
|
||||
|
||||
if(strcmp(keyValuePair->key,
|
||||
"file") == 0)
|
||||
{
|
||||
printf("Size of fileVar - %p\n",fileVar);
|
||||
memcpy(&fileVar,
|
||||
keyValuePair->value,
|
||||
sizeof(fileVar));
|
||||
printf("Size of fileVar1 - %p\n",fileVar);
|
||||
curl_mime_data(part,
|
||||
fileVar->fileData,
|
||||
fileVar->fileSize);
|
||||
curl_mime_filename(part,
|
||||
"image.png");
|
||||
} else {
|
||||
curl_mime_data(part,
|
||||
keyValuePair->value,
|
||||
CURL_ZERO_TERMINATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
curl_easy_setopt(handle, CURLOPT_MIMEPOST,
|
||||
mime);
|
||||
}
|
||||
}
|
||||
|
||||
list_ForEach(listEntry, headerParameters) {
|
||||
keyValuePair_t *keyValuePair = listEntry->data;
|
||||
if((keyValuePair->key != NULL) &&
|
||||
(keyValuePair->value != NULL) )
|
||||
{
|
||||
char *headerValueToWrite = assembleHeaderField(
|
||||
keyValuePair->key, keyValuePair->value);
|
||||
curl_slist_append(headers, headerValueToWrite);
|
||||
free(headerValueToWrite);
|
||||
}
|
||||
}
|
||||
// this would only be generated for apiKey authentication
|
||||
#ifdef API_KEY
|
||||
list_ForEach(listEntry, apiClient->apiKeys) {
|
||||
keyValuePair_t *apiKey = listEntry->data;
|
||||
if((apiKey->key != NULL) &&
|
||||
(apiKey->value != NULL) )
|
||||
{
|
||||
char *headerValueToWrite = assembleHeaderField(
|
||||
apiKey->key, apiKey->value);
|
||||
curl_slist_append(headers, headerValueToWrite);
|
||||
free(headerValueToWrite);
|
||||
}
|
||||
}
|
||||
#endif // API_KEY
|
||||
|
||||
char *targetUrl =
|
||||
assembleTargetUrl(apiClient->basePath,
|
||||
operationParameter,
|
||||
queryParameters);
|
||||
|
||||
curl_easy_setopt(handle, CURLOPT_URL, targetUrl);
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_WRITEFUNCTION,
|
||||
writeDataCallback);
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_WRITEDATA,
|
||||
&apiClient->dataReceived);
|
||||
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(handle, CURLOPT_VERBOSE, 0); // to get curl debug msg 0: to disable, 1L:to enable
|
||||
// this would only be generated for OAuth2 authentication
|
||||
#ifdef OAUTH2
|
||||
if(apiClient->accessToken != NULL) {
|
||||
// curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_XOAUTH2_BEARER,
|
||||
apiClient->accessToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// this would only be generated for basic authentication:
|
||||
#ifdef BASIC_AUTH
|
||||
char *authenticationToken;
|
||||
|
||||
if((apiClient->username != NULL) &&
|
||||
(apiClient->password != NULL) )
|
||||
{
|
||||
authenticationToken = malloc(strlen(
|
||||
apiClient->username) +
|
||||
strlen(
|
||||
apiClient->password) +
|
||||
2);
|
||||
sprintf(authenticationToken,
|
||||
"%s:%s",
|
||||
apiClient->username,
|
||||
apiClient->password);
|
||||
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_HTTPAUTH,
|
||||
CURLAUTH_BASIC);
|
||||
curl_easy_setopt(handle,
|
||||
CURLOPT_USERPWD,
|
||||
authenticationToken);
|
||||
}
|
||||
|
||||
#endif // BASIC_AUTH
|
||||
|
||||
if(bodyParameters != NULL) {
|
||||
postData(handle, bodyParameters);
|
||||
}
|
||||
|
||||
res = curl_easy_perform(handle);
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
|
||||
free(targetUrl);
|
||||
|
||||
if(contentType != NULL) {
|
||||
free(buffContent);
|
||||
}
|
||||
|
||||
if(res == CURLE_OK) {
|
||||
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &apiClient->response_code);
|
||||
} else {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
#ifdef BASIC_AUTH
|
||||
if((apiClient->username != NULL) &&
|
||||
(apiClient->password != NULL) )
|
||||
{
|
||||
free(authenticationToken);
|
||||
}
|
||||
#endif // BASIC_AUTH
|
||||
curl_easy_cleanup(handle);
|
||||
if(formParameters != NULL) {
|
||||
free(formString);
|
||||
curl_mime_free(mime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t writeDataCallback(void *buffer, size_t size, size_t nmemb, void *userp) {
|
||||
*(char **) userp = strdup(buffer);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
char *strReplace(char *orig, char *rep, char *with) {
|
||||
char *result; // the return string
|
||||
char *ins; // the next insert point
|
||||
char *tmp; // varies
|
||||
int lenRep; // length of rep (the string to remove)
|
||||
int lenWith; // length of with (the string to replace rep with)
|
||||
int lenFront; // distance between rep and end of last rep
|
||||
int count; // number of replacements
|
||||
|
||||
// sanity checks and initialization
|
||||
if(!orig || !rep)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
lenRep = strlen(rep);
|
||||
if(lenRep == 0) {
|
||||
return NULL; // empty rep causes infinite loop during count
|
||||
}
|
||||
if(!with) {
|
||||
with = "";
|
||||
}
|
||||
lenWith = strlen(with);
|
||||
|
||||
// count the number of replacements needed
|
||||
ins = orig;
|
||||
for(count = 0; tmp = strstr(ins, rep); ++count) {
|
||||
ins = tmp + lenRep;
|
||||
}
|
||||
|
||||
tmp = result = malloc(strlen(orig) + (lenWith - lenRep) * count + 1);
|
||||
|
||||
if(!result) {
|
||||
return NULL;
|
||||
}
|
||||
char *originalPointer = orig; // copying original pointer to free the memory
|
||||
// first time through the loop, all the variable are set correctly
|
||||
// from here on,
|
||||
// tmp points to the end of the result string
|
||||
// ins points to the next occurrence of rep in orig
|
||||
// orig points to the remainder of orig after "end of rep"
|
||||
while(count--) {
|
||||
ins = strstr(orig, rep);
|
||||
lenFront = ins - orig;
|
||||
tmp = strncpy(tmp, orig, lenFront) + lenFront;
|
||||
tmp = strcpy(tmp, with) + lenWith;
|
||||
orig += lenFront + lenRep; // move to next "end of rep"
|
||||
}
|
||||
strcpy(tmp, orig);
|
||||
free(originalPointer);
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef INCLUDE_API_CLIENT_H
|
||||
#define INCLUDE_API_CLIENT_H
|
||||
|
||||
#include "list.h"
|
||||
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef struct apiClient_t {
|
||||
char *basePath;
|
||||
void *dataReceived;
|
||||
long response_code;
|
||||
// this would only be generated for basic authentication
|
||||
#ifdef BASIC_AUTH
|
||||
char *username;
|
||||
char *password;
|
||||
#endif // BASIC_AUTH
|
||||
// this would only be generated for OAUTH2 authentication
|
||||
#ifdef OAUTH2
|
||||
char *accessToken;
|
||||
#endif // OAUTH2
|
||||
#ifdef API_KEY
|
||||
//this would only be generated for apiKey authentication
|
||||
list_t *apiKeys;
|
||||
#endif // API_KEY
|
||||
} apiClient_t;
|
||||
|
||||
typedef struct FileStruct
|
||||
{
|
||||
char* fileData;
|
||||
long fileSize;
|
||||
}FileStruct;
|
||||
|
||||
apiClient_t* apiClient_create();
|
||||
|
||||
void apiClient_free(apiClient_t *apiClient);
|
||||
|
||||
void apiClient_invoke(apiClient_t *apiClient,char* operationParameter, list_t *queryParameters, list_t *headerParameters, list_t *formParameters,list_t *headerType,list_t *contentType, char *bodyParameters, char *requestType);
|
||||
|
||||
char *strReplace(char *orig, char *rep, char *with);
|
||||
|
||||
#endif // INCLUDE_API_CLIENT_H
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "keyValuePair.h"
|
||||
|
||||
keyValuePair_t *keyValuePair_create(char *key, void *value) {
|
||||
keyValuePair_t *keyValuePair = malloc(sizeof(keyValuePair_t));
|
||||
keyValuePair->key = key;
|
||||
keyValuePair->value = value;
|
||||
return keyValuePair;
|
||||
}
|
||||
|
||||
void keyValuePair_free(keyValuePair_t *keyValuePair) {
|
||||
free(keyValuePair);
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "apiClient.h"
|
||||
#include "cJSON.h"
|
||||
#include "pet.h"
|
||||
#include "PetAPI.h"
|
||||
#include "category.h"
|
||||
#include "tag.h"
|
||||
#include "keyValuePair.h"
|
||||
|
||||
#define EXAMPLE_CATEGORY_NAME "Example Category"
|
||||
#define EXAMPLE_CATEGORY_ID 5
|
||||
#define EXAMPLE_PET_NAME "Example Pet"
|
||||
#define EXAMPLE_URL_1 "http://www.github.com"
|
||||
#define EXAMPLE_URL_2 "http://www.gitter.im"
|
||||
#define EXAMPLE_TAG_1_NAME "beautiful code"
|
||||
#define EXAMPLE_TAG_2_NAME "at least I tried"
|
||||
#define EXAMPLE_TAG_1_ID 1
|
||||
#define EXAMPLE_TAG_2_ID 542353
|
||||
#define EXAMPLE_PET_ID 1234 // Set to 0 to generate a new pet
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
// Add pet test
|
||||
apiClient_t *apiClient = apiClient_create();
|
||||
|
||||
char *categoryName = malloc(strlen(EXAMPLE_CATEGORY_NAME) + 1);
|
||||
strcpy(categoryName, EXAMPLE_CATEGORY_NAME);
|
||||
|
||||
category_t *category =
|
||||
category_create(EXAMPLE_CATEGORY_ID, categoryName);
|
||||
|
||||
char *petName = malloc(strlen(EXAMPLE_PET_NAME) + 1);
|
||||
strcpy(petName, EXAMPLE_PET_NAME);
|
||||
|
||||
char *exampleUrl1 = malloc(strlen(EXAMPLE_URL_1) + 1);
|
||||
strcpy(exampleUrl1, EXAMPLE_URL_1);
|
||||
|
||||
char *exampleUrl2 = malloc(strlen(EXAMPLE_URL_2) + 1);
|
||||
strcpy(exampleUrl2, EXAMPLE_URL_2);
|
||||
|
||||
list_t *photoUrls = list_create();
|
||||
|
||||
list_addElement(photoUrls, exampleUrl1);
|
||||
list_addElement(photoUrls, exampleUrl2);
|
||||
|
||||
char *exampleTag1Name = malloc(strlen(EXAMPLE_TAG_1_NAME) + 1);
|
||||
strcpy(exampleTag1Name, EXAMPLE_TAG_1_NAME);
|
||||
tag_t *exampleTag1 = tag_create(EXAMPLE_TAG_1_ID, exampleTag1Name);
|
||||
|
||||
char *exampleTag2Name = malloc(strlen(EXAMPLE_TAG_2_NAME) + 1);
|
||||
strcpy(exampleTag2Name, EXAMPLE_TAG_2_NAME);
|
||||
tag_t *exampleTag2 = tag_create(EXAMPLE_TAG_2_ID, exampleTag2Name);
|
||||
|
||||
list_t *tags = list_create();
|
||||
|
||||
list_addElement(tags, exampleTag1);
|
||||
list_addElement(tags, exampleTag2);
|
||||
|
||||
|
||||
status_e status = available;
|
||||
pet_t *pet =
|
||||
pet_create(EXAMPLE_PET_ID,
|
||||
category,
|
||||
petName,
|
||||
photoUrls,
|
||||
tags,
|
||||
status);
|
||||
|
||||
PetAPI_addPet(apiClient, pet);
|
||||
pet_free(pet);
|
||||
|
||||
//Pet update with form test
|
||||
char *petName1 = "Rocky Handsome";
|
||||
|
||||
char *petName2 = "sold";
|
||||
|
||||
apiClient_t *apiClient1 = apiClient_create();
|
||||
PetAPI_updatePetWithForm(apiClient1, EXAMPLE_PET_ID, petName1,
|
||||
petName2);
|
||||
|
||||
|
||||
//Get pet by id test
|
||||
apiClient_t *apiClient2 = apiClient_create();
|
||||
pet_t *mypet = PetAPI_getPetById(apiClient2, EXAMPLE_PET_ID);
|
||||
|
||||
cJSON *JSONR = pet_convertToJSON(mypet);
|
||||
char *petJson = cJSON_Print(JSONR);
|
||||
printf("Data is:%s\n", petJson);
|
||||
|
||||
assert(strcmp(mypet->name, "Rocky Handsome") == 0);
|
||||
assert(mypet->id == EXAMPLE_PET_ID);
|
||||
assert(strcmp(mypet->category->name, EXAMPLE_CATEGORY_NAME) == 0);
|
||||
assert(mypet->category->id == EXAMPLE_CATEGORY_ID);
|
||||
assert(strcmp(list_getElementAt(mypet->photoUrls,
|
||||
0)->data, EXAMPLE_URL_1) == 0);
|
||||
assert(strcmp(list_getElementAt(mypet->photoUrls,
|
||||
1)->data, EXAMPLE_URL_2) == 0);
|
||||
assert(((tag_t *) list_getElementAt(mypet->tags,
|
||||
0)->data)->id == EXAMPLE_TAG_1_ID);
|
||||
assert(((tag_t *) list_getElementAt(mypet->tags,
|
||||
1)->data)->id == EXAMPLE_TAG_2_ID);
|
||||
assert(strcmp(((tag_t *) list_getElementAt(mypet->tags, 0)->data)->name,
|
||||
EXAMPLE_TAG_1_NAME) == 0);
|
||||
assert(strcmp(((tag_t *) list_getElementAt(mypet->tags, 1)->data)->name,
|
||||
EXAMPLE_TAG_2_NAME) == 0);
|
||||
|
||||
free(petJson);
|
||||
cJSON_Delete(JSONR);
|
||||
pet_free(mypet);
|
||||
|
||||
//Pet upload file Test
|
||||
apiClient_t *apiClient3 = apiClient_create();
|
||||
FILE *file = fopen("/opt/image.png", "r");
|
||||
if(file != NULL){
|
||||
api_response_t *respo = PetAPI_uploadFile(apiClient3,
|
||||
EXAMPLE_PET_ID,
|
||||
"dec",
|
||||
file);
|
||||
|
||||
api_response_free(respo);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "apiClient.h"
|
||||
#include "cJSON.h"
|
||||
#include "order.h"
|
||||
#include "StoreAPI.h"
|
||||
#include "keyValuePair.h"
|
||||
|
||||
#define ORDER_ID 1234
|
||||
#define PET_ID 12345
|
||||
#define QUANTITY 50
|
||||
#define SHIP_DATE "2018-09-24T10:19:09.592Z"
|
||||
#define STATUS placed
|
||||
#define COMPLETE true
|
||||
|
||||
/*
|
||||
Creates one pet and adds it. Then gets the pet with the just added ID and compare if the values are equal.
|
||||
Could fail if someone else makes changes to the added pet, before it can be fetched again.
|
||||
*/
|
||||
int main() {
|
||||
//place order test
|
||||
apiClient_t *apiClient = apiClient_create();
|
||||
|
||||
char *shipdate = malloc(strlen(SHIP_DATE) + 1);
|
||||
strcpy(shipdate, SHIP_DATE);
|
||||
|
||||
order_t *neworder = order_create(ORDER_ID,
|
||||
PET_ID,
|
||||
QUANTITY,
|
||||
shipdate,
|
||||
STATUS,
|
||||
COMPLETE);
|
||||
|
||||
order_t *returnorder = StoreAPI_placeOrder(apiClient, neworder);
|
||||
|
||||
cJSON *JSONNODE = order_convertToJSON(returnorder);
|
||||
|
||||
char *dataToPrint = cJSON_Print(JSONNODE);
|
||||
|
||||
printf("Placed order: \n%s\n", dataToPrint);
|
||||
order_free(neworder);
|
||||
order_free(returnorder);
|
||||
cJSON_Delete(JSONNODE);
|
||||
free(dataToPrint);
|
||||
|
||||
//order get by id test
|
||||
apiClient_t *apiClient2 = apiClient_create();
|
||||
|
||||
neworder = StoreAPI_getOrderById(apiClient2, 1234);
|
||||
|
||||
JSONNODE = order_convertToJSON(neworder);
|
||||
|
||||
char *dataToPrint1 = cJSON_Print(JSONNODE);
|
||||
|
||||
printf("Order received: \n%s\n", dataToPrint1);
|
||||
|
||||
order_free(neworder);
|
||||
cJSON_Delete(JSONNODE);
|
||||
free(dataToPrint1);
|
||||
|
||||
//delete order test
|
||||
apiClient_t *apiClient3 = apiClient_create();
|
||||
|
||||
char *orderid = malloc(strlen("1234") + 1);
|
||||
strcpy(orderid, "1234");
|
||||
|
||||
StoreAPI_deleteOrder(apiClient3, orderid);
|
||||
|
||||
printf("Order Deleted \n");
|
||||
free(orderid);
|
||||
|
||||
|
||||
// get order by id test
|
||||
apiClient_t *apiClient4 = apiClient_create();
|
||||
|
||||
neworder = StoreAPI_getOrderById(apiClient4, 1234);
|
||||
|
||||
if(neworder == NULL) {
|
||||
printf("Order Not present \n");
|
||||
}
|
||||
|
||||
//get inventory test
|
||||
apiClient_t *apiClient5 = apiClient_create();
|
||||
list_t *elementToReturn;
|
||||
elementToReturn = StoreAPI_getInventory(apiClient5);
|
||||
listEntry_t *listEntry;
|
||||
list_ForEach(listEntry, elementToReturn) {
|
||||
keyValuePair_free(listEntry->data);
|
||||
}
|
||||
list_free(elementToReturn);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_BUFFER_LENGTH 9
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
|
||||
#include "keyValuePair.h"
|
||||
|
||||
int main() {
|
||||
printf("Hello world1\n");
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "apiClient.h"
|
||||
#include "cJSON.h"
|
||||
#include "keyValuePair.h"
|
||||
#include "user.h"
|
||||
#include "UserAPI.h"
|
||||
|
||||
#define USER_ID 1234
|
||||
#define USER_NAME "example123"
|
||||
#define FIRST_NAME "Example1"
|
||||
#define LAST_NAME "Example2Last"
|
||||
#define LAST_NAME1 "LastName"
|
||||
#define EMAIL "example@example.com"
|
||||
#define PASSWORD "thisisexample!123"
|
||||
#define PHONE "+123456789"
|
||||
#define USER_STATUS 4
|
||||
|
||||
|
||||
int main() {
|
||||
//create user test
|
||||
apiClient_t *apiClient = apiClient_create();
|
||||
|
||||
char *username = malloc(strlen(USER_NAME) + 1);
|
||||
strcpy(username, USER_NAME);
|
||||
char *firstname = malloc(strlen(FIRST_NAME) + 1);
|
||||
strcpy(firstname, FIRST_NAME);
|
||||
char *lastname = malloc(strlen(LAST_NAME) + 1);
|
||||
strcpy(lastname, LAST_NAME);
|
||||
char *email = malloc(strlen(EMAIL) + 1);
|
||||
strcpy(email, EMAIL);
|
||||
char *password = malloc(strlen(PASSWORD) + 1);
|
||||
strcpy(password, PASSWORD);
|
||||
char *phone = malloc(strlen(PHONE) + 1);
|
||||
strcpy(phone, PHONE);
|
||||
|
||||
user_t *newuser = user_create(USER_ID,
|
||||
username,
|
||||
firstname,
|
||||
lastname,
|
||||
email,
|
||||
password,
|
||||
phone,
|
||||
USER_STATUS);
|
||||
|
||||
UserAPI_createUser(apiClient, newuser);
|
||||
user_free(newuser);
|
||||
|
||||
//get user by name test
|
||||
apiClient_t *apiClient1 = apiClient_create();
|
||||
user_t *returnUser = UserAPI_getUserByName(apiClient1, USER_NAME);
|
||||
|
||||
cJSON *JSONNODE = user_convertToJSON(returnUser);
|
||||
|
||||
char *dataToPrint = cJSON_Print(JSONNODE);
|
||||
|
||||
printf("User is: \n%s\n", dataToPrint);
|
||||
user_free(returnUser);
|
||||
cJSON_Delete(JSONNODE);
|
||||
free(dataToPrint);
|
||||
|
||||
//update user test
|
||||
{
|
||||
apiClient_t *apiClient2 = apiClient_create();
|
||||
char *username1 = malloc(strlen(USER_NAME) + 1);
|
||||
strcpy(username1, USER_NAME);
|
||||
char *firstname = malloc(strlen(FIRST_NAME) + 1);
|
||||
strcpy(firstname, FIRST_NAME);
|
||||
char *lastname = malloc(strlen(LAST_NAME) + 1);
|
||||
strcpy(lastname, LAST_NAME);
|
||||
char *email = malloc(strlen(EMAIL) + 1);
|
||||
strcpy(email, EMAIL);
|
||||
char *password = malloc(strlen(PASSWORD) + 1);
|
||||
strcpy(password, PASSWORD);
|
||||
char *phone = malloc(strlen(PHONE) + 1);
|
||||
strcpy(phone, PHONE);
|
||||
|
||||
user_t *newuser1 = user_create(USER_ID,
|
||||
username1,
|
||||
firstname,
|
||||
lastname,
|
||||
email,
|
||||
password,
|
||||
phone,
|
||||
USER_STATUS);
|
||||
|
||||
UserAPI_updateUser(apiClient2, username1, newuser1);
|
||||
user_free(newuser1);
|
||||
}
|
||||
|
||||
//login user test
|
||||
{
|
||||
char *username1 = malloc(strlen(USER_NAME) + 1);
|
||||
strcpy(username1, USER_NAME);
|
||||
char *password = malloc(strlen(PASSWORD) + 1);
|
||||
strcpy(password, PASSWORD);
|
||||
apiClient_t *apiClient3 = apiClient_create();
|
||||
|
||||
char *loginuserreturn = UserAPI_loginUser(apiClient3,
|
||||
username1,
|
||||
password);
|
||||
|
||||
printf("Login User: %s\n", loginuserreturn);
|
||||
free(loginuserreturn);
|
||||
free(username1);
|
||||
free(password);
|
||||
}
|
||||
|
||||
// logout user test
|
||||
apiClient_t *apiClient4 = apiClient_create();
|
||||
|
||||
UserAPI_logoutUser(apiClient4);
|
||||
|
||||
|
||||
// delete user test
|
||||
apiClient_t *apiClient5 = apiClient_create();
|
||||
|
||||
UserAPI_deleteUser(apiClient5, "example123");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 7
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type __stdcall
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
|
||||
#endif
|
||||
#else /* !WIN32 */
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user