Merge remote-tracking branch 'origin' into sync_master_230

This commit is contained in:
wing328 2017-02-10 23:31:36 +08:00
commit acd10318f7
1480 changed files with 60531 additions and 12438 deletions

View File

@ -1,3 +1,4 @@
.git/
*.iml *.iml
out/ out/
*.ipr *.ipr
@ -13,35 +14,13 @@ generated-sources/*
generated-code/* generated-code/*
*.swp *.swp
*.swo *.swo
*.bak
/target project/
/generated-files samples/*
/nbactions.xml target/
*.pyc .idea/
__pycache__ .lib/
samples/server-generator/scalatra/output
samples/server-generator/node/output/node_modules
samples/server-generator/scalatra/target
samples/server-generator/scalatra/output/.history
samples/client/petstore/qt5cpp/PetStore/moc_*
samples/client/petstore/qt5cpp/PetStore/*.o
samples/client/petstore/objc/PetstoreClient.xcworkspace/xcuserdata
samples/client/petstore/qt5cpp/build-*
samples/client/petstore/qt5cpp/PetStore/PetStore
samples/client/petstore/qt5cpp/PetStore/Makefile
samples/client/petstore/java/hello.txt
samples/client/petstore/android/default/hello.txt
samples/client/petstore/objc/Build
samples/client/petstore/objc/Pods
samples/server/petstore/nodejs/node_modules
target
.idea
.lib
atlassian-ide-plugin.xml
.DS_Store .DS_Store
samples/client/petstore/php/SwaggerClient-php/composer.lock # Not needed in a linux container
samples/client/petstore/php/SwaggerClient-php/vendor/ bin/windows/*
samples/client/petstore/silex/SwaggerServer/composer.lock
samples/client/petstore/silex/SwaggerServer/venodr/

View File

@ -24,6 +24,12 @@ before_install:
- docker pull swaggerapi/petstore - 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 run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore
- docker ps -a - 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
# show host table to confirm petstore.swagger.io is mapped to localhost # show host table to confirm petstore.swagger.io is mapped to localhost
- cat /etc/hosts - cat /etc/hosts
@ -34,7 +40,15 @@ install:
- export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$PATH" - export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$PATH"
script: script:
# fail fast
- set -e
# fail if templates/generators contain carriage return '\r'
- /bin/bash ./bin/utils/detect_carriage_return.sh
# fail if generators contain tab '\t'
- /bin/bash ./bin/utils/detect_tab_in_java_class.sh
# run integration tests defined in maven pom.xml
- mvn verify -Psamples - mvn verify -Psamples
# docker test
- if [ $DOCKER_HUB_USERNAME ]; then docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD && docker build -t $DOCKER_IMAGE_NAME ./modules/swagger-generator && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_IMAGE_NAME:latest $DOCKER_IMAGE_NAME:$TRAVIS_TAG; fi && docker push $DOCKER_IMAGE_NAME; fi - if [ $DOCKER_HUB_USERNAME ]; then docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD && docker build -t $DOCKER_IMAGE_NAME ./modules/swagger-generator && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_IMAGE_NAME:latest $DOCKER_IMAGE_NAME:$TRAVIS_TAG; fi && docker push $DOCKER_IMAGE_NAME; fi
env: env:

View File

@ -30,6 +30,7 @@ For a list of variables available in the template, please refer to this [page](h
### Style guide ### Style guide
Code change should conform to the programming style guide of the respective languages: Code change should conform to the programming style guide of the respective languages:
- Android: https://source.android.com/source/code-style.html - Android: https://source.android.com/source/code-style.html
- Bash: https://github.com/bahamas10/bash-style-guide
- C#: https://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx - C#: https://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx
- C++: https://google.github.io/styleguide/cppguide.html - C++: https://google.github.io/styleguide/cppguide.html
- Clojure: https://github.com/bbatsov/clojure-style-guide - Clojure: https://github.com/bbatsov/clojure-style-guide
@ -75,3 +76,5 @@ To start the CI tests, you can run `mvn verify -Psamples` (assuming you've all t
- Document the fix in the code to make the code more readable - Document the fix in the code to make the code more readable
- Make sure test cases passed after the change (one way is to leverage https://travis-ci.org/ to run the CI tests) - Make sure test cases passed after the change (one way is to leverage https://travis-ci.org/ to run the CI tests)
- File a PR with meaningful title, description and commit messages. A good example is [PR-3306](https://github.com/swagger-api/swagger-codegen/pull/3306) - File a PR with meaningful title, description and commit messages. A good example is [PR-3306](https://github.com/swagger-api/swagger-codegen/pull/3306)
- Recommended git settings
- `git config --global core.autocrlf input` to tell Git convert CRLF to LF on commit but not the other way around

View File

@ -1,13 +1,22 @@
FROM maven:3.3-jdk-7 FROM jimschubert/8-jdk-alpine-mvn:1.0
WORKDIR /src ENV GEN_DIR /opt/swagger-codegen
VOLUME /src
VOLUME /root/.m2/repository
ADD . /opt/swagger-codegen RUN set -x && \
apk add --no-cache bash
RUN cd /opt/swagger-codegen && mvn package RUN mkdir /opt
ENTRYPOINT ["java", "-jar", "/opt/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"] ADD . ${GEN_DIR}
CMD ["help"] VOLUME ${MAVEN_HOME}/.m2/repository
WORKDIR ${GEN_DIR}
RUN mvn -am -pl "modules/swagger-codegen-cli" package
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["build"]

111
README.md
View File

@ -15,8 +15,8 @@
## Overview ## 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: 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**, **C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Go**, **Groovy**, **Haskell**, **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign), **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **Python**, **Ruby**, **Scala**, **Swift** (2.x, 3.x), **Typescript** (Angular1.x, Angular2.x, Fetch, Node) - **API clients**: **ActionScript**, **Bash**, **C#** (.net 2.0, 4.0 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **Go**, **Groovy**, **Haskell**, **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign), **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **Python**, **Ruby**, **Scala**, **Swift** (2.x, 3.x), **Typescript** (Angular1.x, Angular2.x, Fetch, Node)
- **Server stubs**: **C#** (ASP.NET Core, NancyFx), **Erlang**, **Go**, **Haskell**, **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy), **PHP** (Lumen, Slim, Silex), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Scala** (Scalatra) - **Server stubs**: **C#** (ASP.NET Core, NancyFx), **Erlang**, **Go**, **Haskell**, **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy), **PHP** (Lumen, Slim, Silex, [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Scala** ([Finch](https://github.com/finagle/finch), Scalatra)
- **API documentation generators**: **HTML**, **Confluence Wiki** - **API documentation generators**: **HTML**, **Confluence Wiki**
- **Others**: **JMeter** - **Others**: **JMeter**
@ -110,16 +110,41 @@ After cloning the project, you can build it from source with this command:
mvn clean package mvn clean package
``` ```
### Homebrew
To install, run `brew install swagger-codegen`
Here is an example usage:
```
swagger-codegen generate -i http://petstore.swagger.io/v2/swagger.json -l ruby -o /tmp/test/
```
### Docker ### Docker
#### Build and run using docker
#### Development in docker
You can use `run-in-docker.sh` to do all development. This script maps your local repository to `/gen`
in the docker container. It also maps `~/.m2/repository` to the appropriate container location.
To execute `mvn package`:
``` ```
git clone https://github.com/swagger-api/swagger-codegen git clone https://github.com/swagger-api/swagger-codegen
cd swagger-codegen cd swagger-codegen
./run-in-docker.sh mvn package ./run-in-docker.sh mvn package
``` ```
Build artifacts are now accessible in your working directory.
Once built, `run-in-docker.sh` will act as an executable for swagger-codegen-cli. To generate code, you'll need to output to a directory under `/gen` (e.g. `/gen/out`). For example:
```
./run-in-docker.sh help # Executes 'help' command for swagger-codegen-cli
./run-in-docker.sh langs # Executes 'langs' command for swagger-codegen-cli
./run-in-docker.sh /gen/bin/go-petstore.sh # Builds the Go client
./run-in-docker.sh generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml \
-l go -o /gen/out/go-petstore -DpackageName=petstore # generates go client, outputs locally to ./out/go-petstore
```
#### Run Docker in Vagrant #### Run Docker in Vagrant
Prerequisite: install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads). Prerequisite: install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
@ -132,18 +157,54 @@ cd /vagrant
./run-in-docker.sh mvn package ./run-in-docker.sh mvn package
``` ```
#### Public Docker image #### Public Pre-built Docker images
- https://hub.docker.com/r/swaggerapi/swagger-generator/ (official) - https://hub.docker.com/r/swaggerapi/swagger-generator/ (official web service)
- https://hub.docker.com/r/jimschubert/swagger-codegen-cli/ (unofficial) - https://hub.docker.com/r/swaggerapi/swagger-codegen-cli/ (official CLI)
=======
### Homebrew ##### Swagger Generator Docker Image
To install, run `brew install swagger-codegen`
The Swagger Generator image can act as a self-hosted web application and API for generating code. This container can be incorporated into a CI pipeline, and requires at least two HTTP requests and some docker orchestration to access generated code.
Example usage (note this assumes `jq` is installed for command line processing of JSON):
Here is an example usage:
``` ```
swagger-codegen generate -i http://petstore.swagger.io/v2/swagger.json -l ruby -o /tmp/test/ # Start container and save the container id
CID=$(docker run -d swaggerapi/swagger-generator)
# allow for startup
sleep 5
# Get the IP of the running container
GEN_IP=$(docker inspect --format '{{.NetworkSettings.IPAddress}}' $CID)
# Execute an HTTP request and store the download link
RESULT=$(curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
"swaggerUrl": "http://petstore.swagger.io/v2/swagger.json"
}' 'http://localhost:8188/api/gen/clients/javascript' | jq '.link' | tr -d '"')
# Download the generated zip and redirect to a file
curl $RESULT > result.zip
# Shutdown the swagger generator image
docker stop $CID && docker rm $CID
``` ```
In the example above, `result.zip` will contain the generated client.
##### Swagger Codegen Docker Image
The Swagger Codegen image acts as a standalone executable. It can be used as an alternative to installing via homebrew, or for developers who are unable to install Java or upgrade the installed version.
To generate code with this image, you'll need to mount a local location as a volume.
Example:
```
docker run --rm -v ${PWD}:/local swagger-api/swagger-codegen generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l go \
-o /local/out/go
```
The generated code will be located under `./out/go` in the current directory.
## Getting Started ## Getting Started
To generate a PHP client for http://petstore.swagger.io/v2/swagger.json, please run the following To generate a PHP client for http://petstore.swagger.io/v2/swagger.json, please run the following
@ -289,6 +350,10 @@ OPTIONS
the format of swaggerType=generatedType,swaggerType=generatedType. the format of swaggerType=generatedType,swaggerType=generatedType.
For example: array=List,map=Map,string=String For example: array=List,map=Map,string=String
--reserved-words-mappings <import mappings>
specifies how a reserved name should be escaped to. Otherwise, the
default _<name> is used. For example id=identifier
-v, --verbose -v, --verbose
verbose mode verbose mode
@ -331,6 +396,10 @@ You would then compile your library in the `output/myLibrary` folder with `mvn p
``` ```
java -cp output/myLibrary/target/myClientCodegen-swagger-codegen-1.0.0.jar:modules/swagger-codegen-cli/target/swagger-codegen-cli.jar io.swagger.codegen.SwaggerCodegen java -cp output/myLibrary/target/myClientCodegen-swagger-codegen-1.0.0.jar:modules/swagger-codegen-cli/target/swagger-codegen-cli.jar io.swagger.codegen.SwaggerCodegen
``` ```
For Windows users, you will need to use `;` instead of `:` in the classpath, e.g.
```
java -cp output/myLibrary/target/myClientCodegen-swagger-codegen-1.0.0.jar;modules/swagger-codegen-cli/target/swagger-codegen-cli.jar io.swagger.codegen.SwaggerCodegen
```
Note the `myClientCodegen` is an option now, and you can use the usual arguments for generating your library: Note the `myClientCodegen` is an option now, and you can use the usual arguments for generating your library:
@ -459,6 +528,7 @@ AndroidClientCodegen.java
AspNet5ServerCodegen.java AspNet5ServerCodegen.java
AspNetCoreServerCodegen.java AspNetCoreServerCodegen.java
AsyncScalaClientCodegen.java AsyncScalaClientCodegen.java
BashClientCodegen.java
CSharpClientCodegen.java CSharpClientCodegen.java
ClojureClientCodegen.java ClojureClientCodegen.java
CsharpDotNet2ClientCodegen.java CsharpDotNet2ClientCodegen.java
@ -784,25 +854,32 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [goTransverse](http://www.gotransverse.com/api) - [goTransverse](http://www.gotransverse.com/api)
- [GraphHopper](https://graphhopper.com/) - [GraphHopper](https://graphhopper.com/)
- [Gravitate Solutions](http://gravitatesolutions.com/) - [Gravitate Solutions](http://gravitatesolutions.com/)
- [Hewlett Packard Enterprise](https://hpe.com)
- [High Technologies Center](http://htc-cs.com)
- [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications) - [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications)
- [Intent HQ](http://www.intenthq.com) - [Intent HQ](http://www.intenthq.com)
- [Interactive Intelligence](http://developer.mypurecloud.com/) - [Interactive Intelligence](http://developer.mypurecloud.com/)
- [Kabuku](http://www.kabuku.co.jp/en) - [Kabuku](http://www.kabuku.co.jp/en)
- [Kurio](https://kurio.co.id)
- [Kuroi](http://kuroiwebdesign.com/) - [Kuroi](http://kuroiwebdesign.com/)
- [Kuary](https://kuary.com/) - [Kuary](https://kuary.com/)
- [Kubernetes](https://kubernetes.io/)
- [LANDR Audio](https://www.landr.com/) - [LANDR Audio](https://www.landr.com/)
- [Lascaux](http://www.lascaux.it/) - [Lascaux](http://www.lascaux.it/)
- [Leica Geosystems AG](http://leica-geosystems.com) - [Leica Geosystems AG](http://leica-geosystems.com)
- [LiveAgent](https://www.ladesk.com/) - [LiveAgent](https://www.ladesk.com/)
- [LXL Tech](http://lxltech.com) - [LXL Tech](http://lxltech.com)
- [MailMojo](https://mailmojo.no/)
- [Mindera](http://mindera.com/) - [Mindera](http://mindera.com/)
- [Mporium](http://mporium.com/) - [Mporium](http://mporium.com/)
- [Neverfail](https://neverfail.com/)
- [nViso](http://www.nviso.ch/) - [nViso](http://www.nviso.ch/)
- [Okiok](https://www.okiok.com) - [Okiok](https://www.okiok.com)
- [Onedata](http://onedata.org) - [Onedata](http://onedata.org)
- [OrderCloud.io](http://ordercloud.io) - [OrderCloud.io](http://ordercloud.io)
- [OSDN](https://osdn.jp) - [OSDN](https://osdn.jp)
- [PagerDuty](https://www.pagerduty.com) - [PagerDuty](https://www.pagerduty.com)
- [PagerTree](https://pagertree.com)
- [Pepipost](https://www.pepipost.com) - [Pepipost](https://www.pepipost.com)
- [Plexxi](http://www.plexxi.com) - [Plexxi](http://www.plexxi.com)
- [Pixoneye](http://www.pixoneye.com/) - [Pixoneye](http://www.pixoneye.com/)
@ -819,9 +896,12 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [Saritasa](https://www.saritasa.com/) - [Saritasa](https://www.saritasa.com/)
- [SCOOP Software GmbH](http://www.scoop-software.de) - [SCOOP Software GmbH](http://www.scoop-software.de)
- [Shine Solutions](https://shinesolutions.com/) - [Shine Solutions](https://shinesolutions.com/)
- [Simpfony](https://www.simpfony.com/)
- [Skurt](http://www.skurt.com) - [Skurt](http://www.skurt.com)
- [Slamby](https://www.slamby.com/)
- [SmartRecruiters](https://www.smartrecruiters.com/) - [SmartRecruiters](https://www.smartrecruiters.com/)
- [snapCX](https://snapcx.io) - [snapCX](https://snapcx.io)
- [SPINEN](http://www.spinen.com)
- [SRC](https://www.src.si/) - [SRC](https://www.src.si/)
- [StyleRecipe](http://stylerecipe.co.jp) - [StyleRecipe](http://stylerecipe.co.jp)
- [Svenska Spel AB](https://www.svenskaspel.se/) - [Svenska Spel AB](https://www.svenskaspel.se/)
@ -832,6 +912,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [VMware](https://vmware.com/) - [VMware](https://vmware.com/)
- [W.UP](http://wup.hu/?siteLang=en) - [W.UP](http://wup.hu/?siteLang=en)
- [Wealthfront](https://www.wealthfront.com/) - [Wealthfront](https://www.wealthfront.com/)
- [Webever GmbH](https://www.webever.de/)
- [WEXO A/S](https://www.wexo.dk/) - [WEXO A/S](https://www.wexo.dk/)
- [Zalando](https://tech.zalando.com) - [Zalando](https://tech.zalando.com)
- [ZEEF.com](https://zeef.com/) - [ZEEF.com](https://zeef.com/)
@ -882,15 +963,19 @@ Swagger Codegen core team members are contributors who have been making signific
| Python Flask | | | Python Flask | |
| Ruby Sinatra | @wing328 (2016/05/01) | | | Ruby Sinatra | @wing328 (2016/05/01) | |
| Scala Scalatra | | | | Scala Scalatra | | |
| Scala Finch | @jimschubert (2017/01/28) |
## Template Creator ## Template Creator
Here is a list of template creators: Here is a list of template creators:
* API Clients: * API Clients:
* Akka-Scala: @cchafer * Akka-Scala: @cchafer
* Bash: @bkryza
* C++ REST: @Danielku15 * C++ REST: @Danielku15
* C# (.NET 2.0): @who * C# (.NET 2.0): @who
* Clojure: @xhh * Clojure: @xhh
* Dart: @yissachar * Dart: @yissachar
* Elixir: @niku
* Groovy: @victorgit * Groovy: @victorgit
* Go: @wing328 * Go: @wing328
* Java (Feign): @davidkiss * Java (Feign): @davidkiss
@ -922,7 +1007,9 @@ Here is a list of template creators:
* JAX-RS CXF (CDI): @nickcmaynard * JAX-RS CXF (CDI): @nickcmaynard
* PHP Lumen: @abcsum * PHP Lumen: @abcsum
* PHP Slim: @jfastnacht * PHP Slim: @jfastnacht
* PHP Zend Expressive (with Path Handler): @Articus
* Ruby on Rails 5: @zlx * Ruby on Rails 5: @zlx
* Scala Finch: @jimschubert
* Documentation * Documentation
* HTML Doc 2: @jhitchcock * HTML Doc 2: @jhitchcock
* Confluence Wiki: @jhitchcock * Confluence Wiki: @jhitchcock
@ -972,7 +1059,7 @@ When code is generated from this project, it shall be considered **AS IS** and o
License License
------- -------
Copyright 2016 SmartBear Software Copyright 2017 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

31
bin/bash-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"
args="$@ generate -t modules/swagger-codegen/src/main/resources/bash -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l bash -o samples/client/petstore/bash -c modules/swagger-codegen/src/test/resources/2_0/bash-config.json"
java $JAVA_OPTS -jar $executable $args

31
bin/elixir-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"
args="$@ generate -t modules/swagger-codegen/src/main/resources/elixir -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l elixir -o samples/client/petstore/elixir"
java $JAVA_OPTS -jar $executable $args

31
bin/finch-petstore-server.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/finch -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l finch -o samples/server/petstore/finch"
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/JavaJaxRS/cxf -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l jaxrs-cxf -o samples/server/petstore/jaxrs-cxf-annotated-base-path -DhideGenerationTimestamp=true,useAnnotatedBasePath=true"
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/JavaJaxRS/cxf -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l jaxrs-cxf -o samples/server/petstore/jaxrs-cxf-non-spring-app -DhideGenerationTimestamp=true,generateNonSpringApplication=true"
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. # 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" export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaJaxRS/cxf -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l jaxrs-cxf -o samples/server/petstore/jaxrs-cxf -DhideGenerationTimestamp=true" ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaJaxRS/cxf -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l jaxrs-cxf -o samples/server/petstore/jaxrs-cxf -DhideGenerationTimestamp=true"
java $JAVA_OPTS -jar $executable $ags java $JAVA_OPTS -jar $executable $ags

View File

@ -26,6 +26,7 @@ fi
# if you've executed sbt assembly previously it will use that instead. # 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" export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaJaxRS -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l jaxrs-spec -o samples/server/petstore/jaxrs-spec -DhideGenerationTimestamp=true" ags="$@ generate -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"
java $JAVA_OPTS -jar $executable $ags 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. # 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" 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" 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"
java $JAVA_OPTS -jar $executable $ags java $JAVA_OPTS -jar $executable $ags

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead. # 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" export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
# complex module name used for testing # complex module name used for testing
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l perl -o samples/client/petstore/perl" ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l perl -o samples/client/petstore/perl -DhideGenerationTimestamp=true"
java $JAVA_OPTS -jar $executable $ags java $JAVA_OPTS -jar $executable $ags

View File

@ -1,6 +1,8 @@
#!/bin/sh #!/bin/sh
./bin/spring-cloud-feign-petstore.sh ./bin/spring-cloud-feign-petstore.sh
./bin/spring-delegate.sh
./bin/spring-delegate-j8.sh
./bin/spring-stubs.sh ./bin/spring-stubs.sh
./bin/spring-mvc-petstore-j8-async-server.sh ./bin/spring-mvc-petstore-j8-async-server.sh
./bin/springboot-petstore-server.sh ./bin/springboot-petstore-server.sh

34
bin/spring-delegate-j8.sh Executable file
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/JavaSpring -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l spring -o samples/server/petstore/springboot-delegate-j8 -DdelegatePattern=true,hideGenerationTimestamp=true,java8=true"
echo "Removing files and folders under samples/server/petstore/springboot-delegate-j8/src/main"
rm -rf samples/server/petstore/springboot-delegate-j8/src/main
find samples/server/petstore/springboot -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
java $JAVA_OPTS -jar $executable $ags

34
bin/spring-delegate.sh Executable file
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/JavaSpring -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l spring -o samples/server/petstore/springboot-delegate -DdelegatePattern=true,hideGenerationTimestamp=true"
echo "Removing files and folders under samples/server/petstore/springboot-delegate/src/main"
rm -rf samples/server/petstore/springboot-delegate/src/main
find samples/server/petstore/springboot -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,18 @@
#!/bin/bash
# grep for \r in the templates
grep -RUIl $'\r$' modules/swagger-codegen/src/main/resources/*
if [ $? -ne 1 ]; then
echo "Templates contain carriage return '/r'. Please remove it and try again."
exit 1;
fi
# grep for \r in the generators
grep -RUIl $'\r$' modules/swagger-codegen/src/main/java/io/swagger/codegen/*.java
if [ $? -ne 1 ]; then
echo "Generators contain carriage return '/r'. Please remove it and try again."
exit 1;
fi

View File

@ -0,0 +1,10 @@
#!/bin/bash
# grep for \t in the generators
grep -RUIl $'\t$' modules/swagger-codegen/src/main/java/io/swagger/codegen/*.java
if [ $? -ne 1 ]; then
echo "Generators (Java class files) contain tab '/t'. Please remove it and try again."
exit 1;
fi

View File

@ -0,0 +1,2 @@
call .\bin\windows\javascript-petstore.bat
call .\bin\windows\javascript-promise-petstore.bat

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
) )
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.json -l javascript -o samples\client\petstore\javascript set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l javascript -o samples\client\petstore\javascript
java %JAVA_OPTS% -jar %executable% %ags% java -DappName=PetstoreClient %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 -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l javascript -o samples\client\petstore\javascript-promise --additional-properties usePromises=true
java -DappName=PetstoreClient %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 -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l ze-ph -o samples\server\petstore\ze-ph
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/ze-ph -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l ze-ph -o samples/server/petstore/ze-ph"
java $JAVA_OPTS -jar $executable $ags

24
docker-entrypoint.sh Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -euo pipefail
# GEN_DIR allows to share the entrypoint between Dockerfile and run-in-docker.sh (backward compatible)
GEN_DIR=${GEN_DIR:-/opt/swagger-codegen}
JAVA_OPTS=${JAVA_OPTS:-"-Xmx1024M -DloggerPath=conf/log4j.properties"}
codegen="${GEN_DIR}/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
case "$1" in
generate|help|langs|meta|config-help)
# 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" package)
fi
command=$1
shift
exec java ${JAVA_OPTS} -jar ${codegen} ${command} "$@"
;;
*) # Any other commands, e.g. docker run imagename ls -la or docker run -it imagename /bin/bash
exec "$@"
;;
esac

View File

@ -0,0 +1,7 @@
FROM java:8-jre-alpine
ADD target/swagger-codegen-cli.jar /opt/swagger-codegen-cli/swagger-codegen-cli.jar
ENTRYPOINT ["java", "-jar", "/opt/swagger-codegen-cli/swagger-codegen-cli.jar"]
CMD ["help"]

View File

@ -118,6 +118,13 @@ public class Generate implements Runnable {
@Option(name = {"--http-user-agent"}, title = "http user agent", description = CodegenConstants.HTTP_USER_AGENT_DESC) @Option(name = {"--http-user-agent"}, title = "http user agent", description = CodegenConstants.HTTP_USER_AGENT_DESC)
private String httpUserAgent; private String httpUserAgent;
@Option(name = {"--reserved-words-mappings"}, title = "import mappings",
description = "specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used. For example id=identifier")
private String reservedWordsMappings;
@Option(name = {"--ignore-file-override"}, title = "ignore file override location", description = CodegenConstants.IGNORE_FILE_OVERRIDE_DESC)
private String ignoreFileOverride;
@Override @Override
public void run() { public void run() {
@ -211,13 +218,17 @@ public class Generate implements Runnable {
configurator.setHttpUserAgent(httpUserAgent); configurator.setHttpUserAgent(httpUserAgent);
} }
if (isNotEmpty(ignoreFileOverride)) {
configurator.setIgnoreFileOverride(ignoreFileOverride);
}
applySystemPropertiesKvp(systemProperties, configurator); applySystemPropertiesKvp(systemProperties, configurator);
applyInstantiationTypesKvp(instantiationTypes, configurator); applyInstantiationTypesKvp(instantiationTypes, configurator);
applyImportMappingsKvp(importMappings, configurator); applyImportMappingsKvp(importMappings, configurator);
applyTypeMappingsKvp(typeMappings, configurator); applyTypeMappingsKvp(typeMappings, configurator);
applyAdditionalPropertiesKvp(additionalProperties, configurator); applyAdditionalPropertiesKvp(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsv(languageSpecificPrimitives, configurator); applyLanguageSpecificPrimitivesCsv(languageSpecificPrimitives, configurator);
applyReservedWordsMappingsKvp(reservedWordsMappings, configurator);
final ClientOptInput clientOptInput = configurator.toClientOptInput(); final ClientOptInput clientOptInput = configurator.toClientOptInput();
new DefaultGenerator().opts(clientOptInput).generate(); new DefaultGenerator().opts(clientOptInput).generate();

View File

@ -45,9 +45,11 @@ mvn clean compile
- `modelPackage` - the package to use for generated model objects/classes - `modelPackage` - the package to use for generated model objects/classes
- `apiPackage` - the package to use for generated api objects/classes - `apiPackage` - the package to use for generated api objects/classes
- `invokerPackage` - the package to use for the generated invoker objects - `invokerPackage` - the package to use for the generated invoker objects
- `modelNamePrefix` and `modelNameSuffix` - Sets the pre- or suffix for model classes and enums. - `modelNamePrefix` and `modelNameSuffix` - Sets the pre- or suffix for model classes and enums
- `useJaxbAnnotations` - enable Jaxb annotations inside the generated models
- `configOptions` - a map of language-specific parameters (see below) - `configOptions` - a map of language-specific parameters (see below)
- `configHelp` - dumps the configuration help for the specified library (generates no sources) - `configHelp` - dumps the configuration help for the specified library (generates no sources)
- `ignoreFileOverride` - specifies the full path to a `.swagger-codegen-ignore` used for pattern based overrides of generated outputs
### Custom Generator ### Custom Generator

View File

@ -21,6 +21,7 @@ import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyImportMapp
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvp; import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvp;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsv; import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsv;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvp; import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvp;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyReservedWordsMappingsKvp;
import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import java.io.File; import java.io.File;
@ -161,6 +162,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "modelNameSuffix", required = false) @Parameter(name = "modelNameSuffix", required = false)
private String modelNameSuffix; private String modelNameSuffix;
/**
* Sets an optional ignoreFileOverride path
*/
@Parameter(name = "ignoreFileOverride", required = false)
private String ignoreFileOverride;
/** /**
* A map of language-specific parameters as passed with the -c option to the command line * A map of language-specific parameters as passed with the -c option to the command line
*/ */
@ -215,6 +222,10 @@ public class CodeGenMojo extends AbstractMojo {
configurator.setGitRepoId(gitRepoId); configurator.setGitRepoId(gitRepoId);
} }
if(isNotEmpty(ignoreFileOverride)) {
configurator.setIgnoreFileOverride(ignoreFileOverride);
}
configurator.setLang(language); configurator.setLang(language);
configurator.setOutputDir(output.getAbsolutePath()); configurator.setOutputDir(output.getAbsolutePath());
@ -284,6 +295,10 @@ public class CodeGenMojo extends AbstractMojo {
if(configOptions.containsKey("additional-properties")) { if(configOptions.containsKey("additional-properties")) {
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(), configurator); applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(), configurator);
} }
if(configOptions.containsKey("reserved-words-mappings")) {
applyReservedWordsMappingsKvp(configOptions.get("reserved-words-mappings").toString(), configurator);
}
} }
if (environmentVariables != null) { if (environmentVariables != null) {
@ -330,7 +345,7 @@ public class CodeGenMojo extends AbstractMojo {
} }
if (addCompileSourceRoot) { if (addCompileSourceRoot) {
final Object sourceFolderObject = configOptions.get(CodegenConstants.SOURCE_FOLDER); final Object sourceFolderObject = configOptions == null ? null : configOptions.get(CodegenConstants.SOURCE_FOLDER);
final String sourceFolder = sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString(); final String sourceFolder = sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString();
String sourceJavaFolder = output.toString() + "/" + sourceFolder; String sourceJavaFolder = output.toString() + "/" + sourceFolder;

View File

@ -56,7 +56,7 @@ public abstract class AbstractGenerator {
if (is == null) { if (is == null) {
is = new FileInputStream(new File(name)); // May throw but never return a null value is = new FileInputStream(new File(name)); // May throw but never return a null value
} }
return new InputStreamReader(is); return new InputStreamReader(is, "UTF-8");
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e.getMessage()); LOGGER.error(e.getMessage());
} }

View File

@ -119,6 +119,8 @@ public interface CodegenConfig {
Set<String> languageSpecificPrimitives(); Set<String> languageSpecificPrimitives();
Map<String, String> reservedWordsMappings();
void preprocessSwagger(Swagger swagger); void preprocessSwagger(Swagger swagger);
void processSwagger(Swagger swagger); void processSwagger(Swagger swagger);
@ -197,4 +199,8 @@ public interface CodegenConfig {
String getHttpUserAgent(); String getHttpUserAgent();
String getCommonTemplateDir(); String getCommonTemplateDir();
void setIgnoreFilePathOverride(String ignoreFileOverride);
String getIgnoreFilePathOverride();
} }

View File

@ -12,6 +12,8 @@ public class CodegenConstants {
public static final String TEMPLATE_DIR = "templateDir"; public static final String TEMPLATE_DIR = "templateDir";
public static final String ALLOW_UNICODE_IDENTIFIERS = "allowUnicodeIdentifiers";
public static final String ALLOW_UNICODE_IDENTIFIERS_DESC = "boolean, toggles whether unicode identifiers are allowed in names or not, default is false";
public static final String INVOKER_PACKAGE = "invokerPackage"; public static final String INVOKER_PACKAGE = "invokerPackage";
public static final String INVOKER_PACKAGE_DESC = "root package for generated code"; public static final String INVOKER_PACKAGE_DESC = "root package for generated code";
@ -19,6 +21,12 @@ public class CodegenConstants {
public static final String PHP_INVOKER_PACKAGE = "phpInvokerPackage"; public static final String PHP_INVOKER_PACKAGE = "phpInvokerPackage";
public static final String PHP_INVOKER_PACKAGE_DESC = "root package for generated php code"; public static final String PHP_INVOKER_PACKAGE_DESC = "root package for generated php code";
public static final String PERL_MODULE_NAME = "perlModuleName";
public static final String PERL_MODULE_NAME_DESC = "root module name for generated perl code";
public static final String PYTHON_PACKAGE_NAME = "pythonPackageName";
public static final String PYTHON_PACKAGE_NAME_DESC = "package name for generated python code";
public static final String GROUP_ID = "groupId"; public static final String GROUP_ID = "groupId";
public static final String GROUP_ID_DESC = "groupId in generated pom.xml"; public static final String GROUP_ID_DESC = "groupId in generated pom.xml";
@ -28,6 +36,33 @@ public class CodegenConstants {
public static final String ARTIFACT_VERSION = "artifactVersion"; public static final String ARTIFACT_VERSION = "artifactVersion";
public static final String ARTIFACT_VERSION_DESC = "artifact version in generated pom.xml"; public static final String ARTIFACT_VERSION_DESC = "artifact version in generated pom.xml";
public static final String ARTIFACT_URL = "artifactUrl";
public static final String ARTIFACT_URL_DESC = "artifact URL in generated pom.xml";
public static final String ARTIFACT_DESCRIPTION = "artifactDescription";
public static final String ARTIFACT_DESCRIPTION_DESC = "artifact description in generated pom.xml";
public static final String SCM_CONNECTION = "scmConnection";
public static final String SCM_CONNECTION_DESC = "SCM connection in generated pom.xml";
public static final String SCM_DEVELOPER_CONNECTION = "scmDeveloperConnection";
public static final String SCM_DEVELOPER_CONNECTION_DESC = "SCM developer connection in generated pom.xml";
public static final String SCM_URL = "scmUrl";
public static final String SCM_URL_DESC = "SCM URL in generated pom.xml";
public static final String DEVELOPER_NAME = "developerName";
public static final String DEVELOPER_NAME_DESC = "developer name in generated pom.xml";
public static final String DEVELOPER_EMAIL = "developerEmail";
public static final String DEVELOPER_EMAIL_DESC = "developer email in generated pom.xml";
public static final String DEVELOPER_ORGANIZATION = "developerOrganization";
public static final String DEVELOPER_ORGANIZATION_DESC = "developer organization in generated pom.xml";
public static final String DEVELOPER_ORGANIZATION_URL = "developerOrganizationUrl";
public static final String DEVELOPER_ORGANIZATION_URL_DESC = "developer organization URL in generated pom.xml";
public static final String LICENSE_NAME = "licenseName"; public static final String LICENSE_NAME = "licenseName";
public static final String LICENSE_NAME_DESC = "The name of the license"; public static final String LICENSE_NAME_DESC = "The name of the license";
@ -86,6 +121,9 @@ public class CodegenConstants {
public static final String USE_COLLECTION = "useCollection"; public static final String USE_COLLECTION = "useCollection";
public static final String USE_COLLECTION_DESC = "Deserialize array types to Collection<T> instead of List<T>."; public static final String USE_COLLECTION_DESC = "Deserialize array types to Collection<T> instead of List<T>.";
public static final String INTERFACE_PREFIX = "interfacePrefix";
public static final String INTERFACE_PREFIX_DESC = "Prefix interfaces with a community standard or widely accepted prefix.";
public static final String RETURN_ICOLLECTION = "returnICollection"; public static final String RETURN_ICOLLECTION = "returnICollection";
public static final String RETURN_ICOLLECTION_DESC = "Return ICollection<T> instead of the concrete type."; public static final String RETURN_ICOLLECTION_DESC = "Return ICollection<T> instead of the concrete type.";
@ -137,8 +175,15 @@ public class CodegenConstants {
public static final String GENERATE_MODEL_TESTS_DESC = "Specifies that model tests are to be generated."; public static final String GENERATE_MODEL_TESTS_DESC = "Specifies that model tests are to be generated.";
public static final String HIDE_GENERATION_TIMESTAMP = "hideGenerationTimestamp"; public static final String HIDE_GENERATION_TIMESTAMP = "hideGenerationTimestamp";
public static final String HIDE_GENERATION_TIMESTAMP_DESC = "Hides the generation timestamp."; public static final String HIDE_GENERATION_TIMESTAMP_DESC = "Hides the generation timestamp when files are generated.";
public static final String GENERATE_PROPERTY_CHANGED = "generatePropertyChanged"; public static final String GENERATE_PROPERTY_CHANGED = "generatePropertyChanged";
public static final String GENERATE_PROPERTY_CHANGED_DESC = "Specifies that models support raising property changed events."; public static final String GENERATE_PROPERTY_CHANGED_DESC = "Specifies that models support raising property changed events.";
public static final String NON_PUBLIC_API = "nonPublicApi";
public static final String NON_PUBLIC_API_DESC = "Generates code with reduced access modifiers; allows embedding elsewhere without exposing non-public API calls to consumers.";
public static final String IGNORE_FILE_OVERRIDE = "ignoreFileOverride";
public static final String IGNORE_FILE_OVERRIDE_DESC = "Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation.";
} }

View File

@ -90,6 +90,7 @@ public class CodegenParameter {
output.collectionFormat = this.collectionFormat; output.collectionFormat = this.collectionFormat;
output.isCollectionFormatMulti = this.isCollectionFormatMulti; output.isCollectionFormatMulti = this.isCollectionFormatMulti;
output.description = this.description; output.description = this.description;
output.unescapedDescription = this.unescapedDescription;
output.baseType = this.baseType; output.baseType = this.baseType;
output.isFormParam = this.isFormParam; output.isFormParam = this.isFormParam;
output.isQueryParam = this.isQueryParam; output.isQueryParam = this.isQueryParam;

View File

@ -7,9 +7,11 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
public class CodegenProperty implements Cloneable { public class CodegenProperty implements Cloneable {
public String baseName, complexType, getter, setter, description, datatype, datatypeWithEnum, public String baseName, complexType, getter, setter, description, datatype,
dataFormat, name, min, max, defaultValue, defaultValueWithParam, baseType, containerType; datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam,
baseType, containerType, title;
/** The 'description' string without escape charcters needed by some programming languages/targets */
public String unescapedDescription; public String unescapedDescription;
/** /**
@ -50,6 +52,9 @@ public class CodegenProperty implements Cloneable {
public String nameInCamelCase; // property name in camel case public String nameInCamelCase; // property name in camel case
// enum name based on the property name, usually use as a prefix (e.g. VAR_NAME) for enum name (e.g. VAR_NAME_VALUE1) // enum name based on the property name, usually use as a prefix (e.g. VAR_NAME) for enum name (e.g. VAR_NAME_VALUE1)
public String enumName; public String enumName;
public Integer maxItems;
public Integer minItems;
@Override @Override
public String toString() { public String toString() {
@ -74,6 +79,7 @@ public class CodegenProperty implements Cloneable {
result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode()); result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode());
result = prime * result + ((defaultValueWithParam == null) ? 0 : defaultValueWithParam.hashCode()); result = prime * result + ((defaultValueWithParam == null) ? 0 : defaultValueWithParam.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((example == null) ? 0 : example.hashCode()); result = prime * result + ((example == null) ? 0 : example.hashCode());
result = prime * result + (exclusiveMaximum ? 13:31); result = prime * result + (exclusiveMaximum ? 13:31);
result = prime * result + (exclusiveMinimum ? 13:31); result = prime * result + (exclusiveMinimum ? 13:31);
@ -117,6 +123,8 @@ public class CodegenProperty implements Cloneable {
result = prime * result + Objects.hashCode(isInherited); result = prime * result + Objects.hashCode(isInherited);
result = prime * result + Objects.hashCode(nameInCamelCase); result = prime * result + Objects.hashCode(nameInCamelCase);
result = prime * result + Objects.hashCode(enumName); result = prime * result + Objects.hashCode(enumName);
result = prime * result + ((maxItems == null) ? 0 : maxItems.hashCode());
result = prime * result + ((minItems == null) ? 0 : minItems.hashCode());
return result; return result;
} }
@ -144,6 +152,9 @@ public class CodegenProperty implements Cloneable {
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) { if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
return false; return false;
} }
if ((this.title == null) ? (other.title != null) : !this.title.equals(other.title)) {
return false;
}
if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) { if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) {
return false; return false;
} }
@ -283,6 +294,12 @@ public class CodegenProperty implements Cloneable {
if (!Objects.equals(this.enumName, other.enumName)) { if (!Objects.equals(this.enumName, other.enumName)) {
return false; return false;
} }
if (this.maxItems != other.maxItems && (this.maxItems == null || !this.maxItems.equals(other.maxItems))) {
return false;
}
if (this.minItems != other.minItems && (this.minItems == null || !this.minItems.equals(other.minItems))) {
return false;
}
return true; return true;
} }

View File

@ -19,6 +19,7 @@ public class CodegenResponse {
public Boolean isFile = Boolean.FALSE; public Boolean isFile = Boolean.FALSE;
public Object schema; public Object schema;
public String jsonSchema; public String jsonSchema;
public Map<String, Object> vendorExtensions;
public boolean isWildcard() { public boolean isWildcard() {
return "0".equals(code) || "default".equals(code); return "0".equals(code) || "default".equals(code);
@ -68,6 +69,8 @@ public class CodegenResponse {
return false; return false;
if (schema != null ? !schema.equals(that.schema) : that.schema != null) if (schema != null ? !schema.equals(that.schema) : that.schema != null)
return false; return false;
if (vendorExtensions != null ? !vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions != null)
return false;
return jsonSchema != null ? jsonSchema.equals(that.jsonSchema) : that.jsonSchema == null; return jsonSchema != null ? jsonSchema.equals(that.jsonSchema) : that.jsonSchema == null;
} }
@ -91,6 +94,7 @@ public class CodegenResponse {
result = 31 * result + (isFile != null ? isFile.hashCode() : 0); result = 31 * result + (isFile != null ? isFile.hashCode() : 0);
result = 31 * result + (schema != null ? schema.hashCode() : 0); result = 31 * result + (schema != null ? schema.hashCode() : 0);
result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0); result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0);
result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0);
return result; return result;
} }
} }

View File

@ -92,6 +92,7 @@ public class DefaultCodegen {
protected Map<String, String> modelTestTemplateFiles = new HashMap<String, String>(); protected Map<String, String> modelTestTemplateFiles = new HashMap<String, String>();
protected Map<String, String> apiDocTemplateFiles = new HashMap<String, String>(); protected Map<String, String> apiDocTemplateFiles = new HashMap<String, String>();
protected Map<String, String> modelDocTemplateFiles = new HashMap<String, String>(); protected Map<String, String> modelDocTemplateFiles = new HashMap<String, String>();
protected Map<String, String> reservedWordsMappings = new HashMap<String, String>();
protected String templateDir; protected String templateDir;
protected String embeddedTemplateDir; protected String embeddedTemplateDir;
protected String commonTemplateDir = "_common"; protected String commonTemplateDir = "_common";
@ -106,6 +107,7 @@ public class DefaultCodegen {
protected String library; protected String library;
protected Boolean sortParamsByRequiredFlag = true; protected Boolean sortParamsByRequiredFlag = true;
protected Boolean ensureUniqueParams = true; protected Boolean ensureUniqueParams = true;
protected Boolean allowUnicodeIdentifiers = false;
protected String gitUserId, gitRepoId, releaseNote; protected String gitUserId, gitRepoId, releaseNote;
protected String httpUserAgent; protected String httpUserAgent;
protected Boolean hideGenerationTimestamp = true; protected Boolean hideGenerationTimestamp = true;
@ -114,6 +116,8 @@ public class DefaultCodegen {
// Then translated back during JSON encoding and decoding // Then translated back during JSON encoding and decoding
protected Map<String, String> specialCharReplacements = new HashMap<String, String>(); protected Map<String, String> specialCharReplacements = new HashMap<String, String>();
protected String ignoreFilePathOverride;
public List<CliOption> cliOptions() { public List<CliOption> cliOptions() {
return cliOptions; return cliOptions;
} }
@ -141,6 +145,11 @@ public class DefaultCodegen {
.get(CodegenConstants.ENSURE_UNIQUE_PARAMS).toString())); .get(CodegenConstants.ENSURE_UNIQUE_PARAMS).toString()));
} }
if (additionalProperties.containsKey(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS)) {
this.setAllowUnicodeIdentifiers(Boolean.valueOf(additionalProperties
.get(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS).toString()));
}
if(additionalProperties.containsKey(CodegenConstants.MODEL_NAME_PREFIX)){ if(additionalProperties.containsKey(CodegenConstants.MODEL_NAME_PREFIX)){
this.setModelNamePrefix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_PREFIX)); this.setModelNamePrefix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_PREFIX));
} }
@ -148,7 +157,6 @@ public class DefaultCodegen {
if(additionalProperties.containsKey(CodegenConstants.MODEL_NAME_SUFFIX)){ if(additionalProperties.containsKey(CodegenConstants.MODEL_NAME_SUFFIX)){
this.setModelNameSuffix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_SUFFIX)); this.setModelNameSuffix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_SUFFIX));
} }
} }
// override with any special post-processing for all models // override with any special post-processing for all models
@ -185,12 +193,18 @@ public class DefaultCodegen {
for (String name : allModels.keySet()) { for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name); CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.parent); CodegenModel parent = allModels.get(cm.parent);
// if a discriminator exists on the parent, don't add this child to the inheritance heirarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) { while (parent != null) {
if (parent.children == null) { if (parent.children == null) {
parent.children = new ArrayList<CodegenModel>(); parent.children = new ArrayList<CodegenModel>();
} }
parent.children.add(cm); parent.children.add(cm);
if (parent.discriminator == null) {
parent = allModels.get(parent.parent); parent = allModels.get(parent.parent);
} else {
parent = null;
}
} }
} }
} }
@ -303,6 +317,10 @@ public class DefaultCodegen {
* @return the sanitized variable name for enum * @return the sanitized variable name for enum
*/ */
public String toEnumVarName(String value, String datatype) { public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "EMPTY";
}
String var = value.replaceAll("\\W+", "_").toUpperCase(); String var = value.replaceAll("\\W+", "_").toUpperCase();
if (var.matches("\\d.*")) { if (var.matches("\\d.*")) {
return "_" + var; return "_" + var;
@ -465,6 +483,10 @@ public class DefaultCodegen {
return modelDocTemplateFiles; return modelDocTemplateFiles;
} }
public Map<String, String> reservedWordsMappings() {
return reservedWordsMappings;
}
public Map<String, String> apiTestTemplateFiles() { public Map<String, String> apiTestTemplateFiles() {
return apiTestTemplateFiles; return apiTestTemplateFiles;
} }
@ -565,6 +587,10 @@ public class DefaultCodegen {
this.ensureUniqueParams = ensureUniqueParams; this.ensureUniqueParams = ensureUniqueParams;
} }
public void setAllowUnicodeIdentifiers(Boolean allowUnicodeIdentifiers) {
this.allowUnicodeIdentifiers = allowUnicodeIdentifiers;
}
/** /**
* Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33) * Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33)
* *
@ -819,6 +845,10 @@ public class DefaultCodegen {
cliOptions.add(CliOption.newBoolean(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants cliOptions.add(CliOption.newBoolean(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants
.ENSURE_UNIQUE_PARAMS_DESC).defaultValue(Boolean.TRUE.toString())); .ENSURE_UNIQUE_PARAMS_DESC).defaultValue(Boolean.TRUE.toString()));
//name formatting options
cliOptions.add(CliOption.newBoolean(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, CodegenConstants
.ALLOW_UNICODE_IDENTIFIERS_DESC).defaultValue(Boolean.FALSE.toString()));
// initialize special character mapping // initialize special character mapping
initalizeSpecialCharacterMapping(); initalizeSpecialCharacterMapping();
} }
@ -1261,6 +1291,18 @@ public class DefaultCodegen {
allProperties = new LinkedHashMap<String, Property>(); allProperties = new LinkedHashMap<String, Property>();
allRequired = new ArrayList<String>(); allRequired = new ArrayList<String>();
m.allVars = new ArrayList<CodegenProperty>(); m.allVars = new ArrayList<CodegenProperty>();
int modelImplCnt = 0; // only one inline object allowed in a ComposedModel
for (Model innerModel: ((ComposedModel)model).getAllOf()) {
if (innerModel instanceof ModelImpl) {
if (m.discriminator == null) {
m.discriminator = ((ModelImpl) innerModel).getDiscriminator();
}
if (modelImplCnt++ > 1) {
LOGGER.warn("More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored.");
break; // only one ModelImpl with discriminator allowed in allOf
}
}
}
} else { } else {
allProperties = null; allProperties = null;
allRequired = null; allRequired = null;
@ -1436,6 +1478,7 @@ public class DefaultCodegen {
property.nameInCamelCase = camelize(property.name, false); property.nameInCamelCase = camelize(property.name, false);
property.description = escapeText(p.getDescription()); property.description = escapeText(p.getDescription());
property.unescapedDescription = p.getDescription(); property.unescapedDescription = p.getDescription();
property.title = p.getTitle();
property.getter = "get" + getterAndSetterCapitalize(name); property.getter = "get" + getterAndSetterCapitalize(name);
property.setter = "set" + getterAndSetterCapitalize(name); property.setter = "set" + getterAndSetterCapitalize(name);
property.example = toExampleValue(p); property.example = toExampleValue(p);
@ -1687,6 +1730,8 @@ public class DefaultCodegen {
property.baseType = getSwaggerType(p); property.baseType = getSwaggerType(p);
// handle inner property // handle inner property
ArrayProperty ap = (ArrayProperty) p; ArrayProperty ap = (ArrayProperty) p;
property.maxItems = ap.getMaxItems();
property.minItems = ap.getMinItems();
CodegenProperty cp = fromProperty(property.name, ap.getItems()); CodegenProperty cp = fromProperty(property.name, ap.getItems());
updatePropertyForArray(property, cp); updatePropertyForArray(property, cp);
} else if (p instanceof MapProperty) { } else if (p instanceof MapProperty) {
@ -1714,6 +1759,7 @@ public class DefaultCodegen {
LOGGER.warn("skipping invalid array property " + Json.pretty(property)); LOGGER.warn("skipping invalid array property " + Json.pretty(property));
return; return;
} }
property.dataFormat = innerProperty.dataFormat;
if (!languageSpecificPrimitives.contains(innerProperty.baseType)) { if (!languageSpecificPrimitives.contains(innerProperty.baseType)) {
property.complexType = innerProperty.baseType; property.complexType = innerProperty.baseType;
} else { } else {
@ -1750,6 +1796,7 @@ public class DefaultCodegen {
property.isPrimitiveType = true; property.isPrimitiveType = true;
} }
property.items = innerProperty; property.items = innerProperty;
property.dataFormat = innerProperty.dataFormat;
// inner item is Enum // inner item is Enum
if (isPropertyInnerMostEnum(property)) { if (isPropertyInnerMostEnum(property)) {
// isEnum is set to true when the type is an enum // isEnum is set to true when the type is an enum
@ -2184,6 +2231,7 @@ public class DefaultCodegen {
r.schema = response.getSchema(); r.schema = response.getSchema();
r.examples = toExamples(response.getExamples()); r.examples = toExamples(response.getExamples());
r.jsonSchema = Json.pretty(response); r.jsonSchema = Json.pretty(response);
r.vendorExtensions = response.getVendorExtensions();
addHeaders(response, r.headers); addHeaders(response, r.headers);
if (r.schema != null) { if (r.schema != null) {
@ -2354,7 +2402,7 @@ public class DefaultCodegen {
// validation // validation
// handle maximum, minimum properly for int/long by removing the trailing ".0" // handle maximum, minimum properly for int/long by removing the trailing ".0"
if ("integer".equals(type)) { if ("integer".equals(qp.getType())) {
p.maximum = qp.getMaximum() == null ? null : String.valueOf(qp.getMaximum().longValue()); p.maximum = qp.getMaximum() == null ? null : String.valueOf(qp.getMaximum().longValue());
p.minimum = qp.getMinimum() == null ? null : String.valueOf(qp.getMinimum().longValue()); p.minimum = qp.getMinimum() == null ? null : String.valueOf(qp.getMinimum().longValue());
} else { } else {
@ -3224,7 +3272,14 @@ public class DefaultCodegen {
// remove everything else other than word, number and _ // remove everything else other than word, number and _
// $php_variable => php_variable // $php_variable => php_variable
return name.replaceAll("[^a-zA-Z0-9_]", ""); if (allowUnicodeIdentifiers) { //could be converted to a single line with ?: operator
name = Pattern.compile("\\W", Pattern.UNICODE_CHARACTER_CLASS).matcher(name).replaceAll("");
}
else {
name = name.replaceAll("\\W", "");
}
return name;
} }
/** /**
@ -3416,11 +3471,44 @@ public class DefaultCodegen {
public boolean convertPropertyToBooleanAndWriteBack(String propertyKey) { public boolean convertPropertyToBooleanAndWriteBack(String propertyKey) {
boolean booleanValue = false; boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) { if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString()); booleanValue = convertPropertyToBoolean(propertyKey);
// write back as boolean // write back as boolean
additionalProperties.put(propertyKey, booleanValue); writePropertyBack(propertyKey, booleanValue);
} }
return booleanValue; return booleanValue;
} }
/**
* Provides an override location, if any is specified, for the .swagger-codegen-ignore.
*
* This is originally intended for the first generation only.
*
* @return a string of the full path to an override ignore file.
*/
public String getIgnoreFilePathOverride() {
return ignoreFilePathOverride;
}
/**
* Sets an override location for the .swagger-codegen.ignore location for the first code generation.
*
* @param ignoreFileOverride The full path to an ignore file
*/
public void setIgnoreFilePathOverride(final String ignoreFileOverride) {
this.ignoreFilePathOverride = ignoreFileOverride;
}
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
}
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}
} }

View File

@ -42,7 +42,21 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
this.swagger = opts.getSwagger(); this.swagger = opts.getSwagger();
this.config = opts.getConfig(); this.config = opts.getConfig();
this.config.additionalProperties().putAll(opts.getOpts().getProperties()); this.config.additionalProperties().putAll(opts.getOpts().getProperties());
ignoreProcessor = new CodegenIgnoreProcessor(this.config.getOutputDir());
String ignoreFileLocation = this.config.getIgnoreFilePathOverride();
if(ignoreFileLocation != null) {
final File ignoreFile = new File(ignoreFileLocation);
if(ignoreFile.exists() && ignoreFile.canRead()) {
this.ignoreProcessor = new CodegenIgnoreProcessor(ignoreFile);
} else {
LOGGER.warn("Ignore file specified at {} is not valid. This will fall back to an existing ignore file if present in the output directory.", ignoreFileLocation);
}
}
if(this.ignoreProcessor == null) {
this.ignoreProcessor = new CodegenIgnoreProcessor(this.config.getOutputDir());
}
return this; return this;
} }

View File

@ -54,12 +54,15 @@ public class CodegenConfigurator {
private String artifactId; private String artifactId;
private String artifactVersion; private String artifactVersion;
private String library; private String library;
private String ignoreFileOverride;
private Map<String, String> systemProperties = new HashMap<String, String>(); private Map<String, String> systemProperties = new HashMap<String, String>();
private Map<String, String> instantiationTypes = new HashMap<String, String>(); private Map<String, String> instantiationTypes = new HashMap<String, String>();
private Map<String, String> typeMappings = new HashMap<String, String>(); private Map<String, String> typeMappings = new HashMap<String, String>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>(); private Map<String, Object> additionalProperties = new HashMap<String, Object>();
private Map<String, String> importMappings = new HashMap<String, String>(); private Map<String, String> importMappings = new HashMap<String, String>();
private Set<String> languageSpecificPrimitives = new HashSet<String>(); private Set<String> languageSpecificPrimitives = new HashSet<String>();
private Map<String, String> reservedWordMappings = new HashMap<String, String>();
private String gitUserId="GIT_USER_ID"; private String gitUserId="GIT_USER_ID";
private String gitRepoId="GIT_REPO_ID"; private String gitRepoId="GIT_REPO_ID";
private String releaseNote="Minor update"; private String releaseNote="Minor update";
@ -342,6 +345,29 @@ public class CodegenConfigurator {
return this; return this;
} }
public Map<String, String> getReservedWordsMappings() {
return reservedWordMappings;
}
public CodegenConfigurator setReservedWordsMappings(Map<String, String> reservedWordsMappings) {
this.reservedWordMappings = reservedWordsMappings;
return this;
}
public CodegenConfigurator addAdditionalReservedWordMapping(String key, String value) {
this.reservedWordMappings.put(key, value);
return this;
}
public String getIgnoreFileOverride() {
return ignoreFileOverride;
}
public CodegenConfigurator setIgnoreFileOverride(final String ignoreFileOverride) {
this.ignoreFileOverride = ignoreFileOverride;
return this;
}
public ClientOptInput toClientOptInput() { public ClientOptInput toClientOptInput() {
Validate.notEmpty(lang, "language must be specified"); Validate.notEmpty(lang, "language must be specified");
@ -355,11 +381,13 @@ public class CodegenConfigurator {
config.setInputSpec(inputSpec); config.setInputSpec(inputSpec);
config.setOutputDir(outputDir); config.setOutputDir(outputDir);
config.setSkipOverwrite(skipOverwrite); config.setSkipOverwrite(skipOverwrite);
config.setIgnoreFilePathOverride(ignoreFileOverride);
config.instantiationTypes().putAll(instantiationTypes); config.instantiationTypes().putAll(instantiationTypes);
config.typeMapping().putAll(typeMappings); config.typeMapping().putAll(typeMappings);
config.importMapping().putAll(importMappings); config.importMapping().putAll(importMappings);
config.languageSpecificPrimitives().addAll(languageSpecificPrimitives); config.languageSpecificPrimitives().addAll(languageSpecificPrimitives);
config.reservedWordsMappings().putAll(reservedWordMappings);
checkAndSetAdditionalProperty(apiPackage, CodegenConstants.API_PACKAGE); checkAndSetAdditionalProperty(apiPackage, CodegenConstants.API_PACKAGE);
checkAndSetAdditionalProperty(modelPackage, CodegenConstants.MODEL_PACKAGE); checkAndSetAdditionalProperty(modelPackage, CodegenConstants.MODEL_PACKAGE);

View File

@ -58,6 +58,13 @@ public final class CodegenConfiguratorUtils {
} }
} }
public static void applyReservedWordsMappingsKvp(String reservedWordMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(reservedWordMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addAdditionalReservedWordMapping(entry.getKey(), entry.getValue());
}
}
private static Set<String> createSetFromCsvList(String csvProperty) { private static Set<String> createSetFromCsvList(String csvProperty) {
final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty); final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty);
return new HashSet<String>(values); return new HashSet<String>(values);
@ -74,4 +81,6 @@ public final class CodegenConfiguratorUtils {
return result; return result;
} }
} }

