Merge branch 'master' into csharp-enum-cleanup

* master: (101 commits)
  [Swift4] Allow for custom dateformatter to be used (#6672)
  [haskell-http-client] fix bug when generating models-only (#6931)
  fix typo: crediential => credential
  minor typo fix
  [csharp] fix enum serialization of first value (#6873)
  [PHP] Improve docs and README (#6935)
  Binary mode for file deserialization in python (#6936)
  add python tornado test to travis
  [Python/tornado] add integration tests and fix bugs (#6925)
  Fix PHP passes response body to ApiException (#6923)
  [TypeScript][Node] Resolve TS2532 error (#6932)
  skip "all" shell script
  minor formatting change
  Fixes Issue #6841, Map for accessing additionalProperties is generated. (#6886)
  add tsloughter as owner erlang
  WIP: initial commit for Erlang client generator (#6502)
  add back php client test
  Switch Travis image from MacOS to Linux (#6937)
  add link to ebook
  [Scala] Default case class Option types to None for non-required fields (#6790)
  ...
This commit is contained in:
James Schubert 2017-11-13 21:46:40 -05:00
commit a0d5079bce
1854 changed files with 93761 additions and 26505 deletions

View File

@ -3,7 +3,7 @@
- [ ] Read the [contribution guidelines](https://github.com/swagger-api/swagger-codegen/blob/master/CONTRIBUTING.md).
- [ ] Ran the shell script under `./bin/` to update Petstore sample so that CIs can verify the change. (For instance, only need to run `./bin/{LANG}-petstore.sh` and `./bin/security/{LANG}-petstore.sh` if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates). Windows batch files can be found in `.\bin\windows\`.
- [ ] Filed the PR against the correct branch: `3.0.0` branch for changes related to OpenAPI spec 3.0. Default: `master`.
- [ ] Copied the [technical committee](https://github.com/swagger-api/swagger-codegen/#swagger-codegen-technical-committee) to review the pull request if your PR is targeting a particular programming langauge.
- [ ] Copied the [technical committee](https://github.com/swagger-api/swagger-codegen/#swagger-codegen-technical-committee) to review the pull request if your PR is targeting a particular programming language.
### Description of the PR

5
.gitignore vendored
View File

@ -90,6 +90,11 @@ samples/client/petstore/silex/SwaggerServer/venodr/
**/vendor/
**/composer.lock
#PHP-Symfony
samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/cache/
samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/logs/
# Perl
samples/client/petstore/perl/deep_module_test/

View File

@ -1,13 +1,14 @@
sudo: required
language: objective-c
osx_image: xcode8.2
language: java
jdk:
- oraclejdk8
cache:
directories:
- $HOME/.m2
- $HOME/.ivy2
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.stack
- $HOME/samples/client/petstore/php/SwaggerClient-php/vendor
- $HOME/samples/client/petstore/ruby/venodr/bundle
- $HOME/samples/client/petstore/python/.venv/
@ -21,13 +22,11 @@ cache:
- $HOME/samples/client/petstore/typescript-fetch/builds/es6-target/typings
- $HOME/samples/client/petstore/typescript-fetch/builds/with-npm-version/node_modules
- $HOME/samples/client/petstore/typescript-fetch/npm/with-npm-version/typings
- $HOME/samples/client/petstore/typescript-angularjs/node_modules
- $HOME/samples/client/petstore/typescript-angularjs/typings
- $HOME/.cocoapods/repos/master
timeout: 1000
# note: docker is not yet supported in iOS build
#services:
# - docker
- $HOME/samples/client/petstore/typescript-angular/node_modules
- $HOME/samples/client/petstore/typescript-angular/typings
services:
- docker
# comment out the host table change to use the public petstore server
addons:
@ -35,60 +34,38 @@ addons:
- petstore.swagger.io
before_install:
- export SW=`pwd`
- rvm list
- rvm use 2.2.5
- gem environment
- gem install bundler -N --no-ri --no-rdoc
- gem install cocoapods -v 1.2.1 -N --no-ri --no-rdoc
- gem install xcpretty -N --no-ri --no-rdoc
- pod --version
# comment out below to avoid errors
#- pod repo update
- pod setup --silent > /dev/null
# required when sudo: required for the Ruby petstore tests
- gem install bundler
- npm install -g typescript
- npm install -g npm
- npm config set registry http://registry.npmjs.org/
- brew install sbt
- brew install leiningen
- brew install bats
- brew install curl
- brew install python3
- pip install virtualenv
- mkdir -p ~/.local/bin
- export PATH=$HOME/.local/bin:$PATH
- travis_retry curl --insecure -L https://www.stackage.org/stack/osx-x86_64 | tar xz --strip-components=1 --include '*/stack' -C ~/.local/bin
# start local petstore server
- git clone -b docker --single-branch https://github.com/wing328/swagger-samples
- cd swagger-samples/java/java-jersey-jaxrs
- sudo mvn jetty:run &
- cd $SW
# NOTE: iOS build not support docker at the moment
- sudo pip install virtualenv
# to run petstore server locally via docker
#- docker pull swaggerapi/petstore
#- docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
#- docker ps -a
- docker pull swaggerapi/petstore
- docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
- docker ps -a
# Add bats test framework and cURL for Bash script integration tests
- sudo add-apt-repository ppa:duggan/bats --yes
- sudo apt-get update -qq
- sudo apt-get install -qq bats
- sudo apt-get install -qq curl
# comment out below as installation failed in travis
# Add rebar3 build tool and recent Erlang/OTP for Erlang petstore server tests.
# - Travis CI does not support rebar3 [yet](https://github.com/travis-ci/travis-ci/issues/6506#issuecomment-275189490).
# - Rely on `kerl` for [pre-compiled versions available](https://docs.travis-ci.com/user/languages/erlang#Choosing-OTP-releases-to-test-against). Rely on installation path chosen by [`travis-erlang-builder`](https://github.com/travis-ci/travis-erlang-builder/blob/e6d016b1a91ca7ecac5a5a46395bde917ea13d36/bin/compile#L18).
# - . ~/otp/18.2.1/activate && erl -version
#- curl -f -L -o ./rebar3 https://s3.amazonaws.com/rebar3/rebar3 && chmod +x ./rebar3 && ./rebar3 version && export PATH="${TRAVIS_BUILD_DIR}:$PATH"
# show host table to confirm petstore.swagger.io is mapped to localhost
- cat /etc/hosts
# show java version
- java -version
# show brew version
- brew --version
# show xcpretty version
- xcpretty -v
# show go version
- go version
# show stack version
- stack --version
install:
# Add Godeps dependencies to GOPATH and PATH
- eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=1.4 bash)"
- export GOPATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace"
- export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$PATH"
- eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=1.4 bash)"
- export GOPATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace"
- export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$PATH"
script:
# fail fast
@ -101,13 +78,11 @@ script:
- /bin/bash ./bin/utils/detect_tab_in_java_class.sh
# run integration tests defined in maven pom.xml
- mvn -q --batch-mode verify -Psamples
### docker-related tasks have been moved to CircleCI
# Below has been moved to CircleCI
# docker: build generator image and push to Docker Hub
#- if [ $DOCKER_HUB_USERNAME ]; then docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD && docker build -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/swagger-generator && 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; fi; fi
## docker: build cli image and push to Docker Hub
#- if [ $DOCKER_HUB_USERNAME ]; then docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD && docker build -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/swagger-codegen-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; fi; fi
#env:
# - DOCKER_GENERATOR_IMAGE_NAME=swaggerapi/swagger-generator DOCKER_CODEGEN_CLI_IMAGE_NAME=swaggerapi/swagger-codegen-cli
after_success:
# push a snapshot version to maven repo
@ -115,3 +90,6 @@ after_success:
mvn clean deploy --settings .travis/settings.xml;
echo "Finished mvn clean deploy for $TRAVIS_BRANCH";
fi;
env:
- DOCKER_GENERATOR_IMAGE_NAME=swaggerapi/swagger-generator DOCKER_CODEGEN_CLI_IMAGE_NAME=swaggerapi/swagger-codegen-cli

View File

@ -13,7 +13,7 @@
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.swagger/swagger-codegen-project/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/io.swagger/swagger-codegen-project)
[![PR Stats](http://issuestats.com/github/swagger-api/swagger-codegen/badge/pr)](http://issuestats.com/github/swagger-api/swagger-codegen) [![Issue Stats](http://issuestats.com/github/swagger-api/swagger-codegen/badge/issue)](http://issuestats.com/github/swagger-api/swagger-codegen)
:star::star::star: If you would like to contribute, please refer to [guidelines](https://github.com/swagger-api/swagger-codegen/blob/master/CONTRIBUTING.md) and a list of [open tasks](https://github.com/swagger-api/swagger-codegen/issues?q=is%3Aopen+is%3Aissue+label%3A%22Need+community+contribution%22).:star::star::star:
:star::star::star: If you would like to contribute, please refer to [guidelines](https://github.com/swagger-api/swagger-codegen/blob/master/CONTRIBUTING.md) and a list of [open tasks](https://github.com/swagger-api/swagger-codegen/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).:star::star::star:
:notebook_with_decorative_cover: For more information, please refer to the [Wiki page](https://github.com/swagger-api/swagger-codegen/wiki) and [FAQ](https://github.com/swagger-api/swagger-codegen/wiki/FAQ) :notebook_with_decorative_cover:
@ -24,8 +24,8 @@
## Overview
This is the swagger codegen project, which allows generation of API client libraries (SDK generation), server stubs and documentation automatically given an [OpenAPI Spec](https://github.com/OAI/OpenAPI-Specification). Currently, the following languages/frameworks are supported:
- **API clients**: **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **Eiffel**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust**, **Scala** (akka, http4s, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (Angular1.x, Angular2.x, Fetch, jQuery, Node)
- **Server stubs**: **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **Go**, **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework), **PHP** (Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Scala** ([Finch](https://github.com/finagle/finch), Scalatra)
- **API clients**: **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **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), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust**, **Scala** (akka, http4s, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (Angular1.x, Angular2.x, Fetch, jQuery, Node)
- **Server stubs**: **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **Go**, **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework), **PHP** (Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust**, **Scala** ([Finch](https://github.com/finagle/finch), Scalatra)
- **API documentation generators**: **HTML**, **Confluence Wiki**
- **Configuration files**: [**Apache2**](https://httpd.apache.org/)
- **Others**: **JMeter**
@ -462,6 +462,10 @@ src/IO.Swagger.Test/Model/AnimalFarmTests.cs
The `.swagger-codegen-ignore` file must exist in the root of the output directory.
Upon first code generation, you may also pass the CLI option `--ignore-file-override=/path/to/ignore_file` for greater control over generated outputs. Note that this is a complete override, and will override the `.swagger-codegen-ignore` file in an output directory when regenerating code.
Editor support for `.swagger-codegen-ignore` files is available in IntelliJ via the [.ignore plugin](https://plugins.jetbrains.com/plugin/7495--ignore).
### Customizing the generator
There are different aspects of customizing the code generator beyond just creating or modifying templates. Each language has a supporting configuration file to handle different type mappings, etc:
@ -516,6 +520,7 @@ CONFIG OPTIONS
okhttp-gson (default) - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1
retrofit - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)
retrofit2 - HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.0-beta2)
google-api-client - HTTP client: google-api-client 1.23.0. JSON processing: Jackson 2.8.9
```
Your config file for Java can look like
@ -730,6 +735,7 @@ Please refer to this [page](https://github.com/swagger-api/swagger-codegen/blob/
Companies/Projects using Swagger Codegen
----------------------------------------
Here are some companies/projects using Swagger Codegen in production. To add your company/project to the list, please visit [README.md](https://github.com/swagger-api/swagger-codegen/blob/master/README.md) and click on the icon to edit the page.
- [Accengage](https://www.accengage.com/)
- [Activehours](https://www.activehours.com/)
- [Acunetix](https://www.acunetix.com/)
- [Atlassian](https://www.atlassian.com/)
@ -760,6 +766,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [everystory.us](http://everystory.us)
- [Expected Behavior](http://www.expectedbehavior.com/)
- [Fastly](https://www.fastly.com/)
- [FINRA](https://github.com/FINRAOS/herd/)
- [Flat](https://flat.io)
- [Finder](http://en.finder.pl/)
- [Fitwell](https://fitwell.co/)
@ -793,6 +800,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [LXL Tech](http://lxltech.com)
- [Lyft](https://www.lyft.com/developers)
- [MailMojo](https://mailmojo.no/)
- [Metaswitch](https://www.metaswitch.com/)
- [Mindera](http://mindera.com/)
- [Mporium](http://mporium.com/)
- [Neverfail](https://neverfail.com/)
@ -901,6 +909,7 @@ Presentations/Videos/Tutorials/Books
- 2017/09/30 - [Swaggerのテンプレートを魔改造した話 #渋谷java](https://www.slideshare.net/int128/swagger-80309224) by [Hidetake Iwata](https://github.com/int128) ([NTT DATA Corporation](http://www.nttdata.com/global/en/))
- 2017/10/04 - [Enterprise-friendly Java client for Microsoft Machine Learning Server](https://blogs.msdn.microsoft.com/mlserver/2017/10/04/enterprise-friendly-java-client-for-microsoft-machine-learning-server/) by [Pratik Palnitkar](https://www.linkedin.com/in/pratikpalnitkar/) ([Microsoft](https://www.microsoft.com/))
- 2017/10/08 - [Generating a REST Ada client with OpenAPI and Swagger Codegen](https://blog.vacs.fr/vacs/blogs/post.html?post=2017/10/08/Generating-a-REST-Ada-client-with-OpenAPI-and-Swagger-Codegen) by [Stephane Carrez](https://github.com/stcarrez)
- 2017/11/08 - [A Beginner's Guide to Code Generation for REST APIs](https://gum.co/swagger_codegen_beginner)(eBook) by [William Cheng](https://twitter.com/wing328)
# Swagger Codegen Core Team
@ -967,9 +976,11 @@ Here is a list of template creators:
* Dart: @yissachar
* Elixir: @niku
* Eiffel: @jvelilla
* Erlang: @tsloughter
* Groovy: @victorgit
* Go: @wing328
* Go (rewritten in 2.3.0): @antihax
* Haskell (http-client): @jonschoning
* Java (Feign): @davidkiss
* Java (Retrofit): @0legg
* Java (Retrofit2): @emilianobonassi
@ -978,6 +989,7 @@ Here is a list of template creators:
* Java (RestTemplate): @nbruno
* Java (RESTEasy): @gayathrigs
* Java (Vertx): @lopesmcc
* Java (Google APIs Client Library): @charlescapps
* Javascript/NodeJS: @jfiala
* Javascript (Closure-annotated Angular) @achew22
* JMeter: @davidkiss
@ -988,6 +1000,7 @@ Here is a list of template creators:
* PowerShell: @beatcracker
* R: @ramnov
* Rust: @farcaller
* Rust (rust-server): @metaswitch
* Scala (scalaz & http4s): @tbrown1979
* Swift: @tkqubo
* Swift 3: @hexelon
@ -1018,6 +1031,7 @@ Here is a list of template creators:
* PHP Symfony: @ksm2
* PHP Zend Expressive (with Path Handler): @Articus
* Ruby on Rails 5: @zlx
* Rust (rust-server): @metaswitch
* Scala Finch: @jimschubert
* Documentation
* HTML Doc 2: @jhitchcock
@ -1029,7 +1043,7 @@ Here is a list of template creators:
Here are the requirements to become a core team member:
- rank within top 50 in https://github.com/swagger-api/swagger-codegen/graphs/contributors
- to contribute, here are some good [starting points](https://github.com/swagger-api/swagger-codegen/issues?q=is%3Aopen+is%3Aissue+label%3A%22Need+community+contribution%22)
- to contribute, here are some good [starting points](https://github.com/swagger-api/swagger-codegen/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
- regular contributions to the project
- about 3 hours per week
- for contribution, it can be addressing issues, reviewing PRs submitted by others, submitting PR to fix bugs or make enhancements, etc
@ -1076,7 +1090,7 @@ If you want to join the committee, please kindly apply by sending an email to wi
| ObjC | |
| Perl | @wing328 (2017/07) |
| PHP | @jebentier (2017/07) @dkarlovi (2017/07) @mandrean (2017/08) @jfastnacht (2017/09) @ackintosh (2017/09) |
| Python | @taxpon (2017/07) @frol (2017/07) @mbohlool (2017/07) @cbornet (2017/09) |
| Python | @taxpon (2017/07) @frol (2017/07) @mbohlool (2017/07) @cbornet (2017/09) @kenjones-cisco (2017/11)|
| R | |
| Ruby | @cliffano (2017/07) @zlx (2017/09) |
| Rust | @frol (2017/07) @farcaller (2017/08) |

View File

@ -0,0 +1,3 @@
{
"targetFramework": "v4.0"
}

31
bin/csharp-petstore-net-40.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
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/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn 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/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l csharp -o samples/client/petstore/csharp/SwaggerClientNet40 --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} -c ./bin/csharp-petstore-net-40.json"
java $JAVA_OPTS -jar $executable $ags

View File

@ -26,6 +26,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/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l csharp -o samples/client/petstore/csharp/SwaggerClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C}"
ags="generate $@ -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l csharp -o samples/client/petstore/csharp/SwaggerClientNet40 --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} -c ./bin/csharp-petstore-net-40.json"
java $JAVA_OPTS -jar $executable $ags

31
bin/erlang-petstore-client.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
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/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn 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 -t modules/swagger-codegen/src/main/resources/erlang-client -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l erlang-client -o samples/client/petstore/erlang-client"
java $JAVA_OPTS -jar $executable $ags

View File

@ -16,3 +16,4 @@
./bin/java-petstore-resttemplate.sh
./bin/java-petstore-resttemplate-withxml.sh
./bin/java-petstore-resteasy.sh
./bin/java-petstore-google-api-client.sh

View File

@ -0,0 +1,4 @@
{
"library": "google-api-client",
"artifactId": "swagger-petstore-google-api-client"
}

View File

@ -0,0 +1,34 @@
#!/bin/sh
SCRIPT="$0"
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/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn 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 -t modules/swagger-codegen/src/main/resources/Java/libraries/google-api-client -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l java -c bin/java-petstore-google-api-client.json -o samples/client/petstore/java/google-api-client -DhideGenerationTimestamp=true"
echo "Removing files and folders under samples/client/petstore/java/google-api-client/src/main"
rm -rf samples/client/petstore/java/google-api-client/src/main
find samples/client/petstore/java/google-api-client -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
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/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn 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 $@ -t modules/swagger-codegen/src/main/resources/nancyfx -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nancyfx -o samples/server/petstore/nancyfx-async --additional-properties packageGuid={768B8DC6-54EE-4D40-9B20-7857E1D742A4},asyncServer=true"
java $JAVA_OPTS -jar $executable $ags

41
bin/php-symfony-petstore.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
SCRIPT="$0"
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
# Make sure that the working directory is the root dir
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "${SCRIPT_DIR}/../"
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
# Make sure that we are regenerating the sample by removing any existing target directory
TARGET_DIR="$SCRIPT_DIR/../samples/server/petstore/php-symfony"
if [ -d "$TARGET_DIR" ]; then
rm -rf $TARGET_DIR
fi
executable="$SCRIPT_DIR/../modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn 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 -t $SCRIPT_DIR/../modules/swagger-codegen/src/main/resources/php-symfony -i $SCRIPT_DIR/../modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l php-symfony -o $TARGET_DIR $@"
java $JAVA_OPTS -jar $executable $ags

View File

@ -8,7 +8,7 @@ echo "Please press CTRL+C to stop or the script will continue in 10 seconds."
sleep 10
for SCRIPT in ./bin/*.sh
for SCRIPT in `ls -l ./bin/*.sh | grep -v all`
do
if [ -f $SCRIPT -a -x $SCRIPT ]
then

31
bin/rust-server-petstore.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
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/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn 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 -t modules/swagger-codegen/src/main/resources/rust-server -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l rust-server -o samples/server/petstore/rust-server -DpackageName=petstore_api"
java $JAVA_OPTS -jar $executable $ags

View File

@ -42,3 +42,7 @@ java $JAVA_OPTS -jar $executable $ags
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift3 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift3 -c ./bin/swift3-petstore-unwraprequired.json -o samples/client/petstore/swift3/unwraprequired"
echo "#### Petstore Swift API client (unwraprequired) ####"
java $JAVA_OPTS -jar $executable $ags
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift3 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift3 -c ./bin/swift3-petstore-objcCompatible.json -o samples/client/petstore/swift3/objcCompatible"
echo "#### Petstore Swift API client (objcCompatible) ####"
java $JAVA_OPTS -jar $executable $ags

View File

@ -38,3 +38,11 @@ java $JAVA_OPTS -jar $executable $ags
echo "Typescript Petstore API client (with interfaces generated)"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l typescript-angular -o samples/client/petstore/typescript-angular-v2/with-interfaces -D withInterfaces=true --additional-properties ngVersion=2"
java $JAVA_OPTS -jar $executable $ags
echo "Typescript Petstore API client (v4 { Adding InjectionToken Over OpaqueToken })"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l typescript-angular -c bin/typescript-petstore-npm.json -o samples/client/petstore/typescript-angular-v4/npm --additional-properties ngVersion=4"
java $JAVA_OPTS -jar $executable $ags
echo "Typescript Petstore API client (v4.3 { Adding HttpClientModule over HttpModule })"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l typescript-angular -c bin/typescript-petstore-npm.json -o samples/client/petstore/typescript-angular-v4.3/npm --additional-properties ngVersion=4.3"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\swagger-codegen\src\main\resources\erlang-client -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l erlang-client -o samples\client\petstore\erlang-client
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate --artifact-id "jaxrs-cxf-client-petstore-client" -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l jaxrs-spec -o samples\server\petstore\jaxrs-spec-interface -DhideGenerationTimestamp=true,serializableModel=true,interfaceOnly=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate --artifact-id "jaxrs-cxf-client-petstore-client" -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l jaxrs-spec -o samples\server\petstore\jaxrs-spec -DhideGenerationTimestamp=true,serializableModel=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l rust-server -o samples\server\petstore\rust-server
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -1,3 +1,7 @@
call .\bin\windows\typescript-angular-v2-with-npm.bat
call .\bin\windows\typescript-angular-v2-interfaces.bat
call .\bin\windows\typescript-angular-v2.bat
call .\bin\windows\typescript-angular-v4-with-npm.bat
call .\bin\windows\typescript-angular-v4.3-with-npm.bat

View File

@ -11,7 +11,7 @@ codegen="${cli}/target/swagger-codegen-cli.jar"
cmdsrc="${cli}/src/main/java/io/swagger/codegen/cmd"
pattern="@Command(name = \"$1\""
if expr "x$1" : 'x[a-z][a-z-]*$' > /dev/null && fgrep -qe "$pattern" "$cmdsrc"/*.java; then
if expr "x$1" : 'x[a-z][a-z-]*$' > /dev/null && fgrep -qe "$pattern" "$cmdsrc"/*.java || expr "$1" = 'help' > /dev/null; then
# If ${GEN_DIR} has been mapped elsewhere from default, and that location has not been built
if [[ ! -f "${codegen}" ]]; then
(cd "${GEN_DIR}" && exec mvn -am -pl "modules/swagger-codegen-cli" -Duser.home=$(dirname MAVEN_CONFIG) package)

View File

@ -11,7 +11,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.2.2</version>
<version>2.2.3</version>
<executions>
<execution>
<goals>

View File

@ -154,6 +154,10 @@ public class CodegenConstants {
public static final String DOTNET_FRAMEWORK_DESC = "The target .NET framework version.";
public static enum MODEL_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, original}
public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, original, UPPERCASE}
public static final String ENUM_PROPERTY_NAMING = "enumPropertyNaming";
public static final String ENUM_PROPERTY_NAMING_DESC = "Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'";
public static final String MODEL_NAME_PREFIX = "modelNamePrefix";
public static final String MODEL_NAME_PREFIX_DESC = "Prefix that will be prepended to all model names. Default is the empty string.";

View File

@ -9,7 +9,6 @@ import java.util.Objects;
import io.swagger.models.ExternalDocs;
public class CodegenModel {
public String parent, parentSchema;
public List<String> interfaces;

View File

@ -12,7 +12,7 @@ import java.util.Arrays;
public class CodegenOperation {
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, hasRequiredParams,
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMapContainer,
isListContainer, isMultipart, hasMore = true,
isResponseBinary = false, isResponseFile = false, hasReference = false,
@ -28,6 +28,7 @@ public class CodegenOperation {
public List<CodegenParameter> queryParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> requiredParams = new ArrayList<CodegenParameter>();
public List<CodegenSecurity> authMethods;
public List<Tag> tags;
public List<CodegenResponse> responses = new ArrayList<CodegenResponse>();
@ -140,6 +141,15 @@ public class CodegenOperation {
return Arrays.asList("PUT", "PATCH").contains(httpMethod.toUpperCase()) && isMemberPath();
}
/**
* Check if body param is allowed for the request method
*
* @return true request method is PUT, PATCH or POST; false otherwise
*/
public boolean isBodyAllowed() {
return Arrays.asList("PUT", "PATCH", "POST").contains(httpMethod.toUpperCase());
}
/**
* Check if act as Restful destroy method
*

View File

@ -14,7 +14,7 @@ public class CodegenParameter {
public String example; // example value (x-example)
public String jsonSchema;
public boolean isString, isNumeric, isInteger, isLong, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid;
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid;
public boolean isListContainer, isMapContainer;
public boolean isFile, notFile;
public boolean isEnum;
@ -138,6 +138,7 @@ public class CodegenParameter {
output.isLong = this.isLong;
output.isDouble = this.isDouble;
output.isFloat = this.isFloat;
output.isNumber = this.isNumber;
output.isBoolean = this.isBoolean;
output.isDate = this.isDate;
output.isDateTime = this.isDateTime;
@ -217,6 +218,8 @@ public class CodegenParameter {
return false;
if (isLong != that.isLong)
return false;
if (isNumber != that.isNumber)
return false;
if (isFloat != that.isFloat)
return false;
if (isDouble != that.isDouble)
@ -308,6 +311,7 @@ public class CodegenParameter {
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);

View File

@ -39,7 +39,7 @@ public class CodegenProperty implements Cloneable {
public boolean hasMore, required, secondaryParam;
public boolean hasMoreNonReadOnly; // for model constructor, true if next properyt is not readonly
public boolean isPrimitiveType, isContainer, isNotContainer;
public boolean isString, isNumeric, isInteger, isLong, isFloat, isDouble, isByteArray, isBinary, isFile, isBoolean, isDate, isDateTime, isUuid;
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile, isBoolean, isDate, isDateTime, isUuid;
public boolean isListContainer, isMapContainer;
public boolean isEnum;
public boolean isReadOnly = false;
@ -118,6 +118,7 @@ public class CodegenProperty implements Cloneable {
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));
@ -272,6 +273,9 @@ public class CodegenProperty implements Cloneable {
if (this.isLong != other.isLong) {
return false;
}
if (this.isNumber != other.isNumber) {
return false;
}
if (this.isFloat != other.isFloat) {
return false;
}

View File

@ -11,7 +11,7 @@ public class CodegenResponse {
public List<Map<String, Object>> examples;
public String dataType, baseType, containerType;
public boolean hasHeaders;
public boolean isString, isNumeric, isInteger, isLong, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid;
public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid;
public boolean isDefault;
public boolean simpleType;
public boolean primitiveType;

View File

@ -2,20 +2,8 @@ package io.swagger.codegen;
import javax.annotation.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -1130,7 +1118,7 @@ public class DefaultCodegen {
String datatype = null;
if (p instanceof StringProperty && "number".equals(p.getFormat())) {
datatype = "BigDecimal";
} else if (p instanceof ByteArrayProperty) {
} else if ((p instanceof ByteArrayProperty) || (p instanceof StringProperty && "byte".equals(p.getFormat()))) {
datatype = "ByteArray";
} else if (p instanceof BinaryProperty) {
datatype = "binary";
@ -1706,20 +1694,7 @@ public class DefaultCodegen {
// type is number and without format
if (p instanceof DecimalProperty && !(p instanceof DoubleProperty) && !(p instanceof FloatProperty)) {
DecimalProperty sp = (DecimalProperty) p;
property.isFloat = true;
/*if (sp.getEnum() != null) {
List<Double> _enum = sp.getEnum();
property._enum = new ArrayList<String>();
for(Double i : _enum) {
property._enum.add(i.toString());
}
property.isEnum = true;
// legacy support
Map<String, Object> allowableValues = new HashMap<String, Object>();
allowableValues.put("values", _enum);
property.allowableValues = allowableValues;
}*/
property.isNumber = true;
}
if (p instanceof DoubleProperty) {
DoubleProperty sp = (DoubleProperty) p;
@ -2231,6 +2206,7 @@ public class DefaultCodegen {
List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> cookieParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> requiredParams = new ArrayList<CodegenParameter>();
if (parameters != null) {
for (Parameter param : parameters) {
@ -2253,13 +2229,6 @@ public class DefaultCodegen {
}
}
// set isPrimitiveType and baseType for allParams
/*if (languageSpecificPrimitives.contains(p.baseType)) {
p.isPrimitiveType = true;
p.baseType = getSwaggerType(p);
}*/
allParams.add(p);
// Issue #2561 (neilotoole) : Moved setting of is<Type>Param flags
// from here to fromParameter().
@ -2280,7 +2249,10 @@ public class DefaultCodegen {
} else if (param instanceof FormParameter) {
formParams.add(p.copy());
}
if (!p.required) {
if (p.required) { //required parameters
requiredParams.add(p.copy());
} else { // optional parameters
op.hasOptionalParams = true;
}
}
@ -2314,6 +2286,7 @@ public class DefaultCodegen {
op.headerParams = addHasMore(headerParams);
// op.cookieParams = cookieParams;
op.formParams = addHasMore(formParams);
op.requiredParams = addHasMore(requiredParams);
op.externalDocs = operation.getExternalDocs();
// legacy support
op.nickname = op.operationId;
@ -2321,6 +2294,7 @@ public class DefaultCodegen {
if (op.allParams.size() > 0) {
op.hasParams = true;
}
op.hasRequiredParams = op.requiredParams.size() > 0;
// set Restful Flag
op.isRestfulShow = op.isRestfulShow();
@ -2373,7 +2347,9 @@ public class DefaultCodegen {
}
r.dataType = cm.datatype;
if (Boolean.TRUE.equals(cm.isString)) {
if (Boolean.TRUE.equals(cm.isByteArray)) {
r.isByteArray = true;
} else if (Boolean.TRUE.equals(cm.isString)) {
r.isString = true;
} else if (Boolean.TRUE.equals(cm.isBoolean)) {
r.isBoolean = true;
@ -2383,14 +2359,15 @@ public class DefaultCodegen {
} else if (Boolean.TRUE.equals(cm.isInteger)) {
r.isInteger = true;
r.isNumeric = true;
} else if (Boolean.TRUE.equals(cm.isNumber)) {
r.isNumber = true;
r.isNumeric = true;
} else if (Boolean.TRUE.equals(cm.isDouble)) {
r.isDouble = true;
r.isNumeric = true;
} else if (Boolean.TRUE.equals(cm.isFloat)) {
r.isFloat = true;
r.isNumeric = true;
} else if (Boolean.TRUE.equals(cm.isByteArray)) {
r.isByteArray = true;
} else if (Boolean.TRUE.equals(cm.isBinary)) {
r.isBinary = true;
} else if (Boolean.TRUE.equals(cm.isFile)) {
@ -2714,6 +2691,8 @@ public class DefaultCodegen {
p.example = "56";
} else if (Boolean.TRUE.equals(p.isFloat)) {
p.example = "3.4";
} else if (Boolean.TRUE.equals(p.isNumber)) {
p.example = "8.14";
} else if (Boolean.TRUE.equals(p.isDouble)) {
p.example = "1.2";
} else if (Boolean.TRUE.equals(p.isBinary)) {
@ -2909,7 +2888,7 @@ public class DefaultCodegen {
* @return true if the library/module/package of the corresponding type needs to be imported
*/
protected boolean needToImport(String type) {
return !defaultIncludes.contains(type)
return StringUtils.isNotBlank(type) && !defaultIncludes.contains(type)
&& !languageSpecificPrimitives.contains(type);
}
@ -3384,8 +3363,17 @@ public class DefaultCodegen {
* @param library Library template
*/
public void setLibrary(String library) {
if (library != null && !supportedLibraries.containsKey(library))
throw new RuntimeException("unknown library: " + library);
if (library != null && !supportedLibraries.containsKey(library)) {
StringBuilder sb = new StringBuilder("Unknown library: " + library + "\nAvailable libraries:");
if(supportedLibraries.size() == 0) {
sb.append("\n ").append("NONE");
} else {
for (String lib : supportedLibraries.keySet()) {
sb.append("\n ").append(lib);
}
}
throw new RuntimeException(sb.toString());
}
this.library = library;
}
@ -3595,7 +3583,10 @@ public class DefaultCodegen {
return;
}
if (Boolean.TRUE.equals(property.isString)) {
if (Boolean.TRUE.equals(property.isByteArray)) {
parameter.isByteArray = true;
parameter.isPrimitiveType = true;
} else if (Boolean.TRUE.equals(property.isString)) {
parameter.isString = true;
parameter.isPrimitiveType = true;
} else if (Boolean.TRUE.equals(property.isBoolean)) {
@ -3613,8 +3604,8 @@ public class DefaultCodegen {
} else if (Boolean.TRUE.equals(property.isFloat)) {
parameter.isFloat = true;
parameter.isPrimitiveType = true;
} else if (Boolean.TRUE.equals(property.isByteArray)) {
parameter.isByteArray = true;
} else if (Boolean.TRUE.equals(property.isNumber)) {
parameter.isNumber = true;
parameter.isPrimitiveType = true;
} else if (Boolean.TRUE.equals(property.isBinary)) {
parameter.isByteArray = true;

View File

@ -68,9 +68,13 @@ public class InlineModelResolver {
Model innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
am.setItems(new RefProperty(existing));
RefProperty refProperty = new RefProperty(existing);
refProperty.setRequired(op.getRequired());
am.setItems(refProperty);
} else {
am.setItems(new RefProperty(modelName));
RefProperty refProperty = new RefProperty(modelName);
refProperty.setRequired(op.getRequired());
am.setItems(refProperty);
addGenerated(modelName, innerModel);
swagger.addDefinition(modelName, innerModel);
}
@ -94,9 +98,13 @@ public class InlineModelResolver {
Model model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
if (existing != null) {
response.setSchema(this.makeRefProperty(existing, property));
Property refProperty = this.makeRefProperty(existing, property);
refProperty.setRequired(op.getRequired());
response.setSchema(refProperty);
} else {
response.setSchema(this.makeRefProperty(modelName, property));
Property refProperty = this.makeRefProperty(modelName, property);
refProperty.setRequired(op.getRequired());
response.setSchema(refProperty);
addGenerated(modelName, model);
swagger.addDefinition(modelName, model);
}
@ -114,9 +122,13 @@ public class InlineModelResolver {
Model innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
ap.setItems(this.makeRefProperty(existing, op));
Property refProperty = this.makeRefProperty(existing, op);
refProperty.setRequired(op.getRequired());
ap.setItems(refProperty);
} else {
ap.setItems(this.makeRefProperty(modelName, op));
Property refProperty = this.makeRefProperty(modelName, op);
refProperty.setRequired(op.getRequired());
ap.setItems(refProperty);
addGenerated(modelName, innerModel);
swagger.addDefinition(modelName, innerModel);
}
@ -135,9 +147,13 @@ public class InlineModelResolver {
Model innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
mp.setAdditionalProperties(new RefProperty(existing));
RefProperty refProperty = new RefProperty(existing);
refProperty.setRequired(op.getRequired());
mp.setAdditionalProperties(refProperty);
} else {
mp.setAdditionalProperties(new RefProperty(modelName));
RefProperty refProperty = new RefProperty(modelName);
refProperty.setRequired(op.getRequired());
mp.setAdditionalProperties(refProperty);
addGenerated(modelName, innerModel);
swagger.addDefinition(modelName, innerModel);
}
@ -174,9 +190,13 @@ public class InlineModelResolver {
if (existing == null) {
swagger.addDefinition(innerModelName, innerModel);
addGenerated(innerModelName, innerModel);
m.setItems(new RefProperty(innerModelName));
RefProperty refProperty = new RefProperty(innerModelName);
refProperty.setRequired(op.getRequired());
m.setItems(refProperty);
} else {
m.setItems(new RefProperty(existing));
RefProperty refProperty = new RefProperty(existing);
refProperty.setRequired(op.getRequired());
m.setItems(refProperty);
}
}
}
@ -271,9 +291,13 @@ public class InlineModelResolver {
String existing = matchGenerated(model);
if (existing != null) {
propsToUpdate.put(key, new RefProperty(existing));
RefProperty refProperty = new RefProperty(existing);
refProperty.setRequired(op.getRequired());
propsToUpdate.put(key, refProperty);
} else {
propsToUpdate.put(key, new RefProperty(modelName));
RefProperty refProperty = new RefProperty(modelName);
refProperty.setRequired(op.getRequired());
propsToUpdate.put(key, refProperty);
modelsToAdd.put(modelName, model);
addGenerated(modelName, model);
swagger.addDefinition(modelName, model);
@ -290,9 +314,13 @@ public class InlineModelResolver {
Model innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
ap.setItems(new RefProperty(existing));
RefProperty refProperty = new RefProperty(existing);
refProperty.setRequired(op.getRequired());
ap.setItems(refProperty);
} else {
ap.setItems(new RefProperty(modelName));
RefProperty refProperty = new RefProperty(modelName);
refProperty.setRequired(op.getRequired());
ap.setItems(refProperty);
addGenerated(modelName, innerModel);
swagger.addDefinition(modelName, innerModel);
}
@ -310,9 +338,13 @@ public class InlineModelResolver {
Model innerModel = modelFromProperty(op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
mp.setAdditionalProperties(new RefProperty(existing));
RefProperty refProperty = new RefProperty(existing);
refProperty.setRequired(op.getRequired());
mp.setAdditionalProperties(refProperty);
} else {
mp.setAdditionalProperties(new RefProperty(modelName));
RefProperty refProperty = new RefProperty(modelName);
refProperty.setRequired(op.getRequired());
mp.setAdditionalProperties(refProperty);
addGenerated(modelName, innerModel);
swagger.addDefinition(modelName, innerModel);
}
@ -399,7 +431,7 @@ public class InlineModelResolver {
/**
* Make a RefProperty
*
*
* @param ref new property name
* @param property Property
* @return
@ -412,7 +444,7 @@ public class InlineModelResolver {
/**
* Copy vendor extensions from Property to another Property
*
*
* @param source source property
* @param target target property
*/

View File

@ -355,7 +355,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
for (Map.Entry<String, Object> entry : models.entrySet()) {
String swaggerName = entry.getKey();
CodegenModel model = ModelUtils.getModelByName(swaggerName, models);
if (model != null) {
for (CodegenProperty var : model.allVars) {
@ -369,7 +368,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
updateCodegenPropertyEnum(var);
// We do this after updateCodegenPropertyEnum to avoid generalities that don't mesh with C#.
// We do these after updateCodegenPropertyEnum to avoid generalities that don't mesh with C#.
var.isPrimitiveType = true;
}
}

View File

@ -166,4 +166,14 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
property.nameInCamelCase = nameInCamelCase;
return property;
}
/**
* Output the Getter name for boolean property, e.g. isActive
*
* @param name the name of the property
* @return getter name based on naming convention
*/
public String toBooleanGetter(String name) {
return "is" + getterAndSetterCapitalize(name);
}
}

View File

@ -18,11 +18,20 @@ import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.DateTimeProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.FileProperty;
import io.swagger.models.properties.FloatProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final String UNDEFINED_VALUE = "undefined";
protected String modelPropertyNaming= "camelCase";
protected Boolean supportsES6 = true;
@ -221,6 +230,49 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
return super.getTypeDeclaration(p);
}
@Override
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
StringProperty sp = (StringProperty) p;
if (sp.getDefault() != null) {
return "\"" + sp.getDefault() + "\"";
}
return UNDEFINED_VALUE;
} else if (p instanceof BooleanProperty) {
return UNDEFINED_VALUE;
} else if (p instanceof DateProperty) {
return UNDEFINED_VALUE;
} else if (p instanceof DateTimeProperty) {
return UNDEFINED_VALUE;
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (p instanceof FloatProperty) {
FloatProperty fp = (FloatProperty) p;
if (fp.getDefault() != null) {
return fp.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (p instanceof IntegerProperty) {
IntegerProperty ip = (IntegerProperty) p;
if (ip.getDefault() != null) {
return ip.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (p instanceof LongProperty) {
LongProperty lp = (LongProperty) p;
if (lp.getDefault() != null) {
return lp.getDefault().toString();
}
return UNDEFINED_VALUE;
} else {
return UNDEFINED_VALUE;
}
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);

View File

@ -15,6 +15,7 @@ public class CSharpClientCodegen 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";
private static final String NETSTANDARD = "v5.0";
private static final String UWP = "uwp";
@ -75,6 +76,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
);
frameworks = new ImmutableMap.Builder<String, String>()
.put(NET35, ".NET Framework 3.5 compatible")
.put(NET40, ".NET Framework 4.0 compatible")
.put(NET45, ".NET Framework 4.5+ compatible")
.put(NETSTANDARD, ".NET Standard 1.3 compatible")
.put(UWP, "Universal Windows Platform (IMPORTANT: this will be decommissioned and replaced by v5.0)")
@ -227,7 +229,13 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
setSupportsUWP(Boolean.TRUE);
additionalProperties.put("supportsAsync", this.supportsAsync);
additionalProperties.put("supportsUWP", this.supportsUWP);
} else if (NET40.equals(this.targetFramework)) {
setTargetFrameworkNuget("net40");
setSupportsAsync(Boolean.FALSE);
if (additionalProperties.containsKey("supportsAsync")) {
additionalProperties.remove("supportsAsync");
}
additionalProperties.put("isNet40", true);
} else {
setTargetFrameworkNuget("net45");
setSupportsAsync(Boolean.TRUE);

View File

@ -179,8 +179,10 @@ public class CppRestClientCodegen extends AbstractCppCodegen {
additionalProperties.put("modelNamespaceDeclarations", modelPackage.split("\\."));
additionalProperties.put("modelNamespace", modelPackage.replaceAll("\\.", "::"));
additionalProperties.put("modelHeaderGuardPrefix", modelPackage.replaceAll("\\.", "_").toUpperCase());
additionalProperties.put("apiNamespaceDeclarations", apiPackage.split("\\."));
additionalProperties.put("apiNamespace", apiPackage.replaceAll("\\.", "::"));
additionalProperties.put("apiHeaderGuardPrefix", apiPackage.replaceAll("\\.", "_").toUpperCase());
additionalProperties.put("declspec", declspec);
additionalProperties.put("defaultInclude", defaultInclude);
}
@ -312,7 +314,7 @@ public class CppRestClientCodegen extends AbstractCppCodegen {
@Override
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
return "U(\"\")";
return "utility::conversions::to_string_t(\"\")";
} else if (p instanceof BooleanProperty) {
return "false";
} else if (p instanceof DateProperty) {

View File

@ -0,0 +1,391 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.parameters.Parameter;
import java.io.File;
import java.util.*;
import java.io.Writer;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ErlangClientCodegen extends DefaultCodegen implements CodegenConfig {
static Logger LOGGER = LoggerFactory.getLogger(ErlangClientCodegen.class);
protected String packageName = "swagger";
protected String packageVersion = "1.0.0";
protected String sourceFolder = "src";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "erlang-client";
}
public String getHelp() {
return "Generates an Erlang client library (beta).";
}
public ErlangClientCodegen() {
super();
outputFolder = "generated-code/erlang";
modelTemplateFiles.put("model.mustache", ".erl");
apiTemplateFiles.put("api.mustache", ".erl");
embeddedTemplateDir = templateDir = "erlang-client";
setReservedWordsLowerCase(
Arrays.asList(
"after","and","andalso","band","begin","bnot","bor","bsl","bsr","bxor","case",
"catch","cond","div","end","fun","if","let","not","of","or","orelse","receive",
"rem","try","when","xor"
)
);
instantiationTypes.clear();
typeMapping.clear();
typeMapping.put("enum", "binary()");
typeMapping.put("date", "calendar:date()");
typeMapping.put("datetime", "calendar:datetime()");
typeMapping.put("date-time", "calendar:datetime()");
typeMapping.put("boolean", "boolean()");
typeMapping.put("string", "binary()");
typeMapping.put("integer", "integer()");
typeMapping.put("int", "integer()");
typeMapping.put("float", "integer()");
typeMapping.put("long", "integer()");
typeMapping.put("double", "float()");
typeMapping.put("array", "list()");
typeMapping.put("map", "maps:map()");
typeMapping.put("number", "integer()");
typeMapping.put("bigdecimal", "float()");
typeMapping.put("List", "list()");
typeMapping.put("object", "maps:map()");
typeMapping.put("file", "binary()");
typeMapping.put("binary", "binary()");
typeMapping.put("bytearray", "binary()");
typeMapping.put("byte", "binary()");
typeMapping.put("uuid", "binary()");
typeMapping.put("password", "binary()");
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Erlang application name (convention: lowercase).")
.defaultValue(this.packageName));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Erlang application version")
.defaultValue(this.packageVersion));
}
@Override
public String getTypeDeclaration(String name) {
return name + ":" + name + "()";
}
@Override
public String getTypeDeclaration(Property p) {
String swaggerType = getSwaggerType(p);
if (typeMapping.containsKey(swaggerType)) {
return typeMapping.get(swaggerType);
}
return swaggerType;
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if(typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if(languageSpecificPrimitives.contains(type))
return (type);
}
else
type = getTypeDeclaration(toModelName(snakeCase(swaggerType)));
return type;
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
}
else {
setPackageName("swagger");
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
}
else {
setPackageVersion("1.0.0");
}
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
additionalProperties.put("length", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(length(fragment.context()));
}
});
additionalProperties.put("qsEncode", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(qsEncode(fragment.context()));
}
});
modelPackage = packageName;
apiPackage = packageName;
supportingFiles.add(new SupportingFile("rebar.config.mustache","", "rebar.config"));
supportingFiles.add(new SupportingFile("app.src.mustache", "", "src" + File.separator + this.packageName + ".app.src"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
public String qsEncode(Object o) {
String r = new String();
CodegenParameter q = (CodegenParameter) o;
if (q.isListContainer) {
r += "[{<<\"" + q.baseName + "\">>, X} || X <- " + q.paramName + "]";
} else {
r += "{<<\"" + q.baseName + "\">>, " + q.paramName + "}";
}
return r;
}
@Override
public String escapeReservedWord(String name)
{
// Can't start with an underscore, as our fields need to start with an
// UppercaseLetter so that Go treats them as public/visible.
// Options?
// - MyName
// - AName
// - TheName
// - XName
// - X_Name
// ... or maybe a suffix?
// - Name_ ... think this will work.
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return camelize(name) + '_';
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator;
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator;
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = sanitizeName(name.replaceAll("-", "_"));
// for reserved word or word starting with number, append _
if (isReservedWord(name))
name = escapeReservedWord(name);
return name;
}
@Override
public String toParamName(String name) {
return camelize(toVarName(name));
}
@Override
public String toModelName(String name) {
return this.packageName + "_" + underscore(name.replaceAll("-", "_"));
}
@Override
public String toApiName(String name) {
return this.packageName + "_" + underscore(name.replaceAll("-", "_"));
}
@Override
public String toModelFilename(String name) {
return this.packageName + "_" + underscore(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. PetApi.erl => pet_api.erl
return this.packageName + "_" + underscore(name) + "_api";
}
@Override
public String toOperationId(String 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 " + underscore(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return underscore(operationId);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> os = (List<CodegenOperation>) operations.get("operation");
List<ExtendedCodegenOperation> newOs = new ArrayList<ExtendedCodegenOperation>();
Pattern pattern = Pattern.compile("(.*)\\{([^\\}]+)\\}(.*)");
for (CodegenOperation o : os) {
// force http method to lower case
o.httpMethod = o.httpMethod.toLowerCase();
if (o.isListContainer) {
o.returnType = "[" + o.returnBaseType + "]";
}
ArrayList<String> pathTemplateNames = new ArrayList<String>();
Matcher matcher = pattern.matcher(o.path);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
String pathTemplateName = matcher.group(2);
matcher.appendReplacement(buffer, "$1" + "\", " + camelize(pathTemplateName) + ", \"" + "$3");
pathTemplateNames.add(pathTemplateName);
}
ExtendedCodegenOperation eco = new ExtendedCodegenOperation(o);
if (buffer.toString().isEmpty()) {
eco.setReplacedPathName(o.path);
} else {
eco.setReplacedPathName(buffer.toString());
}
eco.setPathTemplateNames(pathTemplateNames);
newOs.add(eco);
}
operations.put("operation", newOs);
return objs;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
String length(Object o) {
return Integer.toString((((ExtendedCodegenOperation) o).allParams).size());
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
class ExtendedCodegenOperation extends CodegenOperation {
private List<String> pathTemplateNames = new ArrayList<String>();
private String replacedPathName;
public ExtendedCodegenOperation(CodegenOperation o) {
super();
// Copy all fields of CodegenOperation
this.responseHeaders.addAll(o.responseHeaders);
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
this.subresourceOperation = o.subresourceOperation;
this.isMapContainer = o.isMapContainer;
this.isListContainer = o.isListContainer;
this.isMultipart = o.isMultipart;
this.hasMore = o.hasMore;
this.isResponseBinary = o.isResponseBinary;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;
this.httpMethod = o.httpMethod;
this.returnBaseType = o.returnBaseType;
this.returnContainer = o.returnContainer;
this.summary = o.summary;
this.unescapedNotes = o.unescapedNotes;
this.notes = o.notes;
this.baseName = o.baseName;
this.defaultResponse = o.defaultResponse;
this.discriminator = o.discriminator;
this.consumes = o.consumes;
this.produces = o.produces;
this.bodyParam = o.bodyParam;
this.allParams = o.allParams;
this.bodyParams = o.bodyParams;
this.pathParams = o.pathParams;
this.queryParams = o.queryParams;
this.headerParams = o.headerParams;
this.formParams = o.formParams;
this.authMethods = o.authMethods;
this.tags = o.tags;
this.responses = o.responses;
this.imports = o.imports;
this.examples = o.examples;
this.externalDocs = o.externalDocs;
this.vendorExtensions = o.vendorExtensions;
this.nickname = o.nickname;
this.operationIdLowerCase = o.operationIdLowerCase;
this.operationIdCamelCase = o.operationIdCamelCase;
}
public List<String> getPathTemplateNames() {
return pathTemplateNames;
}
public void setPathTemplateNames(List<String> pathTemplateNames) {
this.pathTemplateNames = pathTemplateNames;
}
public String getReplacedPathName() {
return replacedPathName;
}
public void setReplacedPathName(String replacedPathName) {
this.replacedPathName = replacedPathName;
}
}
}

View File

@ -248,17 +248,30 @@ public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig
for (CodegenParameter p : op.allParams) {
// TODO: This hacky, should be converted to mappings if possible to keep it clean.
// This could also be done using template imports
if(Boolean.TRUE.equals(p.isPrimitiveType)) {
if(p.isPathParam && p.isPrimitiveType) {
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType.toLowerCase());
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
} else if(Boolean.TRUE.equals(p.isBodyParam)) {
} else if(p.isHeaderParam) {
if(p.required) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "header(\"" + p.baseName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
} else {
p.vendorExtensions.put("x-codegen-normalized-path-type", "headerOption(\"" + p.baseName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", "Option["+ p.dataType + "]");
}
} else if(p.isQueryParam) {
if(p.isContainer || p.isListContainer) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "params(\"" + p.baseName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType.replaceAll("^[^\\[]+", "Seq"));
} else {
p.vendorExtensions.put("x-codegen-normalized-path-type", "param(\"" + p.baseName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
}
} else if(p.isBodyParam) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "jsonBody["+ p.dataType + "]");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
} else if(Boolean.TRUE.equals(p.isContainer) || Boolean.TRUE.equals(p.isListContainer)) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "params(\""+ p.paramName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType.replaceAll("^[^\\[]+", "Seq"));
} else if(Boolean.TRUE.equals(p.isFile)) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "fileUpload(\""+ p.paramName + "\")");
} else if(p.isFile) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "fileUpload(\""+ p.baseName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", "FileUpload");
} else {
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType);

View File

@ -2,7 +2,6 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.Model;
import io.swagger.models.ModelImpl;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.properties.*;
@ -10,8 +9,6 @@ import io.swagger.models.properties.*;
import java.util.*;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConstants;
@ -24,6 +21,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.regex.Matcher;
@ -38,16 +36,18 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
protected String defaultDateFormat = "%Y-%m-%d";
protected Boolean useMonadLogger = false;
protected Boolean genEnums = true;
// CLI PROPS
public static final String PROP_ALLOW_FROMJSON_NULLS = "allowFromJsonNulls";
public static final String PROP_ALLOW_TOJSON_NULLS = "allowToJsonNulls";
public static final String PROP_DATETIME_FORMAT = "dateTimeFormat";
public static final String PROP_DATE_FORMAT = "dateFormat";
public static final String PROP_GENERATE_ENUMS = "generateEnums";
public static final String PROP_GENERATE_FORM_URLENCODED_INSTANCES = "generateFormUrlEncodedInstances";
public static final String PROP_GENERATE_LENSES = "generateLenses";
public static final String PROP_GENERATE_MODEL_CONSTRUCTORS = "generateModelConstructors";
public static final String PROP_INLINE_CONSUMES_CONTENT_TYPES = "inlineConsumesContentTypes";
public static final String PROP_INLINE_MIME_TYPES = "inlineMimeTypes";
public static final String PROP_MODEL_DERIVING = "modelDeriving";
public static final String PROP_STRICT_FIELDS = "strictFields";
public static final String PROP_USE_MONAD_LOGGER = "useMonadLogger";
@ -58,21 +58,26 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
private static final Pattern LEADING_UNDERSCORE = Pattern.compile("^_+");
static final String MEDIA_TYPE = "mediaType";
static final String MIME_NO_CONTENT = "MimeNoContent";
// vendor extensions
static final String X_ALL_UNIQUE_PARAMS = "x-allUniqueParams";
static final String X_COLLECTION_FORMAT = "x-collectionFormat";
static final String X_DUPLICATE = "x-duplicate";
static final String X_HADDOCK_PATH = "x-haddockPath";
static final String X_HAS_BODY_OR_FORM_PARAM = "x-hasBodyOrFormParam";
static final String X_HAS_ENUM_SECTION = "x-hasEnumSection";
static final String X_HAS_MIME_FORM_URL_ENCODED = "x-hasMimeFormUrlEncoded";
static final String X_HAS_NEW_TAG = "x-hasNewTag";
static final String X_HAS_OPTIONAL_PARAMS = "x-hasOptionalParams";
static final String X_HAS_UNKNOWN_MIME_TYPES = "x-hasUnknownMimeTypes";
static final String X_HAS_UNKNOWN_RETURN = "x-hasUnknownReturn";
static final String X_INLINE_CONTENT_TYPE = "x-inlineContentType";
static final String X_INLINE_ACCEPT = "x-inlineAccept";
static final String X_IS_BODY_OR_FORM_PARAM = "x-isBodyOrFormParam";
static final String X_IS_BODY_PARAM = "x-isBodyParam";
static final String X_MEDIA_DATA_TYPE = "x-mediaDataType";
static final String X_DATA_TYPE = "x-dataType";
static final String X_ENUM_VALUES = "x-enumValues";
static final String X_MEDIA_IS_JSON = "x-mediaIsJson";
static final String X_MIME_TYPES = "x-mimeTypes";
static final String X_OPERATION_TYPE = "x-operationType";
@ -82,14 +87,15 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
static final String X_STRICT_FIELDS = "x-strictFields";
static final String X_UNKNOWN_MIME_TYPES = "x-unknownMimeTypes";
static final String X_USE_MONAD_LOGGER = "x-useMonadLogger";
static final String X_NEWTYPE = "x-newtype";
static final String X_ENUM = "x-enum";
protected Map<String, CodegenParameter> uniqueParamsByName = new HashMap<String, CodegenParameter>();
protected ArrayList<Map<String,String>> unknownMimeTypes = new ArrayList<>();
protected Map<String, Map<String,Object>> uniqueParamNameTypes = new HashMap<>();
protected Map<String, Set<String>> modelMimeTypes = new HashMap<>();
protected Map<String, String> knownMimeDataTypes = new HashMap<>();
protected Set<String> typeNames = new HashSet<String>();
protected Map<String, String> knownMimeDataTypes = new HashMap<String, String>();
protected Map<String, Set<String>> modelMimeTypes = new HashMap<String, Set<String>>();
protected String lastTag = "";
protected ArrayList<Map<String,String>> unknownMimeTypes = new ArrayList<Map<String,String>>();
public CodegenType getTag() {
return CodegenType.CLIENT;
@ -138,7 +144,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
"instance", "let", "in",
"mdo", "module", "newtype",
"proc", "qualified", "rec",
"type", "where", "pure", "return"
"type", "where", "pure", "return",
"Accept", "ContentType"
)
);
@ -212,8 +219,10 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
cliOptions.add(CliOption.newBoolean(PROP_ALLOW_TOJSON_NULLS, "allow emitting JSON Null during model encoding to JSON").defaultValue(Boolean.FALSE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_LENSES, "Generate Lens optics for Models").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_MODEL_CONSTRUCTORS, "Generate smart constructors (only supply required fields) for models").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_ENUMS, "Generate specific datatypes for swagger enums").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_FORM_URLENCODED_INSTANCES, "Generate FromForm/ToForm instances for models that are used by operations that produce or consume application/x-www-form-urlencoded").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_INLINE_CONSUMES_CONTENT_TYPES, "Inline (hardcode) the content-type on operations that do not have multiple content-types (Consumes)").defaultValue(Boolean.FALSE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_INLINE_MIME_TYPES, "Inline (hardcode) the content-type and accept parameters on operations, when there is only 1 option").defaultValue(Boolean.FALSE.toString()));
cliOptions.add(CliOption.newString(PROP_MODEL_DERIVING, "Additional classes to include in the deriving() clause of Models"));
cliOptions.add(CliOption.newBoolean(PROP_STRICT_FIELDS, "Add strictness annotations to all model fields").defaultValue((Boolean.TRUE.toString())));
@ -237,12 +246,15 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
public void setGenerateModelConstructors(Boolean value) {
additionalProperties.put(PROP_GENERATE_MODEL_CONSTRUCTORS, value);
}
public void setGenerateEnums(Boolean value) {
additionalProperties.put(PROP_GENERATE_ENUMS, value);
genEnums = value;
}
public void setGenerateFormUrlEncodedInstances(Boolean value) {
additionalProperties.put(PROP_GENERATE_FORM_URLENCODED_INSTANCES, value);
}
public void setInlineConsumesContentTypes (Boolean value) {
additionalProperties.put(PROP_INLINE_CONSUMES_CONTENT_TYPES, value);
public void setInlineMimeTypes(Boolean value) {
additionalProperties.put(PROP_INLINE_MIME_TYPES, value);
}
public void setGenerateLenses(Boolean value) {
@ -311,16 +323,22 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
setGenerateModelConstructors(true);
}
if (additionalProperties.containsKey(PROP_GENERATE_ENUMS)) {
setGenerateEnums(convertPropertyToBoolean(PROP_GENERATE_ENUMS));
} else {
setGenerateEnums(true);
}
if (additionalProperties.containsKey(PROP_GENERATE_FORM_URLENCODED_INSTANCES)) {
setGenerateFormUrlEncodedInstances(convertPropertyToBoolean(PROP_GENERATE_FORM_URLENCODED_INSTANCES));
} else {
setGenerateFormUrlEncodedInstances(true);
}
if (additionalProperties.containsKey(PROP_INLINE_CONSUMES_CONTENT_TYPES)) {
setInlineConsumesContentTypes(convertPropertyToBoolean(PROP_INLINE_CONSUMES_CONTENT_TYPES));
if (additionalProperties.containsKey(PROP_INLINE_MIME_TYPES)) {
setInlineMimeTypes(convertPropertyToBoolean(PROP_INLINE_MIME_TYPES));
} else {
setInlineConsumesContentTypes(false);
setInlineMimeTypes(false);
}
if (additionalProperties.containsKey(PROP_GENERATE_LENSES)) {
@ -515,7 +533,19 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
op.vendorExtensions.put(X_HAS_OPTIONAL_PARAMS, true);
}
deduplicateParameter(param);
if (typeMapping.containsKey(param.dataType)
|| param.isMapContainer || param.isListContainer
|| param.isPrimitiveType || param.isFile || param.isEnum) {
String dataType = genEnums && param.isEnum ? param.datatypeWithEnum : param.dataType;
String paramNameType = toDedupedName(toTypeName("Param", param.paramName), dataType, !param.isEnum);
param.vendorExtensions.put(X_PARAM_NAME_TYPE, paramNameType);
HashMap<String, Object> props = new HashMap<>();
props.put(X_IS_BODY_PARAM, param.isBodyParam);
addToUniques(X_NEWTYPE, paramNameType, dataType, props);
}
}
processPathExpr(op);
@ -550,6 +580,17 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
ops.get(0).vendorExtensions.put(X_HAS_NEW_TAG, true);
}
updateGlobalAdditionalProps();
return ret;
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
updateGlobalAdditionalProps();
return super.postProcessAllModels(objs);
}
public void updateGlobalAdditionalProps() {
additionalProperties.put(X_HAS_UNKNOWN_MIME_TYPES, !unknownMimeTypes.isEmpty());
Collections.sort(unknownMimeTypes, new Comparator<Map<String, String>>() {
@ -560,19 +601,17 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
});
additionalProperties.put(X_UNKNOWN_MIME_TYPES, unknownMimeTypes);
ArrayList<CodegenParameter> params = new ArrayList<>(uniqueParamsByName.values());
Collections.sort(params, new Comparator<CodegenParameter>() {
ArrayList<Map<String,Object>> params = new ArrayList<>(uniqueParamNameTypes.values());
Collections.sort(params, new Comparator<Map<String,Object>>() {
@Override
public int compare(CodegenParameter o1, CodegenParameter o2) {
public int compare(Map<String,Object> o1, Map<String,Object> o2) {
return
((String) o1.vendorExtensions.get(X_PARAM_NAME_TYPE))
((String) o1.get(X_PARAM_NAME_TYPE))
.compareTo(
(String) o2.vendorExtensions.get(X_PARAM_NAME_TYPE));
(String) o2.get(X_PARAM_NAME_TYPE));
}
});
additionalProperties.put(X_ALL_UNIQUE_PARAMS, params);
return ret;
}
@Override
@ -615,12 +654,6 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
prop.name = toVarName(prefix, prop.name);
}
//String dataOrNewtype = "data";
// check if it's a ModelImpl before casting
if (!(mod instanceof ModelImpl)) {
return model;
}
return model;
}
@ -661,6 +694,9 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
op.vendorExtensions.put(X_HAS_UNKNOWN_RETURN, true);
} else {
returnType = "NoContent";
if(!op.vendorExtensions.containsKey(X_INLINE_ACCEPT)) {
SetNoContent(op, X_INLINE_ACCEPT);
}
}
}
if (returnType.indexOf(" ") >= 0) {
@ -670,9 +706,12 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
}
private void processProducesConsumes(CodegenOperation op) {
if (!(Boolean) op.vendorExtensions.get(X_HAS_BODY_OR_FORM_PARAM)) {
SetNoContent(op, X_INLINE_CONTENT_TYPE);
}
if (op.hasConsumes) {
for (Map<String, String> m : op.consumes) {
processMediaType(op,m);
processMediaType(op, m);
processInlineConsumesContentType(op, m);
}
@ -683,12 +722,14 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (op.hasProduces) {
for (Map<String, String> m : op.produces) {
processMediaType(op,m);
processInlineProducesContentType(op, m);
}
}
}
private void processInlineConsumesContentType(CodegenOperation op, Map<String, String> m) {
if ((boolean) additionalProperties.get(PROP_INLINE_CONSUMES_CONTENT_TYPES)
if (op.vendorExtensions.containsKey(X_INLINE_CONTENT_TYPE)) return;
if ((boolean) additionalProperties.get(PROP_INLINE_MIME_TYPES)
&& op.consumes.size() == 1) {
op.vendorExtensions.put(X_INLINE_CONTENT_TYPE, m);
for (CodegenParameter param : op.allParams) {
@ -699,51 +740,80 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
}
}
private void deduplicateParameter(CodegenParameter param) {
if (typeMapping.containsKey(param.dataType) || param.isPrimitiveType || param.isListContainer || param.isMapContainer || param.isFile) {
String paramNameType = toTypeName("Param", param.paramName);
if (uniqueParamsByName.containsKey(paramNameType)) {
if(!checkParamForDuplicates(paramNameType, param)) {
paramNameType = paramNameType + param.dataType;
if(!checkParamForDuplicates(paramNameType, param)) {
while (typeNames.contains(paramNameType)) {
paramNameType = generateNextName(paramNameType);
if(checkParamForDuplicates(paramNameType, param)) {
break;
}
}
}
uniqueParamsByName.put(paramNameType, param);
}
} else {
while (typeNames.contains(paramNameType)) {
paramNameType = generateNextName(paramNameType);
if(checkParamForDuplicates(paramNameType, param)) {
break;
}
}
uniqueParamsByName.put(paramNameType, param);
}
param.vendorExtensions.put(X_PARAM_NAME_TYPE, paramNameType);
typeNames.add(paramNameType);
private void processInlineProducesContentType(CodegenOperation op, Map<String, String> m) {
if ((boolean) additionalProperties.get(PROP_INLINE_MIME_TYPES)
&& op.produces.size() == 1) {
op.vendorExtensions.put(X_INLINE_ACCEPT, m);
}
}
public Boolean checkParamForDuplicates(String paramNameType, CodegenParameter param) {
CodegenParameter lastParam = this.uniqueParamsByName.get(paramNameType);
if (lastParam != null && lastParam.dataType != null && lastParam.dataType.equals(param.dataType)) {
param.vendorExtensions.put(X_DUPLICATE, true);
return true;
private void SetNoContent(CodegenOperation op, String inlineExtentionName) {
Map<String, String> m = new HashMap<>();
m.put(X_MEDIA_DATA_TYPE, MIME_NO_CONTENT);
op.vendorExtensions.put(inlineExtentionName, m);
}
private String toDedupedName(String paramNameType, String dataType, Boolean appendDataType) {
if (appendDataType
&& uniqueParamNameTypes.containsKey(paramNameType)
&& !isDuplicate(paramNameType, dataType)) {
paramNameType = paramNameType + dataType;
}
while (typeNames.contains(paramNameType)) {
if (isDuplicate(paramNameType, dataType)) {
break;
}
paramNameType = generateNextName(paramNameType);
}
typeNames.add(paramNameType);
return paramNameType;
}
public Boolean isDuplicate(String paramNameType, String dataType) {
Map<String, Object> lastParam = this.uniqueParamNameTypes.get(paramNameType);
if (lastParam != null) {
String comparisonKey = lastParam.containsKey(X_ENUM) ? X_ENUM_VALUES : X_DATA_TYPE;
String lastParamDataType = (String) lastParam.get(comparisonKey);
if (lastParamDataType != null && lastParamDataType.equals(dataType)) {
return true;
}
}
return false;
}
private Pair<Boolean, String> isDuplicateEnumValues(String enumValues) {
for (Map<String, Object> vs : uniqueParamNameTypes.values()) {
if (enumValues.equals(vs.get(X_ENUM_VALUES))) {
return Pair.of(true, (String) vs.get(X_PARAM_NAME_TYPE));
}
}
return Pair.of(false, null);
}
private void addToUniques(String xGroup, String paramNameType, String dataType, Map<String, Object> props) {
HashMap<String, Object> m = new HashMap<>();
m.put(X_PARAM_NAME_TYPE, paramNameType);
m.put(X_DATA_TYPE, dataType);
m.put(xGroup, true);
m.putAll(props);
uniqueParamNameTypes.put(paramNameType, m);
}
private void addEnumToUniques(String paramNameType, String datatype, String enumValues, Map<String, Object> allowableValues, String description) {
HashMap<String, Object> props = new HashMap<>();
props.put("allowableValues", allowableValues);
if(StringUtils.isNotBlank(description)) {
props.put("description", description);
}
props.put(X_ENUM_VALUES, enumValues);
addToUniques(X_ENUM, paramNameType, datatype, props);
additionalProperties.put(X_HAS_ENUM_SECTION, true);
}
// build the parameterized path segments, according to pathParams
private void processPathExpr(CodegenOperation op) {
String xPath = "[\"" + escapeText(op.path) + "\"]";
@ -835,7 +905,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
private String getMimeDataType(String mimeType) {
if (StringUtils.isBlank(mimeType)) {
return "MimeNoContent";
return MIME_NO_CONTENT;
}
if (knownMimeDataTypes.containsKey(mimeType)) {
return knownMimeDataTypes.get(mimeType);
@ -962,20 +1032,121 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
}
@Override
public String toEnumName(CodegenProperty property) {
return "Enum'" + toTypeName("", property.name);
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.isEnum = genEnums && cm.isEnum;
if(cm.isAlias) {
cm.vendorExtensions.put(X_DATA_TYPE, cm.dataType);
}
for (CodegenProperty var : cm.vars) {
String datatype = genEnums && !StringUtils.isBlank(var.datatypeWithEnum)
? var.datatypeWithEnum
: var.datatype;
var.vendorExtensions.put(X_DATA_TYPE, datatype);
}
}
return postProcessModelsEnum(objs);
}
@Override
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
Map<String, Object> objsEnum = super.postProcessModelsEnum(objs);
if (genEnums) {
List<Object> models = (List<Object>) objsEnum.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.isEnum && cm.allowableValues != null) {
updateAllowableValuesNames(cm.classname, cm.allowableValues);
addEnumToUniques(cm.classname, cm.dataType, cm.allowableValues.values().toString(), cm.allowableValues, cm.description);
}
}
}
return objsEnum;
}
@Override
protected void updateDataTypeWithEnumForMap(CodegenProperty property) {
CodegenProperty baseItem = property.items;
while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMapContainer) || Boolean.TRUE.equals(baseItem.isListContainer))) {
baseItem = baseItem.items;
}
if (baseItem != null) {
// this replacement is/needs to be language-specific
property.datatypeWithEnum = property.datatypeWithEnum.replace(baseItem.baseType + ")", toEnumName(baseItem) + ")");
property.enumName = toEnumName(property);
if (property.defaultValue != null) {
property.defaultValue = property.defaultValue.replace(", " + property.items.baseType, ", " + toEnumName(property.items));
}
}
}
@Override
public String toEnumName(CodegenProperty var) {
if (!genEnums) return super.toEnumName(var);
if (var.items != null && var.items.isEnum) {
return toEnumName(var.items);
}
String paramNameType = "E'" + toTypeName("", var.name);
String enumValues = var._enum.toString();
Pair<Boolean, String> duplicateEnum = isDuplicateEnumValues(enumValues);
if (duplicateEnum.getLeft()) {
paramNameType = duplicateEnum.getRight();
} else {
paramNameType = toDedupedName(paramNameType, enumValues, false);
var.datatypeWithEnum = paramNameType;
updateCodegenPropertyEnum(var);
addEnumToUniques(paramNameType, var.datatype, enumValues, var.allowableValues, var.description);
}
return paramNameType;
}
@Override
public void updateCodegenPropertyEnum(CodegenProperty var) {
super.updateCodegenPropertyEnum(var);
if (!genEnums) return;
updateCodegenPropertyEnumValues(var, var.datatypeWithEnum);
}
public void updateCodegenPropertyEnumValues(CodegenProperty var, String paramNameType) {
if (var.items != null && var.items.allowableValues != null) {
updateCodegenPropertyEnumValues(var.items, var.items.datatypeWithEnum);
return;
}
if(var.isEnum && var.allowableValues != null) {
updateAllowableValuesNames(paramNameType, var.allowableValues);
}
}
private void updateAllowableValuesNames(String paramNameType, Map<String, Object> allowableValues) {
if (allowableValues == null) {
return;
}
for (Map<String, String> enumVar : (List<Map<String, String>>) allowableValues.get("enumVars")) {
enumVar.put("name", paramNameType + enumVar.get("name"));
}
}
@Override
public String toEnumVarName(String value, String datatype) {
if (!genEnums) return super.toEnumVarName(value, datatype);
List<String> num = new ArrayList<>(Arrays.asList("integer","int","double","long","float"));
if (value.length() == 0) {
return "E'Empty";
return "'Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return "E'" + sanitizeName(getSymbolName(value));
return "'" + StringUtils.capitalize(sanitizeName(getSymbolName(value)));
}
// number
@ -984,10 +1155,10 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
varName = varName.replaceAll("-", "Minus_");
varName = varName.replaceAll("\\+", "Plus_");
varName = varName.replaceAll("\\.", "_Dot_");
return "E'" + sanitizeName(varName);
return "'" + StringUtils.capitalize(sanitizeName(varName));
}
return "E'" + sanitizeName(value);
return "'" + StringUtils.capitalize(sanitizeName(value));
}
@Override

View File

@ -1,10 +1,13 @@
package io.swagger.codegen.languages;
import static java.util.Collections.sort;
import com.google.common.collect.LinkedListMultimap;
import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.codegen.languages.features.GzipFeatures;
import io.swagger.codegen.languages.features.PerformBeanValidationFeatures;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@ -49,6 +52,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected boolean useGzipFeature = false;
protected boolean useRuntimeException = false;
public JavaClientCodegen() {
super();
outputFolder = "generated-code" + File.separator + "java";
@ -78,6 +82,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
supportedLibraries.put("resttemplate", "HTTP client: Spring RestTemplate 4.3.9-RELEASE. JSON processing: Jackson 2.8.9");
supportedLibraries.put("resteasy", "HTTP client: Resteasy client 3.1.3.Final. JSON processing: Jackson 2.8.9");
supportedLibraries.put("vertx", "HTTP client: VertX client 3.2.4. JSON processing: Jackson 2.8.9");
supportedLibraries.put("google-api-client", "HTTP client: Google API client 1.23.0. JSON processing: Jackson 2.8.9");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
libraryOption.setEnum(supportedLibraries);
@ -168,10 +173,13 @@ public class JavaClientCodegen extends AbstractJavaCodegen
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
}
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
// google-api-client doesn't use the Swagger auth, because it uses Google Credential directly (HttpRequestInitializer)
if (!"google-api-client".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
}
supportingFiles.add(new SupportingFile( "gradlew.mustache", "", "gradlew") );
supportingFiles.add(new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat") );
supportingFiles.add(new SupportingFile( "gradle-wrapper.properties.mustache",
@ -192,7 +200,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
apiDocTemplateFiles.remove("api_doc.mustache");
}
if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary())) {
if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary() || "google-api-client".equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
@ -236,6 +244,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
apiTemplateFiles.put("apiImpl.mustache", "Impl.java");
apiTemplateFiles.put("rxApiImpl.mustache", ".java");
supportingFiles.remove(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
} else if ("google-api-client".equals(getLibrary())) {
additionalProperties.put("jackson", "true");
} else {
LOGGER.error("Unknown library option (-l/--library): " + getLibrary());
}
@ -316,10 +326,34 @@ public class JavaClientCodegen extends AbstractJavaCodegen
if (operation.returnType == null) {
operation.returnType = "Void";
}
if (usesRetrofit2Library() && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/"))
if (usesRetrofit2Library() && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/")){
operation.path = operation.path.substring(1);
}
// sorting operation parameters to make sure path params are parsed before query params
if (operation.allParams != null) {
sort(operation.allParams, new Comparator<CodegenParameter>() {
@Override
public int compare(CodegenParameter one, CodegenParameter another) {
if (one.isPathParam && another.isQueryParam) {
return -1;
}
if (one.isQueryParam && another.isPathParam){
return 1;
}
return 0;
}
});
Iterator<CodegenParameter> iterator = operation.allParams.iterator();
while (iterator.hasNext()){
CodegenParameter param = iterator.next();
param.hasMore = iterator.hasNext();
}
}
}
}
}
// camelize path variables for Feign client

View File

@ -272,6 +272,12 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
}
if (operation.returnType != null) {
if (operation.returnType.equals("Boolean")) {
operation.vendorExtensions.put("missingReturnInfoIfNeeded", "true");
}
if (operation.returnType.equals("BigDecimal")) {
operation.vendorExtensions.put("missingReturnInfoIfNeeded", "1.0");
}
if (operation.returnType.startsWith("List")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");

View File

@ -23,6 +23,7 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
protected String packageName = "io.swagger.client";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected CodegenConstants.ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase;
/**
* Constructs an instance of `KotlinClientCodegen`.
@ -56,17 +57,26 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
));
// this includes hard reserved words defined by https://github.com/JetBrains/kotlin/blob/master/core/descriptors/src/org/jetbrains/kotlin/renderer/KeywordStringsGenerated.java
// as well as select soft (contextual) keywords
// as well as keywords from https://kotlinlang.org/docs/reference/keyword-reference.html
reservedWords = new HashSet<String>(Arrays.asList(
"abstract",
"annotation",
"as",
"break",
"case",
"catch",
"class",
"companion",
"const",
"constructor",
"continue",
"crossinline",
"data",
"delegate",
"do",
"else",
"enum",
"external",
"false",
"final",
"finally",
@ -74,20 +84,33 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
"fun",
"if",
"in",
"infix",
"init",
"inline",
"inner",
"interface",
"internal",
"is",
"it",
"lateinit",
"lazy",
"noinline",
"null",
"object",
"open",
"operator",
"out",
"override",
"package",
"private",
"protected",
"public",
"reified",
"return",
"sealed",
"super",
"suspend",
"tailrec",
"this",
"throw",
"true",
@ -96,6 +119,7 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
"typeof",
"val",
"var",
"vararg",
"when",
"while"
));
@ -149,12 +173,17 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("LocalTime", "java.time.LocalTime");
specialCharReplacements.put(";", "Semicolon");
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC).defaultValue(sourceFolder));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Client package name (e.g. io.swagger).").defaultValue(this.packageName));
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, "Client package's organization (i.e. maven groupId).").defaultValue(groupId));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, "Client artifact id (name of generated jar).").defaultValue(artifactId));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "Client package version.").defaultValue(artifactVersion));
CliOption enumPropertyNamingOpt = new CliOption(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_DESC);
cliOptions.add(enumPropertyNamingOpt.defaultValue(enumPropertyNaming.name()));
}
public CodegenType getTag() {
@ -193,6 +222,10 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.ENUM_PROPERTY_NAMING)) {
setEnumPropertyNaming((String) additionalProperties.get(CodegenConstants.ENUM_PROPERTY_NAMING));
}
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
} else {
@ -255,6 +288,27 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("infrastructure/Errors.kt.mustache", infrastructureFolder, "Errors.kt"));
}
/**
* Sets the naming convention for Kotlin enum properties
*
* @param enumPropertyNamingType The string representation of the naming convention, as defined by {@link CodegenConstants.ENUM_PROPERTY_NAMING_TYPE}
*/
public void setEnumPropertyNaming(final String enumPropertyNamingType) {
try {
this.enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.valueOf(enumPropertyNamingType);
} catch (IllegalArgumentException ex) {
StringBuilder sb = new StringBuilder(enumPropertyNamingType + " is an invalid enum property naming option. Please choose from:");
for (CodegenConstants.ENUM_PROPERTY_NAMING_TYPE t : CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.values()) {
sb.append("\n ").append(t.name());
}
throw new RuntimeException(sb.toString());
}
}
public CodegenConstants.ENUM_PROPERTY_NAMING_TYPE getEnumPropertyNaming() {
return this.enumPropertyNaming;
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
@ -289,7 +343,8 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String escapeReservedWord(String name) {
return "_" + name;
// TODO: Allow enum escaping as an option (e.g. backticks vs append/prepend underscore vs match model property escaping).
return String.format("`%s`", name);
}
/**
@ -300,12 +355,25 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
* @return capitalized model name
*/
@Override
public String toModelName(String name) {
if(!name.startsWith("kotlin.") && !name.startsWith("java.")) {
return initialCaps(modelNamePrefix + name + modelNameSuffix);
} else {
public String toModelName(final String name) {
// Allow for explicitly configured kotlin.* and java.* types
if (name.startsWith("kotlin.") || name.startsWith("java.")) {
return name;
}
// If importMapping contains name, assume this is a legitimate model name.
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
String modifiedName = name.replaceAll("\\.", "");
modifiedName = sanitizeKotlinSpecificNames(modifiedName);
if (reservedWords.contains(modifiedName)) {
modifiedName = escapeReservedWord(modifiedName);
}
return titleCase(modifiedName);
}
/**
@ -386,4 +454,84 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return postProcessModelsEnum(super.postProcessModels(objs));
}
/**
* Return the sanitized variable name for enum
*
* @param value enum variable name
* @param datatype data type
* @return the sanitized variable name for enum
*/
@Override
public String toEnumVarName(String value, String datatype) {
String modified;
if (value.length() == 0) {
modified = "EMPTY";
} else {
modified = value;
modified = sanitizeKotlinSpecificNames(modified);
}
switch (getEnumPropertyNaming()) {
case original:
// NOTE: This is provided as a last-case allowance, but will still result in reserved words being escaped.
modified = value;
break;
case camelCase:
// NOTE: Removes hyphens and underscores
modified = camelize(modified, true);
break;
case PascalCase:
// NOTE: Removes hyphens and underscores
String result = camelize(modified);
modified = titleCase(result);
break;
case snake_case:
// NOTE: Removes hyphens
modified = underscore(modified);
break;
case UPPERCASE:
modified = modified.toUpperCase();
break;
}
if (reservedWords.contains(modified)) {
return escapeReservedWord(modified);
}
return modified;
}
private String titleCase(final String input) {
return input.substring(0, 1).toUpperCase() + input.substring(1);
}
/**
* Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}.
*
* @param name string to be sanitize
* @return sanitized string
*/
private String sanitizeKotlinSpecificNames(final String name) {
String word = name;
for (Map.Entry<String, String> specialCharacters : specialCharReplacements.entrySet()) {
// Underscore is the only special character we'll allow
if (!specialCharacters.getKey().equals("_")) {
word = word.replaceAll("\\Q" + specialCharacters.getKey() + "\\E", specialCharacters.getValue());
}
}
// Fallback, replace unknowns with underscore.
word = word.replaceAll("\\W+", "_");
if (word.matches("\\d.*")) {
word = "_" + word;
}
// _, __, and ___ are reserved in Kotlin. Treat all names with only underscores consistently, regardless of count.
if (word.matches("^_*$")) {
word = word.replaceAll("\\Q_\\E", "Underscore");
}
return word;
}
}

View File

@ -46,6 +46,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
private static final String IMMUTABLE_OPTION = "immutable";
private static final String USE_BASE_PATH = "writeModulePath";
private static final String PACKAGE_CONTEXT = "packageContext";
private static final String ASYNC_SERVER = "asyncServer";
private static final Map<String, Predicate<Property>> propertyToSwaggerTypeMapping =
createPropertyToSwaggerTypeMapping();
@ -57,6 +58,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
private final Multimap<String, CodegenModel> childrenByParent = ArrayListMultimap.create();
private final BiMap<String, String> modelNameMapping = HashBiMap.create();
/** If set to true, we will generate c# async endpoints and service interfaces */
private boolean asyncServer = false;
public NancyFXServerCodegen() {
outputFolder = "generated-code" + File.separator + getName();
apiTemplateFiles.put("api.mustache", ".cs");
@ -87,6 +91,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection);
addSwitch(IMMUTABLE_OPTION, "Enabled by default. If disabled generates model classes with setters", true);
addSwitch(USE_BASE_PATH, "Enabled by default. If disabled, module paths will not mirror api base path", true);
addSwitch(ASYNC_SERVER, "Set to true to enable the generation of async routes/endpoints.", false);
typeMapping.putAll(nodaTimeTypesMappings());
languageSpecificPrimitives.addAll(nodaTimePrimitiveTypes());
@ -128,6 +133,10 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
setPackageGuid((String) additionalProperties.get(OPTIONAL_PROJECT_GUID));
}
if (additionalProperties.containsKey(ASYNC_SERVER)) {
setAsyncServer(Boolean.valueOf(additionalProperties.get(ASYNC_SERVER).toString()));
}
additionalProperties.put("packageGuid", packageGuid);
setupModelTemplate();
@ -199,7 +208,11 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
public void setPackageGuid(String packageGuid) {
this.packageGuid = packageGuid;
}
public void setAsyncServer(boolean asyncServer) {
this.asyncServer = asyncServer;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder() + File.separator + API_NAMESPACE;

View File

@ -67,6 +67,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("float");
languageSpecificPrimitives.add("list");
languageSpecificPrimitives.add("dict");
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
@ -189,21 +190,16 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
setPackageUrl((String) additionalProperties.get(PACKAGE_URL));
}
String swaggerFolder = packageName;
modelPackage = swaggerFolder + File.separatorChar + "models";
apiPackage = swaggerFolder + File.separatorChar + "apis";
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFolder, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFolder, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", packageName, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", packageName, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", packageName + File.separatorChar + modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", packageName + File.separatorChar + apiPackage, "__init__.py"));
if(Boolean.FALSE.equals(excludeTests)) {
supportingFiles.add(new SupportingFile("__init__test.mustache", testFolder, "__init__.py"));
@ -212,23 +208,42 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFolder, "api_client.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", packageName, "api_client.py"));
if ("asyncio".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packageName, "rest.py"));
additionalProperties.put("asyncio", "true");
} else if ("tornado".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("tornado/rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packageName, "rest.py"));
additionalProperties.put("tornado", "true");
} else {
supportingFiles.add(new SupportingFile("rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("rest.mustache", packageName, "rest.py"));
}
modelPackage = packageName + "." + modelPackage;
apiPackage = packageName + "." + apiPackage;
}
private static String dropDots(String str) {
return str.replaceAll("\\.", "_");
}
@Override
public String toModelImport(String name) {
String modelImport;
if (StringUtils.startsWithAny(name,"import", "from")) {
modelImport = name;
} else {
modelImport = "from ";
if (!"".equals(modelPackage())) {
modelImport += modelPackage() + ".";
}
modelImport += toModelFilename(name)+ " import " + name;
}
return modelImport;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models

View File

@ -99,8 +99,7 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("file", "File");
typeMapping.put("binary", "Vec<u8>");
typeMapping.put("ByteArray", "String");
// TODO what should 'object' mapped to
typeMapping.put("object", "Object");
typeMapping.put("object", "Value");
// no need for rust
//importMapping = new HashMap<String, String>();

View File

@ -0,0 +1,963 @@
package io.swagger.codegen.languages;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import io.swagger.codegen.*;
import io.swagger.models.*;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.*;
import io.swagger.util.Yaml;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(RustServerCodegen.class);
private HashMap<String, String> modelXmlNames = new HashMap<String, String>();
protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "swagger-server";
protected String apiPath = "rust-server";
protected String packageName;
protected String packageVersion;
protected String externCrateName;
public RustServerCodegen() {
super();
// set the output folder here
outputFolder = "generated-code/rust-server";
/*
* Models. You can write model files using the modelTemplateFiles map.
* if you want to create one template for file, you can do so here.
* for multiple files for model, just put another entry in the `modelTemplateFiles` with
* a different extension
*/
modelTemplateFiles.clear();
/*
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
* as with models, add multiple entries with different extensions for multiple files per
* class
*/
apiTemplateFiles.clear();
/*
* Template Location. This is the location which templates will be read from. The generator
* will use the resource stream to attempt to read the templates.
*/
embeddedTemplateDir = templateDir = "rust-server";
/*
* Reserved words. Override this with reserved words specific to your language
*/
setReservedWordsLowerCase(
Arrays.asList(
// From https://doc.rust-lang.org/grammar.html#keywords
"abstract", "alignof", "as", "become", "box", "break", "const",
"continue", "crate", "do", "else", "enum", "extern", "false",
"final", "fn", "for", "if", "impl", "in", "let", "loop", "macro",
"match", "mod", "move", "mut", "offsetof", "override", "priv",
"proc", "pub", "pure", "ref", "return", "Self", "self", "sizeof",
"static", "struct", "super", "trait", "true", "type", "typeof",
"unsafe", "unsized", "use", "virtual", "where", "while", "yield"
)
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"map",
"array")
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"bool",
"char",
"i8",
"i16",
"i32",
"i64",
"u8",
"u16",
"u32",
"u64",
"isize",
"usize",
"f32",
"f64",
"str")
);
instantiationTypes.clear();
instantiationTypes.put("array", "Vec");
instantiationTypes.put("map", "Map");
typeMapping.clear();
typeMapping.put("number", "f64");
typeMapping.put("integer", "i32");
typeMapping.put("long", "i64");
typeMapping.put("float", "f32");
typeMapping.put("double", "f64");
typeMapping.put("string", "String");
typeMapping.put("UUID", "uuid::Uuid");
typeMapping.put("byte", "u8");
typeMapping.put("ByteArray", "swagger::ByteArray");
typeMapping.put("binary", "swagger::ByteArray");
typeMapping.put("boolean", "bool");
typeMapping.put("date", "chrono::DateTime<chrono::Utc>");
typeMapping.put("DateTime", "chrono::DateTime<chrono::Utc>");
typeMapping.put("password", "String");
typeMapping.put("File", "Box<Stream<Item=Vec<u8>, Error=Error> + Send>");
typeMapping.put("file", "Box<Stream<Item=Vec<u8>, Error=Error> + Send>");
typeMapping.put("array", "Vec");
typeMapping.put("map", "HashMap");
importMapping = new HashMap<String, String>();
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME,
"Rust crate name (convention: snake_case).")
.defaultValue("swagger_client"));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION,
"Rust crate version.")
.defaultValue("1.0.0"));
/*
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
additionalProperties.put("apiVersion", apiVersion);
additionalProperties.put("serverPort", serverPort);
additionalProperties.put("apiPath", apiPath);
/*
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
* it will be processed by the template engine. Otherwise, it will be copied
*/
supportingFiles.add(new SupportingFile("swagger.mustache", "api", "swagger.yaml"));
supportingFiles.add(new SupportingFile("Cargo.mustache", "", "Cargo.toml"));
supportingFiles.add(new SupportingFile("cargo-config", ".cargo", "config"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs"));
supportingFiles.add(new SupportingFile("models.mustache", "src", "models.rs"));
supportingFiles.add(new SupportingFile("server.mustache", "src", "server.rs"));
supportingFiles.add(new SupportingFile("client.mustache", "src", "client.rs"));
supportingFiles.add(new SupportingFile("mimetypes.mustache", "src", "mimetypes.rs"));
supportingFiles.add(new SupportingFile("example-server.mustache", "examples", "server.rs"));
supportingFiles.add(new SupportingFile("example-client.mustache", "examples", "client.rs"));
supportingFiles.add(new SupportingFile("example-server_lib.mustache", "examples/server_lib", "mod.rs"));
supportingFiles.add(new SupportingFile("example-ca.pem", "examples", "ca.pem"));
supportingFiles.add(new SupportingFile("example-server-chain.pem", "examples", "server-chain.pem"));
supportingFiles.add(new SupportingFile("example-server-key.pem", "examples", "server-key.pem"));
writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
}
else {
setPackageName("swagger_client");
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
}
else {
setPackageVersion("1.0.0");
}
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
additionalProperties.put("externCrateName", externCrateName);
}
public void setPackageName(String packageName) {
this.packageName = packageName;
// Also set the extern crate name, which has any '-' replace with a '_'.
this.externCrateName = packageName.replace('-', '_');
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
@Override
public String apiPackage() {
return apiPath;
}
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.swagger.codegen.CodegenType
*/
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -l flag.
*
* @return the friendly name for the generator
*/
@Override
public String getName() {
return "rust-server";
}
/**
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
*/
@Override
public String getHelp() {
return "Generates a Rust client/server library (beta) using the swagger-codegen project.";
}
@Override
public void preprocessSwagger(Swagger swagger) {
Info info = swagger.getInfo();
List versionComponents = new ArrayList(Arrays.asList(info.getVersion().split("[.]")));
if (versionComponents.size() < 1) {
versionComponents.add("1");
}
while (versionComponents.size() < 3) {
versionComponents.add("0");
}
info.setVersion(StringUtils.join(versionComponents, "."));
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "default";
}
return underscore(name);
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reseved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated
*/
@Override
public String apiFileFolder() {
return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
}
@Override
public String toModelName(String name) {
// camelize the model name
// phone_number => PhoneNumber
String camelizedName = camelize(toModelFilename(name));
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
camelizedName = "Model" + camelizedName;
LOGGER.warn(camelizedName + " (reserved word) cannot be used as model name. Renamed to " + camelizedName);
}
// model name starts with number
else if (name.matches("^\\d.*")) {
// e.g. 200Response => Model200Response (after camelize)
camelizedName = "Model" + camelizedName;
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelizedName);
}
return camelizedName;
}
@Override
public String toParamName(String name) {
// should be the same as variable name (stolen from RubyClientCodegen)
return toVarName(name);
}
@Override
public String toVarName(String name) {
String sanitizedName = super.sanitizeName(name);
// for reserved word or word starting with number, append _
if (isReservedWord(sanitizedName) || sanitizedName.matches("^\\d.*")) {
sanitizedName = escapeReservedWord(sanitizedName);
}
return underscore(sanitizedName);
}
@Override
public String toOperationId(String 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 " + camelize(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return camelize(operationId);
}
@Override
public String toModelFilename(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
}
return underscore(name);
}
@Override
public String toEnumName(CodegenProperty property) {
return sanitizeName(camelize(property.name)) + "Enum";
}
@Override
public String toEnumVarName(String value, String datatype) {
String var = null;
if (value.length() == 0) {
var = "EMPTY";
}
// for symbol, e.g. $, #
else if (getSymbolName(value) != null) {
var = getSymbolName(value).toUpperCase();
}
// number
else if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
var = varName;
}
// string
var = value.replaceAll("\\W+", "_").toUpperCase();
if (var.matches("\\d.*")) {
var = "_" + var;
} else {
var = sanitizeName(var);
}
return var;
}
@Override
public String toEnumValue(String value, String datatype) {
if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
return value;
} else {
return "\"" + escapeText(value) + "\"";
}
}
@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. PetApi.go => pet_api.go
return underscore(name);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger);
op.vendorExtensions.put("operation_id", underscore(op.operationId));
op.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase());
op.vendorExtensions.put("path", op.path.replace("{", ":").replace("}", ""));
op.vendorExtensions.put("HttpMethod", Character.toUpperCase(op.httpMethod.charAt(0)) + op.httpMethod.substring(1).toLowerCase());
op.vendorExtensions.put("httpmethod", op.httpMethod.toLowerCase());
for (CodegenParameter param : op.allParams) {
String example = null;
if (param.isString) {
if (param.dataFormat != null && param.dataFormat.equals("byte")) {
param.vendorExtensions.put("formatString", "\\\"{:?}\\\"");
example = "swagger::ByteArray(\"" + ((param.example != null) ? param.example : "") + "\".to_string().into_bytes())";
} else {
param.vendorExtensions.put("formatString", "\\\"{}\\\"");
example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()";
}
} else if (param.isPrimitiveType) {
if ((param.isByteArray) ||
(param.isBinary)) {
// Binary primitive types don't implement `Display`.
param.vendorExtensions.put("formatString", "{:?}");
example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))";
} else {
param.vendorExtensions.put("formatString", "{}");
example = (param.example != null) ? param.example : "";
}
} else if (param.isListContainer) {
param.vendorExtensions.put("formatString", "{:?}");
example = (param.example != null) ? param.example : "&Vec::new()";
} else if (param.isFile) {
param.vendorExtensions.put("formatString", "{:?}");
op.vendorExtensions.put("hasFile", true);
additionalProperties.put("apiHasFile", true);
example = "Box::new(stream::once(Ok(b\"hello\".to_vec()))) as Box<Stream<Item=_, Error=_> + Send>";
} else {
param.vendorExtensions.put("formatString", "{:?}");
if (param.example != null) {
example = "serde_json::from_str::<" + param.dataType + ">(\"" + param.example + "\").expect(\"Failed to parse JSON example\")";
}
}
if (param.required) {
if (example != null) {
param.vendorExtensions.put("example", example);
} else if (param.isListContainer) {
// Use the empty list if we don't have an example
param.vendorExtensions.put("example", "&Vec::new()");
}
else {
// If we don't have an example that we can provide, we need to disable the client example, as it won't build.
param.vendorExtensions.put("example", "???");
op.vendorExtensions.put("noClientExample", Boolean.TRUE);
}
} else if ((param.dataFormat != null)&&((param.dataFormat.equals("date-time")) || (param.dataFormat.equals("date")))) {
param.vendorExtensions.put("formatString", "{:?}");
param.vendorExtensions.put("example", "None");
} else {
// Not required, so override the format string and example
param.vendorExtensions.put("formatString", "{:?}");
if (param.isFile) {
// Optional file types are wrapped in a future
param.vendorExtensions.put("example", (example != null) ? "Box::new(future::ok(Some(" + example + "))) as Box<Future<Item=_, Error=_> + Send>" : "None");
} else {
param.vendorExtensions.put("example", (example != null) ? "Some(" + example + ")" : "None");
}
}
}
List<String> consumes = new ArrayList<String>();
if (operation.getConsumes() != null) {
if (operation.getConsumes().size() > 0) {
// use consumes defined in the operation
consumes = operation.getConsumes();
}
} else if (swagger != null && swagger.getConsumes() != null && swagger.getConsumes().size() > 0) {
// use consumes defined globally
consumes = swagger.getConsumes();
LOGGER.debug("No consumes defined in operation. Using global consumes (" + swagger.getConsumes() + ") for " + op.operationId);
}
boolean consumesXml = false;
// if "consumes" is defined (per operation or using global definition)
if (consumes != null && !consumes.isEmpty()) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
for (String key : consumes) {
Map<String, String> mediaType = new HashMap<String, String>();
String mimeType = processMimeType(key);
if (mimeType.startsWith("Application/Xml")) {
additionalProperties.put("usesXml", true);
consumesXml = true;
}
mediaType.put("mediaType", mimeType);
c.add(mediaType);
}
op.consumes = c;
op.hasConsumes = true;
}
List<String> produces = new ArrayList<String>();
if (operation.getProduces() != null) {
if (operation.getProduces().size() > 0) {
// use produces defined in the operation
produces = operation.getProduces();
}
} else if (swagger != null && swagger.getProduces() != null && swagger.getProduces().size() > 0) {
// use produces defined globally
produces = swagger.getProduces();
LOGGER.debug("No produces defined in operation. Using global produces (" + swagger.getProduces() + ") for " + op.operationId);
}
boolean producesXml = false;
if (produces != null && !produces.isEmpty()) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
for (String key : produces) {
Map<String, String> mediaType = new HashMap<String, String>();
String mimeType = processMimeType(key);
if (mimeType.startsWith("Application/Xml")) {
additionalProperties.put("usesXml", true);
producesXml = true;
}
mediaType.put("mediaType", mimeType);
c.add(mediaType);
}
op.produces = c;
op.hasProduces = true;
}
if (op.bodyParam != null) {
if (paramHasXmlNamespace(op.bodyParam, definitions)){
op.bodyParam.vendorExtensions.put("has_namespace", "true");
}
for (String key : definitions.keySet()) {
op.bodyParam.vendorExtensions.put("model_key", key);
}
op.bodyParam.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase());
if (consumesXml) {
op.bodyParam.vendorExtensions.put("consumesXml", true);
}
}
for (CodegenParameter param : op.bodyParams) {
if (paramHasXmlNamespace(param, definitions)){
param.vendorExtensions.put("has_namespace", "true");
}
param.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase());
if (consumesXml) {
param.vendorExtensions.put("consumesXml", true);
}
}
for (CodegenParameter param : op.headerParams) {
// Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property.
param.vendorExtensions.put("typeName", toModelName(param.baseName));
}
for (CodegenResponse rsp : op.responses) {
rsp.message = camelize(rsp.message.split("[^A-Za-z ]")[0].replace(" ", "_"));
rsp.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase());
rsp.vendorExtensions.put("uppercase_message", underscore(rsp.message).toUpperCase());
if (rsp.dataType != null) {
rsp.vendorExtensions.put("uppercase_data_type", (rsp.dataType.replace("models::", "")).toUpperCase());
if (producesXml) {
rsp.vendorExtensions.put("producesXml", true);
}
// Check whether we're returning an object with a defined XML namespace.
Object property = rsp.schema;
if ((property != null) && (property instanceof RefProperty)){
RefProperty refProperty = (RefProperty) property;
String refName = refProperty.get$ref();
if (refName.indexOf("#/definitions/") == 0) {
refName = refName.substring("#/definitions/".length());
}
Model model = definitions.get(refName);
if ((model != null) && (model instanceof ModelImpl)) {
Xml xml = ((ModelImpl) model).getXml();
if ((xml != null) && (xml.getNamespace() != null)){
rsp.vendorExtensions.put("has_namespace", "true");
}
}
}
}
for (CodegenProperty header : rsp.headers) {
header.nameInCamelCase = toModelName(header.baseName);
}
}
for (CodegenProperty header : op.responseHeaders) {
header.nameInCamelCase = toModelName(header.baseName);
}
return op;
}
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && dataType.equals(typeMapping.get("File").toString());
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
String innerType = getTypeDeclaration(inner);
StringBuilder typeDeclaration = new StringBuilder(typeMapping.get("array")).append("<");
if (inner instanceof RefProperty) {
typeDeclaration.append("models::");
}
typeDeclaration.append(innerType).append(">");
return typeDeclaration.toString();
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
String innerType = getTypeDeclaration(inner);
StringBuilder typeDeclaration = new StringBuilder(typeMapping.get("map")).append("<").append(typeMapping.get("string")).append(", ");
if (inner instanceof RefProperty) {
typeDeclaration.append("models::");
}
typeDeclaration.append(innerType).append(">");
return typeDeclaration.toString();
} else if (p instanceof RefProperty) {
String datatype;
try {
RefProperty r = (RefProperty) p;
datatype = r.get$ref();
if (datatype.indexOf("#/definitions/") == 0) {
datatype = toModelName(datatype.substring("#/definitions/".length()));
}
} catch (Exception e) {
LOGGER.warn("Error obtaining the datatype from RefProperty:" + p + ". Datatype default to Object");
datatype = "Object";
LOGGER.error(e.getMessage(), e);
}
return datatype;
} else if (p instanceof FileProperty) {
return typeMapping.get("File").toString();
}
return super.getTypeDeclaration(p);
}
@Override
public CodegenParameter fromParameter(Parameter param, Set<String> imports) {
CodegenParameter parameter = super.fromParameter(param, imports);
if(param instanceof BodyParameter) {
BodyParameter bp = (BodyParameter) param;
Model model = bp.getSchema();
if (model instanceof RefModel) {
String name = ((RefModel) model).getSimpleRef();
name = toModelName(name);
// We need to be able to look up the model in the model definitions later.
parameter.vendorExtensions.put("uppercase_data_type", name.toUpperCase());
name = "models::" + getTypeDeclaration(name);
parameter.baseType = name;
parameter.dataType = name;
String refName = ((RefModel) model).get$ref();
if (refName.indexOf("#/definitions/") == 0) {
refName = refName.substring("#/definitions/".length());
}
parameter.vendorExtensions.put("refName", refName);
} else if (model instanceof ModelImpl) {
parameter.vendorExtensions.put("refName", ((ModelImpl) model).getName());
}
}
return parameter;
}
@Override
public CodegenProperty fromProperty(String name, Property p) {
CodegenProperty property = super.fromProperty(name, p);
if (p instanceof RefProperty) {
property.datatype = "models::" + property.datatype;
}
return property;
}
@Override
public String toInstantiationType(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return instantiationTypes.get("array") + "<" + getSwaggerType(inner) + ">";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSwaggerType(inner) + ">";
} else {
return null;
}
}
@Override
public CodegenModel fromModel(String name, Model model) {
return fromModel(name, model, null);
}
@Override
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel mdl = super.fromModel(name, model, allDefinitions);
mdl.vendorExtensions.put("upperCaseName", name.toUpperCase());
if (model instanceof ModelImpl) {
ModelImpl modelImpl = (ModelImpl) model;
mdl.dataType = typeMapping.get(modelImpl.getType());
}
if (model instanceof ArrayModel) {
ArrayModel am = (ArrayModel) model;
if ((am.getItems() != null) &&
(am.getItems().getXml() != null)){
// If this model's items require wrapping in xml, squirrel
// away the xml name so we can insert it into the relevant model fields.
String xmlName = am.getItems().getXml().getName();
if (xmlName != null) {
mdl.vendorExtensions.put("itemXmlName", xmlName);
modelXmlNames.put("models::" + mdl.classname, xmlName);
}
}
mdl.arrayModelType = toModelName(mdl.arrayModelType);
}
if (mdl.xmlNamespace != null) {
additionalProperties.put("usesXmlNamespaces", true);
}
return mdl;
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs){
Map<String, Object> newObjs = super.postProcessAllModels(objs);
//Index all CodegenModels by model name.
HashMap<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
}
}
for (Entry<String, CodegenModel> entry : allModels.entrySet()){
String modelName = entry.getKey();
CodegenModel model = entry.getValue();
for(CodegenProperty prop : model.vars){
String xmlName = modelXmlNames.get(prop.datatype);
if (xmlName != null){
prop.vendorExtensions.put("itemXmlName", xmlName);
}
}
}
return newObjs;
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Swagger swagger = (Swagger)objs.get("swagger");
if(swagger != null) {
try {
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
} catch (JsonProcessingException e) {
LOGGER.error(e.getMessage(), e);
}
}
return super.postProcessSupportingFileData(objs);
}
@Override
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
StringProperty dp = (StringProperty) p;
if (dp.getDefault() != null) {
return "\"" + dp.getDefault() + "\".to_string()";
}
} else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p;
if (dp.getDefault() != null) {
if (dp.getDefault().toString().equalsIgnoreCase("false"))
return "false";
else
return "true";
}
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
}
return null;
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
if(!languageSpecificPrimitives.contains(property.datatype)) {
// If we use a more qualified model name, then only camelize the actual type, not the qualifier.
if(property.datatype.contains(":")) {
int position = property.datatype.lastIndexOf(":");
property.datatype = property.datatype.substring(0, position) + camelize(property.datatype.substring(position));
} else {
property.datatype = camelize(property.datatype, false);
}
}
// Handle custom unsigned integer formats.
if ("integer".equals(property.baseType)) {
if ("uint32".equals(property.dataFormat)) {
property.datatype = "u32";
} else if ("uint64".equals(property.dataFormat)) {
property.datatype = "u64";
}
}
property.name = underscore(property.name);
if (!property.required) {
property.defaultValue = (property.defaultValue != null) ? "Some(" + property.defaultValue + ")" : "None";
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return super.postProcessModelsEnum(objs);
}
private boolean paramHasXmlNamespace(CodegenParameter param, Map<String, Model> definitions){
Object refName = param.vendorExtensions.get("refName");
if ((refName != null) && (refName instanceof String)) {
String name = (String) refName;
Model model = definitions.get(name);
if ((model != null) && (model instanceof ModelImpl)) {
Xml xml = ((ModelImpl) model).getXml();
if ((xml != null) && (xml.getNamespace() != null)) {
return true;
}
}
}
return false;
}
private String processMimeType(String mimeType){
// Transform mime type into a form that the hyper mime! macro can handle.
String result = "";
String[] split_attributes = mimeType.split(";");
String media = split_attributes[0];
String[] mediaTypes = media.split("/");
if (mediaTypes.length == 2) {
if (mediaTypes[0].equals("*")){
result += "Star";
} else {
result += escapeText(escapeQuotationMark(initialCaps(mediaTypes[0])));
}
result += "/";
if (mediaTypes[1].equals("*")) {
result += "Star";
} else {
result += escapeText(escapeQuotationMark(initialCaps(mediaTypes[1])));
}
} else {
LOGGER.error("Failed to parse media type: "
+ mimeType
+ ", media types should have exactly one /");
}
if (split_attributes.length == 2) {
String attributes = "";
String[] attrs = split_attributes[1].split(",");
for (String attr : attrs) {
String[] keyValuePair =attr.split("=");
if (keyValuePair.length == 2) {
attributes += "(\""
+ escapeText(escapeQuotationMark(keyValuePair[0].trim()))
+ "\")=(\""
+ escapeText(escapeQuotationMark(keyValuePair[1].trim()))
+ "\")";
} else {
LOGGER.error("Failed to parse parameter attributes: "
+ split_attributes[1]
+ ", attributes must be a comma separated list of 'key=value' pairs");
}
}
result += "; " + attributes;
}
return result;
}
}

View File

@ -246,8 +246,6 @@ public class SpringCodegen extends AbstractJavaCodegen
additionalProperties.put(SINGLE_CONTENT_TYPES, "true");
this.setSingleContentTypes(true);
}
additionalProperties.put("useSpringCloudClient", true);
} else {
apiTemplateFiles.put("apiController.mustache", "Controller.java");
supportingFiles.add(new SupportingFile("apiException.mustache",

View File

@ -32,7 +32,9 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
protected String bundleExtensionName;
protected String bundleAlias;
protected String controllerDirName = "Controller";
protected String serviceDirName = "Service";
protected String controllerPackage;
protected String servicePackage;
protected Boolean phpLegacySupport = Boolean.TRUE;
protected HashSet<String> typeHintable;
@ -74,7 +76,9 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
modelDocPath = docsBasePath + File.separator + modelDirName;
outputFolder = "generated-code" + File.separator + "php";
apiTemplateFiles.put("api_controller.mustache", ".php");
modelTestTemplateFiles.put("model_test.mustache", ".php");
modelTestTemplateFiles.put("testing/model_test.mustache", ".php");
apiTestTemplateFiles = new HashMap<String, String>();
apiTestTemplateFiles.put("testing/api_test.mustache", ".php");
embeddedTemplateDir = templateDir = "php-symfony";
setReservedWordsLowerCase(
@ -105,13 +109,10 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
)
);
//instantiationTypes.put("array", "array");
//instantiationTypes.put("map", "map");
defaultIncludes = new HashSet<String>(
Arrays.asList(
"\\DateTime",
"\\SplFileObject"
"UploadedFile"
)
);
@ -135,7 +136,7 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
typeMapping.put("boolean", "bool");
typeMapping.put("Date", "\\DateTime");
typeMapping.put("DateTime", "\\DateTime");
typeMapping.put("file", "\\SplFileObject");
typeMapping.put("file", "UploadedFile");
typeMapping.put("map", "array");
typeMapping.put("array", "array");
typeMapping.put("list", "array");
@ -242,6 +243,7 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
additionalProperties.put("controllerPackage", controllerPackage);
additionalProperties.put("servicePackage", servicePackage);
additionalProperties.put("apiTestsPackage", apiTestsPackage);
additionalProperties.put("modelTestsPackage", modelTestsPackage);
@ -275,14 +277,28 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
supportingFiles.add(new SupportingFile("Extension.mustache", dependencyInjectionDir, bundleExtensionName + ".php"));
supportingFiles.add(new SupportingFile("ApiPass.mustache", dependencyInjectionDir + File.separator + "Compiler", bundleName + "ApiPass.php"));
supportingFiles.add(new SupportingFile("ApiServer.mustache", toPackagePath(apiPackage, srcBasePath), "ApiServer.php"));
supportingFiles.add(new SupportingFile("ModelSerializer.mustache", toPackagePath(modelPackage, srcBasePath), "ModelSerializer.php"));
supportingFiles.add(new SupportingFile("ModelInterface.mustache", toPackagePath(modelPackage, srcBasePath), "ModelInterface.php"));
// Serialization components
supportingFiles.add(new SupportingFile("serialization/SerializerInterface.mustache", toPackagePath(servicePackage, srcBasePath), "SerializerInterface.php"));
supportingFiles.add(new SupportingFile("serialization/JmsSerializer.mustache", toPackagePath(servicePackage, srcBasePath), "JmsSerializer.php"));
supportingFiles.add(new SupportingFile("serialization/StrictJsonDeserializationVisitor.mustache", toPackagePath(servicePackage, srcBasePath), "StrictJsonDeserializationVisitor.php"));
supportingFiles.add(new SupportingFile("serialization/TypeMismatchException.mustache", toPackagePath(servicePackage, srcBasePath), "TypeMismatchException.php"));
// Validation components
supportingFiles.add(new SupportingFile("validation/ValidatorInterface.mustache", toPackagePath(servicePackage, srcBasePath), "ValidatorInterface.php"));
supportingFiles.add(new SupportingFile("validation/SymfonyValidator.mustache", toPackagePath(servicePackage, srcBasePath), "SymfonyValidator.php"));
// Testing components
supportingFiles.add(new SupportingFile("testing/phpunit.xml.mustache", getPackagePath(), "phpunit.xml.dist"));
supportingFiles.add(new SupportingFile("testing/pom.xml", getPackagePath(), "pom.xml"));
supportingFiles.add(new SupportingFile("testing/AppKernel.php", toPackagePath(testsPackage, srcBasePath), "AppKernel.php"));
supportingFiles.add(new SupportingFile("testing/test_config.yml", toPackagePath(testsPackage, srcBasePath), "test_config.yml"));
supportingFiles.add(new SupportingFile("routing.mustache", configDir, "routing.yml"));
supportingFiles.add(new SupportingFile("services.mustache", configDir, "services.yml"));
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
supportingFiles.add(new SupportingFile("README.mustache", getPackagePath(), "README.md"));
supportingFiles.add(new SupportingFile("phpunit.xml.mustache", getPackagePath(), "phpunit.xml.dist"));
supportingFiles.add(new SupportingFile(".travis.yml", getPackagePath(), ".travis.yml"));
supportingFiles.add(new SupportingFile(".php_cs", getPackagePath(), ".php_cs"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", getPackagePath(), "git_push.sh"));
@ -329,6 +345,14 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
if (!typeHint.isEmpty()) {
param.vendorExtensions.put("x-parameterType", typeHint);
}
// Quote default values for strings
// @todo: The default values for headers, forms and query params are handled
// in DefaultCodegen fromParameter with no real possibility to override
// the functionality. Thus we are handling quoting of string values here
if (param.dataType.equals("string") && param.defaultValue != null && !param.defaultValue.isEmpty()) {
param.defaultValue = "'"+param.defaultValue+"'";
}
}
for (CodegenResponse response : op.responses) {
@ -340,9 +364,6 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
if (response.dataType != null) {
final String dataType = extractSimpleName(response.dataType);
response.vendorExtensions.put("x-simpleName", dataType);
// if (!typeMapping.containsValue(dataType)) {
// imports.add(response.dataType.replaceFirst("\\[\\]$", ""));
// }
}
}
@ -364,19 +385,15 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
ArrayList<Object> modelsArray = (ArrayList<Object>) objs.get("models");
Map<String, Object> models = (Map<String, Object>) modelsArray.get(0);
CodegenModel model = (CodegenModel) models.get("model");
HashSet<String> imports = new HashSet<>();
// Simplify model var type
for (CodegenProperty var : model.vars) {
if (var.datatype != null) {
final String importType = var.datatype.replaceFirst("\\[\\]$", "");
final String dataType = extractSimpleName(var.datatype);
final boolean isScalarType = typeMapping.containsValue(importType);
var.vendorExtensions.put("x-fullType", var.datatype);
if (!isScalarType) {
var.vendorExtensions.put("x-typeAnnotation", dataType.endsWith("[]") ? "array" : dataType);
imports.add(importType);
var.datatype = dataType;
// Determine if the paramter type is supported as a type hint and make it available
// to the templating engine
String typeHint = getTypeHint(var.datatype);
if (!typeHint.isEmpty()) {
var.vendorExtensions.put("x-parameterType", typeHint);
}
if (var.isBoolean) {
@ -385,8 +402,6 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
}
}
objs.put("useStatements", new ArrayList<>(imports));
return objs;
}
@ -425,6 +440,7 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
apiTestsPackage = testsPackage + "\\" + apiDirName;
modelTestsPackage = testsPackage + "\\" + modelDirName;
controllerPackage = invokerPackage + "\\" + controllerDirName;
servicePackage = invokerPackage + "\\" + serviceDirName;
}
@Override
@ -485,6 +501,26 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC
}
}
@Override
public String toEnumValue(String value, String datatype) {
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
return value;
} else {
return "\"" + escapeText(value) + "\"";
}
}
/**
* Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33)
*
* @param pattern the pattern (regular expression)
* @return properly-escaped pattern
*/
@Override
public String toRegularExpression(String pattern) {
return escapeText(pattern);
}
public String toApiName(String name) {
if (name.isEmpty()) {
return "DefaultApiInterface";

View File

@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import java.io.File;
import java.lang.StringBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -82,7 +83,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
supportingFiles.add(new SupportingFile("apis.mustache", apiPackage().replace('.', File.separatorChar), "api.ts"));
supportingFiles.add(new SupportingFile("index.mustache", getIndexDirectory(), "index.ts"));
supportingFiles.add(new SupportingFile("api.module.mustache", getIndexDirectory(), "api.module.ts"));
supportingFiles.add(new SupportingFile("rxjs-operators.mustache", getIndexDirectory(), "rxjs-operators.ts"));
supportingFiles.add(new SupportingFile("rxjs-operators.mustache", getIndexDirectory(), "rxjs-operators.ts"));
supportingFiles.add(new SupportingFile("configuration.mustache", getIndexDirectory(), "configuration.ts"));
supportingFiles.add(new SupportingFile("variables.mustache", getIndexDirectory(), "variables.ts"));
supportingFiles.add(new SupportingFile("encoder.mustache", getIndexDirectory(), "encoder.ts"));
@ -149,7 +150,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
public boolean isDataTypeFile(final String dataType) {
return dataType != null && dataType.equals("Blob");
}
@Override
public String getTypeDeclaration(Property p) {
Property inner;
@ -247,8 +248,54 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
}
}
// Convert path to TypeScript template string, applying URI encoding
op.path = op.path.replaceAll("\\{(.*?)\\}", "\\$\\{encodeURIComponent(String($1))\\}");
// Prep a string buffer where we're going to set up our new version of the string.
StringBuffer pathBuffer = new StringBuffer();
// Set up other variables for tracking the current state of the string.
int insideCurly = 0;
boolean foundUnderscore = false;
// Iterate through existing string, one character at a time.
for(int i = 0; i < op.path.length(); i++) {
switch(op.path.charAt(i)) {
case '{':
// We entered curly braces, so track that.
insideCurly++;
// Add the more complicated component instead of just the brace.
pathBuffer.append("${encodeURIComponent(String(");
break;
case '}':
// We exited curly braces, so track that.
insideCurly--;
// Add the more complicated component instead of just the brace.
pathBuffer.append("))}");
break;
case '_':
// If we're inside the curly brace, the following character will need to be uppercase.
// Otherwise, just add the character.
if (insideCurly > 0) {
foundUnderscore = true;
} else {
pathBuffer.append(op.path.charAt(i));
}
break;
default:
// If we previously found an underscore, we need an uppercase letter.
// Otherwise, just add the character.
if (foundUnderscore) {
pathBuffer.append(Character.toUpperCase(op.path.charAt(i)));
foundUnderscore = false;
} else {
pathBuffer.append(op.path.charAt(i));
}
break;
}
}
// Overwrite path to TypeScript template string, after applying everything we just did.
op.path = pathBuffer.toString();
}
// Add additional filename information for model imports in the services
@ -272,7 +319,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
CodegenModel cm = (CodegenModel) mo.get("model");
mo.put("tsImports", toTsImports(cm,cm.imports));
}
return result;
}

View File

@ -51,6 +51,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
supportingFiles.add(new SupportingFile("index.mustache", "", "index.ts"));
supportingFiles.add(new SupportingFile("api.mustache", "", "api.ts"));
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.ts"));
supportingFiles.add(new SupportingFile("custom.d.mustache", "", "custom.d.ts"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));

View File

@ -53,13 +53,16 @@ public class {{classname}} {
{{/returnType}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @Deprecated
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}

View File

@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git

View File

@ -0,0 +1,112 @@
package {{invokerPackage}};
import {{apiPackage}}.*;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
{{#joda}}
import com.fasterxml.jackson.datatype.joda.JodaModule;
{{/joda}}
{{#java8}}
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
{{/java8}}
{{#threetenbp}}
import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
{{/threetenbp}}
{{#threetenbp}}
import org.threeten.bp.*;
{{/threetenbp}}
import com.google.api.client.googleapis.util.Utils;
import com.google.api.client.http.AbstractHttpContent;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.Json;
import java.io.IOException;
import java.io.OutputStream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
{{>generatedAnnotation}}
public class ApiClient {
private final String basePath;
private final HttpRequestFactory httpRequestFactory;
private final ObjectMapper objectMapper;
private static final String defaultBasePath = "{{basePath}}";
// A reasonable default object mapper. Client can pass in a chosen ObjectMapper anyway, this is just for reasonable defaults.
private static ObjectMapper createDefaultObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setDateFormat(new RFC3339DateFormat());
{{#joda}}
objectMapper.registerModule(new JodaModule());
{{/joda}}
{{#java8}}
objectMapper.registerModule(new JavaTimeModule());
{{/java8}}
{{#threetenbp}}
ThreeTenModule module = new ThreeTenModule();
module.addDeserializer(Instant.class, CustomInstantDeserializer.INSTANT);
module.addDeserializer(OffsetDateTime.class, CustomInstantDeserializer.OFFSET_DATE_TIME);
module.addDeserializer(ZonedDateTime.class, CustomInstantDeserializer.ZONED_DATE_TIME);
objectMapper.registerModule(module);
{{/threetenbp}}
return objectMapper;
}
public ApiClient() {
this(null, null, null, null);
}
public ApiClient(
String basePath,
HttpTransport httpTransport,
HttpRequestInitializer initializer,
ObjectMapper objectMapper
) {
this.basePath = basePath == null ? defaultBasePath : (
basePath.endsWith("/") ? basePath.substring(0, basePath.length() - 1) : basePath
);
this.httpRequestFactory = (httpTransport == null ? Utils.getDefaultTransport() : httpTransport).createRequestFactory(initializer);
this.objectMapper = (objectMapper == null ? createDefaultObjectMapper() : objectMapper);
}
public HttpRequestFactory getHttpRequestFactory() {
return httpRequestFactory;
}
public String getBasePath() {
return basePath;
}
public ObjectMapper getObjectMapper() {
return objectMapper;
}
public class JacksonJsonHttpContent extends AbstractHttpContent {
/* A POJO that can be serialized with a com.fasterxml Jackson ObjectMapper */
private final Object data;
public JacksonJsonHttpContent(Object data) {
super(Json.MEDIA_TYPE);
this.data = data;
}
@Override
public void writeTo(OutputStream out) throws IOException {
objectMapper.writeValue(out, data);
}
}
// Builder pattern to get API instances for this client.
{{#apiInfo}}{{#apis}}
public {{classname}} {{classVarName}}Api() {
return new {{classname}}(this);
}
{{/apis}}{{/apiInfo}}
}

View File

@ -0,0 +1,152 @@
package {{package}};
import {{invokerPackage}}.ApiClient;
{{#imports}}import {{import}};
{{/imports}}
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpMethods;
import com.google.api.client.http.HttpResponse;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
private ApiClient {{localVariablePrefix}}apiClient;
public {{classname}}() {
this(new ApiClient());
}
public {{classname}}(ApiClient apiClient) {
this.{{localVariablePrefix}}apiClient = apiClient;
}
public ApiClient getApiClient() {
return {{localVariablePrefix}}apiClient;
}
public void setApiClient(ApiClient apiClient) {
this.{{localVariablePrefix}}apiClient = apiClient;
}
{{#operation}}
/**{{#summary}}
* {{summary}}{{/summary}}{{#notes}}
* {{notes}}{{/notes}}{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{message}}{{/message}}{{/responses}}{{#allParams}}
* @param {{paramName}} {{description}}{{^description}}The {{paramName}} parameter{{/description}}{{/allParams}}{{#returnType}}
* @return {{returnType}}{{/returnType}}
* @throws IOException if an error occurs while attempting to invoke the API{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
**/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws IOException {
{{#returnType}}HttpResponse response = {{/returnType}}{{operationId}}ForHttpResponse({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
TypeReference typeRef = new TypeReference<{{{returnType}}}>() {};
return apiClient.getObjectMapper().readValue(response.getContent(), typeRef);{{/returnType}}
}
/**{{#summary}}
* {{summary}}{{/summary}}{{#notes}}
* {{notes}}{{/notes}}{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{message}}{{/message}}{{/responses}}{{#requiredParams}}
* @param {{paramName}} {{description}}{{^description}}The {{paramName}} parameter{{/description}}{{/requiredParams}}
* @param params Map of query params. A collection will be interpreted as passing in multiple instances of the same query param.{{#returnType}}
* @return {{returnType}}{{/returnType}}
* @throws IOException if an error occurs while attempting to invoke the API{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
**/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#requiredParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}{{#hasRequiredParams}}, {{/hasRequiredParams}}Map<String, Object> params) throws IOException {
{{#returnType}}HttpResponse response = {{/returnType}}{{operationId}}ForHttpResponse({{#requiredParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}{{#hasRequiredParams}}, {{/hasRequiredParams}}params);{{#returnType}}
TypeReference typeRef = new TypeReference<{{{returnType}}}>() {};
return apiClient.getObjectMapper().readValue(response.getContent(), typeRef);{{/returnType}}
}
public HttpResponse {{operationId}}ForHttpResponse({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws IOException {
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
throw new IllegalArgumentException("Missing the required parameter '{{paramName}}' when calling {{operationId}}");
}
{{/required}}{{/allParams}}
{{#hasPathParams}}
// create a map of path variables
final Map<String, Object> uriVariables = new HashMap<String, Object>();{{#pathParams}}
uriVariables.put("{{baseName}}", {{{paramName}}});{{/pathParams}}
{{/hasPathParams}}
UriBuilder uriBuilder = UriBuilder.fromUri(apiClient.getBasePath() + "{{{path}}}");{{#hasQueryParams}}
{{#queryParams}}if ({{paramName}} != null) {
uriBuilder = uriBuilder.queryParam("{{baseName}}", {{paramName}});
}{{#hasMore}}{{/hasMore}}{{/queryParams}}{{/hasQueryParams}}
String url = uriBuilder{{#hasPathParams}}.buildFromMap(uriVariables).toString();{{/hasPathParams}}{{^hasPathParams}}.build().toString();{{/hasPathParams}}
GenericUrl genericUrl = new GenericUrl(url);
HttpContent content = postBody == null ? null : apiClient.new JacksonJsonHttpContent(postBody);
return apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content).execute();
}
public HttpResponse {{operationId}}ForHttpResponse({{#requiredParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}{{#hasRequiredParams}}, {{/hasRequiredParams}}Map<String, Object> params) throws IOException {
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
throw new IllegalArgumentException("Missing the required parameter '{{paramName}}' when calling {{operationId}}");
}
{{/required}}{{/allParams}}
{{#hasPathParams}}
// create a map of path variables
final Map<String, Object> uriVariables = new HashMap<String, Object>();{{#pathParams}}
uriVariables.put("{{baseName}}", {{{paramName}}});{{/pathParams}}
{{/hasPathParams}}
UriBuilder uriBuilder = UriBuilder.fromUri(apiClient.getBasePath() + "{{{path}}}");
if (params == null) {
params = new HashMap<String, Object>();
}{{#queryParams}}{{#required}}
// Add the required query param '{{paramName}}' to the map of query params
params.put("{{paramName}}", {{paramName}});{{/required}}{{/queryParams}}
for (Map.Entry<String, Object> entry: params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (key != null && value != null) {
if (value instanceof Collection) {
uriBuilder = uriBuilder.queryParam(key, ((Collection) value).toArray());
} else {
uriBuilder = uriBuilder.queryParam(key, value);
}
}
}
String url = uriBuilder{{#hasPathParams}}.buildFromMap(uriVariables).toString();{{/hasPathParams}}{{^hasPathParams}}.build().toString();{{/hasPathParams}}
GenericUrl genericUrl = new GenericUrl(url);
HttpContent content = postBody == null ? null : apiClient.new JacksonJsonHttpContent(postBody);
return apiClient.getHttpRequestFactory().buildRequest(HttpMethods.{{httpMethod}}, genericUrl, content).execute();
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,45 @@
{{>licenseInfo}}
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Test;
import org.junit.Ignore;
import java.io.IOException;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
/**
* API tests for {{classname}}
*/
@Ignore
public class {{classname}}Test {
private final {{classname}} api = new {{classname}}();
{{#operations}}{{#operation}}
/**
* {{summary}}
*
* {{notes}}
*
* @throws IOException
* if the Api call fails
*/
@Test
public void {{operationId}}Test() throws IOException {
{{#allParams}}
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
{{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
// TODO: test validations
}
{{/operation}}{{/operations}}
}

View File

@ -0,0 +1,142 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}'
version = '{{artifactVersion}}'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.+'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
}
}
repositories {
jcenter()
}
if(hasProperty('target') && target == 'android') {
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
}
compileOptions {
{{#java8}}
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
{{/java8}}
{{^java8}}
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
{{/java8}}
}
// Rename the aar correctly
libraryVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.aar')) {
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
dependencies {
provided 'javax.annotation:jsr250-api:1.0'
}
}
afterEvaluate {
android.libraryVariants.all { variant ->
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
task.description = "Create jar artifact for ${variant.name}"
task.dependsOn variant.javaCompile
task.from variant.javaCompile.destinationDir
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
artifacts.add('archives', task);
}
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
} else {
apply plugin: 'java'
apply plugin: 'maven'
{{#java8}}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
{{/java8}}
{{^java8}}
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
{{/java8}}
install {
repositories.mavenInstaller {
pom.artifactId = '{{artifactId}}'
}
}
task execute(type:JavaExec) {
main = System.getProperty('mainClass')
classpath = sourceSets.main.runtimeClasspath
}
}
ext {
swagger_annotations_version = "1.5.15"
jackson_version = "2.8.9"
google_api_client_version = "1.23.0"
jersey_common_version = "2.25.1"
jodatime_version = "2.9.9"
junit_version = "4.12"
{{#threetenbp}}
jackson_threeten_version = "2.6.4"
{{/threetenbp}}
}
dependencies {
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
compile "com.google.api-client:google-api-client:${google_api_client_version}"
compile "org.glassfish.jersey.core:jersey-common:${jersey_common_version}"
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version"
{{#java8}}
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
{{/java8}}
{{#joda}}
compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version"
compile "joda-time:joda-time:$jodatime_version"
{{/joda}}
{{#threetenbp}}
compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_threeten_version"
{{/threetenbp}}
{{#withXml}}
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jackson_version"
{{/withXml}}
testCompile "junit:junit:$junit_version"
}

View File

@ -0,0 +1,33 @@
lazy val root = (project in file(".")).
settings(
organization := "{{groupId}}",
name := "{{artifactId}}",
version := "{{artifactVersion}}",
scalaVersion := "2.11.4",
scalacOptions ++= Seq("-feature"),
javacOptions in compile ++= Seq("-Xlint:deprecation"),
publishArtifact in (Compile, packageDoc) := false,
resolvers += Resolver.mavenLocal,
libraryDependencies ++= Seq(
"io.swagger" % "swagger-annotations" % "1.5.15",
"com.google.api-client" % "google-api-client" % "1.23.0",
"org.glassfish.jersey.core" % "jersey-common" % "2.25.1",
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.9" % "compile",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.9" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.9" % "compile",
{{#withXml}}
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-xml" % "2.8.9" % "compile",
{{/withXml}}
{{#joda}}
"com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.8.9" % "compile",
{{/joda}}
{{#java8}}
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.8.9" % "compile",
{{/java8}}
{{#threetenbp}}
"com.github.joschi.jackson" % "jackson-datatype-threetenbp" % "2.6.4" % "compile",
{{/threetenbp}}
"junit" % "junit" % "4.12" % "test",
"com.novocode" % "junit-interface" % "0.10" % "test"
)
)

View File

@ -0,0 +1,278 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<scm>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<systemProperties>
<property>
<name>loggerPath</name>
<value>conf/log4j.properties</value>
</property>
</systemProperties>
<argLine>-Xms512m -Xmx1500m</argLine>
<parallel>methods</parallel>
<forkMode>pertest</forkMode>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- attach test jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<id>add_sources</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add_test_sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
{{#java8}}
<source>1.8</source>
<target>1.8</target>
{{/java8}}
{{^java8}}
<source>1.7</source>
<target>1.7</target>
{{/java8}}
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
<!-- HTTP client: google-api-client -->
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>${google-api-client-version}</version>
</dependency>
<!-- Jersey common to get an implementation of javax.ws.rs.core.UriBuilder for building URLs from templates -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>${jersey-common-version}</version>
</dependency>
<!-- JSON processing: jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
{{#withXml}}
<!-- XML processing: Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson-version}</version>
</dependency>
{{/withXml}}
{{#java8}}
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-version}</version>
</dependency>
{{/java8}}
{{#joda}}
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime-version}</version>
</dependency>
{{/joda}}
{{#threetenbp}}
<dependency>
<groupId>com.github.joschi.jackson</groupId>
<artifactId>jackson-datatype-threetenbp</artifactId>
<version>${jackson-threetenbp-version}</version>
</dependency>
{{/threetenbp}}
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<swagger-annotations-version>1.5.15</swagger-annotations-version>
<google-api-client-version>1.23.0</google-api-client-version>
<jersey-common-version>2.25.1</jersey-common-version>
<jackson-version>2.8.9</jackson-version>
{{#joda}}
<jodatime-version>2.9.9</jodatime-version>
{{/joda}}
{{#threetenbp}}
<jackson-threetenbp-version>2.6.4</jackson-threetenbp-version>
{{/threetenbp}}
<maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.12</junit-version>
</properties>
</project>

View File

@ -306,6 +306,27 @@ public class ApiClient {
return this;
}
/**
* read timeout (in milliseconds).
* @return Read timeout
*/
public int getReadTimeout() {
return readTimeout;
}
/**
* Set the read timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
* @param readTimeout Read timeout in milliseconds
* @return API client
*/
public ApiClient setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
httpClient.property(ClientProperties.READ_TIMEOUT, readTimeout);
return this;
}
/**
* Get the date format used to parse/format date parameters.
* @return Date format

View File

@ -50,13 +50,16 @@ public class {{classname}} {
{{/returnType}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @Deprecated
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}

View File

@ -426,7 +426,7 @@ public class ApiClient {
}
/**
* Set the tempoaray folder path (for downloading files)
* Set the temporary folder path (for downloading files)
*
* @param tempFolderPath Temporary folder path
* @return ApiClient
@ -448,6 +448,7 @@ public class ApiClient {
/**
* Sets the connect timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
*
* @param connectionTimeout connection timeout in milliseconds
* @return Api client
@ -457,6 +458,50 @@ public class ApiClient {
return this;
}
/**
* Get read timeout (in milliseconds).
*
* @return Timeout in milliseconds
*/
public int getReadTimeout() {
return httpClient.getReadTimeout();
}
/**
* Sets the read timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
*
* @param readTimeout read timeout in milliseconds
* @return Api client
*/
public ApiClient setReadTimeout(int readTimeout) {
httpClient.setReadTimeout(readTimeout, TimeUnit.MILLISECONDS);
return this;
}
/**
* Get write timeout (in milliseconds).
*
* @return Timeout in milliseconds
*/
public int getWriteTimeout() {
return httpClient.getWriteTimeout();
}
/**
* Sets the write timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
*
* @param writeTimeout connection timeout in milliseconds
* @return Api client
*/
public ApiClient setWriteTimeout(int writeTimeout) {
httpClient.setWriteTimeout(writeTimeout, TimeUnit.MILLISECONDS);
return this;
}
/**
* Format the given parameter object into string.
*

View File

@ -70,14 +70,20 @@ public class {{classname}} {
* @param progressRequestListener Progress request listener
* @return Call to execute
* @throws ApiException If fail to serialize the request body object
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public com.squareup.okhttp.Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
// create path and map variables
String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
@ -122,7 +128,10 @@ public class {{classname}} {
String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarCollectionQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAuthNames, progressRequestListener);
}
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
@SuppressWarnings("rawtypes")
private com.squareup.okhttp.Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
{{^performBeanValidation}}
@ -132,7 +141,7 @@ public class {{classname}} {
throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{operationId}}(Async)");
}
{{/required}}{{/allParams}}
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener);
return {{localVariablePrefix}}call;
@ -150,7 +159,7 @@ public class {{classname}} {
if (violations.size() == 0) {
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener);
return {{localVariablePrefix}}call;
} else {
throw new BeanValidationException((Set) violations);
}
@ -161,12 +170,8 @@ public class {{classname}} {
e.printStackTrace();
throw new ApiException(e.getMessage());
}
{{/performBeanValidation}}
}
/**
@ -175,11 +180,17 @@ public class {{classname}} {
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}}
* @return {{returnType}}{{/returnType}}
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
{{#returnType}}ApiResponse<{{{returnType}}}> {{localVariablePrefix}}resp = {{/returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
return {{localVariablePrefix}}resp.getData();{{/returnType}}
@ -191,11 +202,17 @@ public class {{classname}} {
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
* @return ApiResponse&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}&gt;
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}null, null);
{{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType();
@ -209,11 +226,17 @@ public class {{classname}} {
* @param callback The callback to be executed when the API call finishes
* @return The request call
* @throws ApiException If fail to process the API call, e.g. serializing the request body object
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public com.squareup.okhttp.Call {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException {
ProgressResponseBody.ProgressListener progressListener = null;

View File

@ -46,13 +46,16 @@ public class {{classname}} {
* @return {{{returnType}}}{{/returnType}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @Deprecated
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}

View File

@ -22,6 +22,16 @@ import javax.validation.constraints.*;
import javax.validation.Valid;
{{/useBeanValidation}}
{{#appName}}
/**
* {{{appName}}}
*
{{#appDescription}}
* <p>{{{appDescription}}}
*
{{/appDescription}}
*/
{{/appName}}
@Path("{{^useAnnotatedBasePath}}/{{/useAnnotatedBasePath}}{{#useAnnotatedBasePath}}{{contextPath}}{{/useAnnotatedBasePath}}")
@Api(value = "/", description = "{{description}}")
{{#addConsumesProducesJson}}
@ -32,6 +42,16 @@ public interface {{classname}} {
{{#operations}}
{{#operation}}
{{#summary}}
/**
* {{summary}}
*
{{#notes}}
* {{notes}}
*
{{/notes}}
*/
{{/summary}}
@{{httpMethod}}
{{#subresourceOperation}}@Path("{{{path}}}"){{/subresourceOperation}}
{{#hasConsumes}}

View File

@ -25,9 +25,29 @@ import org.springframework.stereotype.Service;
{{/useSpringAnnotationConfig}}
{{#description}}
{{/description}}
{{#appName}}
/**
* {{{appName}}}
*
{{#appDescription}}
* <p>{{{appDescription}}}
{{/appDescription}}
*
*/
{{/appName}}
public class {{classname}}ServiceImpl implements {{classname}} {
{{#operations}}
{{#operation}}
{{#summary}}
/**
* {{summary}}
*
{{#notes}}
* {{notes}}
*
{{/notes}}
*/
{{/summary}}
public {{>returnTypes}} {{nickname}}({{#allParams}}{{>queryParamsImpl}}{{>pathParamsImpl}}{{>headerParamsImpl}}{{>bodyParamsImpl}}{{>formParamsImpl}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
// TODO: Implement...

View File

@ -42,7 +42,15 @@ import org.springframework.test.context.web.WebAppConfiguration;
/**
* API tests for {{classname}}
{{#appName}}
* {{{appName}}}
*
{{/appName}}
{{#appDescription}}
* <p>{{{appDescription}}}
*
{{/appDescription}}
* API tests for {{classname}}
*/
{{#generateSpringBootApplication}}
@RunWith(SpringJUnit4ClassRunner.class)
@ -91,10 +99,14 @@ public class {{classname}}Test {
{{#operations}}{{#operation}}
/**
{{#summary}}
* {{summary}}
*
{{#notes}}
* {{notes}}
*
{{/notes}}
{{/summary}}
* @throws ApiException
* if the Api call fails
*/

View File

@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import com.fasterxml.jackson.annotation.JsonProperty;
{{#withXml}}
@XmlAccessorType(XmlAccessType.FIELD)
@ -16,6 +17,9 @@ import javax.xml.bind.annotation.XmlEnumValue;
{{^parent}}@XmlRootElement(name="{{classname}}"){{/parent}}
{{/withXml}}
{{#description}}
/**
* {{{description}}}
**/
@ApiModel(description="{{{description}}}")
{{/description}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
@ -28,6 +32,11 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
@XmlElement(name="{{baseName}}"{{#required}}, required = {{required}}{{/required}})
{{/withXml}}
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
{{#description}}
/**
* {{{description}}}
**/
{{/description}}
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/vars}}
{{#vars}}
@ -46,12 +55,22 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{/maximum}}
* @return {{name}}
**/
@JsonProperty("{{baseName}}")
{{#vendorExtensions.extraAnnotation}}
{{{vendorExtensions.extraAnnotation}}}
{{/vendorExtensions.extraAnnotation}}
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} public {{{datatypeWithEnum}}} {{getter}}() {
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} {{#isEnum}}{{^isListContainer}}{{^isMapContainer}}public {{datatype}} {{getter}}() {
if ({{name}} == null) {
return null;
}
return {{name}}.value();
}{{/isMapContainer}}{{/isListContainer}}{{/isEnum}}{{#isEnum}}{{#isListContainer}}public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}
}{{/isListContainer}}{{/isEnum}}{{#isEnum}}{{#isMapContainer}}public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}{{/isMapContainer}}{{/isEnum}}{{^isEnum}}public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}{{/isEnum}}
{{^isReadOnly}}
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {

View File

@ -4,6 +4,9 @@
<artifactId>{{artifactId}}</artifactId>
<packaging>jar</packaging>
<name>{{artifactId}}</name>
{{#appDescription}}
<description>{{appDescription}}</description>
{{/appDescription}}
<version>{{artifactVersion}}</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>

View File

@ -4,6 +4,9 @@
<artifactId>{{artifactId}}</artifactId>
<packaging>war</packaging>
<name>{{artifactId}}</name>
{{#appDescription}}
<description>{{appDescription}}</description>
{{/appDescription}}
<version>{{artifactVersion}}</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>

View File

@ -1 +1 @@
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}} @QueryParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}}
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @QueryParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}}

View File

@ -1,5 +1,6 @@
import io.swagger.annotations.*;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
{{#description}}@ApiModel(description = "{{{description}}}"){{/description}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
@ -29,6 +30,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
{{#vendorExtensions.extraAnnotation}}{{{vendorExtensions.extraAnnotation}}}{{/vendorExtensions.extraAnnotation}}
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
@JsonProperty("{{baseName}}")
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}

View File

@ -17,6 +17,17 @@
play.filters.headers.contentSecurityPolicy=null
{{#useBeanValidation}}
# When using bean validation with the swagger api, the validator will check that every constraint is respected
# This is very useful when testing but could add a lot of overhead if you return a lot of data. Benchmark have
# shown that the time it takes to validate is exponential.
# If this is a concern in your application, or if you don't want to validate the output coming from your API for
# respecting its contract, set the "output" property below to "false". Since there is not a lot of data as input for
# an endpoint, I highly suggest you let the "input" property set to true.
useInputBeanValidation=true
useOutputBeanValidation=true
{{/useBeanValidation}}
{{#handleExceptions}}
play.http.errorHandler="swagger.ErrorHandler"
{{/handleExceptions}}

View File

@ -1 +1 @@
{{#isBoolean}}Boolean.valueOf({{/isBoolean}}{{#isInteger}}Integer.parseInt({{/isInteger}}{{#isDouble}}Double.parseDouble({{/isDouble}}{{#isLong}}Long.parseLong({{/isLong}}{{#isFloat}}Float.parseFloat({{/isFloat}}{{#isUuid}}UUID.fromString({{/isUuid}}{{#isDateTime}}OffsetDateTime.parse({{/isDateTime}}
{{#isBoolean}}Boolean.valueOf({{/isBoolean}}{{#isInteger}}Integer.parseInt({{/isInteger}}{{#isDouble}}Double.parseDouble({{/isDouble}}{{#isLong}}Long.parseLong({{/isLong}}{{#isFloat}}Float.parseFloat({{/isFloat}}{{#isUuid}}UUID.fromString({{/isUuid}}{{#isDateTime}}OffsetDateTime.parse({{/isDateTime}}{{#isDate}}LocalDate.parse({{/isDate}}{{#isByteArray}}{{/isByteArray}}{{#isNumber}}new BigDecimal({{/isNumber}}

View File

@ -1 +1 @@
{{#isBoolean}}){{/isBoolean}}{{#isInteger}}){{/isInteger}}{{#isDouble}}){{/isDouble}}{{#isLong}}){{/isLong}}{{#isFloat}}){{/isFloat}}{{#isUuid}}){{/isUuid}}{{#isDateTime}}){{/isDateTime}}
{{#isBoolean}}){{/isBoolean}}{{#isInteger}}){{/isInteger}}{{#isDouble}}){{/isDouble}}{{#isLong}}){{/isLong}}{{#isFloat}}){{/isFloat}}{{#isUuid}}){{/isUuid}}{{#isDateTime}}){{/isDateTime}}{{#isDate}}){{/isDate}}{{#isByteArray}}.getBytes(){{/isByteArray}}{{#isNumber}}){{/isNumber}}

View File

@ -1 +1 @@
{{#items.isBoolean}}Boolean.valueOf({{/items.isBoolean}}{{#items.isInteger}}Integer.parseInt({{/items.isInteger}}{{#items.isDouble}}Double.parseDouble({{/items.isDouble}}{{#items.isLong}}Long.parseLong({{/items.isLong}}{{#items.isFloat}}Float.parseFloat({{/items.isFloat}}{{#items.isUuid}}UUID.fromString({{/items.isUuid}}{{#items.isDateTime}}OffsetDateTime.parse({{/items.isDateTime}}
{{#items.isBoolean}}Boolean.valueOf({{/items.isBoolean}}{{#items.isInteger}}Integer.parseInt({{/items.isInteger}}{{#items.isDouble}}Double.parseDouble({{/items.isDouble}}{{#items.isLong}}Long.parseLong({{/items.isLong}}{{#items.isFloat}}Float.parseFloat({{/items.isFloat}}{{#items.isUuid}}UUID.fromString({{/items.isUuid}}{{#items.isDateTime}}OffsetDateTime.parse({{/items.isDateTime}}{{#items.isDate}}LocalDate.parse({{/items.isDate}}{{#isByteArray}}{{/isByteArray}}{{#isNumber}}new BigDecimal({{/isNumber}}

View File

@ -1 +1 @@
{{#items.isBoolean}}){{/items.isBoolean}}{{#items.isInteger}}){{/items.isInteger}}{{#items.isDouble}}){{/items.isDouble}}{{#items.isLong}}){{/items.isLong}}{{#items.isFloat}}){{/items.isFloat}}{{#items.isUuid}}){{/items.isUuid}}{{#items.isDateTime}}){{/items.isDateTime}}
{{#items.isBoolean}}){{/items.isBoolean}}{{#items.isInteger}}){{/items.isInteger}}{{#items.isDouble}}){{/items.isDouble}}{{#items.isLong}}){{/items.isLong}}{{#items.isFloat}}){{/items.isFloat}}{{#items.isUuid}}){{/items.isUuid}}{{#items.isDateTime}}){{/items.isDateTime}}{{#items.isDate}}){{/items.isDate}}{{#isByteArray}}.getBytes(){{/isByteArray}}{{#isNumber}}){{/isNumber}}

View File

@ -18,7 +18,14 @@ public class {{classname}}ControllerImp {{#useInterfaces}}implements {{classname
{{#useInterfaces}}@Override{{/useInterfaces}}
public {{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}} {
//Do your magic!!!
{{#returnType}}{{#isResponseFile}}return new FileInputStream("replace this");{{/isResponseFile}}{{^isResponseFile}}return new {{>returnTypesNoVoidNoAbstract}}();{{/isResponseFile}}{{/returnType}}
{{#returnType}}
{{#isResponseFile}}
return new FileInputStream("replace this");
{{/isResponseFile}}
{{^isResponseFile}}
return new {{>returnTypesNoVoidNoAbstract}}({{#vendorExtensions.missingReturnInfoIfNeeded}}{{vendorExtensions.missingReturnInfoIfNeeded}}{{/vendorExtensions.missingReturnInfoIfNeeded}});
{{/isResponseFile}}
{{/returnType}}
}
{{/operation}}

View File

@ -21,6 +21,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
{{#useBeanValidation}}
import javax.validation.constraints.*;
import play.Configuration;
{{/useBeanValidation}}
{{#wrapCalls}}
@ -35,13 +36,19 @@ public class {{classname}}Controller extends Controller {
private final {{classname}}ControllerImp{{#useInterfaces}}Interface{{/useInterfaces}} imp;
{{/controllerOnly}}
private final ObjectMapper mapper;
{{#useBeanValidation}}
private final Configuration configuration;
{{/useBeanValidation}}
@Inject
private {{classname}}Controller({{^controllerOnly}}{{classname}}ControllerImp{{#useInterfaces}}Interface{{/useInterfaces}} imp{{/controllerOnly}}) {
private {{classname}}Controller({{#useBeanValidation}}Configuration configuration{{^controllerOnly}}, {{/controllerOnly}}{{/useBeanValidation}}{{^controllerOnly}}{{classname}}ControllerImp{{#useInterfaces}}Interface{{/useInterfaces}} imp{{/controllerOnly}}) {
{{^controllerOnly}}
this.imp = imp;
{{/controllerOnly}}
mapper = new ObjectMapper();
{{#useBeanValidation}}
this.configuration = configuration;
{{/useBeanValidation}}
}
{{#operation}}
@ -55,12 +62,21 @@ public class {{classname}}Controller extends Controller {
if (node{{paramName}} != null) {
{{paramName}} = mapper.readValue(node{{paramName}}.toString(), {{#isContainer}}new TypeReference<{{{dataType}}}>(){}{{/isContainer}}{{^isContainer}}{{{dataType}}}.class{{/isContainer}});
{{#useBeanValidation}}
{{#isListContainer}}for ({{{baseType}}} curItem : {{paramName}}) {
curItem.validate();
}{{/isListContainer}}{{#isMapContainer}}for (Map.Entry<String, {{{baseType}}}> entry : {{paramName}}.entrySet()) {
entry.getValue().validate();
if (configuration.getBoolean("useInputBeanValidation")) {
{{#isListContainer}}
for ({{{baseType}}} curItem : {{paramName}}) {
SwaggerUtils.validate(curItem);
}
{{/isListContainer}}
{{#isMapContainer}}
for (Map.Entry<String, {{{baseType}}}> entry : {{paramName}}.entrySet()) {
SwaggerUtils.validate(entry.getValue());
}
{{/isMapContainer}}
{{^isContainer}}
SwaggerUtils.validate({{paramName}});
{{/isContainer}}
}
{{/isMapContainer}}{{^isContainer}}{{paramName}}.validate();{{/isContainer}}
{{/useBeanValidation}}
} else {
{{#required}}
@ -173,13 +189,30 @@ public class {{classname}}Controller extends Controller {
{{/collectionFormat}}
{{/headerParams}}
{{^controllerOnly}}
{{#returnType}}{{>returnTypesNoVoid}} obj = {{/returnType}}imp.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}{{^isResponseFile}}{{^returnTypeIsPrimitive}}{{#useBeanValidation}}
{{#isListContainer}}for ({{{returnType}}} curItem : obj) {
curItem.validate();
}{{/isListContainer}}{{#isMapContainer}}for (Map.Entry<String, {{{returnType}}}> entry : obj.entrySet()) {
entry.getValue().validate();
{{#returnType}}{{>returnTypesNoVoid}} obj = {{/returnType}}imp.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#returnType}}
{{^isResponseFile}}
{{^returnTypeIsPrimitive}}
{{#useBeanValidation}}
if (configuration.getBoolean("useOutputBeanValidation")) {
{{#isListContainer}}
for ({{{returnType}}} curItem : obj) {
SwaggerUtils.validate(curItem);
}
{{/isListContainer}}
{{#isMapContainer}}
for (Map.Entry<String, {{{returnType}}}> entry : obj.entrySet()) {
SwaggerUtils.validate(entry.getValue());
}
{{/isMapContainer}}
{{^returnContainer}}
SwaggerUtils.validate(obj);
{{/returnContainer}}
}
{{/isMapContainer}}{{^returnContainer}}obj.validate();{{/returnContainer}}{{/useBeanValidation}}{{/returnTypeIsPrimitive}}{{/isResponseFile}}{{/returnType}}
{{/useBeanValidation}}
{{/returnTypeIsPrimitive}}
{{/isResponseFile}}
{{/returnType}}
{{#returnType}}
{{^isResponseFile}}JsonNode result = mapper.valueToTree(obj);
return ok(result);

View File

@ -134,22 +134,4 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
}
return o.toString().replace("\n", "\n ");
}
{{#useBeanValidation}}
public void validate() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<{{classname}}>> constraintViolations = validator.validate(this);
if (constraintViolations.size() > 0) {
StringBuilder errors = new StringBuilder();
for (ConstraintViolation<{{classname}}> contraintes : constraintViolations) {
errors.append(String.format("%s.%s %s\n",
contraintes.getRootBeanClass().getSimpleName(),
contraintes.getPropertyPath(),
contraintes.getMessage()));
}
throw new RuntimeException("Bean validation : " + errors);
}
}
{{/useBeanValidation}}
}

View File

@ -9,6 +9,13 @@ import java.lang.annotation.Target;
import java.text.SimpleDateFormat;
import java.util.*;
{{#useBeanValidation}}
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
{{/useBeanValidation}}
public class SwaggerUtils {
{{#wrapCalls}}
@ -19,6 +26,24 @@ public class SwaggerUtils {
}
{{/wrapCalls}}
{{#useBeanValidation}}
public static <T> void validate(T obj) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
if (constraintViolations.size() > 0) {
StringBuilder errors = new StringBuilder();
for (ConstraintViolation<T> contraintes : constraintViolations) {
errors.append(String.format("%s.%s %s\n",
contraintes.getRootBeanClass().getSimpleName(),
contraintes.getPropertyPath(),
contraintes.getMessage()));
}
throw new RuntimeException("Bean validation : " + errors);
}
}
{{/useBeanValidation}}
public static List<String> parametersToList(String collectionFormat, String[] values){
List<String> params = new ArrayList<>();

View File

@ -7,12 +7,19 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#jdk8-no-delegate}}
import com.fasterxml.jackson.databind.ObjectMapper;
{{/jdk8-no-delegate}}
import io.swagger.annotations.*;
{{#jdk8}}
{{#jdk8-no-delegate}}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
{{/jdk8}}
{{/jdk8-no-delegate}}
import org.springframework.http.ResponseEntity;
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated;
{{/useBeanValidation}}
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@ -21,26 +28,54 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
{{^useSpringCloudClient}}
import java.io.IOException;
{{/useSpringCloudClient}}
{{#jdk8-no-delegate}}
import javax.servlet.http.HttpServletRequest;
{{/jdk8-no-delegate}}
{{#useBeanValidation}}
import javax.validation.Valid;
import javax.validation.constraints.*;
{{/useBeanValidation}}
{{#jdk8-no-delegate}}
import java.io.IOException;
{{/jdk8-no-delegate}}
import java.util.List;
{{#useOptional}}
{{#jdk8-no-delegate}}
import java.util.Optional;
{{/useOptional}}
{{/jdk8-no-delegate}}
{{^jdk8-no-delegate}}
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{/jdk8-no-delegate}}
{{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
{{/async}}
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.*;
import javax.validation.Valid;
{{/useBeanValidation}}
{{>generatedAnnotation}}
@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API")
{{#operations}}
public interface {{classname}} {
{{#jdk8}}
{{^isDelegate}}
Logger log = LoggerFactory.getLogger({{classname}}.class);
default Optional<ObjectMapper> getObjectMapper() {
return Optional.empty();
}
default Optional<HttpServletRequest> getRequest() {
return Optional.empty();
}
default Optional<String> getAcceptHeader() {
return getRequest().map(r -> r.getHeader("Accept"));
}
{{/isDelegate}}
{{#isDelegate}}
{{classname}}Delegate getDelegate();
{{/isDelegate}}
{{/jdk8}}
{{#operation}}
@ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
@ -54,7 +89,9 @@ public interface {{classname}} {
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}} })
{{#implicitHeaders}}
@ApiImplicitParams({
{{#headerParams}}{{>implicitHeader}}{{/headerParams}}
{{#headerParams}}
{{>implicitHeader}}
{{/headerParams}}
})
{{/implicitHeaders}}
@RequestMapping(value = "{{{path}}}",{{#singleContentTypes}}
@ -63,20 +100,29 @@ public interface {{classname}} {
produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}}
consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}}
method = RequestMethod.{{httpMethod}})
{{#useSpringCloudClient}}
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}){{^jdk8}};{{/jdk8}}{{#jdk8}} {
// do some magic!
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<{{>returnTypes}}>(HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
{{^isDelegate}}
if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
{{#examples}}
if (getAcceptHeader().get().contains("{{{contentType}}}")) {
try {
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(getObjectMapper().get().readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
} catch (IOException e) {
log.error("Couldn't serialize response for content type {{{contentType}}}", e);
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR){{#async}}){{/async}};
}
}
{{/examples}}
} else {
log.warn("ObjectMapper or HttpServletRequest not configured in default {{classname}} interface so no example is generated");
}
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
{{/isDelegate}}
{{#isDelegate}}
return getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/isDelegate}}
}{{/jdk8}}
{{/useSpringCloudClient}}
{{^useSpringCloudClient}}
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},{{/allParams}} @RequestHeader(value = "Accept", required = false) String accept) throws Exception{{^jdk8}};{{/jdk8}}{{#jdk8}} {
// do some magic!
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK){{#async}}){{/async}};
}{{/jdk8}}
{{/useSpringCloudClient}}
{{/operation}}
}
{{/operations}}

View File

@ -1,16 +1,21 @@
package {{package}};
{{^jdk8-no-delegate}}
{{^jdk8}}
{{#imports}}import {{import}};
{{/imports}}
{{/jdk8}}
{{^isDelegate}}
import com.fasterxml.jackson.databind.ObjectMapper;
{{/isDelegate}}
{{^jdk8}}
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
{{/jdk8-no-delegate}}
{{/jdk8}}
import org.springframework.stereotype.Controller;
{{^jdk8-no-delegate}}
{{^jdk8}}
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@ -18,31 +23,35 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{#async}}
import java.util.concurrent.Callable;
{{/async}}
{{/jdk8-no-delegate}}
{{^useSpringCloudClient}}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
{{/useSpringCloudClient}}
{{#useBeanValidation}}
{{#useBeanValidation}}
import javax.validation.constraints.*;
import javax.validation.Valid;
{{/useBeanValidation}}
{{/useBeanValidation}}
{{/jdk8}}
{{^isDelegate}}
import javax.servlet.http.HttpServletRequest;
{{#jdk8}}
import java.util.Optional;
{{/jdk8}}
{{/isDelegate}}
{{^jdk8-no-delegate}}
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{/jdk8-no-delegate}}
{{^jdk8}}
{{^isDelegate}}
import java.io.IOException;
{{/isDelegate}}
import java.util.List;
{{#async}}
import java.util.concurrent.Callable;
{{/async}}
{{/jdk8}}
{{>generatedAnnotation}}
@Controller
{{#operations}}
public class {{classname}}Controller implements {{classname}} {
private final ObjectMapper objectMapper;
public {{classname}}Controller(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
{{#isDelegate}}
private final {{classname}}Delegate delegate;
@ -51,48 +60,78 @@ public class {{classname}}Controller implements {{classname}} {
public {{classname}}Controller({{classname}}Delegate delegate) {
this.delegate = delegate;
}
{{#jdk8}}
@Override
public {{classname}}Delegate getDelegate() {
return delegate;
}
{{/jdk8}}
{{/isDelegate}}
{{^isDelegate}}
{{^jdk8}}
private static final Logger log = LoggerFactory.getLogger({{classname}}Controller.class);
{{/jdk8}}
private final ObjectMapper objectMapper;
private final HttpServletRequest request;
@org.springframework.beans.factory.annotation.Autowired
public {{classname}}Controller(ObjectMapper objectMapper, HttpServletRequest request) {
this.objectMapper = objectMapper;
this.request = request;
}
{{#jdk8}}
@Override
public Optional<ObjectMapper> getObjectMapper() {
return Optional.ofNullable(objectMapper);
}
@Override
public Optional<HttpServletRequest> getRequest() {
return Optional.ofNullable(request);
}
{{/jdk8}}
{{/isDelegate}}
{{^jdk8-no-delegate}}
{{^jdk8}}
{{#operation}}
public {{#async}}Callable<{{/async}}ResponseEntity<{{>returnTypes}}>{{#async}}>{{/async}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},
{{/allParams}}@RequestHeader(value = "Accept", required = false) String accept) throws Exception {
// do some magic!
{{#useSpringCloudClient}}
{{^isDelegate}}
{{^async}}
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
{{/async}}
{{#async}}
return new Callable<ResponseEntity<{{>returnTypes}}>>() {
@Override
public ResponseEntity<{{>returnTypes}}> call() throws Exception {
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
}
};
{{/async}}
{{/isDelegate}}
{{#isDelegate}}
return delegate.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/isDelegate}}
{{/useSpringCloudClient}}
{{^useSpringCloudClient}}
public {{#async}}Callable<{{/async}}ResponseEntity<{{>returnTypes}}>{{#async}}>{{/async}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}) {
{{^isDelegate}}
{{^async}}
String accept = request.getHeader("Accept");
{{#examples}}
if (accept != null && accept.contains("{{{contentType}}}")) {
return new ResponseEntity<{{>returnTypes}}>(objectMapper.readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.OK);
try {
return new ResponseEntity<{{>returnTypes}}>(objectMapper.readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.NOT_IMPLEMENTED);
} catch (IOException e) {
log.error("Couldn't serialize response for content type {{{contentType}}}", e);
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
{{/examples}}
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.NOT_IMPLEMENTED);
{{/async}}
{{#async}}
return new Callable<ResponseEntity<{{>returnTypes}}>>() {
@Override
public ResponseEntity<{{>returnTypes}}> call() throws Exception {
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
public ResponseEntity<{{>returnTypes}}> call() {
String accept = request.getHeader("Accept");
{{#examples}}
if (accept != null && accept.contains("{{{contentType}}}")) {
try {
return new ResponseEntity<{{>returnTypes}}>(objectMapper.readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.NOT_IMPLEMENTED);
} catch (IOException e) {
log.error("Couldn't serialize response for content type {{{contentType}}}", e);
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
{{/examples}}
return new ResponseEntity<{{>returnTypes}}>(HttpStatus.NOT_IMPLEMENTED);
}
};
{{/async}}
@ -100,10 +139,9 @@ public class {{classname}}Controller implements {{classname}} {
{{#isDelegate}}
return delegate.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/isDelegate}}
{{/useSpringCloudClient}}
}
{{/operation}}
{{/jdk8-no-delegate}}
{{/jdk8}}
}
{{/operations}}

View File

@ -2,13 +2,33 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import io.swagger.annotations.*;{{#jdk8}}
import org.springframework.http.HttpStatus;{{/jdk8}}
{{#jdk8}}
import com.fasterxml.jackson.databind.ObjectMapper;
{{/jdk8}}
import io.swagger.annotations.*;
{{#jdk8}}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
{{/jdk8}}
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
{{#jdk8}}
import java.io.IOException;
{{/jdk8}}
{{#jdk8}}
import javax.servlet.http.HttpServletRequest;
{{/jdk8}}
import java.util.List;
{{#jdk8}}
import java.util.Optional;
{{/jdk8}}
{{^jdk8}}
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{/jdk8}}
{{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
{{/async}}
@ -16,11 +36,26 @@ import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture
{{#operations}}
/**
* A delegate to be called by the {@link {{classname}}Controller}}.
* Should be implemented as a controller but without the {@link org.springframework.stereotype.Controller} annotation.
* Instead, use spring to autowire this class into the {@link {{classname}}Controller}.
* Implement this interface with a {@link org.springframework.stereotype.Service} annotated class.
*/
{{>generatedAnnotation}}
public interface {{classname}}Delegate {
{{#jdk8}}
Logger log = LoggerFactory.getLogger({{classname}}.class);
default Optional<ObjectMapper> getObjectMapper() {
return Optional.empty();
}
default Optional<HttpServletRequest> getRequest() {
return Optional.empty();
}
default Optional<String> getAcceptHeader() {
return getRequest().map(r -> r.getHeader("Accept"));
}
{{/jdk8}}
{{#operation}}
/**
@ -28,8 +63,21 @@ public interface {{classname}}Delegate {
*/
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{{dataType}}}{{/isFile}}{{#isFile}}MultipartFile{{/isFile}} {{paramName}}{{#hasMore}},
{{/hasMore}}{{/allParams}}){{^jdk8}};{{/jdk8}}{{#jdk8}} {
// do some magic!
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK){{#async}}){{/async}};
if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
{{#examples}}
if (getAcceptHeader().get().contains("{{{contentType}}}")) {
try {
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(getObjectMapper().get().readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
} catch (IOException e) {
log.error("Couldn't serialize response for content type {{{contentType}}}", e);
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR){{#async}}){{/async}};
}
}
{{/examples}}
} else {
log.warn("ObjectMapper or HttpServletRequest not configured in default {{classname}} interface so no example is generated");
}
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
}{{/jdk8}}
{{/operation}}

View File

@ -1,20 +1,20 @@
{{#pattern}} @Pattern(regexp="{{{pattern}}}"){{/pattern}}{{!
{{#pattern}}@Pattern(regexp="{{{pattern}}}") {{/pattern}}{{!
minLength && maxLength set
}}{{#minLength}}{{#maxLength}} @Size(min={{minLength}},max={{maxLength}}){{/maxLength}}{{/minLength}}{{!
}}{{#minLength}}{{#maxLength}}@Size(min={{minLength}},max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
minLength set, maxLength not
}}{{#minLength}}{{^maxLength}} @Size(min={{minLength}}){{/maxLength}}{{/minLength}}{{!
}}{{#minLength}}{{^maxLength}}@Size(min={{minLength}}) {{/maxLength}}{{/minLength}}{{!
minLength not set, maxLength set
}}{{^minLength}}{{#maxLength}} @Size(max={{maxLength}}){{/maxLength}}{{/minLength}}{{!
}}{{^minLength}}{{#maxLength}}@Size(max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
@Size: minItems && maxItems set
}}{{#minItems}}{{#maxItems}} @Size(min={{minItems}},max={{maxItems}}){{/maxItems}}{{/minItems}}{{!
}}{{#minItems}}{{#maxItems}}@Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
@Size: minItems set, maxItems not
}}{{#minItems}}{{^maxItems}} @Size(min={{minItems}}){{/maxItems}}{{/minItems}}{{!
}}{{#minItems}}{{^maxItems}}@Size(min={{minItems}}) {{/maxItems}}{{/minItems}}{{!
@Size: minItems not set && maxItems set
}}{{^minItems}}{{#maxItems}} @Size(max={{maxItems}}){{/maxItems}}{{/minItems}}{{!
}}{{^minItems}}{{#maxItems}}@Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
check for integer or long / all others=decimal type with @Decimal*
isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{!
isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{!
}}{{#isLong}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}") {{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -1 +1 @@
{{#required}} @NotNull{{/required}}{{>beanValidationCore}}
{{#required}}@NotNull {{/required}}{{>beanValidationCore}}

View File

@ -1 +1 @@
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}} {{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @PathVariable("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isPathParam}}
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @PathVariable("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isPathParam}}

View File

@ -91,6 +91,10 @@
this.agent = new superagent.agent();
}
/*
* Allow user to override superagent agent
*/
this.requestAgent = null;
};
{{#emitJSDoc}} /**
@ -408,6 +412,12 @@
// set header parameters
request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
// set requestAgent if it is set by user
if (this.requestAgent) {
request.agent(this.requestAgent);
}
// set request timeout
request.timeout(this.timeout);

View File

@ -1,3 +1,3 @@
{
"presets": ["es2015", "stage-0"]
}
"presets": ["env", "stage-0"]
}

View File

@ -78,6 +78,12 @@ export default class ApiClient {
if (typeof window === 'undefined') {
this.agent = new superagent.agent();
}
/*
* Allow user to override superagent agent
*/
this.requestAgent = null;
}
{{#emitJSDoc}}/**
@ -396,6 +402,11 @@ export default class ApiClient {
// set header parameters
request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
// set requestAgent if it is set by user
if (this.requestAgent) {
request.agent(this.requestAgent);
}
// set request timeout
request.timeout(this.timeout);

View File

@ -12,12 +12,12 @@
},
"dependencies": {
"babel": "^6.23.0",
"babel-cli": "^6.24.1",
"babel-cli": "^6.26.0",
"superagent": "3.5.2"
},
"devDependencies": {
"babel-core": "6.18.0",
"babel-preset-es2015": "^6.24.1",
"babel-core": "6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-stage-0": "^6.24.1",
"expect.js": "~0.3.1",
"mocha": "~2.3.4",

View File

@ -13,6 +13,7 @@ io.swagger.codegen.languages.CsharpDotNet2ClientCodegen
io.swagger.codegen.languages.DartClientCodegen
io.swagger.codegen.languages.ElixirClientCodegen
io.swagger.codegen.languages.EiffelClientCodegen
io.swagger.codegen.languages.ErlangClientCodegen
io.swagger.codegen.languages.ErlangServerCodegen
io.swagger.codegen.languages.FinchServerCodegen
io.swagger.codegen.languages.FlashClientCodegen
@ -56,6 +57,7 @@ io.swagger.codegen.languages.Rails5ServerCodegen
io.swagger.codegen.languages.RestbedCodegen
io.swagger.codegen.languages.RubyClientCodegen
io.swagger.codegen.languages.RustClientCodegen
io.swagger.codegen.languages.RustServerCodegen
io.swagger.codegen.languages.ScalaClientCodegen
io.swagger.codegen.languages.ScalatraServerCodegen
io.swagger.codegen.languages.ScalazClientCodegen

View File

@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git

View File

@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git

View File

@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git

View File

@ -8,6 +8,6 @@
/// Enum {{name}} for {{{value}}}
/// </summary>
[EnumMember(Value = {{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isFloat}}"{{/isFloat}}{{#isDouble}}"{{/isDouble}}{{{value}}}{{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isFloat}}"{{/isFloat}})]
{{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^-last}},
{{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^isInteger}} = {{-index}}{{/isInteger}}{{^-last}},
{{/-last}}{{/enumVars}}{{/allowableValues}}
}

View File

@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git

View File

@ -5,8 +5,8 @@
* {{description}}
*/
#ifndef {{classname}}_H_
#define {{classname}}_H_
#ifndef {{apiHeaderGuardPrefix}}_{{classname}}_H_
#define {{apiHeaderGuardPrefix}}_{{classname}}_H_
{{{defaultInclude}}}
#include "ApiClient.h"
@ -44,6 +44,6 @@ protected:
}
{{/apiNamespaceDeclarations}}
#endif /* {{classname}}_H_ */
#endif /* {{apiHeaderGuardPrefix}}_{{classname}}_H_ */
{{/operations}}

View File

@ -32,13 +32,13 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == nullptr)
{
throw ApiException(400, U("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}"));
throw ApiException(400, utility::conversions::to_string_t("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}"));
}
{{/isContainer}}{{/isPrimitiveType}}{{/required}}{{/allParams}}
std::shared_ptr<ApiConfiguration> apiConfiguration( m_ApiClient->getConfiguration() );
utility::string_t path = U("{{{path}}}");
{{#pathParams}}boost::replace_all(path, U("{") U("{{baseName}}") U("}"), ApiClient::parameterToString({{{paramName}}}));
utility::string_t path = utility::conversions::to_string_t("{{{path}}}");
{{#pathParams}}boost::replace_all(path, utility::conversions::to_string_t("{") + utility::conversions::to_string_t("{{baseName}}") + utility::conversions::to_string_t("}"), ApiClient::parameterToString({{{paramName}}}));
{{/pathParams}}
std::map<utility::string_t, utility::string_t> queryParams;
@ -48,7 +48,7 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
std::unordered_set<utility::string_t> responseHttpContentTypes;
{{#produces}}
responseHttpContentTypes.insert( U("{{mediaType}}") );
responseHttpContentTypes.insert( utility::conversions::to_string_t("{{mediaType}}") );
{{/produces}}
utility::string_t responseHttpContentType;
@ -57,27 +57,27 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
if ( responseHttpContentTypes.size() == 0 )
{
{{#vendorExtensions.x-codegen-response.isString}}
responseHttpContentType = U("text/plain");
responseHttpContentType = utility::conversions::to_string_t("text/plain");
{{/vendorExtensions.x-codegen-response.isString}}
{{^vendorExtensions.x-codegen-response.isString}}
responseHttpContentType = U("application/json");
responseHttpContentType = utility::conversions::to_string_t("application/json");
{{/vendorExtensions.x-codegen-response.isString}}
}
// JSON
else if ( responseHttpContentTypes.find(U("application/json")) != responseHttpContentTypes.end() )
else if ( responseHttpContentTypes.find(utility::conversions::to_string_t("application/json")) != responseHttpContentTypes.end() )
{
responseHttpContentType = U("application/json");
responseHttpContentType = utility::conversions::to_string_t("application/json");
}
// multipart formdata
else if( responseHttpContentTypes.find(U("multipart/form-data")) != responseHttpContentTypes.end() )
else if( responseHttpContentTypes.find(utility::conversions::to_string_t("multipart/form-data")) != responseHttpContentTypes.end() )
{
responseHttpContentType = U("multipart/form-data");
responseHttpContentType = utility::conversions::to_string_t("multipart/form-data");
}
{{#vendorExtensions.x-codegen-response.isString}}
// plain text
else if( responseHttpContentTypes.find(U("text/plain")) != responseHttpContentTypes.end() )
else if( responseHttpContentTypes.find(utility::conversions::to_string_t("text/plain")) != responseHttpContentTypes.end() )
{
responseHttpContentType = U("text/plain");
responseHttpContentType = utility::conversions::to_string_t("text/plain");
}
{{/vendorExtensions.x-codegen-response.isString}}
{{#vendorExtensions.x-codegen-response-ishttpcontent}}
@ -90,15 +90,15 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{^vendorExtensions.x-codegen-response-ishttpcontent}}
else
{
throw ApiException(400, U("{{classname}}->{{operationId}} does not produce any supported media type"));
throw ApiException(400, utility::conversions::to_string_t("{{classname}}->{{operationId}} does not produce any supported media type"));
}
{{/vendorExtensions.x-codegen-response-ishttpcontent}}
headerParams[U("Accept")] = responseHttpContentType;
headerParams[utility::conversions::to_string_t("Accept")] = responseHttpContentType;
std::unordered_set<utility::string_t> consumeHttpContentTypes;
{{#consumes}}
consumeHttpContentTypes.insert( U("{{mediaType}}") );
consumeHttpContentTypes.insert( utility::conversions::to_string_t("{{mediaType}}") );
{{/consumes}}
{{#allParams}}
@ -108,30 +108,30 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{
{{#isContainer}}
{{#isQueryParam}}
queryParams[U("{{baseName}}")] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
queryParams[utility::conversions::to_string_t("{{baseName}}")] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
{{/isQueryParam}}
{{#isHeaderParam}}
headerParams[U("{{baseName}}")] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
headerParams[utility::conversions::to_string_t("{{baseName}}")] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
{{/isHeaderParam}}
{{#isFormParam}}
{{^isFile}}
formParams[ U("{{baseName}}") ] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
formParams[ utility::conversions::to_string_t("{{baseName}}") ] = ApiClient::parameterToArrayString<{{items.datatype}}>({{paramName}});
{{/isFile}}
{{/isFormParam}}
{{/isContainer}}
{{^isContainer}}
{{#isQueryParam}}
queryParams[U("{{baseName}}")] = ApiClient::parameterToString({{paramName}});
queryParams[utility::conversions::to_string_t("{{baseName}}")] = ApiClient::parameterToString({{paramName}});
{{/isQueryParam}}
{{#isHeaderParam}}
headerParams[U("{{baseName}}")] = ApiClient::parameterToString({{paramName}});
headerParams[utility::conversions::to_string_t("{{baseName}}")] = ApiClient::parameterToString({{paramName}});
{{/isHeaderParam}}
{{#isFormParam}}
{{#isFile}}
fileParams[ U("{{baseName}}") ] = {{paramName}};
fileParams[ utility::conversions::to_string_t("{{baseName}}") ] = {{paramName}};
{{/isFile}}
{{^isFile}}
formParams[ U("{{baseName}}") ] = ApiClient::parameterToString({{paramName}});
formParams[ utility::conversions::to_string_t("{{baseName}}") ] = ApiClient::parameterToString({{paramName}});
{{/isFile}}
{{/isFormParam}}
{{/isContainer}}
@ -144,9 +144,9 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
utility::string_t requestHttpContentType;
// use JSON if possible
if ( consumeHttpContentTypes.size() == 0 || consumeHttpContentTypes.find(U("application/json")) != consumeHttpContentTypes.end() )
if ( consumeHttpContentTypes.size() == 0 || consumeHttpContentTypes.find(utility::conversions::to_string_t("application/json")) != consumeHttpContentTypes.end() )
{
requestHttpContentType = U("application/json");
requestHttpContentType = utility::conversions::to_string_t("application/json");
{{#bodyParam}}
web::json::value json;
@ -177,9 +177,9 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{/bodyParam}}
}
// multipart formdata
else if( consumeHttpContentTypes.find(U("multipart/form-data")) != consumeHttpContentTypes.end() )
else if( consumeHttpContentTypes.find(utility::conversions::to_string_t("multipart/form-data")) != consumeHttpContentTypes.end() )
{
requestHttpContentType = U("multipart/form-data");
requestHttpContentType = utility::conversions::to_string_t("multipart/form-data");
{{#bodyParam}}
std::shared_ptr<MultipartFormData> multipart(new MultipartFormData);
{{#isPrimitiveType}}
@ -197,28 +197,28 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{/items.isDateTime}}{{^items.isDateTime}}jsonArray.push_back( item.get() ? item->toJson() : web::json::value::null() );
{{/items.isDateTime}}{{/items.isString}}{{/items.isPrimitiveType}}
}
multipart->add(ModelBase::toHttpContent(U("{{paramName}}"), web::json::value::array(jsonArray), U("application/json")));
multipart->add(ModelBase::toHttpContent(utility::conversions::to_string_t("{{paramName}}"), web::json::value::array(jsonArray), utility::conversions::to_string_t("application/json")));
}
{{/isListContainer}}
{{^isListContainer}}
{{#isString}}multipart->add(ModelBase::toHttpContent(U("{{paramName}}"), {{paramName}}));
{{#isString}}multipart->add(ModelBase::toHttpContent(utility::conversions::to_string_t("{{paramName}}"), {{paramName}}));
{{/isString}}
{{^isString}}
if({{paramName}}.get())
{
{{paramName}}->toMultipart(multipart, U("{{paramName}}"));
{{paramName}}->toMultipart(multipart, utility::conversions::to_string_t("{{paramName}}"));
}
{{/isString}}
{{/isListContainer}}
{{/isPrimitiveType}}
httpBody = multipart;
requestHttpContentType += U("; boundary=") + multipart->getBoundary();
requestHttpContentType += utility::conversions::to_string_t("; boundary=") + multipart->getBoundary();
{{/bodyParam}}
}
else
{
throw ApiException(415, U("{{classname}}->{{operationId}} does not consume any supported media type"));
throw ApiException(415, utility::conversions::to_string_t("{{classname}}->{{operationId}} does not consume any supported media type"));
}
{{#authMethods}}
@ -226,19 +226,19 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{#isApiKey}}
{{#isKeyInHeader}}
{
utility::string_t apiKey = apiConfiguration->getApiKey(U("{{keyParamName}}"));
utility::string_t apiKey = apiConfiguration->getApiKey(utility::conversions::to_string_t("{{keyParamName}}"));
if ( apiKey.size() > 0 )
{
headerParams[U("{{keyParamName}}")] = apiKey;
headerParams[utility::conversions::to_string_t("{{keyParamName}}")] = apiKey;
}
}
{{/isKeyInHeader}}
{{#isKeyInQuery}}
{
utility::string_t apiKey = apiConfiguration->getApiKey(U("{{keyParamName}}"));
utility::string_t apiKey = apiConfiguration->getApiKey(utility::conversions::to_string_t("{{keyParamName}}"));
if ( apiKey.size() > 0 )
{
queryParams[U("{{keyParamName}}")] = apiKey;
queryParams[utility::conversions::to_string_t("{{keyParamName}}")] = apiKey;
}
}
{{/isKeyInQuery}}
@ -251,7 +251,7 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{/isOAuth}}
{{/authMethods}}
return m_ApiClient->callApi(path, U("{{httpMethod}}"), queryParams, httpBody, headerParams, formParams, fileParams, requestHttpContentType)
return m_ApiClient->callApi(path, utility::conversions::to_string_t("{{httpMethod}}"), queryParams, httpBody, headerParams, formParams, fileParams, requestHttpContentType)
.then([=](web::http::http_response response)
{
// 1xx - informational : OK
@ -262,18 +262,18 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
if (response.status_code() >= 400)
{
throw ApiException(response.status_code()
, U("error calling {{operationId}}: ") + response.reason_phrase()
, utility::conversions::to_string_t("error calling {{operationId}}: ") + response.reason_phrase()
, std::make_shared<std::stringstream>(response.extract_utf8string(true).get()));
}
// check response content type
if(response.headers().has(U("Content-Type")))
if(response.headers().has(utility::conversions::to_string_t("Content-Type")))
{
utility::string_t contentType = response.headers()[U("Content-Type")];
utility::string_t contentType = response.headers()[utility::conversions::to_string_t("Content-Type")];
if( contentType.find(responseHttpContentType) == std::string::npos )
{
throw ApiException(500
, U("error calling {{operationId}}: unexpected response type: ") + contentType
, utility::conversions::to_string_t("error calling {{operationId}}: unexpected response type: ") + contentType
, std::make_shared<std::stringstream>(response.extract_utf8string(true).get()));
}
}
@ -304,7 +304,7 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{{returnType}}} result({{{defaultResponse}}});
{{/returnContainer}}
if(responseHttpContentType == U("application/json"))
if(responseHttpContentType == utility::conversions::to_string_t("application/json"))
{
web::json::value json = web::json::value::parse(response);
@ -330,18 +330,18 @@ pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/r
{{/vendorExtensions.x-codegen-response.isPrimitiveType}}{{^vendorExtensions.x-codegen-response.isPrimitiveType}}{{#vendorExtensions.x-codegen-response.isString}}result = ModelBase::stringFromJson(json);
{{/vendorExtensions.x-codegen-response.isString}}{{^vendorExtensions.x-codegen-response.isString}}result->fromJson(json);{{/vendorExtensions.x-codegen-response.isString}}{{/vendorExtensions.x-codegen-response.isPrimitiveType}}{{/isMapContainer}}{{/isListContainer}}
}{{#vendorExtensions.x-codegen-response.isString}}
else if(responseHttpContentType == U("text/plain"))
else if(responseHttpContentType == utility::conversions::to_string_t("text/plain"))
{
result = response;
}{{/vendorExtensions.x-codegen-response.isString}}
// else if(responseHttpContentType == U("multipart/form-data"))
// else if(responseHttpContentType == utility::conversions::to_string_t("multipart/form-data"))
// {
// TODO multipart response parsing
// }
else
{
throw ApiException(500
, U("error calling {{operationId}}: unsupported response type"));
, utility::conversions::to_string_t("error calling {{operationId}}: unsupported response type"));
}
return result;

View File

@ -5,8 +5,8 @@
* This is an API client responsible for stating the HTTP calls
*/
#ifndef ApiClient_H_
#define ApiClient_H_
#ifndef {{apiHeaderGuardPrefix}}_ApiClient_H_
#define {{apiHeaderGuardPrefix}}_ApiClient_H_
{{{defaultInclude}}}
#include "ApiConfiguration.h"
@ -48,7 +48,7 @@ public:
for( size_t i = 0; i < value.size(); i++)
{
if( i > 0) ss << U(", ");
if( i > 0) ss << utility::conversions::to_string_t(", ");
ss << ApiClient::parameterToString(value[i]);
}
@ -75,4 +75,4 @@ protected:
}
{{/apiNamespaceDeclarations}}
#endif /* ApiClient_H_ */
#endif /* {{apiHeaderGuardPrefix}}_ApiClient_H_ */

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