View File

@ -9,13 +9,22 @@ import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty; import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.DateProperty; import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.DateTimeProperty; import io.swagger.models.properties.DateTimeProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty; import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.DecimalProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.BaseIntegerProperty;
import io.swagger.models.properties.AbstractNumericProperty;
import io.swagger.models.properties.PasswordProperty;
import io.swagger.models.properties.UUIDProperty;
import io.swagger.models.properties.Property; import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty; import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty; import io.swagger.models.properties.StringProperty;
import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -25,6 +34,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
public class XmlExampleGenerator { public class XmlExampleGenerator {
protected final Logger LOGGER = LoggerFactory.getLogger(XmlExampleGenerator.class);
public static String NEWLINE = "\n"; public static String NEWLINE = "\n";
public static String TAG_START = "<"; public static String TAG_START = "<";
public static String CLOSE_TAG = ">"; public static String CLOSE_TAG = ">";
@ -163,45 +173,44 @@ public class XmlExampleGenerator {
return sb.toString(); return sb.toString();
} }
/**
* Get the example string value for the given Property.
*
* If an example value was not provided in the specification, a default will be generated.
*
* @param property Property to get example string for
*
* @return Example String
*/
protected String getExample(Property property) { protected String getExample(Property property) {
if (property instanceof DateTimeProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample().toString(); return property.getExample().toString();
} else { } else if (property instanceof DateTimeProperty) {
return "2000-01-23T04:56:07.000Z"; return "2000-01-23T04:56:07.000Z";
}
} else if (property instanceof StringProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "string";
}
} else if (property instanceof DateProperty) { } else if (property instanceof DateProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "2000-01-23"; return "2000-01-23";
}
} else if (property instanceof IntegerProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "0";
}
} else if (property instanceof BooleanProperty) { } else if (property instanceof BooleanProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "true"; return "true";
}
} else if (property instanceof LongProperty) { } else if (property instanceof LongProperty) {
if (property.getExample() != null) { return "123456789";
return property.getExample().toString(); } else if (property instanceof DoubleProperty) { // derived from DecimalProperty so make sure this is first
} else { return "3.149";
return "123456"; } else if (property instanceof DecimalProperty) {
return "1.3579";
} else if (property instanceof PasswordProperty) {
return "********";
} else if (property instanceof UUIDProperty) {
return "046b6c7f-0b8a-43b9-b35d-6489e6daee91";
// do these last in case the specific types above are derived from these classes
} else if (property instanceof StringProperty) {
return "aeiou";
} else if (property instanceof BaseIntegerProperty) {
return "123";
} else if (property instanceof AbstractNumericProperty) {
return "1.23";
} }
} LOGGER.warn("default example value not implemented for " + property);
return "not implemented " + property; return "";
} }
@SuppressWarnings("static-method") @SuppressWarnings("static-method")

View File

@ -8,34 +8,71 @@ import org.slf4j.LoggerFactory;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
/**
* Presents a processing utility for parsing and evaluating files containing common ignore patterns. (.swagger-codegen-ignore)
*/
public class CodegenIgnoreProcessor { public class CodegenIgnoreProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(CodegenIgnoreProcessor.class); private static final Logger LOGGER = LoggerFactory.getLogger(CodegenIgnoreProcessor.class);
private final String outputPath;
private File ignoreFile = null;
private List<Rule> exclusionRules = new ArrayList<>(); private List<Rule> exclusionRules = new ArrayList<>();
private List<Rule> inclusionRules = new ArrayList<>(); private List<Rule> inclusionRules = new ArrayList<>();
public CodegenIgnoreProcessor(String outputPath) { /**
this.outputPath = outputPath; * Loads the default ignore file (.swagger-codegen-ignore) from the specified path.
final File directory = new File(outputPath); *
if(directory.exists() && directory.isDirectory()){ * @param baseDirectory The base directory of the files to be processed. This contains the ignore file.
final File codegenIgnore = new File(directory, ".swagger-codegen-ignore"); */
if(codegenIgnore.exists() && codegenIgnore.isFile()){ public CodegenIgnoreProcessor(final String baseDirectory) {
try { this(baseDirectory, ".swagger-codegen-ignore");
loadCodegenRules(codegenIgnore);
} catch (IOException e) {
LOGGER.error("Could not process .swagger-codegen-ignore.", e.getMessage());
} }
/**
* Loads the specified ignore file by name ([ignoreFile]) from the specified path.
*
* @param baseDirectory The base directory of the files to be processed. This contains the ignore file.
* @param ignoreFile The file containing ignore patterns.
*/
@SuppressWarnings("WeakerAccess")
public CodegenIgnoreProcessor(final String baseDirectory, final String ignoreFile) {
final File directory = new File(baseDirectory);
final File targetIgnoreFile = new File(directory, ignoreFile);
if (directory.exists() && directory.isDirectory()) {
loadFromFile(targetIgnoreFile);
} else { } else {
// log info message LOGGER.warn("Directory does not exist, or is inaccessible. No file will be evaluated.");
LOGGER.info("No .swagger-codegen-ignore file found.");
}
} }
} }
void loadCodegenRules(File codegenIgnore) throws IOException { /**
* Constructs an instance of {@link CodegenIgnoreProcessor} from an ignore file defined by {@code targetIgnoreFile}.
*
* @param targetIgnoreFile The ignore file location.
*/
public CodegenIgnoreProcessor(final File targetIgnoreFile) {
loadFromFile(targetIgnoreFile);
}
private void loadFromFile(File targetIgnoreFile) {
if (targetIgnoreFile.exists() && targetIgnoreFile.isFile()) {
try {
loadCodegenRules(targetIgnoreFile);
this.ignoreFile = targetIgnoreFile;
} catch (IOException e) {
LOGGER.error(String.format("Could not process %s.", targetIgnoreFile.getName()), e.getMessage());
}
} else {
// log info message
LOGGER.info(String.format("No %s file found.", targetIgnoreFile.getName()));
}
}
void loadCodegenRules(final File codegenIgnore) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(codegenIgnore))) { try (BufferedReader reader = new BufferedReader(new FileReader(codegenIgnore))) {
String line; String line;
@ -61,8 +98,17 @@ public class CodegenIgnoreProcessor {
} }
} }
public boolean allowsFile(File targetFile) { /**
File file = new File(new File(this.outputPath).toURI().relativize(targetFile.toURI()).getPath()); * Determines whether or not a file defined by {@code toEvaluate} is allowed,
* under the exclusion rules from the ignore file being processed.
*
* @param targetFile The file to check against exclusion rules from the ignore file.
* @return {@code false} if file matches any pattern in the ignore file (disallowed), otherwise {@code true} (allowed).
*/
public boolean allowsFile(final File targetFile) {
if(this.ignoreFile == null) return true;
File file = new File(this.ignoreFile.getParentFile().toURI().relativize(targetFile.toURI()).getPath());
Boolean directoryExcluded = false; Boolean directoryExcluded = false;
Boolean exclude = false; Boolean exclude = false;
if(exclusionRules.size() == 0 && inclusionRules.size() == 0) { if(exclusionRules.size() == 0 && inclusionRules.size() == 0) {
@ -124,10 +170,23 @@ public class CodegenIgnoreProcessor {
return Boolean.FALSE.equals(exclude); return Boolean.FALSE.equals(exclude);
} }
/**
* Allows a consumer to manually inspect explicit "inclusion rules". That is, patterns in the ignore file which have been negated.
*
* @return A {@link ImmutableList#copyOf(Collection)} of rules which possibly negate exclusion rules in the ignore file.
*/
public List<Rule> getInclusionRules() { public List<Rule> getInclusionRules() {
return ImmutableList.copyOf(inclusionRules); return ImmutableList.copyOf(inclusionRules);
} }
/**
* Allows a consumer to manually inspect all "exclusion rules". That is, patterns in the ignore file which represent
* files and directories to be excluded, unless explicitly overridden by {@link CodegenIgnoreProcessor#getInclusionRules()} rules.
*
* NOTE: Existence in this list doesn't mean a file is excluded. The rule can be overridden by {@link CodegenIgnoreProcessor#getInclusionRules()} rules.
*
* @return A {@link ImmutableList#copyOf(Collection)} of rules which define exclusions by patterns in the ignore file.
*/
public List<Rule> getExclusionRules() { public List<Rule> getExclusionRules() {
return ImmutableList.copyOf(exclusionRules); return ImmutableList.copyOf(exclusionRules);
} }

View File

@ -51,6 +51,8 @@ public abstract class Rule {
* Example: **\/*.bak excludes all backup. Adding !/test.bak will include test.bak in the project root. * Example: **\/*.bak excludes all backup. Adding !/test.bak will include test.bak in the project root.
* <p> * <p>
* NOTE: It is not possible to re-include a file if a parent directory of that file is excluded. * NOTE: It is not possible to re-include a file if a parent directory of that file is excluded.
*
* @return {@code true} if the rule is negated (inverse), otherwise {@code false} (normal).
*/ */
public Boolean getNegated() { public Boolean getNegated() {
return this.syntax != null && this.syntax.size() > 0 && this.syntax.get(0).getToken() == IgnoreLineParser.Token.NEGATE; return this.syntax != null && this.syntax.size() > 0 && this.syntax.get(0).getToken() == IgnoreLineParser.Token.NEGATE;

View File

@ -27,6 +27,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
protected String packageCompany = "Swagger"; protected String packageCompany = "Swagger";
protected String packageCopyright = "No Copyright"; protected String packageCopyright = "No Copyright";
protected String interfacePrefix = "I";
protected String sourceFolder = "src"; protected String sourceFolder = "src";
// TODO: Add option for test folder output location. Nice to allow e.g. ./test instead of ./src. // TODO: Add option for test folder output location. Nice to allow e.g. ./test instead of ./src.
@ -254,6 +256,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES)) { if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES)) {
setOptionalEmitDefaultValue(Boolean.valueOf(additionalProperties.get(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES).toString())); setOptionalEmitDefaultValue(Boolean.valueOf(additionalProperties.get(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES).toString()));
} }
if (additionalProperties.containsKey(CodegenConstants.INTERFACE_PREFIX)) {
String useInterfacePrefix = additionalProperties.get(CodegenConstants.INTERFACE_PREFIX).toString();
if("false".equals(useInterfacePrefix.toLowerCase())) {
setInterfacePrefix("");
} else if(!"true".equals(useInterfacePrefix.toLowerCase())) {
// NOTE: if user passes "true" explicitly, we use the default I- prefix. The other supported case here is a custom prefix.
setInterfacePrefix(sanitizeName(useInterfacePrefix));
}
}
// This either updates additionalProperties with the above fixes, or sets the default if the option was not specified.
additionalProperties.put(CodegenConstants.INTERFACE_PREFIX, interfacePrefix);
} }
@Override @Override
@ -405,6 +420,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -466,7 +484,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (p instanceof StringProperty) { if (p instanceof StringProperty) {
StringProperty dp = (StringProperty) p; StringProperty dp = (StringProperty) p;
if (dp.getDefault() != null) { if (dp.getDefault() != null) {
return "\"" + dp.getDefault() + "\""; String _default = dp.getDefault();
if (dp.getEnum() == null) {
return "\"" + _default + "\"";
} else {
// convert to enum var name later in postProcessModels
return _default;
}
} }
} else if (p instanceof BooleanProperty) { } else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p; BooleanProperty dp = (BooleanProperty) p;
@ -613,8 +637,20 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
this.sourceFolder = sourceFolder; this.sourceFolder = sourceFolder;
} }
public String getInterfacePrefix() {
return interfacePrefix;
}
public void setInterfacePrefix(final String interfacePrefix) {
this.interfacePrefix = interfacePrefix;
}
@Override @Override
public String toEnumVarName(String name, String datatype) { public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(name) != null) { if (getSymbolName(name) != null) {
return camelize(getSymbolName(name)); return camelize(getSymbolName(name));

View File

@ -52,6 +52,15 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";
protected String artifactId = "swagger-java"; protected String artifactId = "swagger-java";
protected String artifactVersion = "1.0.0"; protected String artifactVersion = "1.0.0";
protected String artifactUrl = "https://github.com/swagger-api/swagger-codegen";
protected String artifactDescription = "Swagger Java";
protected String developerName = "Swagger";
protected String developerEmail = "apiteam@swagger.io";
protected String developerOrganization = "Swagger";
protected String developerOrganizationUrl = "http://swagger.io";
protected String scmConnection = "scm:git:git@github.com:swagger-api/swagger-codegen.git";
protected String scmDeveloperConnection = "scm:git:git@github.com:swagger-api/swagger-codegen.git";
protected String scmUrl = "https://github.com/swagger-api/swagger-codegen";
protected String licenseName = "Unlicense"; protected String licenseName = "Unlicense";
protected String licenseUrl = "http://unlicense.org"; protected String licenseUrl = "http://unlicense.org";
protected String projectFolder = "src" + File.separator + "main"; protected String projectFolder = "src" + File.separator + "main";
@ -118,6 +127,15 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC)); cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC)); cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC)); cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_URL, CodegenConstants.ARTIFACT_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_DESCRIPTION, CodegenConstants.ARTIFACT_DESCRIPTION_DESC));
cliOptions.add(new CliOption(CodegenConstants.SCM_CONNECTION, CodegenConstants.SCM_CONNECTION_DESC));
cliOptions.add(new CliOption(CodegenConstants.SCM_DEVELOPER_CONNECTION, CodegenConstants.SCM_DEVELOPER_CONNECTION_DESC));
cliOptions.add(new CliOption(CodegenConstants.SCM_URL, CodegenConstants.SCM_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_NAME, CodegenConstants.DEVELOPER_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_EMAIL, CodegenConstants.DEVELOPER_EMAIL_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_ORGANIZATION, CodegenConstants.DEVELOPER_ORGANIZATION_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_ORGANIZATION_URL, CodegenConstants.DEVELOPER_ORGANIZATION_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.LICENSE_NAME, CodegenConstants.LICENSE_NAME_DESC)); cliOptions.add(new CliOption(CodegenConstants.LICENSE_NAME, CodegenConstants.LICENSE_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.LICENSE_URL, CodegenConstants.LICENSE_URL_DESC)); cliOptions.add(new CliOption(CodegenConstants.LICENSE_URL, CodegenConstants.LICENSE_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC)); cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
@ -191,6 +209,60 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion); additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
} }
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_URL)) {
this.setArtifactUrl((String) additionalProperties.get(CodegenConstants.ARTIFACT_URL));
} else {
additionalProperties.put(CodegenConstants.ARTIFACT_URL, artifactUrl);
}
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_DESCRIPTION)) {
this.setArtifactDescription((String) additionalProperties.get(CodegenConstants.ARTIFACT_DESCRIPTION));
} else {
additionalProperties.put(CodegenConstants.ARTIFACT_DESCRIPTION, artifactDescription);
}
if (additionalProperties.containsKey(CodegenConstants.SCM_CONNECTION)) {
this.setScmConnection((String) additionalProperties.get(CodegenConstants.SCM_CONNECTION));
} else {
additionalProperties.put(CodegenConstants.SCM_CONNECTION, scmConnection);
}
if (additionalProperties.containsKey(CodegenConstants.SCM_DEVELOPER_CONNECTION)) {
this.setScmDeveloperConnection((String) additionalProperties.get(CodegenConstants.SCM_DEVELOPER_CONNECTION));
} else {
additionalProperties.put(CodegenConstants.SCM_DEVELOPER_CONNECTION, scmDeveloperConnection);
}
if (additionalProperties.containsKey(CodegenConstants.SCM_URL)) {
this.setScmUrl((String) additionalProperties.get(CodegenConstants.SCM_URL));
} else {
additionalProperties.put(CodegenConstants.SCM_URL, scmUrl);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_NAME)) {
this.setDeveloperName((String) additionalProperties.get(CodegenConstants.DEVELOPER_NAME));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_NAME, developerName);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_EMAIL)) {
this.setDeveloperEmail((String) additionalProperties.get(CodegenConstants.DEVELOPER_EMAIL));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_EMAIL, developerEmail);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_ORGANIZATION)) {
this.setDeveloperOrganization((String) additionalProperties.get(CodegenConstants.DEVELOPER_ORGANIZATION));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_ORGANIZATION, developerOrganization);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_ORGANIZATION_URL)) {
this.setDeveloperOrganizationUrl((String) additionalProperties.get(CodegenConstants.DEVELOPER_ORGANIZATION_URL));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_ORGANIZATION_URL, developerOrganizationUrl);
}
if (additionalProperties.containsKey(CodegenConstants.LICENSE_NAME)) { if (additionalProperties.containsKey(CodegenConstants.LICENSE_NAME)) {
this.setLicenseName((String) additionalProperties.get(CodegenConstants.LICENSE_NAME)); this.setLicenseName((String) additionalProperties.get(CodegenConstants.LICENSE_NAME));
} else { } else {
@ -336,6 +408,9 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -434,11 +509,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override @Override
public String toModelName(final String name) { public String toModelName(final String name) {
final String sanitizedName = sanitizeName(modelNamePrefix + name + modelNameSuffix); final String sanitizedName = sanitizeName(name);
String nameWithPrefixSuffix = sanitizedName;
if (!StringUtils.isEmpty(modelNamePrefix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = modelNamePrefix + "_" + nameWithPrefixSuffix;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = nameWithPrefixSuffix + "_" + modelNameSuffix;
}
// camelize the model name // camelize the model name
// phone_number => PhoneNumber // phone_number => PhoneNumber
final String camelizedName = camelize(sanitizedName); final String camelizedName = camelize(nameWithPrefixSuffix);
// model name cannot use reserved keyword, e.g. return // model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) { if (isReservedWord(camelizedName)) {
@ -448,7 +534,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
} }
// model name starts with number // model name starts with number
if (name.matches("^\\d.*")) { if (camelizedName.matches("^\\d.*")) {
final String modelName = "Model" + camelizedName; // e.g. 200Response => Model200Response (after camelize) final String modelName = "Model" + camelizedName; // e.g. 200Response => Model200Response (after camelize)
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName); LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
return modelName; return modelName;
@ -815,6 +901,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override @Override
public String toEnumVarName(String value, String datatype) { public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "EMPTY";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(value) != null) { if (getSymbolName(value) != null) {
return getSymbolName(value).toUpperCase(); return getSymbolName(value).toUpperCase();
@ -929,6 +1019,42 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.artifactVersion = artifactVersion; this.artifactVersion = artifactVersion;
} }
public void setArtifactUrl(String artifactUrl) {
this.artifactUrl = artifactUrl;
}
public void setArtifactDescription(String artifactDescription) {
this.artifactDescription = artifactDescription;
}
public void setScmConnection(String scmConnection) {
this.scmConnection = scmConnection;
}
public void setScmDeveloperConnection(String scmDeveloperConnection) {
this.scmDeveloperConnection = scmDeveloperConnection;
}
public void setScmUrl(String scmUrl) {
this.scmUrl = scmUrl;
}
public void setDeveloperName(String developerName) {
this.developerName = developerName;
}
public void setDeveloperEmail(String developerEmail) {
this.developerEmail = developerEmail;
}
public void setDeveloperOrganization(String developerOrganization) {
this.developerOrganization = developerOrganization;
}
public void setDeveloperOrganizationUrl(String developerOrganizationUrl) {
this.developerOrganizationUrl = developerOrganizationUrl;
}
public void setLicenseName(String licenseName) { public void setLicenseName(String licenseName) {
this.licenseName = licenseName; this.licenseName = licenseName;
} }
@ -1008,4 +1134,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return escapeText(pattern); return escapeText(pattern);
} }
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
}
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}
@Override
public String sanitizeTag(String tag) {
return camelize(sanitizeName(tag));
}
} }

View File

@ -1,6 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.*; import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation; import io.swagger.models.Operation;
import io.swagger.models.Path; import io.swagger.models.Path;
import io.swagger.models.Swagger; import io.swagger.models.Swagger;
@ -10,7 +11,7 @@ import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen { public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
/** /**
* Name of the sub-directory in "src/main/resource" where to find the * Name of the sub-directory in "src/main/resource" where to find the
* Mustache template for the JAX-RS Codegen. * Mustache template for the JAX-RS Codegen.
@ -19,6 +20,9 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
protected String implFolder = "src/main/java"; protected String implFolder = "src/main/java";
protected String testResourcesFolder = "src/test/resources"; protected String testResourcesFolder = "src/test/resources";
protected String title = "Swagger Server"; protected String title = "Swagger Server";
protected boolean useBeanValidation = true;
static Logger LOGGER = LoggerFactory.getLogger(AbstractJavaJAXRSServerCodegen.class); static Logger LOGGER = LoggerFactory.getLogger(AbstractJavaJAXRSServerCodegen.class);
public AbstractJavaJAXRSServerCodegen() public AbstractJavaJAXRSServerCodegen()
@ -40,6 +44,8 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
cliOptions.add(new CliOption(CodegenConstants.IMPL_FOLDER, CodegenConstants.IMPL_FOLDER_DESC)); cliOptions.add(new CliOption(CodegenConstants.IMPL_FOLDER, CodegenConstants.IMPL_FOLDER_DESC));
cliOptions.add(new CliOption("title", "a title describing the application")); cliOptions.add(new CliOption("title", "a title describing the application"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
} }
@ -60,6 +66,15 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
if (additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) { if (additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) {
implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER); implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER);
} }
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
} }
@Override @Override
@ -204,4 +219,9 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
private String implFileFolder(String output) { private String implFileFolder(String output) {
return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/'); return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
} }
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
} }

View File

@ -253,6 +253,9 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -589,6 +592,10 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
@Override @Override
public String toEnumVarName(String name, String datatype) { public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(name) != null) { if (getSymbolName(name) != null) {
return (getSymbolName(name)).toUpperCase(); return (getSymbolName(name)).toUpperCase();

View File

@ -68,6 +68,9 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -112,7 +112,6 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
} }
} }
@Override @Override
public CodegenType getTag() { public CodegenType getTag() {
return CodegenType.CLIENT; return CodegenType.CLIENT;
@ -120,6 +119,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -291,6 +293,10 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override @Override
public String toEnumVarName(String name, String datatype) { public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(name) != null) { if (getSymbolName(name) != null) {
return camelize(getSymbolName(name)); return camelize(getSymbolName(name));

View File

@ -154,6 +154,9 @@ public class AkkaScalaClientCodegen extends AbstractScalaCodegen implements Code
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "`" + name + "`"; return "`" + name + "`";
} }

View File

@ -120,6 +120,9 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -14,8 +14,6 @@ import static java.util.UUID.randomUUID;
public class AspNetCoreServerCodegen extends AbstractCSharpCodegen { public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
protected String sourceFolder = "src" + File.separator + packageName;
private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}"; private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}";
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
@ -24,6 +22,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
public AspNetCoreServerCodegen() { public AspNetCoreServerCodegen() {
super(); super();
setSourceFolder("src");
outputFolder = "generated-code" + File.separator + this.getName(); outputFolder = "generated-code" + File.separator + this.getName();
modelTemplateFiles.put("model.mustache", ".cs"); modelTemplateFiles.put("model.mustache", ".cs");
@ -91,38 +90,53 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
apiPackage = packageName + ".Controllers"; apiPackage = packageName + ".Controllers";
modelPackage = packageName + ".Models"; modelPackage = packageName + ".Models";
String packageFolder = sourceFolder + File.separator + packageName;
supportingFiles.add(new SupportingFile("NuGet.Config", "", "NuGet.Config")); supportingFiles.add(new SupportingFile("NuGet.Config", "", "NuGet.Config"));
supportingFiles.add(new SupportingFile("global.json", "", "global.json")); supportingFiles.add(new SupportingFile("global.json", "", "global.json"));
supportingFiles.add(new SupportingFile("build.sh.mustache", "", "build.sh")); supportingFiles.add(new SupportingFile("build.sh.mustache", "", "build.sh"));
supportingFiles.add(new SupportingFile("build.bat.mustache", "", "build.bat")); supportingFiles.add(new SupportingFile("build.bat.mustache", "", "build.bat"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("Solution.mustache", "", this.packageName + ".sln")); supportingFiles.add(new SupportingFile("Solution.mustache", "", this.packageName + ".sln"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", this.sourceFolder, "Dockerfile")); supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("gitignore", this.sourceFolder, ".gitignore")); supportingFiles.add(new SupportingFile("gitignore", packageFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("appsettings.json", this.sourceFolder, "appsettings.json")); supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("project.json.mustache", this.sourceFolder, "project.json")); supportingFiles.add(new SupportingFile("project.json.mustache", packageFolder, "project.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", this.sourceFolder, "Startup.cs")); supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Program.mustache", this.sourceFolder, "Program.cs")); supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs"));
supportingFiles.add(new SupportingFile("web.config", this.sourceFolder, "web.config")); supportingFiles.add(new SupportingFile("web.config", packageFolder, "web.config"));
supportingFiles.add(new SupportingFile("Project.xproj.mustache", this.sourceFolder, this.packageName + ".xproj")); supportingFiles.add(new SupportingFile("Project.xproj.mustache", packageFolder, this.packageName + ".xproj"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", this.sourceFolder + File.separator + "Properties", "launchSettings.json")); supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", packageFolder + File.separator + "Properties", "launchSettings.json"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", this.sourceFolder + File.separator + "wwwroot", "README.md")); supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", this.sourceFolder + File.separator + "wwwroot", "index.html")); supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", this.sourceFolder + File.separator + "wwwroot", "web.config")); supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config"));
}
@Override
public void setSourceFolder(final String sourceFolder) {
if(sourceFolder == null) {
LOGGER.warn("No sourceFolder specified, using default");
this.sourceFolder = "src" + File.separator + this.packageName;
} else if(!sourceFolder.equals("src") && !sourceFolder.startsWith("src")) {
LOGGER.warn("ASP.NET Core requires source code exists under src. Adjusting.");
this.sourceFolder = "src" + File.separator + sourceFolder;
} else {
this.sourceFolder = sourceFolder;
}
} }
@Override @Override
public String apiFileFolder() { public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + "Controllers"; return outputFolder + File.separator + sourceFolder + File.separator + packageName + File.separator + "Controllers";
} }
@Override @Override
public String modelFileFolder() { public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + "Models"; return outputFolder + File.separator + sourceFolder + File.separator + packageName + File.separator + "Models";
} }
@Override @Override

View File

@ -0,0 +1,662 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import io.swagger.models.parameters.*;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.io.File;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class BashClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0";
protected String curlOptions;
protected boolean processMarkdown = false;
protected String scriptName = "client.sh";
protected boolean generateBashCompletion = false;
protected boolean generateZshCompletion = false;
protected String hostEnvironmentVariable;
protected String basicAuthEnvironmentVariable;
protected String apiKeyAuthEnvironmentVariable;
public static final String CURL_OPTIONS = "curlOptions";
public static final String PROCESS_MARKDOWN = "processMarkdown";
public static final String SCRIPT_NAME = "scriptName";
public static final String
GENERATE_BASH_COMPLETION = "generateBashCompletion";
public static final String
GENERATE_ZSH_COMPLETION = "generateZshCompletion";
public static final String
HOST_ENVIRONMENT_VARIABLE_NAME = "hostEnvironmentVariable";
public static final String
BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME = "basicAuthEnvironmentVariable";
public static final String
APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME = "apiKeyAuthEnvironmentVariable";
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.swagger.codegen.CodegenType
*/
public CodegenType getTag() {
return CodegenType.CLIENT;
}
/**
* 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
*/
public String getName() {
return "bash";
}
/**
* Returns human-friendly help for the generator. Provide the consumer with
* help tips, parameters here
*
* @return A string value for the help message
*/
public String getHelp() {
return "Generates a Bash client script based on cURL.";
}
public BashClientCodegen() {
super();
/**
* Set the output folder here
*/
outputFolder = "generated-code/bash";
/**
* No model files.
*/
modelTemplateFiles.clear();
/**
* No API files.
*/
apiTemplateFiles.clear();
/**
* Templates location for client script and bash completion template.
*/
embeddedTemplateDir = templateDir = "bash";
/**
* Allow the user to force the script to always include certain cURL
* comamnds
*/
cliOptions.add(CliOption.newString(CURL_OPTIONS, "Default cURL options"));
cliOptions.add(CliOption.newBoolean(PROCESS_MARKDOWN,
"Convert all Markdown Markup into terminal formatting"));
cliOptions.add(CliOption.newString(SCRIPT_NAME,
"The name of the script that will be generated "+
"(e.g. petstore-cli)"));
cliOptions.add(CliOption.newBoolean(GENERATE_BASH_COMPLETION,
"Whether to generate the Bash completion script"));
cliOptions.add(CliOption.newBoolean(GENERATE_ZSH_COMPLETION,
"Whether to generate the Zsh completion script"));
cliOptions.add(CliOption.newString(HOST_ENVIRONMENT_VARIABLE_NAME,
"Name of environment variable where host can be defined "+
"(e.g. PETSTORE_HOST='http://petstore.swagger.io:8080')"));
cliOptions.add(CliOption.newString(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME,
"Name of environment variable where username and password "
+
"can be defined (e.g. PETSTORE_CREDS='username:password')"));
cliOptions.add(CliOption.newBoolean(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME,
"Name of environment variable where API key "
+
"can be defined (e.g. PETSTORE_APIKEY='kjhasdGASDa5asdASD')"));
/**
* Bash reserved words.
*/
reservedWords = new HashSet<String> (
Arrays.asList(
"case",
"do",
"done",
"elif",
"else",
"esac",
"fi",
"for",
"function",
"if",
"in",
"select",
"then",
"time",
"until",
"while")
);
typeMapping.clear();
typeMapping.put("array", "array");
typeMapping.put("map", "map");
typeMapping.put("List", "array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "integer");
typeMapping.put("float", "float");
typeMapping.put("number", "integer");
typeMapping.put("DateTime", "string");
typeMapping.put("long", "integer");
typeMapping.put("short", "integer");
typeMapping.put("char", "string");
typeMapping.put("double", "float");
typeMapping.put("object", "map");
typeMapping.put("integer", "integer");
typeMapping.put("ByteArray", "string");
typeMapping.put("binary", "binary");
/**
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files.
*/
additionalProperties.put("apiVersion", apiVersion);
/**
* Language Specific Primitives. These types will not trigger imports by
* the client generator
*/
languageSpecificPrimitives = new HashSet<String>();
}
@Override
public void processOpts() {
super.processOpts();
String curlopts = "";
if (additionalProperties.containsKey(CURL_OPTIONS)) {
setCurlOptions(additionalProperties.get(CURL_OPTIONS).toString());
additionalProperties.put("x-codegen-curl-options", curlopts);
}
if (additionalProperties.containsKey(PROCESS_MARKDOWN)) {
setProcessMarkdown(
Boolean.parseBoolean(
additionalProperties.get(PROCESS_MARKDOWN).toString()));
}
if (additionalProperties.containsKey(GENERATE_BASH_COMPLETION)) {
setGenerateBashCompletion(
Boolean.parseBoolean(
additionalProperties.get(GENERATE_BASH_COMPLETION).toString()));
}
if (additionalProperties.containsKey(GENERATE_ZSH_COMPLETION)) {
setGenerateZshCompletion(
Boolean.parseBoolean(
additionalProperties.get(GENERATE_ZSH_COMPLETION).toString()));
}
if (additionalProperties.containsKey(SCRIPT_NAME)) {
setScriptName(additionalProperties.get(SCRIPT_NAME).toString());
}
additionalProperties.put("x-codegen-script-name", scriptName);
if (additionalProperties.containsKey(HOST_ENVIRONMENT_VARIABLE_NAME)) {
setHostEnvironmentVariable(
additionalProperties.get(HOST_ENVIRONMENT_VARIABLE_NAME).toString());
additionalProperties.put("x-codegen-host-env", hostEnvironmentVariable);
}
if (additionalProperties.containsKey(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME)) {
setBasicAuthEnvironmentVariable(
additionalProperties.get(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME).toString());
additionalProperties.put("x-codegen-basicauth-env", basicAuthEnvironmentVariable);
}
if (additionalProperties.containsKey(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME)) {
setApiKeyAuthEnvironmentVariable(
additionalProperties.get(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME).toString());
additionalProperties.put("x-codegen-apikey-env", apiKeyAuthEnvironmentVariable);
}
supportingFiles.add(new SupportingFile(
"client.mustache", "", scriptName));
supportingFiles.add(new SupportingFile(
"bash-completion.mustache", "", scriptName+".bash-completion"));
supportingFiles.add(new SupportingFile(
"zsh-completion.mustache", "", "_"+scriptName));
supportingFiles.add(new SupportingFile(
"README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile(
"Dockerfile.mustache", "", "Dockerfile"));
}
public void setCurlOptions(String curlOptions) {
this.curlOptions = curlOptions;
}
public void setProcessMarkdown(boolean processMarkdown) {
this.processMarkdown = processMarkdown;
}
public void setScriptName(String scriptName) {
this.scriptName = scriptName;
}
public void setGenerateBashCompletion(boolean generateBashCompletion) {
this.generateBashCompletion = generateBashCompletion;
}
public void setGenerateZshCompletion(boolean generateZshCompletion) {
this.generateZshCompletion = generateZshCompletion;
}
public void setHostEnvironmentVariable(String hostEnvironmentVariable) {
this.hostEnvironmentVariable = hostEnvironmentVariable;
}
public void setBasicAuthEnvironmentVariable(String
basicAuthEnvironmentVariable) {
this.basicAuthEnvironmentVariable = basicAuthEnvironmentVariable;
}
public void setApiKeyAuthEnvironmentVariable(String
apiKeyAuthEnvironmentVariable) {
this.apiKeyAuthEnvironmentVariable = apiKeyAuthEnvironmentVariable;
}
/**
* 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) {
return "_" + name; // add an underscore to the name
}
/**
* Location to write model files. You can use the modelPackage() as defined
* when the class is instantiated.
*/
public String modelFileFolder() {
return outputFolder;
}
/**
* Location to write api files. You can use the apiPackage() as defined when
* the class is instantiated.
*/
@Override
public String apiFileFolder() {
return outputFolder;
}
/**
* Optional - type declaration. This is a String which is used by the
* templates to instantiate your types. There is typically special handling
* for different property types
*
* @return a string value used as the `dataType` field for model templates,
* `returnType` for api templates
*/
@Override
public String getTypeDeclaration(Property p) {
if(p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
}
else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
/**
* Optional - swagger type conversion. This is used to map swagger types in
* a `Property` into either language specific types via `typeMapping` or into
* complex models if there is not a mapping.
*
* @return a string value of the type or complex model for this property
* @see io.swagger.models.properties.Property
*/
@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 = swaggerType;
return toModelName(type);
}
/**
* Convert Swagger Parameter object to Codegen Parameter object
*
* @param param Swagger parameter object
* @param imports set of imports for library/package/module
* @return Codegen Parameter object
*/
@Override
public CodegenParameter fromParameter(Parameter param, Set<String> imports) {
CodegenParameter p = super.fromParameter(param, imports);
if(param instanceof BodyParameter) {
Model model = ((BodyParameter)param).getSchema();
}
else if(param instanceof SerializableParameter) {
/**
* Currently it's not possible to specify in the codegen other collection
* formats than 'multi'
*/
SerializableParameter sparam = (SerializableParameter)param;
if( sparam.getCollectionFormat() != null
&& !sparam.getCollectionFormat().isEmpty()) {
String collectionFormat = sparam.getCollectionFormat();
if(sparam.isExclusiveMaximum()!=null && sparam.isExclusiveMaximum()) {
p.vendorExtensions.put("x-codegen-collection-max-items",
sparam.getMaxItems());
}
if(sparam.isExclusiveMinimum()!=null && sparam.isExclusiveMinimum()) {
p.vendorExtensions.put("x-codegen-collection-min-items",
sparam.getMinItems());
}
if( (collectionFormat.equals("multi"))
&& (param.getIn().equals("query")) ) {
/**
* 'multi' is only supported for query parameters
*/
p.vendorExtensions.put("x-codegen-collection-multi", true);
}
else if(collectionFormat.equals("csv")) {
p.vendorExtensions.put("x-codegen-collection-csv", true);
}
else if(collectionFormat.equals("ssv")) {
p.vendorExtensions.put("x-codegen-collection-ssv", true);
}
else if(collectionFormat.equals("tsv")) {
p.vendorExtensions.put("x-codegen-collection-tsv", true);
}
else if(collectionFormat.equals("pipes")) {
p.vendorExtensions.put("x-codegen-collection-pipes", true);
}
else {
/** Unsupported collection format */
}
}
}
return p;
}
/**
* Override with any special text escaping logic
*/
@SuppressWarnings("static-method")
public String escapeText(String input) {
if (input == null) {
return input;
}
/**
* Trim the input text always.
*/
String result = input.trim();
/**
* remove standalone '\'
*
* replace " with \"
* outter unescape to retain the original multi-byte characters
*/
result = escapeUnsafeCharacters(
StringEscapeUtils.unescapeJava(
StringEscapeUtils.escapeJava(result).replace("\\/", "/"))
.replace("\\", "\\\\")
.replace("\"", "\\\""));
if(this.processMarkdown) {
/**
* Convert markdown strong **Bold text** and __Bold text__
* to bash bold control sequences (tput bold)
*/
result = result.replaceAll("(?m)(^|\\s)\\*{2}([\\w\\d ]+)\\*{2}($|\\s)",
"\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)");
result = result.replaceAll("(?m)(^|\\s)_{2}([\\w\\d ]+)_{2}($|\\s)",
"\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)");
/**
* Convert markdown *Italics text* and _Italics text_ to bash dim
* control sequences (tput dim)
*/
result = result.replaceAll("(?m)(^|\\s)\\*{1}([\\w\\d ]+)\\*{1}($|\\s)",
"\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)");
result = result.replaceAll("(?m)(^|\\s)_{1}([\\w\\d ]+)_{1}($|\\s)",
"\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)");
/**
* Convert all markdown section 1 level headers with bold
*/
result = result.replaceAll("(?m)^\\#\\s+(.+)$",
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
+"$1\\$\\(tput sgr0\\)");
/**
* Convert all markdown section 2 level headers with bold
*/
result = result.replaceAll("(?m)^\\#\\#\\s+(.+)$",
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
+"$1\\$\\(tput sgr0\\)");
/**
* Convert all markdown section 3 level headers with bold
*/
result = result.replaceAll("(?m)^\\#\\#\\#\\s+(.+)$",
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
+"$1\\$\\(tput sgr0\\)");
/**
* Convert all markdown code blocks into --- delimited sections
*/
result = result.replaceAll("(?m)\\s*```.*$",
"\n---");
result = result.replaceAll("(?m)\\s*\\'\\'\\'.*$",
"\n---");
/**
* Remove any trailing new line at the end of the string
*/
result = result.replaceAll("\\s+$", "");
}
return result;
}
@Override
public String escapeQuotationMark(String input) {
return input;
}
/**
* Override with any special text escaping logic to handle unsafe
* characters so as to avoid code injection.
*
* @param input String to be cleaned up
* @return string with unsafe characters removed or escaped
*/
public String escapeUnsafeCharacters(String input) {
/**
* Replace backticks with normal single quotes.
*/
String result = input.replaceAll("`", "'");
return result;
}
@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);
/**
* Check if the operation has a Bash codegen specific description
* for help
*/
if(op.vendorExtensions.containsKey("x-bash-codegen-description")) {
String bash_description
= (String)op.vendorExtensions.get("x-bash-codegen-description");
op.vendorExtensions.put("x-bash-codegen-description",
escapeText(bash_description));
}
/**
* Check if operation has an 'x-code-samples' vendor extension with
* Shell example
*/
if(op.vendorExtensions.containsKey("x-code-samples")) {
List codesamples = (List)op.vendorExtensions.get("x-code-samples");
for (Object codesample : codesamples) {
ObjectNode codesample_object = (ObjectNode)codesample;
if((codesample_object.get("lang").asText()).equals("Shell")) {
op.vendorExtensions.put("x-bash-codegen-sample",
escapeUnsafeCharacters(
codesample_object.get("source").asText()));
}
}
}
for (CodegenParameter p : op.bodyParams) {
if(p.dataType != null && definitions.get(p.dataType) != null) {
/**
* If the operation produces Json and has nonempty example
* try to reformat it.
*/
if(operation.getConsumes() != null
&& operation.getConsumes().contains("application/json")
&& definitions.get(p.dataType).getExample() != null) {
ObjectMapper mapper = new ObjectMapper();
try {
p.vendorExtensions.put(
"x-codegen-body-example",
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
definitions.get(p.dataType).getExample()));
}
catch(JsonProcessingException e) {
e.printStackTrace();
}
}
else {
/**
* Otherwise present whatever is provided as example
*/
p.vendorExtensions.put(
"x-codegen-body-example",
definitions.get(p.dataType).getExample());
}
}
}
return op;
}
/**
* Preprocess original properties from the Swagger definition where necessary.
*
* @param swagger [description]
*/
@Override
public void preprocessSwagger(Swagger swagger) {
super.preprocessSwagger(swagger);
if ("/".equals(swagger.getBasePath())) {
swagger.setBasePath("");
}
if(swagger.getInfo() != null
&& swagger.getInfo().getVendorExtensions()!=null) {
String bash_codegen_app_description
= (String)swagger.getInfo().getVendorExtensions()
.get("x-bash-codegen-description");
if(bash_codegen_app_description != null) {
bash_codegen_app_description
= escapeText(bash_codegen_app_description);
additionalProperties.put("x-bash-codegen-app-description",
bash_codegen_app_description);
}
}
}
}

View File

@ -1,6 +1,9 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.sun.org.apache.bcel.internal.classfile.Code;
import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType; import io.swagger.codegen.CodegenType;
import io.swagger.codegen.CodegenModel; import io.swagger.codegen.CodegenModel;
@ -45,6 +48,9 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected Map<Character, String> regexModifiers; protected Map<Character, String> regexModifiers;
protected final Map<String, String> frameworks; protected final Map<String, String> frameworks;
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
public CSharpClientCodegen() { public CSharpClientCodegen() {
super(); super();
modelTemplateFiles.put("model.mustache", ".cs"); modelTemplateFiles.put("model.mustache", ".cs");
@ -72,6 +78,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.OPTIONAL_PROJECT_GUID_DESC, CodegenConstants.OPTIONAL_PROJECT_GUID_DESC,
null); null);
addOption(CodegenConstants.INTERFACE_PREFIX,
CodegenConstants.INTERFACE_PREFIX_DESC,
interfacePrefix);
CliOption framework = new CliOption( CliOption framework = new CliOption(
CodegenConstants.DOTNET_FRAMEWORK, CodegenConstants.DOTNET_FRAMEWORK,
CodegenConstants.DOTNET_FRAMEWORK_DESC CodegenConstants.DOTNET_FRAMEWORK_DESC
@ -126,6 +136,18 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.PACKAGE_DESCRIPTION_DESC, CodegenConstants.PACKAGE_DESCRIPTION_DESC,
this.generatePropertyChanged); this.generatePropertyChanged);
// NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo
// https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx
// to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen
// should rely on default public visibility.
addSwitch(CodegenConstants.NON_PUBLIC_API,
CodegenConstants.NON_PUBLIC_API_DESC,
this.nonPublicApi);
addSwitch(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS,
CodegenConstants.ALLOW_UNICODE_IDENTIFIERS_DESC,
this.allowUnicodeIdentifiers);
regexModifiers = new HashMap<Character, String>(); regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase"); regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline"); regexModifiers.put('m', "Multiline");
@ -228,6 +250,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
.get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString())); .get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString()));
} }
if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) {
setNonPublicApi(Boolean.valueOf(additionalProperties.get(CodegenConstants.NON_PUBLIC_API).toString()));
}
final String testPackageName = testPackageName(); final String testPackageName = testPackageName();
String packageFolder = sourceFolder + File.separator + packageName; String packageFolder = sourceFolder + File.separator + packageName;
String clientPackageDir = packageFolder + File.separator + clientPackage; String clientPackageDir = packageFolder + File.separator + clientPackage;
@ -293,6 +319,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
if (optionalProjectFileFlag) { if (optionalProjectFileFlag) {
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
supportingFiles.add(new SupportingFile("Project.mustache", packageFolder, packageName + ".csproj")); supportingFiles.add(new SupportingFile("Project.mustache", packageFolder, packageName + ".csproj"));
supportingFiles.add(new SupportingFile("nuspec.mustache", packageFolder, packageName + ".nuspec"));
if(Boolean.FALSE.equals(excludeTests)) { if(Boolean.FALSE.equals(excludeTests)) {
// NOTE: This exists here rather than previous excludeTests block because the test project is considered an optional project file. // NOTE: This exists here rather than previous excludeTests block because the test project is considered an optional project file.
@ -494,6 +521,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
@Override @Override
public String toEnumVarName(String value, String datatype) { public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(value) != null) { if (getSymbolName(value) != null) {
return camelize(getSymbolName(value)); return camelize(getSymbolName(value));
@ -547,6 +578,14 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.generatePropertyChanged = generatePropertyChanged; this.generatePropertyChanged = generatePropertyChanged;
} }
public boolean isNonPublicApi() {
return nonPublicApi;
}
public void setNonPublicApi(final boolean nonPublicApi) {
this.nonPublicApi = nonPublicApi;
}
@Override @Override
public String toModelDocFilename(String name) { public String toModelDocFilename(String name) {
return toModelFilename(name); return toModelFilename(name);

View File

@ -62,7 +62,7 @@ public class CppRestClientCodegen extends DefaultCodegen implements CodegenConfi
apiTemplateFiles.put("api-header.mustache", ".h"); apiTemplateFiles.put("api-header.mustache", ".h");
apiTemplateFiles.put("api-source.mustache", ".cpp"); apiTemplateFiles.put("api-source.mustache", ".cpp");
templateDir = "cpprest"; embeddedTemplateDir = templateDir = "cpprest";
cliOptions.clear(); cliOptions.clear();

View File

@ -10,6 +10,8 @@ import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property; import io.swagger.models.properties.Property;
import io.swagger.codegen.CliOption; import io.swagger.codegen.CliOption;
import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -171,6 +173,9 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -230,11 +235,26 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
@Override @Override
public String toModelName(String name) { public String toModelName(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
name = sanitizeName(name); name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return // model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) { if (isReservedWord(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model 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)
}
// model name starts with number
if (name.matches("^\\d.*")) {
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
} }
// camelize the model name // camelize the model name
@ -281,12 +301,18 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
@Override @Override
public String toOperationId(String operationId) { public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return // throw exception if method name is empty (should not occur as an auto-generated method name will be used)
if (isReservedWord(operationId)) { if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException("Empty method name (operationId) not allowed");
} }
return camelize(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(sanitizeName(operationId));
} }
@Override @Override

View File

@ -175,6 +175,9 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -0,0 +1,388 @@
package io.swagger.codegen.languages;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.codegen.*;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig {
// source folder where to write the files
protected String sourceFolder = "lib";
protected String apiVersion = "1.0.0";
String supportedElixirVersion = "1.4";
List<String> extraApplications = Arrays.asList(":logger");
List<String> deps = Arrays.asList(
"{:tesla, \"~> 0.5.0\"}",
"{:poison, \">= 1.0.0\"}"
);
public ElixirClientCodegen() {
super();
// set the output folder here
outputFolder = "generated-code/elixir";
/**
* 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.put(
"model.mustache", // the template to use
".ex"); // the extension for each file to write
/**
* 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.put(
"api.mustache", // the template to use
".ex"); // the extension for each file to write
/**
* 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.
*/
templateDir = "elixir";
/**
* Reserved words. Override this with reserved words specific to your language
*/
reservedWords = new HashSet<String>(
Arrays.asList(
"sample1", // replace with static values
"sample2")
);
/**
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
additionalProperties.put("apiVersion", apiVersion);
/**
* 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("README.md.mustache", // the input template or file
"", // the destination folder, relative `outputFolder`
"README.md") // the output file
);
supportingFiles.add(new SupportingFile("config.exs.mustache",
"config",
"config.exs")
);
supportingFiles.add(new SupportingFile("mix.exs.mustache",
"",
"mix.exs")
);
supportingFiles.add(new SupportingFile("test_helper.exs.mustache",
"test",
"test_helper.exs")
);
/**
* Language Specific Primitives. These types will not trigger imports by
* the client generator
*/
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"Type1", // replace these with your types
"Type2")
);
}
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.swagger.codegen.CodegenType
*/
public CodegenType getTag() {
return CodegenType.CLIENT;
}
/**
* 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
*/
public String getName() {
return "elixir";
}
/**
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
*/
public String getHelp() {
return "Generates an elixir client library (alpha).";
}
@Override
public void processOpts() {
super.processOpts();
additionalProperties.put("supportedElixirVersion", supportedElixirVersion);
additionalProperties.put("extraApplications", join(",", extraApplications));
additionalProperties.put("deps", deps);
additionalProperties.put("underscored", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(underscored(fragment.execute()));
}
});
additionalProperties.put("modulized", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(modulized(fragment.execute()));
}
});
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) super.postProcessOperations(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) {
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" + "#{" + underscore(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;
}
// We should use String.join if we can use Java8
String join(CharSequence charSequence, Iterable<String> iterable) {
StringBuilder buf = new StringBuilder();
for (String str : iterable) {
if (0 < buf.length()) {
buf.append((charSequence));
}
buf.append(str);
}
return buf.toString();
}
String underscored(String words) {
ArrayList<String> underscoredWords = new ArrayList<String>();
for (String word : words.split(" ")) {
underscoredWords.add(underscore(word));
}
return join("_", underscoredWords);
}
String modulized(String words) {
ArrayList<String> modulizedWords = new ArrayList<String>();
for (String word : words.split(" ")) {
modulizedWords.add(camelize(word));
}
return join("", modulizedWords);
}
/**
* 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) {
return "_" + name; // add an underscore to the name
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
*/
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + underscored((String) additionalProperties.get("appName")) + "/" + "model";
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated
*/
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + underscored((String) additionalProperties.get("appName")) + "/" + "api";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "Default";
}
return initialCaps(name);
}
@Override
public String toApiFilename(String name) {
return snakeCase(name);
}
@Override
public String toModelFilename(String name) {
return snakeCase(name);
}
/**
* Optional - type declaration. This is a String which is used by the templates to instantiate your
* types. There is typically special handling for different property types
*
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
*/
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
/**
* Optional - swagger type conversion. This is used to map swagger types in a `Property` into
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
*
* @return a string value of the type or complex model for this property
* @see io.swagger.models.properties.Property
*/
@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 toModelName(type);
} else
type = swaggerType;
return toModelName(type);
}
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;
}
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;
}
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
// no need to escape as Elixir does not support multi-line comments
return input;
}
}

View File

@ -183,7 +183,10 @@ public class ErlangServerCodegen extends DefaultCodegen implements CodegenConfig
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return name + "_"; // add an underscore to the name if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
} }
/** /**

View File

@ -0,0 +1,320 @@
package io.swagger.codegen.languages;
import com.google.common.base.Strings;
import io.swagger.codegen.*;
import io.swagger.models.Model;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.petstore.client";
protected String groupId = "io.swagger";
protected String artifactId = "finch-server";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/scala";
protected String packageName = "io.swagger.petstore";
public FinchServerCodegen() {
super();
outputFolder = "generated-code/finch";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
embeddedTemplateDir = templateDir = "finch";
apiPackage = packageName + ".apis";
modelPackage = packageName + ".models";
setReservedWordsLowerCase(
Arrays.asList(
// Scala
"abstract", "case", "catch", "class", "def",
"do", "else", "extends", "false", "final",
"finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null",
"object", "override", "package", "private", "protected",
"return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val",
"var", "while", "with", "yield",
// Scala-interop languages keywords
"abstract", "continue", "switch", "assert",
"default", "synchronized", "goto",
"break", "double", "implements", "byte",
"public", "throws", "enum", "instanceof", "transient",
"int", "short", "char", "interface", "static",
"void", "finally", "long", "strictfp", "volatile", "const", "float",
"native")
);
defaultIncludes = new HashSet<String>(
Arrays.asList("double",
"Int",
"Long",
"Float",
"Double",
"char",
"float",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"List",
"Set",
"Map")
);
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "String");
typeMapping.put("boolean", "Boolean");
typeMapping.put("integer", "Int");
typeMapping.put("float", "Float");
typeMapping.put("long", "Long");
typeMapping.put("double", "Double");
typeMapping.put("number", "BigDecimal");
typeMapping.put("date-time", "LocalDateTime");
typeMapping.put("date", "LocalDateTime");
typeMapping.put("file", "File");
typeMapping.put("array", "Seq");
typeMapping.put("list", "List");
typeMapping.put("map", "Map");
typeMapping.put("object", "Object");
typeMapping.put("binary", "Array[Byte]");
typeMapping.put("Date", "LocalDateTime");
typeMapping.put("DateTime", "LocalDateTime");
additionalProperties.put("modelPackage", modelPackage());
additionalProperties.put("apiPackage", apiPackage());
additionalProperties.put("appName", "Swagger Sample");
additionalProperties.put("appDescription", "A sample swagger server");
additionalProperties.put("infoUrl", "http://swagger.io");
additionalProperties.put("infoEmail", "apiteam@swagger.io");
additionalProperties.put("licenseInfo", "Apache 2.0");
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.sbt", "", "build.sbt"));
supportingFiles.add(new SupportingFile("Server.mustache", sourceFolder, "Server.scala"));
supportingFiles.add(new SupportingFile("DataAccessor.mustache", sourceFolder, "DataAccessor.scala"));
supportingFiles.add(new SupportingFile("project/build.properties", "project", "build.properties"));
supportingFiles.add(new SupportingFile("project/plugins.sbt", "project", "plugins.sbt"));
supportingFiles.add(new SupportingFile("sbt", "", "sbt"));
supportingFiles.add(new SupportingFile("endpoint.mustache", sourceFolder, "endpoint.scala"));
supportingFiles.add(new SupportingFile("errors.mustache", sourceFolder, "errors.scala"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"Boolean",
"Double",
"Int",
"Integer",
"Long",
"Float",
"Any",
"AnyVal",
"AnyRef",
"Object")
);
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
importMapping = new HashMap<String, String>();
importMapping.put("BigDecimal", "java.math.BigDecimal");
importMapping.put("UUID", "java.util.UUID");
importMapping.put("File", "java.io.File");
importMapping.put("Date", "java.util.Date");
importMapping.put("Timestamp", "java.sql.Timestamp");
importMapping.put("Map", "scala.collection.immutable.Map");
importMapping.put("HashMap", "scala.collection.immutable.HashMap");
importMapping.put("Seq", "scala.collection.immutable.Seq");
importMapping.put("ArrayBuffer", "scala.collection.mutable.ArrayBuffer");
importMapping.put("DateTime", "java.time.LocalDateTime");
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("LocalTime", "java.time.LocalTime");
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Finch package name (e.g. io.swagger.petstore).")
.defaultValue(this.packageName));
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "finch";
}
@Override
public String getHelp() {
return "Generates a Scala server application with Finch.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar);
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar);
}
/**
* Convert Swagger Model object to Codegen Model object
*
* @param name the name of the model
* @param model Swagger Model object
* @param allDefinitions a map of all Swagger models from the spec
* @return Codegen Model object
*/
@Override
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
return codegenModel;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
op.httpMethod = op.httpMethod.toLowerCase();
String path = new String(op.path);
// remove first /
if (path.startsWith("/")) {
path = path.substring(1);
}
// remove last /
if (path.endsWith("/")) {
path = path.substring(0, path.length()-1);
}
String[] items = path.split("/", -1);
String scalaPath = "";
int pathParamIndex = 0;
for (int i = 0; i < items.length; ++i) {
if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {}
// find the datatype of the parameter
final CodegenParameter cp = op.pathParams.get(pathParamIndex);
// TODO: Handle non-primitives
scalaPath = scalaPath + cp.dataType.toLowerCase();
pathParamIndex++;
} else {
scalaPath = scalaPath + "\"" + items[i] + "\"";
}
if (i != items.length -1) {
scalaPath = scalaPath + " :: ";
}
}
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)) {
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)) {
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 + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", "FileUpload");
} else {
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType);
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
}
}
op.vendorExtensions.put("x-codegen-path", scalaPath);
}
return objs;
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@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 toModelName(type);
}
} else {
type = swaggerType;
}
return toModelName(type);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
}

View File

@ -178,7 +178,10 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return name + "_"; if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
} }
@Override @Override

View File

@ -237,6 +237,9 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name return "_" + name; // add an underscore to the name
} }

View File

@ -43,7 +43,7 @@ public class GoClientCodegen extends DefaultCodegen implements CodegenConfig {
modelDocTemplateFiles.put("model_doc.mustache", ".md"); modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md"); apiDocTemplateFiles.put("api_doc.mustache", ".md");
templateDir = "go"; embeddedTemplateDir = templateDir = "go";
setReservedWordsLowerCase( setReservedWordsLowerCase(
Arrays.asList( Arrays.asList(
@ -181,8 +181,9 @@ public class GoClientCodegen extends DefaultCodegen implements CodegenConfig {
// - X_Name // - X_Name
// ... or maybe a suffix? // ... or maybe a suffix?
// - Name_ ... think this will work. // - Name_ ... think this will work.
if(this.reservedWordsMappings().containsKey(name)) {
// FIXME: This should also really be a customizable option return this.reservedWordsMappings().get(name);
}
return camelize(name) + '_'; return camelize(name) + '_';
} }

View File

@ -204,6 +204,9 @@ public class GoServerCodegen extends DefaultCodegen implements CodegenConfig {
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name return "_" + name; // add an underscore to the name
} }

View File

@ -155,7 +155,10 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return name + "_"; if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
} }
public String firstLetterToUpper(String word) { public String firstLetterToUpper(String word) {

View File

@ -68,7 +68,7 @@ public class JMeterCodegen extends DefaultCodegen implements CodegenConfig {
* Template Location. This is the location which templates will be read from. The generator * 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. * will use the resource stream to attempt to read the templates.
*/ */
templateDir = "JMeter"; embeddedTemplateDir = templateDir = "JMeter";
/* /*
* Api Package. Optional, if needed, this can be used in templates * Api Package. Optional, if needed, this can be used in templates
@ -121,7 +121,10 @@ public class JMeterCodegen extends DefaultCodegen implements CodegenConfig {
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
} }
/** /**

View File

@ -28,8 +28,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean useJaxbAnnotations = true; protected boolean useJaxbAnnotations = true;
protected boolean useBeanValidation = false;
protected boolean generateSpringApplication = false; protected boolean generateSpringApplication = false;
protected boolean useSpringAnnotationConfig = false; protected boolean useSpringAnnotationConfig = false;
@ -56,6 +54,10 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean useLoggingFeatureForTests = false; protected boolean useLoggingFeatureForTests = false;
protected boolean useAnnotatedBasePath = false;
protected boolean generateNonSpringApplication = false;
public JavaCXFServerCodegen() public JavaCXFServerCodegen()
{ {
super(); super();
@ -84,7 +86,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions.add(CliOption.newBoolean(USE_JAXB_ANNOTATIONS, "Use JAXB annotations for XML")); cliOptions.add(CliOption.newBoolean(USE_JAXB_ANNOTATIONS, "Use JAXB annotations for XML"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
cliOptions.add(CliOption.newBoolean(GENERATE_SPRING_APPLICATION, "Generate Spring application")); cliOptions.add(CliOption.newBoolean(GENERATE_SPRING_APPLICATION, "Generate Spring application"));
cliOptions.add(CliOption.newBoolean(USE_SPRING_ANNOTATION_CONFIG, "Use Spring Annotation Config")); cliOptions.add(CliOption.newBoolean(USE_SPRING_ANNOTATION_CONFIG, "Use Spring Annotation Config"));
@ -108,6 +109,9 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions cliOptions
.add(CliOption.newBoolean(ADD_CONSUMES_PRODUCES_JSON, "Add @Consumes/@Produces Json to API interface")); .add(CliOption.newBoolean(ADD_CONSUMES_PRODUCES_JSON, "Add @Consumes/@Produces Json to API interface"));
cliOptions.add(CliOption.newBoolean(USE_ANNOTATED_BASE_PATH, "Use @Path annotations for basePath"));
cliOptions.add(CliOption.newBoolean(GENERATE_NON_SPRING_APPLICATION, "Generate non-Spring application"));
} }
@ -121,11 +125,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.setUseJaxbAnnotations(useJaxbAnnotationsProp); this.setUseJaxbAnnotations(useJaxbAnnotationsProp);
} }
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
boolean useBeanValidationProp = convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION);
this.setUseBeanValidation(useBeanValidationProp);
}
if (additionalProperties.containsKey(ADD_CONSUMES_PRODUCES_JSON)) { if (additionalProperties.containsKey(ADD_CONSUMES_PRODUCES_JSON)) {
this.setAddConsumesProducesJson(convertPropertyToBooleanAndWriteBack(ADD_CONSUMES_PRODUCES_JSON)); this.setAddConsumesProducesJson(convertPropertyToBooleanAndWriteBack(ADD_CONSUMES_PRODUCES_JSON));
} }
@ -159,6 +158,16 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.setGenerateJbossDeploymentDescriptor(generateJbossDeploymentDescriptorProp); this.setGenerateJbossDeploymentDescriptor(generateJbossDeploymentDescriptorProp);
} }
if (additionalProperties.containsKey(USE_ANNOTATED_BASE_PATH)) {
boolean useAnnotatedBasePathProp = convertPropertyToBooleanAndWriteBack(USE_ANNOTATED_BASE_PATH);
this.setUseAnnotatedBasePath(useAnnotatedBasePathProp);
}
if (additionalProperties.containsKey(GENERATE_NON_SPRING_APPLICATION)) {
boolean generateNonSpringApplication = convertPropertyToBooleanAndWriteBack(GENERATE_NON_SPRING_APPLICATION);
this.setGenerateNonSpringApplication(generateNonSpringApplication);
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
writeOptional(outputFolder, new SupportingFile("server/pom.mustache", "", "pom.xml")); writeOptional(outputFolder, new SupportingFile("server/pom.mustache", "", "pom.xml"));
@ -191,10 +200,12 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
(testResourcesFolder + '/'), "application.properties")); (testResourcesFolder + '/'), "application.properties"));
} }
} }
if (this.generateNonSpringApplication) {
writeOptional(outputFolder, new SupportingFile("server/nonspring-web.mustache",
("src/main/webapp/WEB-INF"), "web.xml"));
}
} }
@Override @Override
@ -224,10 +235,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
return "Generates a Java JAXRS Server application based on Apache CXF framework."; return "Generates a Java JAXRS Server application based on Apache CXF framework.";
} }
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
public void setGenerateSpringApplication(boolean generateSpringApplication) { public void setGenerateSpringApplication(boolean generateSpringApplication) {
this.generateSpringApplication = generateSpringApplication; this.generateSpringApplication = generateSpringApplication;
} }
@ -293,4 +300,12 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.addConsumesProducesJson = addConsumesProducesJson; this.addConsumesProducesJson = addConsumesProducesJson;
} }
public void setUseAnnotatedBasePath(boolean useAnnotatedBasePath) {
this.useAnnotatedBasePath = useAnnotatedBasePath;
}
public void setGenerateNonSpringApplication(boolean generateNonSpringApplication) {
this.generateNonSpringApplication = generateNonSpringApplication;
}
} }

View File

@ -1,8 +1,10 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenModel; import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.SupportingFile; import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import java.io.File; import java.io.File;
@ -13,7 +15,10 @@ import java.io.File;
* in /src/gen/java and a sample ServiceImpl in /src/main/java. The API uses CDI * in /src/gen/java and a sample ServiceImpl in /src/main/java. The API uses CDI
* to get an instance of ServiceImpl that implements the Service interface. * to get an instance of ServiceImpl that implements the Service interface.
*/ */
public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen { public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen implements BeanValidationFeatures {
protected boolean useBeanValidation = true;
/** /**
* Default constructor * Default constructor
*/ */
@ -32,6 +37,8 @@ public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
// Updated template directory // Updated template directory
embeddedTemplateDir = templateDir = JAXRS_TEMPLATE_DIRECTORY_NAME embeddedTemplateDir = templateDir = JAXRS_TEMPLATE_DIRECTORY_NAME
+ File.separator + "cxf-cdi"; + File.separator + "cxf-cdi";
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
} }
@Override @Override
@ -43,6 +50,14 @@ public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
public void processOpts() { public void processOpts() {
super.processOpts(); super.processOpts();
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
// writeOptional means these files are only written if they don't already exist // writeOptional means these files are only written if they don't already exist
@ -73,4 +88,7 @@ public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
+ "Apache CXF runtime and a Java EE runtime with CDI enabled."; + "Apache CXF runtime and a Java EE runtime with CDI enabled.";
} }
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
} }

View File

@ -2,25 +2,28 @@ package io.swagger.codegen.languages;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.io.FileUtils;
import io.swagger.codegen.CliOption; import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenModel; import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.SupportingFile; import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation; import io.swagger.models.Operation;
import io.swagger.models.Swagger; import io.swagger.models.Swagger;
import io.swagger.models.properties.Property;
import io.swagger.util.Json; import io.swagger.util.Json;
import org.apache.commons.io.FileUtils;
public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
{ {
public JavaJAXRSSpecServerCodegen() public JavaJAXRSSpecServerCodegen()
{ {
super(); super();
@ -82,6 +85,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
} }
@Override @Override
public String getName() public String getName()
{ {

View File

@ -1,6 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.*; import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation; import io.swagger.models.Operation;
import java.util.*; import java.util.*;

View File

@ -1,6 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.*; import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.codegen.languages.features.JbossFeature; import io.swagger.codegen.languages.features.JbossFeature;
import io.swagger.models.Operation; import io.swagger.models.Operation;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;

View File

@ -84,7 +84,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
modelTestTemplateFiles.put("model_test.mustache", ".js"); modelTestTemplateFiles.put("model_test.mustache", ".js");
apiTemplateFiles.put("api.mustache", ".js"); apiTemplateFiles.put("api.mustache", ".js");
apiTestTemplateFiles.put("api_test.mustache", ".js"); apiTestTemplateFiles.put("api_test.mustache", ".js");
templateDir = "Javascript"; embeddedTemplateDir = templateDir = "Javascript";
apiPackage = "api"; apiPackage = "api";
modelPackage = "model"; modelPackage = "model";
modelDocTemplateFiles.put("model_doc.mustache", ".md"); modelDocTemplateFiles.put("model_doc.mustache", ".md");
@ -314,6 +314,9 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -1021,6 +1024,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
@Override @Override
public String toEnumVarName(String value, String datatype) { public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "empty";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(value) != null) { if (getSymbolName(value) != null) {
return (getSymbolName(value)).toUpperCase(); return (getSymbolName(value)).toUpperCase();

View File

@ -103,6 +103,9 @@ public class JavascriptClosureAngularClientCodegen extends DefaultCodegen implem
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -1,20 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;
import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE; import static io.swagger.codegen.CodegenConstants.*;
import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE_DESC;
import static io.swagger.codegen.CodegenConstants.PACKAGE_NAME;
import static io.swagger.codegen.CodegenConstants.PACKAGE_VERSION;
import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION;
import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION_DESC;
import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG;
import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC;
import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER;
import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER_DESC;
import static io.swagger.codegen.CodegenConstants.USE_COLLECTION;
import static io.swagger.codegen.CodegenConstants.USE_COLLECTION_DESC;
import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET;
import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET_DESC;
import static io.swagger.codegen.CodegenType.SERVER; import static io.swagger.codegen.CodegenType.SERVER;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.UUID.randomUUID; import static java.util.UUID.randomUUID;
@ -71,6 +58,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
outputFolder = "generated-code" + File.separator + getName(); outputFolder = "generated-code" + File.separator + getName();
apiTemplateFiles.put("api.mustache", ".cs"); apiTemplateFiles.put("api.mustache", ".cs");
// Early versions use no prefix for interfaces. Defaulting to I- common practice would break existing users.
setInterfacePrefix("");
// contextually reserved words // contextually reserved words
setReservedWordsLowerCase( setReservedWordsLowerCase(
asList("var", "async", "await", "dynamic", "yield") asList("var", "async", "await", "dynamic", "yield")
@ -82,6 +72,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
addOption(PACKAGE_NAME, "C# package name (convention: Title.Case).", packageName); addOption(PACKAGE_NAME, "C# package name (convention: Title.Case).", packageName);
addOption(PACKAGE_VERSION, "C# package version.", packageVersion); addOption(PACKAGE_VERSION, "C# package version.", packageVersion);
addOption(SOURCE_FOLDER, SOURCE_FOLDER_DESC, sourceFolder); addOption(SOURCE_FOLDER, SOURCE_FOLDER_DESC, sourceFolder);
addOption(INTERFACE_PREFIX, INTERFACE_PREFIX_DESC, interfacePrefix);
// CLI Switches // CLI Switches
addSwitch(SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_BY_REQUIRED_FLAG_DESC, sortParamsByRequiredFlag); addSwitch(SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_BY_REQUIRED_FLAG_DESC, sortParamsByRequiredFlag);
@ -292,6 +283,10 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
@Override @Override
public String toEnumVarName(final String name, final String datatype) { public String toEnumVarName(final String name, final String datatype) {
if (name.length() == 0) {
return "Empty";
}
final String enumName = camelize( final String enumName = camelize(
sanitizeName(name) sanitizeName(name)
.replaceFirst("^_", "") .replaceFirst("^_", "")

View File

@ -147,13 +147,16 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
/** /**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping * 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 * those terms here. This logic is only called if a variable matches the reserved words
* *
* @return the escaped term * @return the escaped term
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
} }
/** /**
@ -307,7 +310,12 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
if (info.getTitle() != null) { if (info.getTitle() != null) {
// when info.title is defined, use it for projectName // when info.title is defined, use it for projectName
// used in package.json // used in package.json
projectName = dashize(info.getTitle()); projectName = info.getTitle()
.replaceAll("[^a-zA-Z0-9]", "-")
.replaceAll("^[-]*", "")
.replaceAll("[-]*$", "")
.replaceAll("[-]{2,}", "-")
.toLowerCase();
this.additionalProperties.put("projectName", projectName); this.additionalProperties.put("projectName", projectName);
} }
} }

View File

@ -539,8 +539,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
return toVarName(name); return toVarName(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 reserved words
*
* @return the escaped term
*/
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -109,7 +109,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString())); CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants cliOptions.add(CliOption.newBoolean(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants
.ENSURE_UNIQUE_PARAMS_DESC).defaultValue(Boolean.TRUE.toString())); .ENSURE_UNIQUE_PARAMS_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
} }
@ -134,6 +135,14 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put("apiDocPath", apiDocPath); additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath); additionalProperties.put("modelDocPath", modelDocPath);
// default HIDE_GENERATION_TIMESTAMP to true
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
} else {
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
}
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiClient.pm")); supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "Configuration.pm")); supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiFactory.pm")); supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiFactory.pm"));
@ -162,6 +171,9 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -232,17 +232,25 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) { if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE)); this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
// Update the invokerPackage for the default apiPackage and modelPackage
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
} else { } else {
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage); additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
} }
if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) { if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
// Update model package to contain the specified model package name and the invoker package
modelPackage = invokerPackage + "\\" + (String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE);
}
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage); additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
}
if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) { if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage); // Update model package to contain the specified model package name and the invoker package
apiPackage = invokerPackage + "\\" + (String) additionalProperties.get(CodegenConstants.API_PACKAGE);
} }
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) { if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME)); this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
@ -308,6 +316,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -480,7 +491,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
// add prefix and/or suffic only if name does not start wth \ (e.g. \DateTime) // add prefix and/or suffic only if name does not start wth \ (e.g. \DateTime)
if (!name.matches("^\\\\.*")) { if (!name.matches("^\\\\.*")) {
name = modelNamePrefix + name + modelNameSuffix; if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
} }
// camelize the model name // camelize the model name
@ -644,6 +661,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toEnumVarName(String name, String datatype) { public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// number // number
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) { if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
String varName = name; String varName = name;

View File

@ -252,6 +252,9 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -199,7 +199,10 @@ public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig {
*/ */
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
} }
/** /**

View File

@ -187,6 +187,9 @@ public class Rails5ServerCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -331,6 +331,9 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }
@ -568,6 +571,10 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toEnumVarName(String name, String datatype) { public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// number // number
if ("Integer".equals(datatype) || "Float".equals(datatype)) { if ("Integer".equals(datatype) || "Float".equals(datatype)) {
String varName = name; String varName = name;

View File

@ -65,7 +65,6 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
// mapped to String as a workaround // mapped to String as a workaround
typeMapping.put("binary", "String"); typeMapping.put("binary", "String");
additionalProperties.put("appName", "Swagger Sample");
additionalProperties.put("appName", "Swagger Sample"); additionalProperties.put("appName", "Swagger Sample");
additionalProperties.put("appDescription", "A sample swagger server"); additionalProperties.put("appDescription", "A sample swagger server");
additionalProperties.put("infoUrl", "http://swagger.io"); additionalProperties.put("infoUrl", "http://swagger.io");

View File

@ -108,6 +108,9 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -105,6 +105,9 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -119,6 +119,9 @@ public class SlimFrameworkServerCodegen extends DefaultCodegen implements Codege
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -1,6 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.*; import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation; import io.swagger.models.Operation;
import io.swagger.models.Path; import io.swagger.models.Path;
import io.swagger.models.Swagger; import io.swagger.models.Swagger;
@ -8,16 +9,18 @@ import io.swagger.models.Swagger;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
public class SpringCodegen extends AbstractJavaCodegen { public class SpringCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
public static final String DEFAULT_LIBRARY = "spring-boot"; public static final String DEFAULT_LIBRARY = "spring-boot";
public static final String TITLE = "title"; public static final String TITLE = "title";
public static final String CONFIG_PACKAGE = "configPackage"; public static final String CONFIG_PACKAGE = "configPackage";
public static final String BASE_PACKAGE = "basePackage"; public static final String BASE_PACKAGE = "basePackage";
public static final String INTERFACE_ONLY = "interfaceOnly"; public static final String INTERFACE_ONLY = "interfaceOnly";
public static final String DELEGATE_PATTERN = "delegatePattern";
public static final String SINGLE_CONTENT_TYPES = "singleContentTypes"; public static final String SINGLE_CONTENT_TYPES = "singleContentTypes";
public static final String JAVA_8 = "java8"; public static final String JAVA_8 = "java8";
public static final String ASYNC = "async"; public static final String ASYNC = "async";
public static final String RESPONSE_WRAPPER = "responseWrapper"; public static final String RESPONSE_WRAPPER = "responseWrapper";
public static final String USE_TAGS = "useTags";
public static final String SPRING_MVC_LIBRARY = "spring-mvc"; public static final String SPRING_MVC_LIBRARY = "spring-mvc";
public static final String SPRING_CLOUD_LIBRARY = "spring-cloud"; public static final String SPRING_CLOUD_LIBRARY = "spring-cloud";
@ -25,10 +28,13 @@ public class SpringCodegen extends AbstractJavaCodegen {
protected String configPackage = "io.swagger.configuration"; protected String configPackage = "io.swagger.configuration";
protected String basePackage = "io.swagger"; protected String basePackage = "io.swagger";
protected boolean interfaceOnly = false; protected boolean interfaceOnly = false;
protected boolean delegatePattern = false;
protected boolean singleContentTypes = false; protected boolean singleContentTypes = false;
protected boolean java8 = false; protected boolean java8 = false;
protected boolean async = false; protected boolean async = false;
protected String responseWrapper = ""; protected String responseWrapper = "";
protected boolean useTags = false;
protected boolean useBeanValidation = true;
public SpringCodegen() { public SpringCodegen() {
super(); super();
@ -50,10 +56,13 @@ public class SpringCodegen extends AbstractJavaCodegen {
cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code")); cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code"));
cliOptions.add(new CliOption(BASE_PACKAGE, "base package for generated code")); cliOptions.add(new CliOption(BASE_PACKAGE, "base package for generated code"));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files.")); cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files."));
cliOptions.add(CliOption.newBoolean(DELEGATE_PATTERN, "Whether to generate the server files using the delegate pattern"));
cliOptions.add(CliOption.newBoolean(SINGLE_CONTENT_TYPES, "Whether to select only one produces/consumes content-type by operation.")); cliOptions.add(CliOption.newBoolean(SINGLE_CONTENT_TYPES, "Whether to select only one produces/consumes content-type by operation."));
cliOptions.add(CliOption.newBoolean(JAVA_8, "use java8 default interface")); cliOptions.add(CliOption.newBoolean(JAVA_8, "use java8 default interface"));
cliOptions.add(CliOption.newBoolean(ASYNC, "use async Callable controllers")); cliOptions.add(CliOption.newBoolean(ASYNC, "use async Callable controllers"));
cliOptions.add(new CliOption(RESPONSE_WRAPPER, "wrap the responses in given type (Future,Callable,CompletableFuture,ListenableFuture,DeferredResult,HystrixCommand,RxObservable,RxSingle or fully qualified type)")); cliOptions.add(new CliOption(RESPONSE_WRAPPER, "wrap the responses in given type (Future,Callable,CompletableFuture,ListenableFuture,DeferredResult,HystrixCommand,RxObservable,RxSingle or fully qualified type)"));
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration."); supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration.");
supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration."); supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration.");
@ -121,10 +130,18 @@ public class SpringCodegen extends AbstractJavaCodegen {
this.setInterfaceOnly(Boolean.valueOf(additionalProperties.get(INTERFACE_ONLY).toString())); this.setInterfaceOnly(Boolean.valueOf(additionalProperties.get(INTERFACE_ONLY).toString()));
} }
if (additionalProperties.containsKey(DELEGATE_PATTERN)) {
this.setDelegatePattern(Boolean.valueOf(additionalProperties.get(DELEGATE_PATTERN).toString()));
}
if (additionalProperties.containsKey(SINGLE_CONTENT_TYPES)) { if (additionalProperties.containsKey(SINGLE_CONTENT_TYPES)) {
this.setSingleContentTypes(Boolean.valueOf(additionalProperties.get(SINGLE_CONTENT_TYPES).toString())); this.setSingleContentTypes(Boolean.valueOf(additionalProperties.get(SINGLE_CONTENT_TYPES).toString()));
} }
if (additionalProperties.containsKey(JAVA_8)) {
this.setJava8(Boolean.valueOf(additionalProperties.get(JAVA_8).toString()));
}
if (additionalProperties.containsKey(ASYNC)) { if (additionalProperties.containsKey(ASYNC)) {
this.setAsync(Boolean.valueOf(additionalProperties.get(ASYNC).toString())); this.setAsync(Boolean.valueOf(additionalProperties.get(ASYNC).toString()));
} }
@ -133,9 +150,26 @@ public class SpringCodegen extends AbstractJavaCodegen {
this.setResponseWrapper((String) additionalProperties.get(RESPONSE_WRAPPER)); this.setResponseWrapper((String) additionalProperties.get(RESPONSE_WRAPPER));
} }
if (additionalProperties.containsKey(USE_TAGS)) {
this.setUseTags(Boolean.valueOf(additionalProperties.get(USE_TAGS).toString()));
}
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
if (this.interfaceOnly && this.delegatePattern) {
throw new IllegalArgumentException(
String.format("Can not generate code with `%s` and `%s` both true.", DELEGATE_PATTERN, INTERFACE_ONLY));
}
if (!this.interfaceOnly) { if (!this.interfaceOnly) {
if (library.equals(DEFAULT_LIBRARY)) { if (library.equals(DEFAULT_LIBRARY)) {
supportingFiles.add(new SupportingFile("homeController.mustache", supportingFiles.add(new SupportingFile("homeController.mustache",
@ -195,6 +229,16 @@ public class SpringCodegen extends AbstractJavaCodegen {
} }
} }
if (!this.delegatePattern && this.java8) {
additionalProperties.put("jdk8-no-delegate", true);
}
if (this.delegatePattern) {
additionalProperties.put("isDelegate", "true");
apiTemplateFiles.put("apiDelegate.mustache", "Delegate.java");
}
if (this.java8) { if (this.java8) {
additionalProperties.put("javaVersion", "1.8"); additionalProperties.put("javaVersion", "1.8");
additionalProperties.put("jdk8", "true"); additionalProperties.put("jdk8", "true");
@ -239,7 +283,7 @@ public class SpringCodegen extends AbstractJavaCodegen {
@Override @Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) { public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
if(library.equals(DEFAULT_LIBRARY) || library.equals(SPRING_MVC_LIBRARY)) { if((library.equals(DEFAULT_LIBRARY) || library.equals(SPRING_MVC_LIBRARY)) && !useTags) {
String basePath = resourcePath; String basePath = resourcePath;
if (basePath.startsWith("/")) { if (basePath.startsWith("/")) {
basePath = basePath.substring(1); basePath = basePath.substring(1);
@ -408,6 +452,8 @@ public class SpringCodegen extends AbstractJavaCodegen {
public void setInterfaceOnly(boolean interfaceOnly) { this.interfaceOnly = interfaceOnly; } public void setInterfaceOnly(boolean interfaceOnly) { this.interfaceOnly = interfaceOnly; }
public void setDelegatePattern(boolean delegatePattern) { this.delegatePattern = delegatePattern; }
public void setSingleContentTypes(boolean singleContentTypes) { public void setSingleContentTypes(boolean singleContentTypes) {
this.singleContentTypes = singleContentTypes; this.singleContentTypes = singleContentTypes;
} }
@ -418,6 +464,10 @@ public class SpringCodegen extends AbstractJavaCodegen {
public void setResponseWrapper(String responseWrapper) { this.responseWrapper = responseWrapper; } public void setResponseWrapper(String responseWrapper) { this.responseWrapper = responseWrapper; }
public void setUseTags(boolean useTags) {
this.useTags = useTags;
}
@Override @Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property); super.postProcessModelProperty(model, property);
@ -463,4 +513,8 @@ public class SpringCodegen extends AbstractJavaCodegen {
return objs; return objs;
} }
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
} }

View File

@ -78,6 +78,9 @@ public class StaticDocCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -24,6 +24,8 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
protected String artifactVersion = "1.0.0"; protected String artifactVersion = "1.0.0";
protected String jsProjectName; protected String jsProjectName;
protected String jsModuleName; protected String jsModuleName;
protected String perlModuleName = "WWW::SwaggerClient";
protected String pythonPackageName = "swagger_client";
public StaticHtml2Generator() { public StaticHtml2Generator() {
super(); super();
@ -40,6 +42,8 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
cliOptions.add(new CliOption("licenseUrl", "a URL pointing to the full license")); cliOptions.add(new CliOption("licenseUrl", "a URL pointing to the full license"));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC)); cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.PHP_INVOKER_PACKAGE, CodegenConstants.PHP_INVOKER_PACKAGE_DESC)); cliOptions.add(new CliOption(CodegenConstants.PHP_INVOKER_PACKAGE, CodegenConstants.PHP_INVOKER_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.PERL_MODULE_NAME, CodegenConstants.PERL_MODULE_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.PYTHON_PACKAGE_NAME, CodegenConstants.PYTHON_PACKAGE_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "C# package name")); cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "C# package name"));
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC)); cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC)); cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
@ -53,6 +57,8 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html"); additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage); additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
additionalProperties.put(CodegenConstants.PHP_INVOKER_PACKAGE, phpInvokerPackage); additionalProperties.put(CodegenConstants.PHP_INVOKER_PACKAGE, phpInvokerPackage);
additionalProperties.put(CodegenConstants.PERL_MODULE_NAME, perlModuleName);
additionalProperties.put(CodegenConstants.PYTHON_PACKAGE_NAME, pythonPackageName);
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.GROUP_ID, groupId); additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId); additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);

View File

@ -235,6 +235,9 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name return "_" + name; // add an underscore to the name
} }
@ -450,14 +453,7 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) { public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
path = normalizePath(path); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. path = normalizePath(path); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
List<Parameter> parameters = operation.getParameters(); // issue 3914 - removed logic designed to remove any parameter of type HeaderParameter
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
return super.fromOperation(path, httpMethod, operation, definitions, swagger); return super.fromOperation(path, httpMethod, operation, definitions, swagger);
} }
@ -512,6 +508,10 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toEnumVarName(String name, String datatype) { public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "empty";
}
// for symbol, e.g. $, # // for symbol, e.g. $, #
if (getSymbolName(name) != null) { if (getSymbolName(name) != null) {
return camelize(WordUtils.capitalizeFully(getSymbolName(name).toUpperCase()), true); return camelize(WordUtils.capitalizeFully(getSymbolName(name).toUpperCase()), true);

View File

@ -235,6 +235,9 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name return "_" + name; // add an underscore to the name
} }
@ -388,6 +391,10 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@SuppressWarnings("static-method") @SuppressWarnings("static-method")
public String toSwiftyEnumName(String value) { public String toSwiftyEnumName(String value) {
if (value.length() == 0) {
return "Empty";
}
if (value.matches("^-?\\d*\\.{0,1}\\d+.*")) { // starts with number if (value.matches("^-?\\d*\\.{0,1}\\d+.*")) { // starts with number
value = "Number" + value; value = "Number" + value;
value = value.replaceAll("-", "Minus"); value = value.replaceAll("-", "Minus");
@ -481,14 +488,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) { public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
path = normalizePath(path); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. path = normalizePath(path); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
List<Parameter> parameters = operation.getParameters(); // issue 3914 - removed logic designed to remove any parameter of type HeaderParameter
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
return super.fromOperation(path, httpMethod, operation, definitions, swagger); return super.fromOperation(path, httpMethod, operation, definitions, swagger);
} }

View File

@ -265,6 +265,9 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; return "_" + name;
} }

View File

@ -3,6 +3,8 @@ package io.swagger.codegen.languages;
import java.io.File; import java.io.File;
import io.swagger.codegen.SupportingFile; import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.CodegenParameter;
import io.swagger.models.properties.Property;
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen { public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
@ -19,7 +21,10 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
@Override @Override
public void processOpts() { public void processOpts() {
super.processOpts(); super.processOpts();
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts")); supportingFiles.add(new SupportingFile("models.mustache", modelPackage().replace('.', File.separatorChar), "models.ts"));
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("git_push.sh.mustache", "", "git_push.sh")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
@ -31,7 +36,54 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
modelTemplateFiles.put("model.mustache", ".ts"); modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts"); apiTemplateFiles.put("api.mustache", ".ts");
embeddedTemplateDir = templateDir = "typescript-angular"; embeddedTemplateDir = templateDir = "typescript-angular";
apiPackage = "API.Client"; apiPackage = "api";
modelPackage = "API.Client"; modelPackage = "model";
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
if(isLanguagePrimitive(swaggerType) || isLanguageGenericType(swaggerType)) {
return swaggerType;
}
return addModelPrefix(swaggerType);
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
parameter.dataType = addModelPrefix(parameter.dataType);
}
private String getIndexDirectory() {
String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.')));
return indexPackage.replace('.', File.separatorChar);
}
private String addModelPrefix(String swaggerType) {
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
} else {
type = swaggerType;
}
if (!isLanguagePrimitive(type) && !isLanguageGenericType(type)) {
type = "models." + swaggerType;
}
return type;
}
private boolean isLanguagePrimitive(String type) {
return languageSpecificPrimitives.contains(type);
}
private boolean isLanguageGenericType(String type) {
for (String genericType: languageGenericTypes) {
if (type.startsWith(genericType + "<")) {
return true;
}
}
return false;
} }
} }

View File

@ -0,0 +1,216 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.Operation;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "ze-ph";
}
@Override
public String getHelp() {
return "Generates PHP server stub using Zend Expressive ( https://zendframework.github.io/zend-expressive ) and Path Handler ( https://github.com/Articus/PathHandler ).";
}
public ZendExpressivePathHandlerServerCodegen() {
super();
embeddedTemplateDir = templateDir = "ze-ph";
invokerPackage = "App";
packagePath = "";
srcBasePath = "src" + File.separator + "App";
apiDirName = "Handler";
modelDirName = "DTO";
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
apiTestTemplateFiles.clear();
modelTestTemplateFiles.clear();
apiDocTemplateFiles.clear();
modelDocTemplateFiles.clear();
supportingFiles.add(new SupportingFile("README.md.mustache", packagePath, "README.md"));
supportingFiles.add(new SupportingFile("composer.json.mustache", packagePath, "composer.json"));
supportingFiles.add(new SupportingFile("index.php", packagePath + File.separator + "public", "index.php"));
supportingFiles.add(new SupportingFile("container.php", packagePath + File.separator + "application", "container.php"));
supportingFiles.add(new SupportingFile("config.yml", packagePath + File.separator + "application", "config.yml"));
supportingFiles.add(new SupportingFile("app.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "app.yml"));
supportingFiles.add(new SupportingFile("path_handler.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "path_handler.yml"));
supportingFiles.add(new SupportingFile("data_transfer.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "data_transfer.yml"));
supportingFiles.add(new SupportingFile("Date.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "Date.php"));
supportingFiles.add(new SupportingFile("DateTime.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "DateTime.php"));
supportingFiles.add(new SupportingFile("Type.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Validator", "Type.php"));
supportingFiles.add(new SupportingFile("ErrorMiddleware.php.mustache", packagePath + File.separator + srcBasePath, "ErrorMiddleware.php"));
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, "1.0.0");
}
/**
* Add operation to group
* Override of default grouping - group by resource path, not tag
*
* @param tag name of the tag
* @param resourcePath path of the resource
* @param operation Swagger Operation object
* @param co Codegen Operation object
* @param operations map of Codegen operations
*/
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
List<CodegenOperation> opList = operations.get(resourcePath);
if (opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(resourcePath, opList);
}
//ignore duplicate operation ids - that means that operation has several tags
int counter = 0;
for (CodegenOperation op : opList) {
if (co.operationId.equals(op.operationId)) {
counter++;
}
}
if (counter == 0) {
co.operationIdLowerCase = co.operationId.toLowerCase();
opList.add(co);
co.baseName = tag;
}
}
/**
* Return the file name of the Api Test
*
* @param name the file name of the Api
* @return the file name of the Api
*/
@Override
public String toApiFilename(String name) {
return toApiName(name);
}
/**
* Output the API (class) name (capitalized) ending with "Api"
* Return DefaultApi if name is empty
*
* @param name the name of the Api
* @return capitalized Api name ending with "Api"
*/
@Override
public String toApiName(String name) {
//Remove }
name = name.replaceAll("[\\}]", "");
return super.toModelName(name);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
objs = super.postProcessOperations(objs);
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
String interfaceToImplement;
StringBuilder interfacesToImplement = new StringBuilder();
String classMethod;
for (CodegenOperation op : operationList) {
switch (op.httpMethod) {
case "GET":
interfaceToImplement = "Operation\\GetInterface";
classMethod = "handleGet";
break;
case "POST":
interfaceToImplement = "Operation\\PostInterface";
classMethod = "handlePost";
break;
case "PATCH":
interfaceToImplement = "Operation\\PatchInterface";
classMethod = "handlePatch";
break;
case "PUT":
interfaceToImplement = "Operation\\PutInterface";
classMethod = "handlePut";
break;
case "DELETE":
interfaceToImplement = "Operation\\DeleteInterface";
classMethod = "handleDelete";
break;
default:
throw new RuntimeException("Unknown HTTP Method " + op.httpMethod + " not allowed");
}
if (interfacesToImplement.length() > 0) {
interfacesToImplement.append(", ");
}
interfacesToImplement.append(interfaceToImplement);
op.httpMethod = classMethod;
}
operations.put("interfacesToImplement", interfacesToImplement.toString());
return objs;
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
objs = super.postProcessSupportingFileData(objs);
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
List<Map<String, Object>> routes = new ArrayList<Map<String, Object>>();
for (Map<String, Object> api : apis) {
String handler = (String) api.get("classname");
String url = (String) api.get("baseName");
if (url.charAt(0) == '/') {
url = url.substring(1);
}
insertRoute(routes, url.split("/"), 0, handler);
}
objs.put("routes", routes);
return objs;
}
private void insertRoute(List<Map<String, Object>> routes, String[] urlParts, int currentUrlPartIndex, String handler) {
if (urlParts.length > currentUrlPartIndex) {
String urlPart = urlParts[currentUrlPartIndex];
//List<Map<String, Object>> subRoutes = null;
Map<String, Object> currentRoute = null;
for (Map<String, Object> route : routes) {
if (urlPart.equals(route.get("name"))) {
currentRoute = route;
break;
}
}
if (currentRoute == null) {
currentRoute = new HashMap<String, Object>();
String routePart = urlPart.replaceAll("^\\{(\\w+)\\}$", ":$1");
boolean isLastUrlPart = currentUrlPartIndex == urlParts.length - 1;
currentRoute.put("name", urlPart);
currentRoute.put("route", "/" + routePart);
currentRoute.put("type", (urlPart == routePart) ? "Literal" : "Segment");
currentRoute.put("handler", isLastUrlPart ? handler : null);
currentRoute.put("hasChildren", false);
currentRoute.put("children", new ArrayList<Map<String, Object>>());
currentRoute.put("padding", StringUtils.repeat(' ', 4 * currentUrlPartIndex));
routes.add(currentRoute);
}
List<Map<String, Object>> subRoutes = (List<Map<String, Object>>) currentRoute.get("children");
insertRoute(subRoutes, urlParts, currentUrlPartIndex + 1, handler);
currentRoute.put("hasChildren", !subRoutes.isEmpty());
}
}
}

View File

@ -15,10 +15,18 @@ public interface CXFServerFeatures
public static final String ADD_CONSUMES_PRODUCES_JSON = "addConsumesProducesJson"; public static final String ADD_CONSUMES_PRODUCES_JSON = "addConsumesProducesJson";
public static final String USE_ANNOTATED_BASE_PATH = "useAnnotatedBasePath";
public static final String GENERATE_NON_SPRING_APPLICATION = "generateNonSpringApplication";
public void setUseWadlFeature(boolean useWadlFeature); public void setUseWadlFeature(boolean useWadlFeature);
public void setUseMultipartFeature(boolean useMultipartFeature); public void setUseMultipartFeature(boolean useMultipartFeature);
public void setAddConsumesProducesJson(boolean addConsumesProducesJson); public void setAddConsumesProducesJson(boolean addConsumesProducesJson);
public void setUseAnnotatedBasePath(boolean useAnnotatedBasePath);
public void setGenerateNonSpringApplication(boolean generateNonSpringApplication);
} }

View File

@ -1,9 +1,10 @@
package io.swagger.codegen.utils; package io.swagger.codegen.utils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import joptsimple.internal.Strings;
import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.isNotEmpty;
@ -22,7 +23,7 @@ public class OptionUtils {
results.add(pair); results.add(pair);
} }
} }
//Strings.isNullOrEmpty(input)
return results; return results;
} }
@ -39,5 +40,4 @@ public class OptionUtils {
return results; return results;
} }
} }

View File

@ -116,6 +116,7 @@ public class ApiClient {
* Build the Client used to make HTTP requests with the latest settings, * Build the Client used to make HTTP requests with the latest settings,
* i.e. objectMapper and debugging. * i.e. objectMapper and debugging.
* TODO: better to use the Builder Pattern? * TODO: better to use the Builder Pattern?
* @return API client
*/ */
public ApiClient rebuildHttpClient() { public ApiClient rebuildHttpClient() {
// Add the JSON serialization support to Jersey // Add the JSON serialization support to Jersey
@ -136,6 +137,7 @@ public class ApiClient {
* Note: If you make changes to the object mapper, remember to set it back via * Note: If you make changes to the object mapper, remember to set it back via
* <code>setObjectMapper</code> in order to trigger HTTP client rebuilding. * <code>setObjectMapper</code> in order to trigger HTTP client rebuilding.
* </p> * </p>
* @return Object mapper
*/ */
public ObjectMapper getObjectMapper() { public ObjectMapper getObjectMapper() {
return objectMapper; return objectMapper;
@ -168,6 +170,7 @@ public class ApiClient {
/** /**
* Gets the status code of the previous request * Gets the status code of the previous request
* @return Status code
*/ */
public int getStatusCode() { public int getStatusCode() {
return statusCode; return statusCode;
@ -175,6 +178,7 @@ public class ApiClient {
/** /**
* Gets the response headers of the previous request * Gets the response headers of the previous request
* @return Response headers
*/ */
public Map<String, List<String>> getResponseHeaders() { public Map<String, List<String>> getResponseHeaders() {
return responseHeaders; return responseHeaders;
@ -182,6 +186,7 @@ public class ApiClient {
/** /**
* Get authentications (key: authentication name, value: authentication). * Get authentications (key: authentication name, value: authentication).
* @return Map of authentication
*/ */
public Map<String, Authentication> getAuthentications() { public Map<String, Authentication> getAuthentications() {
return authentications; return authentications;
@ -199,6 +204,7 @@ public class ApiClient {
/** /**
* Helper method to set username for the first HTTP basic authentication. * Helper method to set username for the first HTTP basic authentication.
* @param username Username
*/ */
public void setUsername(String username) { public void setUsername(String username) {
for (Authentication auth : authentications.values()) { for (Authentication auth : authentications.values()) {
@ -212,6 +218,7 @@ public class ApiClient {
/** /**
* Helper method to set password for the first HTTP basic authentication. * Helper method to set password for the first HTTP basic authentication.
* @param password Password
*/ */
public void setPassword(String password) { public void setPassword(String password) {
for (Authentication auth : authentications.values()) { for (Authentication auth : authentications.values()) {
@ -225,6 +232,7 @@ public class ApiClient {
/** /**
* Helper method to set API key value for the first API key authentication. * Helper method to set API key value for the first API key authentication.
* @param apiKey API key
*/ */
public void setApiKey(String apiKey) { public void setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) { for (Authentication auth : authentications.values()) {
@ -238,6 +246,7 @@ public class ApiClient {
/** /**
* Helper method to set API key prefix for the first API key authentication. * Helper method to set API key prefix for the first API key authentication.
* @param apiKeyPrefix API key prefix
*/ */
public void setApiKeyPrefix(String apiKeyPrefix) { public void setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) { for (Authentication auth : authentications.values()) {
@ -251,6 +260,7 @@ public class ApiClient {
/** /**
* Helper method to set access token for the first OAuth2 authentication. * Helper method to set access token for the first OAuth2 authentication.
* @param accessToken Access token
*/ */
public void setAccessToken(String accessToken) { public void setAccessToken(String accessToken) {
for (Authentication auth : authentications.values()) { for (Authentication auth : authentications.values()) {
@ -264,6 +274,8 @@ public class ApiClient {
/** /**
* Set the User-Agent header's value (by adding to the default header map). * Set the User-Agent header's value (by adding to the default header map).
* @param userAgent User agent
* @return API client
*/ */
public ApiClient setUserAgent(String userAgent) { public ApiClient setUserAgent(String userAgent) {
addDefaultHeader("User-Agent", userAgent); addDefaultHeader("User-Agent", userAgent);
@ -275,6 +287,7 @@ public class ApiClient {
* *
* @param key The header's key * @param key The header's key
* @param value The header's value * @param value The header's value
* @return API client
*/ */
public ApiClient addDefaultHeader(String key, String value) { public ApiClient addDefaultHeader(String key, String value) {
defaultHeaderMap.put(key, value); defaultHeaderMap.put(key, value);
@ -283,6 +296,7 @@ public class ApiClient {
/** /**
* Check that whether debugging is enabled for this API client. * Check that whether debugging is enabled for this API client.
* @return True if debugging is on
*/ */
public boolean isDebugging() { public boolean isDebugging() {
return debugging; return debugging;
@ -292,6 +306,7 @@ public class ApiClient {
* Enable/disable debugging for this API client. * Enable/disable debugging for this API client.
* *
* @param debugging To enable (true) or disable (false) debugging * @param debugging To enable (true) or disable (false) debugging
* @return API client
*/ */
public ApiClient setDebugging(boolean debugging) { public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging; this.debugging = debugging;
@ -302,6 +317,7 @@ public class ApiClient {
/** /**
* Connect timeout (in milliseconds). * Connect timeout (in milliseconds).
* @return Connection timeout
*/ */
public int getConnectTimeout() { public int getConnectTimeout() {
return connectionTimeout; return connectionTimeout;
@ -311,6 +327,8 @@ public class ApiClient {
* Set the connect timeout (in milliseconds). * Set the connect timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and * A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}. * {@link Integer#MAX_VALUE}.
* @param connectionTimeout Connection timeout in milliseconds
* @return API client
*/ */
public ApiClient setConnectTimeout(int connectionTimeout) { public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout; this.connectionTimeout = connectionTimeout;
@ -320,6 +338,7 @@ public class ApiClient {
/** /**
* Get the date format used to parse/format date parameters. * Get the date format used to parse/format date parameters.
* @return Date format
*/ */
public DateFormat getDateFormat() { public DateFormat getDateFormat() {
return dateFormat; return dateFormat;
@ -327,6 +346,8 @@ public class ApiClient {
/** /**
* Set the date format used to parse/format date parameters. * Set the date format used to parse/format date parameters.
* @param dateFormat Date format
* @return API client
*/ */
public ApiClient setDateFormat(DateFormat dateFormat) { public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat; this.dateFormat = dateFormat;
@ -339,6 +360,8 @@ public class ApiClient {
/** /**
* Parse the given string into Date object. * Parse the given string into Date object.
* @param str String
* @return Date
*/ */
public Date parseDate(String str) { public Date parseDate(String str) {
try { try {
@ -350,6 +373,8 @@ public class ApiClient {
/** /**
* Format the given Date object into string. * Format the given Date object into string.
* @param date Date
* @return Date in string format
*/ */
public String formatDate(Date date) { public String formatDate(Date date) {
return dateFormat.format(date); return dateFormat.format(date);
@ -357,6 +382,8 @@ public class ApiClient {
/** /**
* Format the given parameter object into string. * Format the given parameter object into string.
* @param param Object
* @return Object in string format
*/ */
public String parameterToString(Object param) { public String parameterToString(Object param) {
if (param == null) { if (param == null) {
@ -378,7 +405,11 @@ public class ApiClient {
} }
/* /*
Format to {@code Pair} objects. * Format to {@code Pair} objects.
* @param collectionFormat Collection format
* @param name Name
* @param value Value
* @return List of pair
*/ */
public List<Pair> parameterToPairs(String collectionFormat, String name, Object value){ public List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
List<Pair> params = new ArrayList<Pair>(); List<Pair> params = new ArrayList<Pair>();
@ -439,6 +470,8 @@ public class ApiClient {
* application/json * application/json
* application/json; charset=UTF8 * application/json; charset=UTF8
* APPLICATION/JSON * APPLICATION/JSON
* @param mime MIME
* @return True if MIME type is boolean
*/ */
public boolean isJsonMime(String mime) { public boolean isJsonMime(String mime) {
return mime != null && mime.matches("(?i)application\\/json(;.*)?"); return mime != null && mime.matches("(?i)application\\/json(;.*)?");
@ -488,6 +521,8 @@ public class ApiClient {
/** /**
* Escape the given string to be used as URL query value. * Escape the given string to be used as URL query value.
* @param str String
* @return Escaped string
*/ */
public String escapeString(String str) { public String escapeString(String str) {
try { try {
@ -500,6 +535,11 @@ public class ApiClient {
/** /**
* Serialize the given Java object into string according the given * Serialize the given Java object into string according the given
* Content-Type (only JSON is supported for now). * Content-Type (only JSON is supported for now).
* @param obj Object
* @param contentType Content type
* @param formParams Form parameters
* @return Object
* @throws ApiException API exception
*/ */
public Object serialize(Object obj, String contentType, Map<String, Object> formParams) throws ApiException { public Object serialize(Object obj, String contentType, Map<String, Object> formParams) throws ApiException {
if (contentType.startsWith("multipart/form-data")) { if (contentType.startsWith("multipart/form-data")) {
@ -605,6 +645,7 @@ public class ApiClient {
/** /**
* Invoke API by sending HTTP request with the given options. * Invoke API by sending HTTP request with the given options.
* *
* @param <T> Type
* @param path The sub-path of the HTTP URL * @param path The sub-path of the HTTP URL
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE" * @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
* @param queryParams The query parameters * @param queryParams The query parameters
@ -614,7 +655,9 @@ public class ApiClient {
* @param accept The request's Accept header * @param accept The request's Accept header
* @param contentType The request's Content-Type header * @param contentType The request's Content-Type header
* @param authNames The authentications to apply * @param authNames The authentications to apply
* @param returnType Return type
* @return The response body in type of string * @return The response body in type of string
* @throws ApiException API exception
*/ */
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException { public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
@ -653,6 +696,8 @@ public class ApiClient {
* Update query and header parameters based on authentication settings. * Update query and header parameters based on authentication settings.
* *
* @param authNames The authentications to apply * @param authNames The authentications to apply
* @param queryParams Query parameters
* @param headerParams Header parameters
*/ */
private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) { private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
for (String authName : authNames) { for (String authName : authNames) {
@ -664,6 +709,8 @@ public class ApiClient {
/** /**
* Encode the given form parameters as request body. * Encode the given form parameters as request body.
* @param formParams Form parameters
* @return HTTP form encoded parameters
*/ */
private String getXWWWFormUrlencodedParams(Map<String, Object> formParams) { private String getXWWWFormUrlencodedParams(Map<String, Object> formParams) {
StringBuilder formParamBuilder = new StringBuilder(); StringBuilder formParamBuilder = new StringBuilder();

View File

@ -44,9 +44,13 @@ public class {{classname}} {
{{#operation}} {{#operation}}
/** /**
* {{summary}} * {{summary}}
* {{notes}}{{#allParams}} * {{notes}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}} {{#allParams}}
* @return {{{returnType}}}{{/returnType}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
* @throws ApiException if fails to make API call * @throws ApiException if fails to make API call
*/ */
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {

View File

@ -32,21 +32,22 @@
{{^minItems}} {{^minItems}}
{{#maxItems}} {{#maxItems}}
@Size(max={{maxItems}}) @Size(max={{maxItems}})
{{/maxItems}} {{/maxItems}}
{{/minItems}} {{/minItems}}
{{! check for integer / number=decimal type}}
{{#isInteger}}
{{#minimum}} {{#minimum}}
{{#isInteger}}
@Min({{minimum}}) @Min({{minimum}})
{{/isInteger}}
{{#isLong}}
@Min({{minimum}})
{{/isLong}}
{{/minimum}} {{/minimum}}
{{#maximum}} {{#maximum}}
{{#isInteger}}
@Max({{maximum}}) @Max({{maximum}})
{{/isInteger}}
{{#isLong}}
@Max({{maximum}})
{{/isLong}}
{{/maximum}} {{/maximum}}
{{/isInteger}}
{{^isInteger}}
{{#minimum}}
@DecimalMin("{{minimum}}")
{{/minimum}}
{{#maximum}}
@DecimalMax("{{maximum}}")
{{/maximum}}
{{/isInteger}}

View File

@ -53,7 +53,7 @@ public class ApiClient {
this(); this();
for(String authName : authNames) { {{#hasAuthMethods}} for(String authName : authNames) { {{#hasAuthMethods}}
RequestInterceptor auth; RequestInterceptor auth;
{{#authMethods}}if (authName == "{{name}}") { {{#isBasic}} {{#authMethods}}if ("{{name}}".equals(authName)) { {{#isBasic}}
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}} auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}} auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}} auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
@ -172,6 +172,9 @@ public class ApiClient {
* apiClient.setBasePath("http://localhost:8080"); * apiClient.setBasePath("http://localhost:8080");
* XYZApi api = apiClient.buildClient(XYZApi.class); * XYZApi api = apiClient.buildClient(XYZApi.class);
* XYZResponse response = api.someMethod(...); * XYZResponse response = api.someMethod(...);
* @param <T> Type
* @param clientClass Client class
* @return The Client
*/ */
public <T extends Api> T buildClient(Class<T> clientClass) { public <T extends Api> T buildClient(Class<T> clientClass) {
return feignBuilder.target(clientClass, basePath); return feignBuilder.target(clientClass, basePath);
@ -209,7 +212,7 @@ public class ApiClient {
/** /**
* Helper method to configure the first api key found * Helper method to configure the first api key found
* @param apiKey * @param apiKey API key
*/ */
public void setApiKey(String apiKey) { public void setApiKey(String apiKey) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -224,8 +227,8 @@ public class ApiClient {
/** /**
* Helper method to configure the username/password for basic auth or password OAuth * Helper method to configure the username/password for basic auth or password OAuth
* @param username * @param username Username
* @param password * @param password Password
*/ */
public void setCredentials(String username, String password) { public void setCredentials(String username, String password) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -245,7 +248,7 @@ public class ApiClient {
/** /**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one) * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return * @return Token request builder
*/ */
public TokenRequestBuilder getTokenEndPoint() { public TokenRequestBuilder getTokenEndPoint() {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -259,7 +262,7 @@ public class ApiClient {
/** /**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one) * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return * @return Authentication request builder
*/ */
public AuthenticationRequestBuilder getAuthorizationEndPoint() { public AuthenticationRequestBuilder getAuthorizationEndPoint() {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -273,8 +276,8 @@ public class ApiClient {
/** /**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one) * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken * @param accessToken Access Token
* @param expiresIn : validity period in seconds * @param expiresIn Validity period in seconds
*/ */
public void setAccessToken(String accessToken, Long expiresIn) { public void setAccessToken(String accessToken, Long expiresIn) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -288,9 +291,9 @@ public class ApiClient {
/** /**
* Helper method to configure the oauth accessCode/implicit flow parameters * Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId * @param clientId Client ID
* @param clientSecret * @param clientSecret Client secret
* @param redirectURI * @param redirectURI Redirect URI
*/ */
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) { public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -310,7 +313,7 @@ public class ApiClient {
/** /**
* Configures a listener which is notified when a new access token is received. * Configures a listener which is notified when a new access token is received.
* @param accessTokenListener * @param accessTokenListener Acesss token listener
*/ */
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@ -322,14 +325,19 @@ public class ApiClient {
} }
} }
/**
* Gets request interceptor based on authentication name
* @param authName Authentiation name
* @return Request Interceptor
*/
public RequestInterceptor getAuthorization(String authName) { public RequestInterceptor getAuthorization(String authName) {
return apiAuthorizations.get(authName); return apiAuthorizations.get(authName);
} }
/** /**
* Adds an authorization to be used by the client * Adds an authorization to be used by the client
* @param authName * @param authName Authentication name
* @param authorization * @param authorization Request interceptor
*/ */
public void addAuthorization(String authName, RequestInterceptor authorization) { public void addAuthorization(String authName, RequestInterceptor authorization) {
if (apiAuthorizations.containsKey(authName)) { if (apiAuthorizations.containsKey(authName)) {

View File

@ -23,8 +23,12 @@ public interface {{classname}} extends ApiClient.Api {
/** /**
* {{summary}} * {{summary}}
* {{notes}} * {{notes}}
{{#allParams}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} {{#allParams}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
*/ */
@RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}") @RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}")
@Headers({ @Headers({

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