Merge branch 'master' into java-imports

Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java
This commit is contained in:
xhh 2016-02-22 09:24:58 +08:00
commit 8c36ed8409
728 changed files with 38867 additions and 3780 deletions

7
.gitignore vendored
View File

@ -62,6 +62,12 @@ samples/client/petstore/python/.projectile
samples/client/petstore/python/.venv/ samples/client/petstore/python/.venv/
samples/client/petstore/python/dev-requirements.txt.log samples/client/petstore/python/dev-requirements.txt.log
samples/client/petstore/objc/SwaggerClientTests/SwaggerClient.xcodeproj/xcuserdata
samples/client/petstore/swift/SwaggerClientTests/SwaggerClient.xcodeproj/xcuserdata
samples/client/petstore/swift/SwaggerClientTests/SwaggerClient.xcworkspace/xcuserdata
samples/client/petstore/swift/SwaggerClientTests/Pods/Pods.xcodeproj/xcuserdata
samples/client/petstore/swift/SwaggerClientTests/Pods/Pods.xcodeproj/xcshareddata/xcschemes
.settings .settings
*.mustache~ *.mustache~
@ -72,3 +78,4 @@ samples/client/petstore/python/dev-requirements.txt.log
samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/ samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/
samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/ samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/
**/.gradle/

143
README.md
View File

@ -39,16 +39,21 @@ Check out [Swagger-Spec](https://github.com/OAI/OpenAPI-Specification) for addit
- [Generating static html api documentation](#generating-static-html-api-documentation) - [Generating static html api documentation](#generating-static-html-api-documentation)
- [To build a server stub](#to-build-a-server-stub) - [To build a server stub](#to-build-a-server-stub)
- [Node.js](#nodejs) - [Node.js](#nodejs)
- [PHP Slim](#php-slim)
- [PHP Silex](#php-silex) - [PHP Silex](#php-silex)
- [Python Flask (Connexion)](#python-flask-connexion) - [Python Flask (Connexion)](#python-flask-connexion)
- [Ruby Sinatra](#ruby-sinatra) - [Ruby Sinatra](#ruby-sinatra)
- [Scala Scalatra](#scala-scalatra) - [Scala Scalatra](#scala-scalatra)
- [Java JAX-RS](#java-jax-rs) - [Java JAX-RS (Java JAX-RS (Jersey v1.18)](#java-jax-rs-jersey-v118)
- [Java JAX-RS (Apache CXF 3)](#java-jax-rs-apache-cxf-3)
- [Java Spring MVC](#java-spring-mvc) - [Java Spring MVC](#java-spring-mvc)
- [Haskell Servant](#haskell-servant)
- [ASP.NET 5 Web API](#aspnet-5-web-api)
- [To build the codegen library](#to-build-the-codegen-library) - [To build the codegen library](#to-build-the-codegen-library)
- [Workflow Integration](#workflow-integration) - [Workflow Integration](#workflow-integration)
- [Online Generators](#online-generators) - [Online Generators](#online-generators)
- [Guidelines for Contribution](https://github.com/swagger-api/swagger-codegen/wiki/Guidelines-for-Contribution) - [Guidelines for Contribution](https://github.com/swagger-api/swagger-codegen/wiki/Guidelines-for-Contribution)
- [Companies/Projects using Swagger Codegen](#companiesprojects-using-swagger-codegen)
- [License](#license) - [License](#license)
@ -67,7 +72,7 @@ Swagger Codegen Version | Release Date | OpenAPI Spec compatibility | Notes
If you're looking for the latest stable version, you can grab it directly from maven central (you'll need java 7 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from maven central (you'll need java 7 runtime at a minimum):
``` ```
wget http://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.1.4/swagger-codegen-cli-2.1.4.jar swagger-codegen-cli.jar wget http://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.1.5/swagger-codegen-cli-2.1.5.jar -o swagger-codegen-cli.jar
java -jar swagger-codegen-cli.jar help java -jar swagger-codegen-cli.jar help
``` ```
@ -118,7 +123,7 @@ cd swagger-codegen
vagrant up vagrant up
vagrant ssh vagrant ssh
cd /vagrant cd /vagrant
sudo ./run-in-docker.sh mvn package ./run-in-docker.sh mvn package
``` ```
#### Public Docker image #### Public Docker image
@ -156,18 +161,27 @@ with a number of options. You can get the options with the `help generate` comm
``` ```
NAME NAME
swagger generate - Generate code with chosen lang swagger-codegen-cli generate - Generate code with chosen lang
SYNOPSIS SYNOPSIS
swagger generate [(-a <authorization> | --auth <authorization>)] swagger-codegen-cli generate
[(-a <authorization> | --auth <authorization>)]
[--additional-properties <additional properties>]
[--api-package <api package>] [--artifact-id <artifact id>]
[--artifact-version <artifact version>]
[(-c <configuration file> | --config <configuration file>)] [(-c <configuration file> | --config <configuration file>)]
[-D <system properties>] [-D <system properties>] [--group-id <group id>]
(-i <spec file> | --input-spec <spec file>) (-i <spec file> | --input-spec <spec file>)
[--import-mappings <import mappings>]
[--instantiation-types <instantiation types>]
[--invoker-package <invoker package>]
(-l <language> | --lang <language>) (-l <language> | --lang <language>)
[--language-specific-primitives <language specific primitives>]
[--library <library>] [--model-package <model package>]
[(-o <output directory> | --output <output directory>)] [(-o <output directory> | --output <output directory>)]
[(-t <template directory> | --template-dir <template directory>)]
[(-v | --verbose)]
[(-s | --skip-overwrite)] [(-s | --skip-overwrite)]
[(-t <template directory> | --template-dir <template directory>)]
[--type-mappings <type mappings>] [(-v | --verbose)]
OPTIONS OPTIONS
-a <authorization>, --auth <authorization> -a <authorization>, --auth <authorization>
@ -175,6 +189,19 @@ OPTIONS
remotely. Pass in a URL-encoded string of name:header with a comma remotely. Pass in a URL-encoded string of name:header with a comma
separating multiple values separating multiple values
--additional-properties <additional properties>
sets additional properties that can be referenced by the mustache
templates in the format of name=value,name=value
--api-package <api package>
package for generated api classes
--artifact-id <artifact id>
artifactId in generated pom.xml
--artifact-version <artifact version>
artifact version in generated pom.xml
-c <configuration file>, --config <configuration file> -c <configuration file>, --config <configuration file>
Path to json configuration file. File content should be in a json Path to json configuration file. File content should be in a json
format {"optionKey":"optionValue", "optionKey1":"optionValue1"...} format {"optionKey":"optionValue", "optionKey1":"optionValue1"...}
@ -185,25 +212,59 @@ OPTIONS
sets specified system properties in the format of sets specified system properties in the format of
name=value,name=value name=value,name=value
--group-id <group id>
groupId in generated pom.xml
-i <spec file>, --input-spec <spec file> -i <spec file>, --input-spec <spec file>
location of the OpenAPI Spec, as URL or file (required) location of the swagger spec, as URL or file (required)
--import-mappings <import mappings>
specifies mappings between a given class and the import that should
be used for that class in the format of type=import,type=import
--instantiation-types <instantiation types>
sets instantiation type mappings in the format of
type=instantiatedType,type=instantiatedType.For example (in Java):
array=ArrayList,map=HashMap. In other words array types will get
instantiated as ArrayList in generated code.
--invoker-package <invoker package>
root package for generated code
-l <language>, --lang <language> -l <language>, --lang <language>
client language to generate (maybe class name in classpath, client language to generate (maybe class name in classpath,
required) required)
--language-specific-primitives <language specific primitives>
specifies additional language specific primitive types in the format
of type1,type2,type3,type3. For example:
String,boolean,Boolean,Double
--library <library>
library template (sub-template)
--model-package <model package>
package for generated models
-o <output directory>, --output <output directory> -o <output directory>, --output <output directory>
where to write the generated files (current dir by default) where to write the generated files (current dir by default)
-s, --skip-overwrite
specifies if the existing files should be overwritten during the
generation.
-t <template directory>, --template-dir <template directory> -t <template directory>, --template-dir <template directory>
folder containing the template files folder containing the template files
--type-mappings <type mappings>
sets mappings between swagger spec types and generated code types in
the format of swaggerType=generatedType,swaggerType=generatedType.
For example: array=List,map=Map,string=String
-v, --verbose -v, --verbose
verbose mode verbose mode
-s , --skip-overwrite
specifies if the existing files should be overwritten during
the generation
``` ```
You can then compile and run the client, as well as unit tests against it: You can then compile and run the client, as well as unit tests against it:
@ -306,10 +367,11 @@ There are different aspects of customizing the code generator beyond just creati
``` ```
$ ls -1 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ $ ls -1 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/
AbstractJavaJAXRSServerCodegen.java
AbstractTypeScriptClientCodegen.java AbstractTypeScriptClientCodegen.java
AkkaScalaClientCodegen.java AkkaScalaClientCodegen.java
AndroidClientCodegen.java AndroidClientCodegen.java
AndroidVolleyClientCodegen.java AspNet5ServerCodegen.java
AsyncScalaClientCodegen.java AsyncScalaClientCodegen.java
CSharpClientCodegen.java CSharpClientCodegen.java
ClojureClientCodegen.java ClojureClientCodegen.java
@ -317,11 +379,14 @@ CsharpDotNet2ClientCodegen.java
DartClientCodegen.java DartClientCodegen.java
FlashClientCodegen.java FlashClientCodegen.java
FlaskConnexionCodegen.java FlaskConnexionCodegen.java
GoClientCodegen.java
HaskellServantCodegen.java
JMeterCodegen.java
JavaCXFServerCodegen.java
JavaClientCodegen.java JavaClientCodegen.java
JavaInflectorServerCodegen.java JavaInflectorServerCodegen.java
JavaJerseyServerCodegen.java
JavascriptClientCodegen.java JavascriptClientCodegen.java
JaxRSServerCodegen.java
JMeterCodegen.java
NodeJSServerCodegen.java NodeJSServerCodegen.java
ObjcClientCodegen.java ObjcClientCodegen.java
PerlClientCodegen.java PerlClientCodegen.java
@ -501,6 +566,15 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/server/petstore/nodejs -o samples/server/petstore/nodejs
``` ```
### PHP Slim
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l slim \
-o samples/server/petstore/slim
```
### PHP Silex ### PHP Silex
``` ```
@ -563,6 +637,24 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/server/petstore/spring-mvc -o samples/server/petstore/spring-mvc
``` ```
### Haskell Servant
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l haskell-servant \
-o samples/server/petstore/haskell-servant
```
### ASP.NET 5 Web API
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l aspnet5 \
-o samples/server/petstore/aspnet5
```
### To build the codegen library ### To build the codegen library
This will create the swagger-codegen library from source. This will create the swagger-codegen library from source.
@ -593,6 +685,24 @@ Guidelines for Contribution
Please refer to this [page](https://github.com/swagger-api/swagger-codegen/blob/master/CONTRIBUTING.md) Please refer to this [page](https://github.com/swagger-api/swagger-codegen/blob/master/CONTRIBUTING.md)
Companies/Projects using Swagger Codegen
----------------------------------------
Here are some companies/projects using Swagger Codegen. To add your company/project to the list, please submit a PR.
- [Acunetix](https://www.acunetix.com/)
- [Cupix](http://www.cupix.com)
- [Ergon](http://www.ergon.ch/)
- [everystory.us](http://everystory.us)
- [Expected Behavior](http://www.expectedbehavior.com/)
- [nViso](http://www.nviso.ch/)
- [Okiok](https://www.okiok.com)
- [Reload! A/S](https://reload.dk/)
- [Royal Bank of Canada (RBC)](http://www.rbc.com/canada.html)
- [SmartRecruiters](https://www.smartrecruiters.com/)
- [StyleRecipe](http://stylerecipe.co.jp)
- [ThoughtWorks](https://www.thoughtworks.com)
- [uShip](https://www.uship.com/)
- [ZEEF.com](https://zeef.com/)
License License
------- -------
@ -607,3 +717,6 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
---
<img src="http://swagger.io/wp-content/uploads/2016/02/logo.jpg"/>

2
Vagrantfile vendored
View File

@ -23,12 +23,14 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
#Provision #Provision
config.vm.provision "shell", inline: <<-SHELL config.vm.provision "shell", inline: <<-SHELL
sudo touch /var/lib/cloud/instance/locale-check.skip
sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo sh -c 'echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" > /etc/apt/sources.list.d/docker.list' sudo sh -c 'echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" > /etc/apt/sources.list.d/docker.list'
sudo apt-cache policy docker-engine sudo apt-cache policy docker-engine
sudo apt-get update sudo apt-get update
sudo apt-get upgrade -y sudo apt-get upgrade -y
sudo apt-get install -y docker-engine sudo apt-get install -y docker-engine
sudo usermod -aG docker vagrant
SHELL SHELL
end end

View File

@ -23,6 +23,7 @@ cd $APP_DIR
./bin/clojure-petstore.sh ./bin/clojure-petstore.sh
./bin/csharp-petstore.sh ./bin/csharp-petstore.sh
./bin/dynamic-html.sh ./bin/dynamic-html.sh
./bin/haskell-petstore.sh
./bin/html-petstore.sh ./bin/html-petstore.sh
./bin/java-petstore.sh ./bin/java-petstore.sh
./bin/java-petstore-jersey2.sh ./bin/java-petstore-jersey2.sh

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

@ -0,0 +1,31 @@
#!/usr/bin/env bash
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
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 -l aspnet5 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -o samples/server/petstore/aspnet5"
java $JAVA_OPTS -jar $executable $ags

0
bin/go-petstore.sh Normal file → Executable file
View File

31
bin/haskell-servant-petstore.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/haskell-servant -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l haskell-servant -o samples/server/petstore/haskell-servant"
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 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l javascript-closure-angular -o samples/client/petstore/javascript-closure-angular"
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/javascript -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l javascript -o samples/client/petstore/javascript" ags="$@ generate -t modules/swagger-codegen/src/main/resources/Javascript -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l javascript -o samples/client/petstore/javascript"
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags

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/Javascript \
-i modules/swagger-codegen/src/test/resources/2_0/petstore.json -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,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 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l jaxrs-resteasy -o samples/server/petstore/jaxrs-resteasy"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
set JAVA_OPTS=%JAVA_OPTS% -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -t modules\swagger-codegen\src\main\resources\aspnet5 -i modules\swagger-codegen\src\test\resources\2_0\petstore.json -l aspnet5 -o samples\server\petstore\aspnet5\
java %JAVA_OPTS% -jar %executable% %ags%

0
bin/windows/go-petstore.bat Normal file → Executable file
View File

View File

@ -32,8 +32,10 @@ import org.apache.maven.project.MavenProject;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static io.swagger.codegen.plugin.AdditionalParams.*; import static io.swagger.codegen.plugin.AdditionalParams.*;
@ -156,39 +158,35 @@ public class CodeGenMojo extends AbstractMojo {
config.additionalProperties().put(INVOKER_PACKAGE_PARAM, invokerPackage); config.additionalProperties().put(INVOKER_PACKAGE_PARAM, invokerPackage);
} }
Set<String> definedOptions = new HashSet<String>();
for (CliOption langCliOption : config.cliOptions()) {
definedOptions.add(langCliOption.getOpt());
}
if (configOptions != null) { if (configOptions != null) {
for (CliOption langCliOption : config.cliOptions()) {
if (configOptions.containsKey(langCliOption.getOpt())) {
config.additionalProperties().put(langCliOption.getOpt(),
configOptions.get(langCliOption.getOpt()));
}
}
if(configOptions.containsKey("import-mappings")) { if(configOptions.containsKey("import-mappings")) {
Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.get("import-mappings").toString()); Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.remove("import-mappings").toString());
config.importMapping().putAll(mappings); config.importMapping().putAll(mappings);
} }
if(configOptions.containsKey("type-mappings")) { if(configOptions.containsKey("type-mappings")) {
Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.get("type-mappings").toString()); Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.remove("type-mappings").toString());
config.typeMapping().putAll(mappings); config.typeMapping().putAll(mappings);
} }
if(configOptions.containsKey("instantiation-types")) { if(configOptions.containsKey("instantiation-types")) {
Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.get("instantiation-types").toString()); Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.remove("instantiation-types").toString());
config.instantiationTypes().putAll(mappings); config.instantiationTypes().putAll(mappings);
} }
addAdditionalProperties(config, definedOptions, configOptions);
} }
if (null != configurationFile) { if (null != configurationFile) {
Config genConfig = ConfigParser.read(configurationFile); Config genConfig = ConfigParser.read(configurationFile);
if (null != genConfig) { if (null != genConfig) {
for (CliOption langCliOption : config.cliOptions()) { addAdditionalProperties(config, definedOptions, genConfig.getOptions());
if (genConfig.hasOption(langCliOption.getOpt())) {
config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt()));
}
}
} else { } else {
throw new RuntimeException("Unable to read configuration file"); throw new RuntimeException("Unable to read configuration file");
} }
} }
@ -207,8 +205,8 @@ public class CodeGenMojo extends AbstractMojo {
new DefaultGenerator().opts(input).generate(); new DefaultGenerator().opts(input).generate();
} catch (Exception e) { } catch (Exception e) {
// Maven logs exceptions thrown by plugins only if invoked with -e // Maven logs exceptions thrown by plugins only if invoked with -e
// I find it annoying to jump through hoops to get basic diagnostic information, // I find it annoying to jump through hoops to get basic diagnostic information,
// so let's log it in any case: // so let's log it in any case:
getLog().error(e); getLog().error(e);
throw new MojoExecutionException("Code generation failed. See above for the full exception."); throw new MojoExecutionException("Code generation failed. See above for the full exception.");
} }
@ -218,6 +216,15 @@ public class CodeGenMojo extends AbstractMojo {
} }
} }
private void addAdditionalProperties(CodegenConfig config, Set<String> definedOptions, Map<?,?> configOptions) {
for(Map.Entry<?, ?> configEntry : configOptions.entrySet()) {
config.additionalProperties().put(configEntry.getKey().toString(), configEntry.getValue());
if(!definedOptions.contains(configEntry.getKey())) {
getLog().warn("Additional property: " + configEntry.getKey() + " is not defined for this language.");
}
}
}
private static Map<String, String> createMapFromKeyValuePairs(String commaSeparatedKVPairs) { private static Map<String, String> createMapFromKeyValuePairs(String commaSeparatedKVPairs) {
final List<Pair<String, String>> pairs = OptionUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs); final List<Pair<String, String>> pairs = OptionUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs);

View File

@ -19,6 +19,8 @@ public interface CodegenConfig {
Map<String, Object> additionalProperties(); Map<String, Object> additionalProperties();
Map<String, Object> vendorExtensions();
String testPackage(); String testPackage();
String apiPackage(); String apiPackage();
@ -117,6 +119,8 @@ public interface CodegenConfig {
void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations); void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations);
Map<String, Object> postProcessAllModels(Map<String, Object> objs);
Map<String, Object> postProcessModels(Map<String, Object> objs); Map<String, Object> postProcessModels(Map<String, Object> objs);
Map<String, Object> postProcessOperations(Map<String, Object> objs); Map<String, Object> postProcessOperations(Map<String, Object> objs);

View File

@ -60,7 +60,7 @@ public class CodegenConstants {
public static final String OPTIONAL_METHOD_ARGUMENT_DESC = "Optional method argument, e.g. void square(int x=10) (.net 4.0+ only)."; public static final String OPTIONAL_METHOD_ARGUMENT_DESC = "Optional method argument, e.g. void square(int x=10) (.net 4.0+ only).";
public static final String OPTIONAL_ASSEMBLY_INFO = "optionalAssemblyInfo"; public static final String OPTIONAL_ASSEMBLY_INFO = "optionalAssemblyInfo";
public static final String OPTIONAL_ASSEMBLY_INFO_DESC = "Generate AssemblyInfo.cs (Default: true)."; public static final String OPTIONAL_ASSEMBLY_INFO_DESC = "Generate AssemblyInfo.cs.";
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>.";
@ -69,7 +69,7 @@ public class CodegenConstants {
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.";
public static final String OPTIONAL_PROJECT_FILE = "optionalProjectFile"; public static final String OPTIONAL_PROJECT_FILE = "optionalProjectFile";
public static final String OPTIONAL_PROJECT_FILE_DESC = "Generate {PackageName}.csproj (Default: false)."; public static final String OPTIONAL_PROJECT_FILE_DESC = "Generate {PackageName}.csproj.";
public static final String OPTIONAL_PROJECT_GUID = "packageGuid"; public static final String OPTIONAL_PROJECT_GUID = "packageGuid";
public static final String OPTIONAL_PROJECT_GUID_DESC = "The GUID that will be associated with the C# project"; public static final String OPTIONAL_PROJECT_GUID_DESC = "The GUID that will be associated with the C# project";
@ -77,6 +77,9 @@ public class CodegenConstants {
public static final String MODEL_PROPERTY_NAMING = "modelPropertyNaming"; public static final String MODEL_PROPERTY_NAMING = "modelPropertyNaming";
public static final String MODEL_PROPERTY_NAMING_DESC = "Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name"; public static final String MODEL_PROPERTY_NAMING_DESC = "Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name";
public static final String DOTNET_FRAMEWORK = "targetFramework";
public static final String DOTNET_FRAMEWORK_DESC = "The target .NET framework version.";
public static enum MODEL_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, original} public static enum MODEL_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, original}
} }

View File

@ -177,6 +177,9 @@ public class CodegenProperty {
if (this.isEnum != other.isEnum) { if (this.isEnum != other.isEnum) {
return false; return false;
} }
if (this.isReadOnly != other.isReadOnly && (this.isReadOnly == null || !this.isReadOnly.equals(other.isReadOnly))) {
return false;
}
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) { if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
return false; return false;
} }

View File

@ -71,6 +71,7 @@ public class DefaultCodegen {
protected String templateDir; protected String templateDir;
protected String embeddedTemplateDir; protected String embeddedTemplateDir;
protected Map<String, Object> additionalProperties = new HashMap<String, Object>(); protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
protected Map<String, Object> vendorExtensions = new HashMap<String, Object>();
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>(); protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
protected List<CliOption> cliOptions = new ArrayList<CliOption>(); protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite; protected boolean skipOverwrite;
@ -108,12 +109,19 @@ public class DefaultCodegen {
} }
} }
// override with any special post-processing for all models
@SuppressWarnings("static-method")
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
return objs;
}
// override with any special post-processing // override with any special post-processing
@SuppressWarnings("static-method") @SuppressWarnings("static-method")
public Map<String, Object> postProcessModels(Map<String, Object> objs) { public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return objs; return objs;
} }
// override with any special post-processing // override with any special post-processing
@SuppressWarnings("static-method") @SuppressWarnings("static-method")
public Map<String, Object> postProcessOperations(Map<String, Object> objs) { public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
@ -247,6 +255,10 @@ public class DefaultCodegen {
return additionalProperties; return additionalProperties;
} }
public Map<String, Object> vendorExtensions() {
return vendorExtensions;
}
public List<SupportingFile> supportingFiles() { public List<SupportingFile> supportingFiles() {
return supportingFiles; return supportingFiles;
} }
@ -585,6 +597,54 @@ public class DefaultCodegen {
} }
} }
/**
* Return the example value of the property
*
* @param p Swagger property object
* @return string presentation of the example value of the property
*/
@SuppressWarnings("static-method")
public String toExampleValue(Property p) {
if(p.getExample() != null) {
return p.getExample().toString();
}
if (p instanceof StringProperty) {
return "null";
} else if (p instanceof BooleanProperty) {
return "null";
} else if (p instanceof DateProperty) {
return "null";
} else if (p instanceof DateTimeProperty) {
return "null";
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
return "null";
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
return "null";
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
return "null";
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
return "null";
} else {
return "null";
}
}
/** /**
* Return the default value of the property * Return the default value of the property
* *
@ -927,7 +987,7 @@ public class DefaultCodegen {
property.unescapedDescription = p.getDescription(); property.unescapedDescription = p.getDescription();
property.getter = "get" + getterAndSetterCapitalize(name); property.getter = "get" + getterAndSetterCapitalize(name);
property.setter = "set" + getterAndSetterCapitalize(name); property.setter = "set" + getterAndSetterCapitalize(name);
property.example = p.getExample(); property.example = toExampleValue(p);
property.defaultValue = toDefaultValue(p); property.defaultValue = toDefaultValue(p);
property.defaultValueWithParam = toDefaultValueWithParam(name, p); property.defaultValueWithParam = toDefaultValueWithParam(name, p);
property.jsonSchema = Json.pretty(p); property.jsonSchema = Json.pretty(p);
@ -1366,6 +1426,8 @@ public class DefaultCodegen {
} else if (param instanceof FormParameter) { } else if (param instanceof FormParameter) {
if ("file".equalsIgnoreCase(((FormParameter) param).getType())) { if ("file".equalsIgnoreCase(((FormParameter) param).getType())) {
p.isFile = true; p.isFile = true;
} else if("file".equals(p.baseType)){
p.isFile = true;
} else { } else {
p.notFile = true; p.notFile = true;
} }
@ -2033,14 +2095,6 @@ public class DefaultCodegen {
word = m.replaceAll(rep); word = m.replaceAll(rep);
} }
// Replace two underscores with $ to support inner classes.
p = Pattern.compile("(__)(.)");
m = p.matcher(word);
while (m.find()) {
word = m.replaceFirst("\\$" + m.group(2).toUpperCase());
m = p.matcher(word);
}
// Remove all underscores // Remove all underscores
p = Pattern.compile("(_)(.)"); p = Pattern.compile("(_)(.)");
m = p.matcher(word); m = p.matcher(word);
@ -2136,6 +2190,11 @@ public class DefaultCodegen {
return "ERROR_UNKNOWN"; return "ERROR_UNKNOWN";
} }
// if the name is just '$', map it to 'value' for the time being.
if ("$".equals(name)) {
return "value";
}
// input[] => input // input[] => input
name = name.replaceAll("\\[\\]", ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. name = name.replaceAll("\\[\\]", ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
@ -2160,4 +2219,28 @@ public class DefaultCodegen {
// $php_variable => php_variable // $php_variable => php_variable
return name.replaceAll("[^a-zA-Z0-9_]", ""); return name.replaceAll("[^a-zA-Z0-9_]", "");
} }
/**
* only write if the file doesn't exist
*
* @param outputFolder
* @param supportingFile
*/
public void writeOptional(String outputFolder, SupportingFile supportingFile) {
String folder = "";
if(outputFolder != null && !"".equals(outputFolder)) {
folder += outputFolder + File.separator;
}
folder += supportingFile.folder;
if(!"".equals(folder)) {
folder += File.separator + supportingFile.destinationFilename;
}
else {
folder = supportingFile.destinationFilename;
}
if(!new File(folder).exists()) {
supportingFiles.add(supportingFile);
}
}
} }

View File

@ -129,6 +129,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (info.getVersion() != null) { if (info.getVersion() != null) {
config.additionalProperties().put("version", info.getVersion()); config.additionalProperties().put("version", info.getVersion());
} }
if (info.getTermsOfService() != null) {
config.additionalProperties().put("termsOfService", info.getTermsOfService());
}
}
if(swagger.getVendorExtensions() != null) {
config.vendorExtensions().putAll(swagger.getVendorExtensions());
} }
StringBuilder hostBuilder = new StringBuilder(); StringBuilder hostBuilder = new StringBuilder();
@ -176,6 +183,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
sortedModelKeys = updatedKeys; sortedModelKeys = updatedKeys;
} }
// store all processed models
Map<String,Object> allProcessedModels = new HashMap<String, Object>();
// process models only
for (String name : sortedModelKeys) { for (String name : sortedModelKeys) {
try { try {
//don't generate models that have an import mapping //don't generate models that have an import mapping
@ -189,6 +200,26 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Map<String, Object> models = processModels(config, modelMap, definitions); Map<String, Object> models = processModels(config, modelMap, definitions);
models.putAll(config.additionalProperties()); models.putAll(config.additionalProperties());
allProcessedModels.put(name, models);
} catch (Exception e) {
throw new RuntimeException("Could not process model '" + name + "'", e);
}
}
// post process all processed models
allProcessedModels = config.postProcessAllModels(allProcessedModels);
// generate files based on processed models
for (String name: allProcessedModels.keySet()) {
Map<String, Object> models = (Map<String, Object>)allProcessedModels.get(name);
try {
//don't generate models that have an import mapping
if(config.importMapping().containsKey(name)) {
continue;
}
allModels.add(((List<Object>) models.get("models")).get(0)); allModels.add(((List<Object>) models.get("models")).get(0));
for (String templateName : config.modelTemplateFiles().keySet()) { for (String templateName : config.modelTemplateFiles().keySet()) {
@ -271,6 +302,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
operation.put("classVarName", config.toApiVarName(tag)); operation.put("classVarName", config.toApiVarName(tag));
operation.put("importPath", config.toApiImport(tag)); operation.put("importPath", config.toApiImport(tag));
if(!config.vendorExtensions().isEmpty()) {
operation.put("vendorExtensions", config.vendorExtensions());
}
// Pass sortParamsByRequiredFlag through to the Mustache template... // Pass sortParamsByRequiredFlag through to the Mustache template...
boolean sortParamsByRequiredFlag = true; boolean sortParamsByRequiredFlag = true;
if (this.config.additionalProperties().containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) { if (this.config.additionalProperties().containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
@ -602,35 +637,29 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
continue; continue;
} }
Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>(); Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>();
// NOTE: Use only the first security requirement for now. for (Map<String, List<String>> security: securities) {
// See the "security" field of "Swagger Object": for (String securityName : security.keySet()) {
// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#swagger-object SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
// "there is a logical OR between the security requirements" if (securityDefinition != null) {
if (securities.size() > 1) { if(securityDefinition instanceof OAuth2Definition) {
LOGGER.warn("More than 1 security requirements are found, using only the first one"); OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
} OAuth2Definition oauth2Operation = new OAuth2Definition();
Map<String, List<String>> security = securities.get(0); oauth2Operation.setType(oauth2Definition.getType());
for (String securityName : security.keySet()) { oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName); oauth2Operation.setFlow(oauth2Definition.getFlow());
if (securityDefinition != null) { oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
if(securityDefinition instanceof OAuth2Definition) { oauth2Operation.setScopes(new HashMap<String, String>());
OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition; for (String scope : security.get(securityName)) {
OAuth2Definition oauth2Operation = new OAuth2Definition(); if (oauth2Definition.getScopes().containsKey(scope)) {
oauth2Operation.setType(oauth2Definition.getType()); oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl()); }
oauth2Operation.setFlow(oauth2Definition.getFlow()); }
oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl()); authMethods.put(securityName, oauth2Operation);
oauth2Operation.setScopes(new HashMap<String, String>()); } else {
for (String scope : security.get(securityName)) { authMethods.put(securityName, securityDefinition);
if (oauth2Definition.getScopes().containsKey(scope)) { }
oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope)); }
} }
}
authMethods.put(securityName, oauth2Operation);
} else {
authMethods.put(securityName, securityDefinition);
}
}
} }
if (!authMethods.isEmpty()) { if (!authMethods.isEmpty()) {
co.authMethods = config.fromSecurity(authMethods); co.authMethods = config.fromSecurity(authMethods);

View File

@ -5,15 +5,14 @@ import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter; import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.*; import io.swagger.models.properties.*;
import io.swagger.util.Json; import io.swagger.util.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class InlineModelResolver { public class InlineModelResolver {
private Swagger swagger; private Swagger swagger;
private boolean skipMatches; private boolean skipMatches;
@ -219,7 +218,12 @@ public class InlineModelResolver {
Map<String, Model> modelsToAdd = new HashMap<String, Model>(); Map<String, Model> modelsToAdd = new HashMap<String, Model>();
for (String key : properties.keySet()) { for (String key : properties.keySet()) {
Property property = properties.get(key); Property property = properties.get(key);
if (property instanceof ObjectProperty && ((ObjectProperty)property).getProperties().size() > 0) { if(property instanceof ObjectProperty && ((ObjectProperty)property).getProperties() == null) {
MapProperty mp = new MapProperty();
mp.setAdditionalProperties(new StringProperty());
properties.put(key, mp);
}
else if (property instanceof ObjectProperty && ((ObjectProperty)property).getProperties().size() > 0) {
String modelName = uniqueName(path + "_" + key); String modelName = uniqueName(path + "_" + key);
ObjectProperty op = (ObjectProperty) property; ObjectProperty op = (ObjectProperty) property;
@ -277,7 +281,6 @@ public class InlineModelResolver {
swagger.addDefinition(modelName, innerModel); swagger.addDefinition(modelName, innerModel);
} }
} }
} else {
} }
} }
if (propsToUpdate.size() > 0) { if (propsToUpdate.size() > 0) {
@ -294,7 +297,12 @@ public class InlineModelResolver {
@SuppressWarnings("static-method") @SuppressWarnings("static-method")
public Model modelFromProperty(ArrayProperty object, @SuppressWarnings("unused") String path) { public Model modelFromProperty(ArrayProperty object, @SuppressWarnings("unused") String path) {
String description = object.getDescription(); String description = object.getDescription();
String example = object.getExample(); String example = null;
Object obj = object.getExample();
if(obj != null) {
example = obj.toString();
}
Property inner = object.getItems(); Property inner = object.getItems();
if (inner instanceof ObjectProperty) { if (inner instanceof ObjectProperty) {
ArrayModel model = new ArrayModel(); ArrayModel model = new ArrayModel();
@ -308,7 +316,12 @@ public class InlineModelResolver {
public Model modelFromProperty(ObjectProperty object, String path) { public Model modelFromProperty(ObjectProperty object, String path) {
String description = object.getDescription(); String description = object.getDescription();
String example = object.getExample(); String example = null;
Object obj = object.getExample();
if(obj != null) {
example = obj.toString();
}
String name = object.getName(); String name = object.getName();
Xml xml = object.getXml(); Xml xml = object.getXml();
Map<String, Property> properties = object.getProperties(); Map<String, Property> properties = object.getProperties();
@ -330,7 +343,12 @@ public class InlineModelResolver {
@SuppressWarnings("static-method") @SuppressWarnings("static-method")
public Model modelFromProperty(MapProperty object, @SuppressWarnings("unused") String path) { public Model modelFromProperty(MapProperty object, @SuppressWarnings("unused") String path) {
String description = object.getDescription(); String description = object.getDescription();
String example = object.getExample(); String example = null;
Object obj = object.getExample();
if(obj != null) {
example = obj.toString();
}
ArrayModel model = new ArrayModel(); ArrayModel model = new ArrayModel();
model.setDescription(description); model.setDescription(description);

View File

@ -170,37 +170,37 @@ public class XmlExampleGenerator {
protected String getExample(Property property) { protected String getExample(Property property) {
if (property instanceof DateTimeProperty) { if (property instanceof DateTimeProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample(); return property.getExample().toString();
} else { } else {
return dtFormat.format(new Date()); return dtFormat.format(new Date());
} }
} else if (property instanceof StringProperty) { } else if (property instanceof StringProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample(); return property.getExample().toString();
} else { } else {
return "string"; return "string";
} }
} else if (property instanceof DateProperty) { } else if (property instanceof DateProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample(); return property.getExample().toString();
} else { } else {
return dateFormat.format(new Date()); return dateFormat.format(new Date());
} }
} else if (property instanceof IntegerProperty) { } else if (property instanceof IntegerProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample(); return property.getExample().toString();
} else { } else {
return "0"; return "0";
} }
} else if (property instanceof BooleanProperty) { } else if (property instanceof BooleanProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample(); return property.getExample().toString();
} else { } else {
return "true"; return "true";
} }
} else if (property instanceof LongProperty) { } else if (property instanceof LongProperty) {
if (property.getExample() != null) { if (property.getExample() != null) {
return property.getExample(); return property.getExample().toString();
} else { } else {
return "123456"; return "123456";
} }

View File

@ -0,0 +1,514 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public abstract class AbstractCSharpCodegen extends DefaultCodegen implements CodegenConfig {
protected boolean optionalAssemblyInfoFlag = true;
protected boolean optionalProjectFileFlag = false;
protected boolean optionalMethodArgumentFlag = true;
protected boolean useDateTimeOffsetFlag = false;
protected boolean useCollection = false;
protected boolean returnICollection = false;
protected String packageVersion = "1.0.0";
protected String packageName = "IO.Swagger";
protected String sourceFolder = "src" + File.separator + packageName;
protected Set<String> collectionTypes;
protected Set<String> mapTypes;
protected Logger LOGGER = LoggerFactory.getLogger(AbstractCSharpCodegen.class);
public AbstractCSharpCodegen() {
super();
outputFolder = "generated-code" + File.separator + this.getName();
embeddedTemplateDir = templateDir = this.getName();
collectionTypes = new HashSet<String>(
Arrays.asList(
"IList", "List",
"ICollection", "Collection",
"IEnumerable")
);
mapTypes = new HashSet<String>(
Arrays.asList("IDictionary")
);
reservedWords = new HashSet<String>(
Arrays.asList(
// local variable names in API methods (endpoints)
"path_", "pathParams", "queryParams", "headerParams", "formParams", "fileParams",
"postBody", "http_header_accepts", "http_header_accept", "apiKeyValue", "response",
"statusCode",
// C# reserved words
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
"class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else",
"enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for",
"foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock",
"long", "namespace", "new", "null", "object", "operator", "out", "override", "params",
"private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed",
"short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw",
"true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using",
"virtual", "void", "volatile", "while")
);
// TODO: Either include fully qualified names here or handle in DefaultCodegen via lastIndexOf(".") search
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"string",
"bool?",
"double?",
"int?",
"long?",
"float?",
"byte[]",
"ICollection",
"Collection",
"List",
"Dictionary",
"DateTime?",
"DateTimeOffset?",
"String",
"Boolean",
"Double",
"Int32",
"Int64",
"Float",
"Guid",
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
instantiationTypes.put("list", "List");
instantiationTypes.put("map", "Dictionary");
// Nullable types here assume C# 2 support is not part of base
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
typeMapping.put("long", "long?");
typeMapping.put("double", "double?");
typeMapping.put("number", "double?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
typeMapping.put("uuid", "Guid");
}
public void setReturnICollection(boolean returnICollection) {
this.returnICollection = returnICollection;
}
public void setUseCollection(boolean useCollection) {
this.useCollection = useCollection;
if (useCollection) {
typeMapping.put("array", "Collection");
typeMapping.put("list", "Collection");
instantiationTypes.put("array", "Collection");
instantiationTypes.put("list", "Collection");
}
}
public void setOptionalMethodArgumentFlag(boolean flag) {
this.optionalMethodArgumentFlag = flag;
}
protected void addOption(String key, String description, String defaultValue) {
CliOption option = new CliOption(key, description);
if (defaultValue != null) option.defaultValue(defaultValue);
cliOptions.add(option);
}
protected void addSwitch(String key, String description, Boolean defaultValue) {
CliOption option = CliOption.newBoolean(key, description);
if (defaultValue != null) option.defaultValue(defaultValue.toString());
cliOptions.add(option);
}
public void useDateTimeOffset(boolean flag) {
this.useDateTimeOffsetFlag = flag;
if (flag) typeMapping.put("datetime", "DateTimeOffset?");
else typeMapping.put("datetime", "DateTime?");
}
@Override
public void processOpts() {
super.processOpts();
// {{packageVersion}}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
} else {
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
}
// {{sourceFolder}}
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
} else {
additionalProperties.put(CodegenConstants.SOURCE_FOLDER, this.sourceFolder);
}
// {{packageName}}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
// {{useDateTimeOffset}}
if (additionalProperties.containsKey(CodegenConstants.USE_DATETIME_OFFSET)) {
useDateTimeOffset(Boolean.valueOf(additionalProperties.get(CodegenConstants.USE_DATETIME_OFFSET).toString()));
}
additionalProperties.put(CodegenConstants.USE_DATETIME_OFFSET, useDateTimeOffsetFlag);
if (additionalProperties.containsKey(CodegenConstants.USE_COLLECTION)) {
setUseCollection(Boolean.valueOf(additionalProperties.get(CodegenConstants.USE_COLLECTION).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.RETURN_ICOLLECTION)) {
setReturnICollection(Boolean.valueOf(additionalProperties.get(CodegenConstants.RETURN_ICOLLECTION).toString()));
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
for (CodegenProperty var : cm.vars) {
// check to see if model name is same as the property name
// which will result in compilation error
// if found, prepend with _ to workaround the limitation
if (var.name.equals(cm.name)) {
var.name = "_" + var.name;
}
}
}
return objs;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
super.postProcessOperations(objs);
if (objs != null) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
// Check return types for collection
if (operation.returnType != null) {
String typeMapping;
int namespaceEnd = operation.returnType.lastIndexOf(".");
if (namespaceEnd > 0) {
typeMapping = operation.returnType.substring(namespaceEnd);
} else {
typeMapping = operation.returnType;
}
if (this.collectionTypes.contains(typeMapping)) {
operation.isListContainer = true;
operation.returnContainer = operation.returnType;
if (this.returnICollection && (
typeMapping.startsWith("List") ||
typeMapping.startsWith("Collection"))) {
// NOTE: ICollection works for both List<T> and Collection<T>
int genericStart = typeMapping.indexOf("<");
if (genericStart > 0) {
operation.returnType = "ICollection" + typeMapping.substring(genericStart);
}
}
} else {
operation.returnContainer = operation.returnType;
operation.isMapContainer = this.mapTypes.contains(typeMapping);
}
}
processOperation(operation);
}
}
}
return objs;
}
protected void processOperation(CodegenOperation operation) {
// default noop
}
@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);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return camelize(sanitizeName(operationId));
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name);
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
// camelize the variable name
// pet_id => PetId
name = camelize(name);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toParamName(String name) {
// sanitize name
name = sanitizeName(name);
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
// camelize(lower) the variable name
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
/**
* Return the example value of the property
*
* @param p Swagger property object
* @return string presentation of the example value of the property
*/
@Override
public String toExampleValue(Property p) {
if (p instanceof StringProperty) {
StringProperty dp = (StringProperty) p;
if (dp.getExample() != null) {
return "\"" + dp.getExample().toString() + "\"";
}
} else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
} else if (p instanceof DateProperty) {
// TODO
} else if (p instanceof DateTimeProperty) {
// TODO
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getExample() != null) {
return dp.getExample().toString();
}
}
return null;
}
/**
* Return the default value of the property
*
* @param p Swagger property object
* @return string presentation of the default value of the property
*/
@Override
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
StringProperty dp = (StringProperty) p;
if (dp.getDefault() != null) {
return "\"" + dp.getDefault().toString() + "\"";
}
} else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof DateProperty) {
// TODO
} else if (p instanceof DateTimeProperty) {
// TODO
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
}
return null;
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type;
if (typeMapping.containsKey(swaggerType.toLowerCase())) {
type = typeMapping.get(swaggerType.toLowerCase());
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = swaggerType;
}
return toModelName(type);
}
@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 toModelName(String name) {
name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String apiTestFileFolder() {
return outputFolder + ".Test";
}
@Override
public String modelTestFileFolder() {
return outputFolder + ".Test";
}
@Override
public String toApiTestFilename(String name) {
return toApiName(name) + "Tests";
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Tests";
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
}

View File

@ -1,11 +1,5 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenResponse; import io.swagger.codegen.CodegenResponse;
import io.swagger.codegen.CodegenType; import io.swagger.codegen.CodegenType;
@ -13,6 +7,8 @@ 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;
import java.util.*;
public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
{ {
/** /**
@ -49,8 +45,7 @@ public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
} }
@Override @Override
public void preprocessSwagger(Swagger swagger) public void preprocessSwagger(Swagger swagger) {
{
if ( "/".equals(swagger.getBasePath()) ) { if ( "/".equals(swagger.getBasePath()) ) {
swagger.setBasePath(""); swagger.setBasePath("");
} }
@ -93,8 +88,7 @@ public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
} }
@Override @Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
{
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if ( operations != null ) { if ( operations != null ) {
@ -139,8 +133,7 @@ public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
} }
@Override @Override
public String toApiName(final String name) public String toApiName(final String name) {
{
String computed = name; String computed = name;
if ( computed.length() == 0 ) { if ( computed.length() == 0 ) {
return "DefaultApi"; return "DefaultApi";
@ -150,8 +143,7 @@ public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
} }
@Override @Override
public String apiFilename(String templateName, String tag) public String apiFilename(String templateName, String tag) {
{
String result = super.apiFilename(templateName, tag); String result = super.apiFilename(templateName, tag);
if ( templateName.endsWith("Impl.mustache") ) { if ( templateName.endsWith("Impl.mustache") ) {
@ -169,15 +161,12 @@ public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
return result; return result;
} }
private String implFileFolder(String output) private String implFileFolder(String output) {
{
return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/'); return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
} }
@Override @Override
public boolean shouldOverwrite(String filename) public boolean shouldOverwrite(String filename) {
{
return super.shouldOverwrite(filename) && !filename.endsWith("ServiceImpl.java") && !filename.endsWith("ServiceFactory.java"); return super.shouldOverwrite(filename) && !filename.endsWith("ServiceImpl.java") && !filename.endsWith("ServiceFactory.java");
} }
} }

View File

@ -0,0 +1,129 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public class AspNet5ServerCodegen extends AbstractCSharpCodegen {
@SuppressWarnings("hiding")
protected Logger LOGGER = LoggerFactory.getLogger(AspNet5ServerCodegen.class);
public AspNet5ServerCodegen() {
super();
outputFolder = "generated-code" + File.separator + this.getName();
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("controller.mustache", ".cs");
// contextually reserved words
reservedWords.add("var");
reservedWords.add("async");
reservedWords.add("await");
reservedWords.add("dynamic");
reservedWords.add("yield");
cliOptions.clear();
// CLI options
addOption(CodegenConstants.PACKAGE_NAME,
"C# package name (convention: Title.Case).",
this.packageName);
addOption(CodegenConstants.PACKAGE_VERSION,
"C# package version.",
this.packageVersion);
addOption(CodegenConstants.SOURCE_FOLDER,
CodegenConstants.SOURCE_FOLDER_DESC,
sourceFolder);
// CLI Switches
addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC,
this.sortParamsByRequiredFlag);
addSwitch(CodegenConstants.USE_DATETIME_OFFSET,
CodegenConstants.USE_DATETIME_OFFSET_DESC,
this.useDateTimeOffsetFlag);
addSwitch(CodegenConstants.USE_COLLECTION,
CodegenConstants.USE_COLLECTION_DESC,
this.useCollection);
addSwitch(CodegenConstants.RETURN_ICOLLECTION,
CodegenConstants.RETURN_ICOLLECTION_DESC,
this.returnICollection);
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "aspnet5";
}
@Override
public String getHelp() {
return "Generates an ASP.NET 5 Web API server.";
}
@Override
public void processOpts() {
super.processOpts();
apiPackage = packageName + ".Controllers";
modelPackage = packageName + ".Models";
supportingFiles.add(new SupportingFile("global.json", "", "global.json"));
supportingFiles.add(new SupportingFile("build.mustache", "", "build.sh"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", this.sourceFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("gitignore", this.sourceFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("appsettings.json", this.sourceFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("project.mustache", this.sourceFolder, "project.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", this.sourceFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", this.sourceFolder + 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 + "index.html", this.sourceFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", this.sourceFolder + File.separator + "wwwroot", "web.config"));
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + "Controllers";
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + "Models";
}
@Override
protected void processOperation(CodegenOperation operation) {
super.processOperation(operation);
// HACK: Unlikely in the wild, but we need to clean operation paths for MVC Routing
if (operation.path != null) {
String original = operation.path;
operation.path = operation.path.replace("?", "/");
if (!original.equals(operation.path)) {
LOGGER.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source.");
}
}
// Converts, for example, PUT to HttpPut for controller attributes
operation.httpMethod = "Http" + operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase();
}
}

View File

@ -1,5 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType; import io.swagger.codegen.CodegenType;
@ -22,156 +24,106 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig { public class CSharpClientCodegen extends AbstractCSharpCodegen {
@SuppressWarnings({ "unused", "hiding" }) @SuppressWarnings({"unused", "hiding"})
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class); private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
protected boolean optionalAssemblyInfoFlag = true; private static final String NET45 = "v4.5";
protected boolean optionalProjectFileFlag = false; private static final String NET35 = "v3.5";
protected boolean optionalMethodArgumentFlag = true;
protected boolean useDateTimeOffsetFlag = false;
protected boolean useCollection = false;
protected boolean returnICollection = false;
protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}"; protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}";
protected String packageTitle = "Swagger Library"; protected String packageTitle = "Swagger Library";
protected String packageProductName = "SwaggerLibrary"; protected String packageProductName = "SwaggerLibrary";
protected String packageDescription = "A library generated from a Swagger doc"; protected String packageDescription = "A library generated from a Swagger doc";
protected String packageCompany = "Swagger"; protected String packageCompany = "Swagger";
protected String packageCopyright = "No Copyright"; protected String packageCopyright = "No Copyright";
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client"; protected String clientPackage = "IO.Swagger.Client";
protected String sourceFolder = "src" + File.separator + "main" + File.separator + "csharp";
protected String targetFramework = NET45;
protected String targetFrameworkNuget = "net45";
protected boolean supportsAsync = Boolean.TRUE;
protected final Map<String, String> frameworks;
public CSharpClientCodegen() { public CSharpClientCodegen() {
super(); super();
outputFolder = "generated-code" + File.separator + "csharp";
modelTemplateFiles.put("model.mustache", ".cs"); modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs"); apiTemplateFiles.put("api.mustache", ".cs");
embeddedTemplateDir = templateDir = "csharp";
apiPackage = "IO.Swagger.Api";
modelPackage = "IO.Swagger.Model";
reservedWords = new HashSet<String>( modelTestTemplateFiles.put("model_test.mustache", ".cs");
Arrays.asList( apiTestTemplateFiles.put("api_test.mustache", ".cs");
// local variable names in API methods (endpoints)
"path_", "pathParams", "queryParams", "headerParams", "formParams", "fileParams",
"postBody", "http_header_accepts", "http_header_accept", "apiKeyValue", "response",
"statusCode",
// C# reserved words
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
"class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else",
"enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for",
"foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock",
"long", "namespace", "new", "null", "object", "operator", "out", "override", "params",
"private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed",
"short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw",
"true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using",
"virtual", "void", "volatile", "while")
);
// C# client default
languageSpecificPrimitives = new HashSet<String>( setSourceFolder("src" + File.separator + "main" + File.separator + "csharp");
Arrays.asList(
"String",
"string",
"bool?",
"double?",
"int?",
"long?",
"float?",
"byte[]",
"ICollection",
"Collection",
"List",
"Dictionary",
"DateTime?",
"DateTimeOffset?",
"String",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
instantiationTypes.put("list", "List");
instantiationTypes.put("map", "Dictionary");
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
typeMapping.put("long", "long?");
typeMapping.put("double", "double?");
typeMapping.put("number", "double?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
cliOptions.clear(); cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "C# package name (convention: Camel.Case).")
.defaultValue("IO.Swagger"));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "C# package version.").defaultValue("1.0.0"));
cliOptions.add(CliOption.newBoolean(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(CodegenConstants.OPTIONAL_METHOD_ARGUMENT, "C# Optional method argument, " +
"e.g. void square(int x=10) (.net 4.0+ only)."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.OPTIONAL_ASSEMBLY_INFO,
CodegenConstants.OPTIONAL_ASSEMBLY_INFO_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC).defaultValue(sourceFolder));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_DATETIME_OFFSET, CodegenConstants.USE_DATETIME_OFFSET_DESC));
cliOptions.add( CliOption.newBoolean(CodegenConstants.USE_COLLECTION, CodegenConstants.USE_COLLECTION_DESC) // CLI options
.defaultValue(Boolean.FALSE.toString()) ); addOption(CodegenConstants.PACKAGE_NAME,
cliOptions.add( CliOption.newBoolean(CodegenConstants.RETURN_ICOLLECTION, CodegenConstants.RETURN_ICOLLECTION_DESC) "C# package name (convention: Title.Case).",
.defaultValue(Boolean.FALSE.toString()) ); this.packageName);
cliOptions.add(CliOption.newBoolean(CodegenConstants.OPTIONAL_PROJECT_FILE,
CodegenConstants.OPTIONAL_PROJECT_FILE_DESC).defaultValue(Boolean.FALSE.toString())); addOption(CodegenConstants.PACKAGE_VERSION,
cliOptions.add(new CliOption(CodegenConstants.OPTIONAL_PROJECT_GUID, CodegenConstants.OPTIONAL_PROJECT_GUID_DESC)); "C# package version.",
this.packageVersion);
addOption(CodegenConstants.SOURCE_FOLDER,
CodegenConstants.SOURCE_FOLDER_DESC,
sourceFolder);
addOption(CodegenConstants.OPTIONAL_PROJECT_GUID,
CodegenConstants.OPTIONAL_PROJECT_GUID_DESC,
null);
CliOption framework = new CliOption(
CodegenConstants.DOTNET_FRAMEWORK,
CodegenConstants.DOTNET_FRAMEWORK_DESC
);
frameworks = new ImmutableMap.Builder<String, String>()
.put(NET35, ".NET Framework 3.5 compatible")
.put(NET45, ".NET Framework 4.5+ compatible")
.build();
framework.defaultValue(this.targetFramework);
framework.setEnum(frameworks);
cliOptions.add(framework);
// CLI Switches
addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC,
this.sortParamsByRequiredFlag);
addSwitch(CodegenConstants.USE_DATETIME_OFFSET,
CodegenConstants.USE_DATETIME_OFFSET_DESC,
this.useDateTimeOffsetFlag);
addSwitch(CodegenConstants.USE_COLLECTION,
CodegenConstants.USE_COLLECTION_DESC,
this.useCollection);
addSwitch(CodegenConstants.RETURN_ICOLLECTION,
CodegenConstants.RETURN_ICOLLECTION_DESC,
this.returnICollection);
addSwitch(CodegenConstants.OPTIONAL_METHOD_ARGUMENT,
"C# Optional method argument, e.g. void square(int x=10) (.net 4.0+ only).",
this.optionalMethodArgumentFlag);
addSwitch(CodegenConstants.OPTIONAL_ASSEMBLY_INFO,
CodegenConstants.OPTIONAL_ASSEMBLY_INFO_DESC,
this.optionalAssemblyInfoFlag);
addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE,
CodegenConstants.OPTIONAL_PROJECT_FILE_DESC,
this.optionalProjectFileFlag);
} }
@Override @Override
public void processOpts() { public void processOpts() {
super.processOpts(); super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { apiPackage = packageName + ".Api";
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); modelPackage = packageName + ".Model";
} else { clientPackage = packageName + ".Client";
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
}
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)){
setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
}
else
{
additionalProperties.put(CodegenConstants.SOURCE_FOLDER, this.sourceFolder);
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
apiPackage = packageName + ".Api";
modelPackage = packageName + ".Model";
clientPackage = packageName + ".Client";
} else {
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
// Use DateTimeOffset
if (additionalProperties.containsKey(CodegenConstants.USE_DATETIME_OFFSET))
{
useDateTimeOffset(Boolean.valueOf(additionalProperties.get(CodegenConstants.USE_DATETIME_OFFSET).toString()));
}
additionalProperties.put(CodegenConstants.USE_DATETIME_OFFSET, useDateTimeOffsetFlag);
additionalProperties.put("clientPackage", clientPackage); additionalProperties.put("clientPackage", clientPackage);
@ -182,17 +134,33 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
additionalProperties.put("packageCompany", packageCompany); additionalProperties.put("packageCompany", packageCompany);
additionalProperties.put("packageCopyright", packageCopyright); additionalProperties.put("packageCopyright", packageCopyright);
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_FILE)) if (additionalProperties.containsKey(CodegenConstants.DOTNET_FRAMEWORK)) {
{ setTargetFramework((String) additionalProperties.get(CodegenConstants.DOTNET_FRAMEWORK));
setOptionalProjectFileFlag(Boolean.valueOf(
additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_FILE).toString()));
} }
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) if (NET35.equals(this.targetFramework)) {
{ setTargetFrameworkNuget("net35");
setSupportsAsync(Boolean.FALSE);
if(additionalProperties.containsKey("supportsAsync")){
additionalProperties.remove("supportsAsync");
}
} else {
setTargetFrameworkNuget("net45");
setSupportsAsync(Boolean.TRUE);
additionalProperties.put("supportsAsync", this.supportsAsync);
}
additionalProperties.put("targetFrameworkNuget", this.targetFrameworkNuget);
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_FILE)) {
setOptionalProjectFileFlag(Boolean.valueOf(
additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_FILE).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) {
setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID)); setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID));
} }
additionalProperties.put("packageGuid", packageGuid); additionalProperties.put("packageGuid", packageGuid);
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_METHOD_ARGUMENT)) { if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_METHOD_ARGUMENT)) {
setOptionalMethodArgumentFlag(Boolean.valueOf(additionalProperties setOptionalMethodArgumentFlag(Boolean.valueOf(additionalProperties
@ -205,15 +173,6 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
.get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString())); .get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString()));
} }
if (additionalProperties.containsKey(CodegenConstants.USE_COLLECTION)){
setUseCollection(Boolean.valueOf(additionalProperties.get(CodegenConstants.USE_COLLECTION).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.RETURN_ICOLLECTION)){
setReturnICollection(Boolean.valueOf(additionalProperties.get(CodegenConstants.RETURN_ICOLLECTION).toString()));
}
String packageFolder = sourceFolder + File.separator + packageName.replace(".", java.io.File.separator); String packageFolder = sourceFolder + File.separator + packageName.replace(".", java.io.File.separator);
String clientPackageDir = sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator); String clientPackageDir = sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator);
@ -221,9 +180,9 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
//This is necessary to properly generate the project file //This is necessary to properly generate the project file
int packageDepth = packageFolder.length() - packageFolder.replace(java.io.File.separator, "").length(); int packageDepth = packageFolder.length() - packageFolder.replace(java.io.File.separator, "").length();
String binRelativePath = "..\\"; String binRelativePath = "..\\";
for (int i=0; i < packageDepth; i = i+1) for (int i = 0; i < packageDepth; i = i + 1)
binRelativePath += "..\\"; binRelativePath += "..\\";
binRelativePath += "bin\\"; binRelativePath += "vendor\\";
additionalProperties.put("binRelativePath", binRelativePath); additionalProperties.put("binRelativePath", binRelativePath);
supportingFiles.add(new SupportingFile("Configuration.mustache", supportingFiles.add(new SupportingFile("Configuration.mustache",
@ -235,8 +194,6 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("ApiResponse.mustache", supportingFiles.add(new SupportingFile("ApiResponse.mustache",
clientPackageDir, "ApiResponse.cs")); clientPackageDir, "ApiResponse.cs"));
supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll"));
supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll"));
supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat")); supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat"));
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "compile-mono.sh")); supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "compile-mono.sh"));
supportingFiles.add(new SupportingFile("packages.config.mustache", "vendor" + java.io.File.separator, "packages.config")); supportingFiles.add(new SupportingFile("packages.config.mustache", "vendor" + java.io.File.separator, "packages.config"));
@ -250,6 +207,33 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
} }
} }
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
super.postProcessOperations(objs);
if (objs != null) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.returnType != null) {
operation.returnContainer = operation.returnType;
if (this.returnICollection && (
operation.returnType.startsWith("List") ||
operation.returnType.startsWith("Collection"))) {
// NOTE: ICollection works for both List<T> and Collection<T>
int genericStart = operation.returnType.indexOf("<");
if (genericStart > 0) {
operation.returnType = "ICollection" + operation.returnType.substring(genericStart);
}
}
}
}
}
}
return objs;
}
@Override @Override
public CodegenType getTag() { public CodegenType getTag() {
return CodegenType.CLIENT; return CodegenType.CLIENT;
@ -265,155 +249,6 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
return "Generates a CSharp client library."; return "Generates a CSharp client library.";
} }
@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);
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
// camelize the variable name
// pet_id => PetId
name = camelize(name);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toParamName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
// camelize(lower) the variable name
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
super.postProcessOperations(objs);
if(objs != null) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.returnType != null) {
operation.returnContainer = operation.returnType;
if( this.returnICollection && (
operation.returnType.startsWith("List")||
operation.returnType.startsWith("Collection")) ) {
// NOTE: ICollection works for both List<T> and Collection<T>
int genericStart = operation.returnType.indexOf("<");
if(genericStart > 0) {
operation.returnType = "ICollection" + operation.returnType.substring(genericStart);
}
}
}
}
}
}
return objs;
}
@Override
public 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.toLowerCase())) {
type = typeMapping.get(swaggerType.toLowerCase());
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = swaggerType;
}
return toModelName(type);
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return camelize(sanitizeName(operationId));
}
public void setOptionalAssemblyInfoFlag(boolean flag) { public void setOptionalAssemblyInfoFlag(boolean flag) {
this.optionalAssemblyInfoFlag = flag; this.optionalAssemblyInfoFlag = flag;
} }
@ -422,111 +257,24 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
this.optionalProjectFileFlag = flag; this.optionalProjectFileFlag = flag;
} }
public void setOptionalMethodArgumentFlag(boolean flag) {
this.optionalMethodArgumentFlag = flag;
}
public void setReturnICollection(boolean returnICollection) {
this.returnICollection = returnICollection;
}
public void setUseCollection(boolean useCollection) {
this.useCollection = useCollection;
if(useCollection){
typeMapping.put("array", "Collection");
typeMapping.put("list", "Collection");
instantiationTypes.put("array", "Collection");
instantiationTypes.put("list", "Collection");
}
}
public void useDateTimeOffset(boolean flag) {
this.useDateTimeOffsetFlag = flag;
if (flag)
typeMapping.put("datetime", "DateTimeOffset?");
else
typeMapping.put("datetime", "DateTime?");
}
public void setPackageGuid(String packageGuid) { public void setPackageGuid(String packageGuid) {
this.packageGuid = packageGuid; this.packageGuid = packageGuid;
} }
public void setPackageName(String packageName) { public void setTargetFramework(String dotnetFramework) {
this.packageName = packageName; if(!frameworks.containsKey(dotnetFramework)){
} LOGGER.warn("Invalid .NET framework version, defaulting to " + this.targetFramework);
} else {
public void setPackageVersion(String packageVersion) { this.targetFramework = dotnetFramework;
this.packageVersion = packageVersion;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
for (CodegenProperty var : cm.vars) {
// check to see if model name is same as the property name
// which will result in compilation error
// if found, prepend with _ to workaround the limitation
if (var.name.equals(cm.name)) {
var.name = "_" + var.name;
}
}
} }
return objs; LOGGER.info("Generating code for .NET Framework " + this.targetFramework);
} }
/** public void setTargetFrameworkNuget(String targetFrameworkNuget) {
* Return the default value of the property this.targetFrameworkNuget = targetFrameworkNuget;
* }
* @param p Swagger property object
* @return string presentation of the default value of the property
*/
@Override
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
StringProperty dp = (StringProperty) p;
if (dp.getDefault() != null) {
return "\"" + dp.getDefault().toString() + "\"";
}
} else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof DateProperty) {
// TODO
} else if (p instanceof DateTimeProperty) {
// TODO
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
}
return null; public void setSupportsAsync(Boolean supportsAsync){
this.supportsAsync = supportsAsync;
} }
} }

View File

@ -215,6 +215,8 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
@Override @Override
public String toModelName(String name) { public String toModelName(String name) {
name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return // model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) { if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name"); throw new RuntimeException(name + " (reserved word) cannot be used as a model name");

View File

@ -29,7 +29,7 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
protected String packageVersion; protected String packageVersion;
protected String invokerPackage = "io.swagger"; protected String invokerPackage = "io.swagger";
protected String sourceFolder = "src/main/flex"; protected String sourceFolder = "flash";
public FlashClientCodegen() { public FlashClientCodegen() {
super(); super();
@ -83,7 +83,7 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
.defaultValue("1.0.0")); .defaultValue("1.0.0"));
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.SOURCE_FOLDER, "source folder for generated " + cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated " +
"code. e.g. src/main/flex")); "code. e.g. flash"));
} }
@ -124,8 +124,7 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
//modelPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "model"; //modelPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "model";
//apiPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "api"; //apiPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "api";
final String invokerFolder = (sourceFolder + File.separator + invokerPackage + File.separator final String invokerFolder = (sourceFolder + File.separator + "src/" + invokerPackage + File.separator).replace(".", File.separator).replace('.', File.separatorChar);
+ "swagger" + File.separator).replace(".", File.separator).replace('.', File.separatorChar);
supportingFiles.add(new SupportingFile("ApiInvoker.as", invokerFolder + "common", "ApiInvoker.as")); supportingFiles.add(new SupportingFile("ApiInvoker.as", invokerFolder + "common", "ApiInvoker.as"));
supportingFiles.add(new SupportingFile("ApiUrlHelper.as", invokerFolder + "common", "ApiUrlHelper.as")); supportingFiles.add(new SupportingFile("ApiUrlHelper.as", invokerFolder + "common", "ApiUrlHelper.as"));
@ -133,14 +132,15 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("ListWrapper.as", invokerFolder + "common", "ListWrapper.as")); supportingFiles.add(new SupportingFile("ListWrapper.as", invokerFolder + "common", "ListWrapper.as"));
supportingFiles.add(new SupportingFile("SwaggerApi.as", invokerFolder + "common", "SwaggerApi.as")); supportingFiles.add(new SupportingFile("SwaggerApi.as", invokerFolder + "common", "SwaggerApi.as"));
supportingFiles.add(new SupportingFile("XMLWriter.as", invokerFolder + "common", "XMLWriter.as")); supportingFiles.add(new SupportingFile("XMLWriter.as", invokerFolder + "common", "XMLWriter.as"));
supportingFiles.add(new SupportingFile("ApiError.as", invokerFolder + "exception", "ApiErrors.as")); supportingFiles.add(new SupportingFile("ApiError.as", invokerFolder + "exception", "ApiError.as"));
supportingFiles.add(new SupportingFile("ApiErrorCodes.as", invokerFolder + "exception", "ApiErrorCodes.as")); supportingFiles.add(new SupportingFile("ApiErrorCodes.as", invokerFolder + "exception", "ApiErrorCodes.as"));
supportingFiles.add(new SupportingFile("ApiClientEvent.as", invokerFolder + "event", "ApiClientEvent.as")); supportingFiles.add(new SupportingFile("ApiClientEvent.as", invokerFolder + "event", "ApiClientEvent.as"));
supportingFiles.add(new SupportingFile("Response.as", invokerFolder + "event", "Response.as")); supportingFiles.add(new SupportingFile("Response.as", invokerFolder + "event", "Response.as"));
supportingFiles.add(new SupportingFile("build.properties", sourceFolder, "build.properties")); supportingFiles.add(new SupportingFile("build.properties", sourceFolder, "build.properties"));
supportingFiles.add(new SupportingFile("build.xml", sourceFolder, "build.xml")); supportingFiles.add(new SupportingFile("build.xml", sourceFolder, "build.xml"));
supportingFiles.add(new SupportingFile("AirExecutorApp-app.xml", sourceFolder + File.separatorChar supportingFiles.add(new SupportingFile("README.txt", sourceFolder, "README.txt"));
+ "bin", "AirExecutorApp-app.xml")); //supportingFiles.add(new SupportingFile("AirExecutorApp-app.xml", sourceFolder + File.separatorChar
// + "bin", "AirExecutorApp-app.xml"));
supportingFiles.add(new SupportingFile("ASAXB-0.1.1.swc", sourceFolder + File.separatorChar supportingFiles.add(new SupportingFile("ASAXB-0.1.1.swc", sourceFolder + File.separatorChar
+ "lib", "ASAXB-0.1.1.swc")); + "lib", "ASAXB-0.1.1.swc"));
supportingFiles.add(new SupportingFile("as3corelib.swc", sourceFolder + File.separatorChar supportingFiles.add(new SupportingFile("as3corelib.swc", sourceFolder + File.separatorChar
@ -181,13 +181,13 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String apiFileFolder() { public String apiFileFolder() {
return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + "src/"
+ apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar); + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
} }
@Override @Override
public String modelFileFolder() { public String modelFileFolder() {
return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + "src/"
+ modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar); + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
} }
@ -253,7 +253,7 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
} else if (p instanceof ArrayProperty) { } else if (p instanceof ArrayProperty) {
return "new Array()"; return "new Array()";
} else { } else {
return "null"; return "NaN";
} }
} }

View File

@ -0,0 +1,345 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import java.util.*;
import java.io.File;
public class HaskellServantCodegen extends DefaultCodegen implements CodegenConfig {
// source folder where to write the files
protected String sourceFolder = "src";
protected String apiVersion = "0.0.1";
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.swagger.codegen.CodegenType
*/
public CodegenType getTag() {
return CodegenType.SERVER;
}
/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -l flag.
*
* @return the friendly name for the generator
*/
public String getName() {
return "haskell-servant";
}
/**
* 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 HaskellServantCodegen library.";
}
public HaskellServantCodegen() {
super();
// set the output folder here
outputFolder = "generated-code/HaskellServantCodegen";
/**
* 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
".hs"); // 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
".hs"); // 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.
*/
embeddedTemplateDir = templateDir = "haskell-servant";
/**
* Api Package. Optional, if needed, this can be used in templates
*/
apiPackage = "Api";
/**
* Model Package. Optional, if needed, this can be used in templates
*/
modelPackage = "Model";
/**
* Reserved words. Override this with reserved words specific to your language
*/
// from https://wiki.haskell.org/Keywords
reservedWords = new HashSet<String>(
Arrays.asList(
"as", "case", "of",
"class", "data", // "data family", "data instance",
"default", "deriving", // "deriving instance",
"do",
"forall", "foreign", "hiding",
"id",
"if", "then", "else",
"import", "infix", "infixl", "infixr",
"instance", "let", "in",
"mdo", "module", "newtype",
"proc", "qualified", "rec",
"type", // "type family", "type instance",
"where"
)
);
/**
* 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.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("stack.mustache", "", "stack.yaml"));
supportingFiles.add(new SupportingFile("haskell-servant-codegen.mustache", "", "haskell-servant-codegen.cabal"));
supportingFiles.add(new SupportingFile("Setup.mustache", "", "Setup.hs"));
supportingFiles.add(new SupportingFile("LICENSE", "", "LICENSE"));
supportingFiles.add(new SupportingFile("Apis.mustache", "lib", "Apis.hs"));
supportingFiles.add(new SupportingFile("Utils.mustache", "lib", "Utils.hs"));
supportingFiles.add(new SupportingFile("Client.mustache", "client", "Main.hs"));
supportingFiles.add(new SupportingFile("Server.mustache", "server", "Main.hs"));
/**
* Language Specific Primitives. These types will not trigger imports by
* the client generator
*/
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"Bool",
"String",
"Int",
"Integer",
"Float",
"Char",
"Double",
"List",
"FilePath"
)
);
typeMapping.clear();
// typeMapping.put("enum", "NSString");
typeMapping.put("array", "List");
typeMapping.put("set", "Set");
typeMapping.put("boolean", "Bool");
typeMapping.put("string", "String");
typeMapping.put("int", "Int");
typeMapping.put("long", "Integer");
typeMapping.put("float", "Float");
// typeMapping.put("byte", "Byte");
typeMapping.put("short", "Int");
typeMapping.put("char", "Char");
typeMapping.put("double", "Double");
typeMapping.put("DateTime", "Integer");
// typeMapping.put("object", "Map");
typeMapping.put("file", "FilePath");
importMapping.clear();
importMapping.put("Map", "qualified Data.Map as Map");
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
/**
* 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 + "_";
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
*/
public String modelFileFolder() {
return outputFolder + File.separatorChar + "lib" + File.separatorChar + modelPackage().replace('.', File.separatorChar);
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated
*/
@Override
public String apiFileFolder() {
return outputFolder + File.separatorChar + "lib" + File.separatorChar + apiPackage().replace('.', File.separatorChar);
}
/**
* 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 "[" + getTypeDeclaration(inner) + "]";
}
else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return "Map.Map 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);
}
private String capturePath(String path, List<CodegenParameter> pathParams) {
for (CodegenParameter p : pathParams) {
String pName = "{"+p.baseName+"}";
if (path.indexOf(pName) >= 0) {
path = path.replace(pName, "Capture " + "\""+p.baseName+"\" " + p.dataType);
}
}
return path;
}
private String queryPath(String path, List<CodegenParameter> queryParams) {
for (CodegenParameter p : queryParams) {
path += " :> QueryParam \"" + p.baseName + "\" " + p.dataType;
}
return path;
}
private String bodyPath(String path, List<CodegenParameter> bodyParams) {
for (CodegenParameter p : bodyParams) {
path += " :> ReqBody '[JSON] " + p.dataType;
}
return path;
}
private String formPath(String path, List<CodegenParameter> formParams) {
String names = "Form";
for (CodegenParameter p : formParams) {
if(p.dataType.equals("FilePath")){
// file data processing
}
names += p.baseName;
}
if(formParams.size() > 0){
path += " :> ReqBody '[FormUrlEncoded] " + names;
}
return path;
}
private String headerPath(String path, List<CodegenParameter> headerParams) {
for (CodegenParameter p : headerParams) {
path += " :> Header \"" + p.baseName + "\" " + p.dataType;
}
return path;
}
private String filterReturnType(String rt) {
if (rt == null || rt.equals("null")) {
return "()";
} else if (rt.indexOf(" ") >= 0) {
return "(" + rt + ")";
}
return rt;
}
private String addReturnPath(String path, String httpMethod, String returnType) {
return path + " :> " + upperCaseFirst(httpMethod) + " '[JSON] " + filterReturnType(returnType);
}
private String joinStrings(String sep, List<String> ss) {
StringBuilder sb = new StringBuilder();
for (String s : ss) {
if (sb.length() > 0) {
sb.append(sep);
}
sb.append(s);
}
return sb.toString();
}
private String replacePathSplitter(String path) {
String[] ps = path.replaceFirst("/", "").split("/", 0);
List<String> rs = new ArrayList<String>();
for (String p : ps) {
if (p.indexOf("{") < 0) {
rs.add("\"" + p + "\"");
} else {
rs.add(p);
}
}
return joinStrings(" :> ", rs);
}
private String upperCaseFirst(String str) {
char[] array = str.toLowerCase().toCharArray();
array[0] = Character.toUpperCase(array[0]);
return new String(array);
}
private String parseScheme(String basePath) {
return "Http";
}
@Override
public CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger){
CodegenOperation op = super.fromOperation(resourcePath, httpMethod, operation, definitions, swagger);
String path = op.path;
op.nickname = addReturnPath(headerPath(formPath(bodyPath(queryPath(capturePath(replacePathSplitter(path), op.pathParams), op.queryParams), op.bodyParams), op.formParams), op.headerParams), op.httpMethod, op.returnType);
return op;
}
}

View File

@ -38,6 +38,7 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
} }
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"));
} }
@Override @Override

View File

@ -1,46 +1,22 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import io.swagger.codegen.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenParameter;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Model; import io.swagger.models.Model;
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;
import io.swagger.models.parameters.FormParameter; import io.swagger.models.parameters.FormParameter;
import io.swagger.models.parameters.Parameter; import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.*;
import io.swagger.models.properties.BooleanProperty; import org.apache.commons.lang.BooleanUtils;
import io.swagger.models.properties.DoubleProperty; import org.apache.commons.lang.StringUtils;
import io.swagger.models.properties.FloatProperty; import org.slf4j.Logger;
import io.swagger.models.properties.IntegerProperty; import org.slf4j.LoggerFactory;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.MapProperty; import java.io.File;
import io.swagger.models.properties.Property; import java.util.*;
import io.swagger.models.properties.StringProperty; import java.util.regex.Pattern;
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
@ -261,13 +237,13 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
importMapping.put("StringUtil", invokerPackage + ".StringUtil"); importMapping.put("StringUtil", invokerPackage + ".StringUtil");
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/"); final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle")); writeOptional(outputFolder, new SupportingFile("build.gradle.mustache", "", "build.gradle"));
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); writeOptional(outputFolder, new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
supportingFiles.add(new SupportingFile("gradle.properties.mustache", "", "gradle.properties")); writeOptional(outputFolder, new SupportingFile("gradle.properties.mustache", "", "gradle.properties"));
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml")); writeOptional(outputFolder, new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java")); writeOptional(outputFolder, new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java")); supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/"); final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
@ -565,7 +541,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
model.imports.add("HashMap"); model.imports.add("HashMap");
} }
if(model.isEnum == null || model.isEnum) { if(!BooleanUtils.toBoolean(model.isEnum)) {
// needed by all pojos, but not enums // needed by all pojos, but not enums
model.imports.add("ApiModelProperty"); model.imports.add("ApiModelProperty");
model.imports.add("ApiModel"); model.imports.add("ApiModel");
@ -576,7 +552,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
if(StringUtils.isEmpty(lib) || "feign".equals(lib) || "jersey2".equals(lib)) { if(StringUtils.isEmpty(lib) || "feign".equals(lib) || "jersey2".equals(lib)) {
model.imports.add("JsonProperty"); model.imports.add("JsonProperty");
if(model.hasEnums != null || model.hasEnums == true) { if(BooleanUtils.toBoolean(model.hasEnums)) {
model.imports.add("JsonValue"); model.imports.add("JsonValue");
} }
} }

View File

@ -8,22 +8,21 @@ import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property; import io.swagger.models.properties.Property;
import io.swagger.util.Yaml; import io.swagger.util.Yaml;
import java.util.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.*;
public class JavaInflectorServerCodegen extends JavaClientCodegen implements CodegenConfig { public class JavaInflectorServerCodegen extends JavaClientCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(JavaInflectorServerCodegen.class); private static final Logger LOGGER = LoggerFactory.getLogger(JavaInflectorServerCodegen.class);
protected String title = "Swagger Inflector"; protected String title = "Swagger Inflector";
protected String implFolder = "src/main/java";
public JavaInflectorServerCodegen() { public JavaInflectorServerCodegen() {
super(); super();
sourceFolder = "src/main/java"; sourceFolder = "src/gen/java";
modelTemplateFiles.put("model.mustache", ".java"); modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java"); apiTemplateFiles.put("api.mustache", ".java");
embeddedTemplateDir = templateDir = "JavaInflector"; embeddedTemplateDir = templateDir = "JavaInflector";
@ -72,10 +71,10 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen implements Cod
super.processOpts(); super.processOpts();
supportingFiles.clear(); supportingFiles.clear();
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("web.mustache", "src/main/webapp/WEB-INF", "web.xml")); writeOptional(outputFolder, new SupportingFile("web.mustache", "src/main/webapp/WEB-INF", "web.xml"));
supportingFiles.add(new SupportingFile("inflector.mustache", "", "inflector.yaml")); writeOptional(outputFolder, new SupportingFile("inflector.mustache", "", "inflector.yaml"));
supportingFiles.add(new SupportingFile("swagger.mustache", supportingFiles.add(new SupportingFile("swagger.mustache",
"src/main/swagger", "src/main/swagger",
"swagger.yaml") "swagger.yaml")
@ -162,6 +161,18 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen implements Cod
return objs; return objs;
} }
public String apiFilename(String templateName, String tag) {
String result = super.apiFilename(templateName, tag);
if ( templateName.endsWith("api.mustache") ) {
int ix = result.indexOf(sourceFolder);
String beg = result.substring(0, ix);
String end = result.substring(ix + sourceFolder.length());
new java.io.File(beg + implFolder).mkdirs();
result = beg + implFolder + end;
}
return result;
}
@Override @Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) { public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
@ -184,12 +195,4 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen implements Cod
name = name.replaceAll("[^a-zA-Z0-9]+", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. name = name.replaceAll("[^a-zA-Z0-9]+", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
return camelize(name)+ "Controller"; return camelize(name)+ "Controller";
} }
@Override
public boolean shouldOverwrite(String filename) {
return super.shouldOverwrite(filename) &&
!filename.endsWith("pom.xml") &&
!filename.endsWith("README.md") &&
!filename.endsWith("inflector.yaml");
}
} }

View File

@ -47,6 +47,7 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions.add(library); cliOptions.add(library);
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"));
} }
@Override @Override
@ -62,8 +63,15 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen
} }
@Override @Override
public void processOpts() public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
{ super.postProcessModelProperty(model, property);
if("null".equals(property.example)) {
property.example = null;
}
}
@Override
public void processOpts() {
super.processOpts(); super.processOpts();
if ( additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER) ) { if ( additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER) ) {
@ -71,13 +79,13 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen
} }
supportingFiles.clear(); supportingFiles.clear();
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("ApiException.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiException.java")); supportingFiles.add(new SupportingFile("ApiException.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiException.java"));
supportingFiles.add(new SupportingFile("ApiOriginFilter.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiOriginFilter.java")); supportingFiles.add(new SupportingFile("ApiOriginFilter.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiOriginFilter.java"));
supportingFiles.add(new SupportingFile("ApiResponseMessage.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiResponseMessage.java")); supportingFiles.add(new SupportingFile("ApiResponseMessage.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiResponseMessage.java"));
supportingFiles.add(new SupportingFile("NotFoundException.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "NotFoundException.java")); supportingFiles.add(new SupportingFile("NotFoundException.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "NotFoundException.java"));
supportingFiles.add(new SupportingFile("web.mustache", ("src/main/webapp/WEB-INF"), "web.xml")); writeOptional(outputFolder, new SupportingFile("web.mustache", ("src/main/webapp/WEB-INF"), "web.xml"));
supportingFiles.add(new SupportingFile("StringUtil.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "StringUtil.java")); supportingFiles.add(new SupportingFile("StringUtil.mustache", (sourceFolder + '/' + apiPackage).replace(".", "/"), "StringUtil.java"));
if ( additionalProperties.containsKey("dateLibrary") ) { if ( additionalProperties.containsKey("dateLibrary") ) {

View File

@ -0,0 +1,345 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import org.apache.commons.lang.StringUtils;
import java.io.File;
import java.util.*;
public class JavaResteasyServerCodegen extends JavaClientCodegen implements CodegenConfig {
protected String dateLibrary = "default";
protected String title = "Swagger Server";
protected String implFolder = "src/main/java";
public static final String DATE_LIBRARY = "dateLibrary";
public JavaResteasyServerCodegen() {
super();
sourceFolder = "src/gen/java";
invokerPackage = "io.swagger.api";
artifactId = "swagger-jaxrs-resteasy-server";
outputFolder = "generated-code/javaJaxRS";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
apiTemplateFiles.put("apiService.mustache", ".java");
apiTemplateFiles.put("apiServiceImpl.mustache", ".java");
apiTemplateFiles.put("apiServiceFactory.mustache", ".java");
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";
additionalProperties.put("title", title);
embeddedTemplateDir = templateDir = "JavaJaxRS" + File.separator + "resteasy";
for (int i = 0; i < cliOptions.size(); i++) {
if (CodegenConstants.LIBRARY.equals(cliOptions.get(i).getOpt())) {
cliOptions.remove(i);
break;
}
}
CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use");
Map<String, String> dateOptions = new HashMap<String, String>();
dateOptions.put("java8", "Java 8 native");
dateOptions.put("joda", "Joda");
dateLibrary.setEnum(dateOptions);
cliOptions.add(dateLibrary);
CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
library.setDefault(DEFAULT_LIBRARY);
Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
supportedLibraries.put(DEFAULT_LIBRARY, "Resteasy core 3.0.11");
library.setEnum(supportedLibraries);
cliOptions.add(library);
cliOptions.add(new CliOption(CodegenConstants.IMPL_FOLDER, CodegenConstants.IMPL_FOLDER_DESC));
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "jaxrs-resteasy";
}
@Override
public String getHelp() {
return "Generates a Java JAXRS-Resteasy Server application.";
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) {
implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER);
}
supportingFiles.clear();
writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml"));
writeOptional(outputFolder, new SupportingFile("gradle.mustache", "", "build.gradle"));
writeOptional(outputFolder, new SupportingFile("settingsGradle.mustache", "", "settings.gradle"));
writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiException.java"));
supportingFiles.add(new SupportingFile("ApiOriginFilter.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiOriginFilter.java"));
supportingFiles.add(new SupportingFile("ApiResponseMessage.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiResponseMessage.java"));
supportingFiles.add(new SupportingFile("NotFoundException.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "NotFoundException.java"));
writeOptional(outputFolder, new SupportingFile("web.mustache",
("src/main/webapp/WEB-INF"), "web.xml"));
writeOptional(outputFolder, new SupportingFile("jboss-web.mustache",
("src/main/webapp/WEB-INF"), "jboss-web.xml"));
writeOptional(outputFolder, new SupportingFile("RestApplication.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestApplication.java"));
supportingFiles.add(new SupportingFile("StringUtil.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "StringUtil.java"));
if (additionalProperties.containsKey("dateLibrary")) {
setDateLibrary(additionalProperties.get("dateLibrary").toString());
additionalProperties.put(dateLibrary, "true");
}
if ("joda".equals(dateLibrary)) {
typeMapping.put("date", "LocalDate");
typeMapping.put("DateTime", "DateTime");
importMapping.put("LocalDate", "org.joda.time.LocalDate");
importMapping.put("DateTime", "org.joda.time.DateTime");
supportingFiles.add(new SupportingFile("JacksonConfig.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "JacksonConfig.java"));
supportingFiles.add(new SupportingFile("JodaDateTimeProvider.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "JodaDateTimeProvider.java"));
supportingFiles.add(new SupportingFile("JodaLocalDateProvider.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "JodaLocalDateProvider.java"));
} else if ("java8".equals(dateLibrary)) {
additionalProperties.put("java8", "true");
additionalProperties.put("javaVersion", "1.8");
typeMapping.put("date", "LocalDate");
typeMapping.put("DateTime", "LocalDateTime");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
supportingFiles.add(new SupportingFile("LocalDateTimeProvider.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "LocalDateTimeProvider.java"));
supportingFiles.add(new SupportingFile("LocalDateProvider.mustache",
(sourceFolder + '/' + apiPackage).replace(".", "/"), "LocalDateProvider.java"));
}
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
}
int pos = basePath.indexOf("/");
if (pos > 0) {
basePath = basePath.substring(0, pos);
}
if (basePath == "") {
basePath = "default";
} else {
if (co.path.startsWith("/" + basePath)) {
co.path = co.path.substring(("/" + basePath).length());
}
co.subresourceOperation = !co.path.isEmpty();
}
List<CodegenOperation> opList = operations.get(basePath);
if (opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(basePath, opList);
}
opList.add(co);
co.baseName = basePath;
}
@Override
public void preprocessSwagger(Swagger swagger) {
if ("/".equals(swagger.getBasePath())) {
swagger.setBasePath("");
}
String host = swagger.getHost();
String port = "8080";
if (host != null) {
String[] parts = host.split(":");
if (parts.length > 1) {
port = parts[1];
}
}
this.additionalProperties.put("serverPort", port);
if (swagger != null && swagger.getPaths() != null) {
for (String pathname : swagger.getPaths().keySet()) {
Path path = swagger.getPath(pathname);
if (path.getOperations() != null) {
for (Operation operation : path.getOperations()) {
if (operation.getTags() != null) {
List<Map<String, String>> tags = new ArrayList<Map<String, String>>();
for (String tag : operation.getTags()) {
Map<String, String> value = new HashMap<String, String>();
value.put("tag", tag);
value.put("hasMore", "true");
tags.add(value);
}
if (tags.size() > 0) {
tags.get(tags.size() - 1).remove("hasMore");
}
if (operation.getTags().size() > 0) {
String tag = operation.getTags().get(0);
operation.setTags(Arrays.asList(tag));
}
operation.setVendorExtension("x-tags", tags);
}
}
}
}
}
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.hasConsumes == Boolean.TRUE) {
Map<String, String> firstType = operation.consumes.get(0);
if (firstType != null) {
if ("multipart/form-data".equals(firstType.get("mediaType"))) {
operation.isMultipart = Boolean.TRUE;
}
}
}
List<CodegenResponse> responses = operation.responses;
if (responses != null) {
for (CodegenResponse resp : responses) {
if ("0".equals(resp.code)) {
resp.code = "200";
}
}
}
if (operation.returnType == null) {
operation.returnType = "Void";
} else if (operation.returnType.startsWith("List")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("List<".length(), end).trim();
operation.returnContainer = "List";
}
} else if (operation.returnType.startsWith("Map")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Map<".length(), end).split(",")[1].trim();
operation.returnContainer = "Map";
}
} else if (operation.returnType.startsWith("Set")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Set<".length(), end).trim();
operation.returnContainer = "Set";
}
}
}
}
return objs;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
name = sanitizeName(name);
return camelize(name) + "Api";
}
@Override
public String apiFilename(String templateName, String tag) {
String result = super.apiFilename(templateName, tag);
if (templateName.endsWith("Impl.mustache")) {
int ix = result.lastIndexOf('/');
result = result.substring(0, ix) + "/impl" + result.substring(ix, result.length() - 5) + "ServiceImpl.java";
result = result.replace(apiFileFolder(), implFileFolder(implFolder));
} else if (templateName.endsWith("Factory.mustache")) {
int ix = result.lastIndexOf('/');
result = result.substring(0, ix) + "/factories" + result.substring(ix, result.length() - 5) + "ServiceFactory.java";
result = result.replace(apiFileFolder(), implFileFolder(implFolder));
} else if (templateName.endsWith("Service.mustache")) {
int ix = result.lastIndexOf('.');
result = result.substring(0, ix) + "Service.java";
}
return result;
}
private String implFileFolder(String output) {
return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
}
@Override
public boolean shouldOverwrite(String filename) {
return super.shouldOverwrite(filename) && !filename.endsWith("ServiceImpl.java") && !filename.endsWith("ServiceFactory.java");
}
public void setDateLibrary(String library) {
this.dateLibrary = library;
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
if(serializeBigDecimalAsString) {
if (property.baseType.equals("BigDecimal")) {
// we serialize BigDecimal as `string` to avoid precision loss
property.vendorExtensions.put("extraAnnotation", "@JsonSerialize(using = ToStringSerializer.class)");
// this requires some more imports to be added for this model...
model.imports.add("ToStringSerializer");
model.imports.add("JsonSerialize");
}
}
if(model.isEnum == null || model.isEnum) {
final String lib = getLibrary();
if(StringUtils.isEmpty(lib)) {
model.imports.add("JsonProperty");
if(model.hasEnums != null || model.hasEnums == true) {
model.imports.add("JsonValue");
}
}
}
return;
}
}

View File

@ -9,13 +9,29 @@ 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.CodegenType; import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile; import io.swagger.codegen.SupportingFile;
import io.swagger.models.*; import io.swagger.codegen.DefaultCodegen;
import io.swagger.models.Info;
import io.swagger.models.License;
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.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.DateTimeProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.FloatProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.MapProperty;
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 org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -26,10 +42,6 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JavascriptClientCodegen extends DefaultCodegen implements CodegenConfig { public class JavascriptClientCodegen extends DefaultCodegen implements CodegenConfig {
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
private static final Logger LOGGER = LoggerFactory.getLogger(JavascriptClientCodegen.class); private static final Logger LOGGER = LoggerFactory.getLogger(JavascriptClientCodegen.class);
@ -39,6 +51,8 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
private static final String PROJECT_DESCRIPTION = "projectDescription"; private static final String PROJECT_DESCRIPTION = "projectDescription";
private static final String PROJECT_VERSION = "projectVersion"; private static final String PROJECT_VERSION = "projectVersion";
private static final String PROJECT_LICENSE_NAME = "projectLicenseName"; private static final String PROJECT_LICENSE_NAME = "projectLicenseName";
private static final String USE_PROMISES = "usePromises";
private static final String OMIT_MODEL_METHODS = "omitModelMethods";
protected String projectName; protected String projectName;
protected String moduleName; protected String moduleName;
@ -47,6 +61,8 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
protected String sourceFolder = "src"; protected String sourceFolder = "src";
protected String localVariablePrefix = ""; protected String localVariablePrefix = "";
protected boolean usePromises = false;
protected boolean omitModelMethods = false;
public JavascriptClientCodegen() { public JavascriptClientCodegen() {
super(); super();
@ -96,6 +112,12 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
"version of the project (Default: using info.version or \"1.0.0\")")); "version of the project (Default: using info.version or \"1.0.0\")"));
cliOptions.add(new CliOption(PROJECT_LICENSE_NAME, cliOptions.add(new CliOption(PROJECT_LICENSE_NAME,
"name of the license the project uses (Default: using info.license.name)")); "name of the license the project uses (Default: using info.license.name)"));
cliOptions.add(new CliOption(USE_PROMISES,
"use Promises as return values from the client API, instead of superagent callbacks")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(OMIT_MODEL_METHODS,
"omits generation of getters and setters for model classes")
.defaultValue(Boolean.FALSE.toString()));
} }
@Override @Override
@ -133,6 +155,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
typeMapping.put("double", "Number"); typeMapping.put("double", "Number");
typeMapping.put("number", "Number"); typeMapping.put("number", "Number");
typeMapping.put("DateTime", "Date"); typeMapping.put("DateTime", "Date");
typeMapping.put("Date", "Date");
// binary not supported in JavaScript client right now, using String as a workaround // binary not supported in JavaScript client right now, using String as a workaround
typeMapping.put("binary", "String"); typeMapping.put("binary", "String");
@ -161,14 +184,20 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) { if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
sourceFolder = (String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER); sourceFolder = (String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER);
} }
if (additionalProperties.containsKey(USE_PROMISES)) {
usePromises = Boolean.parseBoolean((String)additionalProperties.get(USE_PROMISES));
}
if (additionalProperties.containsKey(OMIT_MODEL_METHODS)) {
omitModelMethods = Boolean.parseBoolean((String)additionalProperties.get(OMIT_MODEL_METHODS));
}
if (swagger.getInfo() != null) { if (swagger.getInfo() != null) {
Info info = swagger.getInfo(); Info info = swagger.getInfo();
if (projectName == null && info.getTitle() != null) { if (StringUtils.isBlank(projectName) && info.getTitle() != null) {
// when projectName is not specified, generate it from info.title // when projectName is not specified, generate it from info.title
projectName = dashize(info.getTitle()); projectName = dashize(info.getTitle());
} }
if (projectVersion == null) { if (StringUtils.isBlank(projectVersion)) {
// when projectVersion is not specified, use info.version // when projectVersion is not specified, use info.version
projectVersion = info.getVersion(); projectVersion = info.getVersion();
} }
@ -185,13 +214,13 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
} }
// default values // default values
if (projectName == null) { if (StringUtils.isBlank(projectName)) {
projectName = "swagger-js-client"; projectName = "swagger-js-client";
} }
if (moduleName == null) { if (StringUtils.isBlank(moduleName)) {
moduleName = camelize(underscore(projectName)); moduleName = camelize(underscore(projectName));
} }
if (projectVersion == null) { if (StringUtils.isBlank(projectVersion)) {
projectVersion = "1.0.0"; projectVersion = "1.0.0";
} }
if (projectDescription == null) { if (projectDescription == null) {
@ -204,6 +233,8 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
additionalProperties.put(PROJECT_VERSION, projectVersion); additionalProperties.put(PROJECT_VERSION, projectVersion);
additionalProperties.put(CodegenConstants.LOCAL_VARIABLE_PREFIX, localVariablePrefix); additionalProperties.put(CodegenConstants.LOCAL_VARIABLE_PREFIX, localVariablePrefix);
additionalProperties.put(CodegenConstants.SOURCE_FOLDER, sourceFolder); additionalProperties.put(CodegenConstants.SOURCE_FOLDER, sourceFolder);
additionalProperties.put(USE_PROMISES, usePromises);
additionalProperties.put(OMIT_MODEL_METHODS, omitModelMethods);
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json")); supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("index.mustache", sourceFolder, "index.js")); supportingFiles.add(new SupportingFile("index.mustache", sourceFolder, "index.js"));
@ -290,38 +321,73 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
@Override @Override
public String getTypeDeclaration(Property p) { public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) { if (p instanceof ArrayProperty) {
// ArrayProperty ap = (ArrayProperty) p; ArrayProperty ap = (ArrayProperty) p;
// Property inner = ap.getItems(); Property inner = ap.getItems();
return getSwaggerType(p); // TODO: + "/* <" + getTypeDeclaration(inner) + "> */"; return "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) { } else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p; MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties(); Property inner = mp.getAdditionalProperties();
return "{String: " + getTypeDeclaration(inner) + "}";
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
} }
return super.getTypeDeclaration(p); return super.getTypeDeclaration(p);
} }
@Override @Override
public String toDefaultValue(Property p) { public String toDefaultValue(Property p) {
if (p instanceof ArrayProperty) { if (p instanceof StringProperty) {
return "[]"; StringProperty dp = (StringProperty) p;
} else if (p instanceof MapProperty) { if (dp.getDefault() != null) {
return "{}"; return "'" + dp.getDefault() + "'";
} else if (p instanceof RefProperty) { }
return "new " + getTypeDeclaration(p) + "()"; } else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof DateProperty) {
// TODO
} else if (p instanceof DateTimeProperty) {
// TODO
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} }
return super.toDefaultValue(p); return null;
} }
@Override @Override
public String toDefaultValueWithParam(String name, Property p) { public String toDefaultValueWithParam(String name, Property p) {
String type = normalizeType(getTypeDeclaration(p));
if (p instanceof RefProperty) { if (p instanceof RefProperty) {
return ".constructFromObject(data." + name + ");"; return " = " + type + ".constructFromObject(data['" + name + "']);";
} else {
return " = ApiClient.convertToType(data['" + name + "'], " + type + ");";
} }
}
return super.toDefaultValueWithParam(name, p); /**
* Normalize type by wrapping primitive types with single quotes.
*/
public String normalizeType(String type) {
return type.replaceAll("\\b(Boolean|Integer|Number|String|Date)\\b", "'$1'");
} }
@Override @Override
@ -351,12 +417,21 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
// method name cannot use reserved keyword, e.g. return // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); operationId = escapeReservedWord(operationId);
} }
return camelize(sanitizeName(operationId), true); return camelize(sanitizeName(operationId), true);
} }
@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);
if (op.returnType != null) {
op.returnType = normalizeType(op.returnType);
}
return op;
}
@Override @Override
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) { public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions); CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
@ -417,11 +492,6 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
return objs; return objs;
} }
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
return objs;
}
@Override @Override
protected boolean needToImport(String type) { protected boolean needToImport(String type) {
return !defaultIncludes.contains(type) return !defaultIncludes.contains(type)

View File

@ -0,0 +1,216 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import java.util.TreeSet;
import java.util.*;
import java.io.File;
public class JavascriptClosureAngularClientCodegen extends DefaultCodegen implements CodegenConfig {
public JavascriptClosureAngularClientCodegen() {
super();
supportsInheritance = false;
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws", "case", "enum",
"instanceof", "return", "transient", "catch", "extends", "int",
"short", "try", "char", "final", "interface", "static", "void",
"class", "finally", "const", "super", "while"));
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"string",
"boolean",
"number",
"Object",
"Blob",
"Date"));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "Object");
typeMapping.put("Object", "Object");
typeMapping.put("File", "Blob");
typeMapping.put("file", "Blob");
typeMapping.put("integer", "number");
typeMapping.put("Map", "Object");
typeMapping.put("map", "Object");
typeMapping.put("DateTime", "Date");
importMapping = new HashMap<String, String>();
defaultIncludes = new HashSet<String>(Arrays.asList(
"Object",
"Array",
"Blob"
));
typeMapping.put("binary", "string");
outputFolder = "generated-code/javascript-closure-angular";
modelTemplateFiles.put("model.mustache", ".js");
apiTemplateFiles.put("api.mustache", ".js");
embeddedTemplateDir = templateDir = "Javascript-Closure-Angular";
apiPackage = "API.Client";
modelPackage = "API.Client";
}
@Override
public String getName() {
return "javascript-closure-angular";
}
@Override
public String getHelp() {
return "Generates a Javascript AngularJS client library annotated with Google Closure Compiler annotations" +
"(https://developers.google.com/closure/compiler/docs/js-for-compiler?hl=en)";
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
public String modelFileFolder() {
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$"))
return name;
// camelize the variable name
// pet_id => PetId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*"))
name = escapeReservedWord(name);
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name))
throw new RuntimeException(name
+ " (reserved word) cannot be used as a model name");
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@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 "Object<!string, "+ getTypeDeclaration(inner) + ">";
} else if (p instanceof FileProperty) {
return "Object";
}
String type = super.getTypeDeclaration(p);
if (type.equals("boolean") ||
type.equals("Date") ||
type.equals("number") ||
type.equals("string")) {
return type;
}
return apiPackage + "." + type;
}
@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 type;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.imports = new TreeSet(cm.imports);
for (CodegenProperty var : cm.vars) {
// handle default value for enum, e.g. available => StatusEnum.available
if (var.isEnum && var.defaultValue != null && !"null".equals(var.defaultValue)) {
var.defaultValue = var.datatypeWithEnum + "." + var.defaultValue;
}
}
}
return objs;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
if (objs.get("imports") instanceof List) {
List<Map<String, String>> imports = (ArrayList<Map<String, String>>)objs.get("imports");
Collections.sort(imports, new Comparator<Map<String, String>>() {
public int compare(Map<String, String> o1, Map<String, String> o2) {
return o1.get("import").compareTo(o2.get("import"));
}
});
objs.put("imports", imports);
}
return objs;
}
}

View File

@ -8,11 +8,11 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import io.swagger.codegen.*; import io.swagger.codegen.*;
import io.swagger.models.Swagger; import io.swagger.models.*;
import io.swagger.models.Info;
import io.swagger.util.Yaml; import io.swagger.util.Yaml;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -20,9 +20,6 @@ import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig { public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(NodeJSServerCodegen.class); private static final Logger LOGGER = LoggerFactory.getLogger(NodeJSServerCodegen.class);
@ -92,18 +89,9 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
"api", "api",
"swagger.yaml") "swagger.yaml")
); );
supportingFiles.add(new SupportingFile("index.mustache", writeOptional(outputFolder, new SupportingFile("index.mustache", "", "index.js"));
"", writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
"index.js") writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
);
supportingFiles.add(new SupportingFile("package.mustache",
"",
"package.json")
);
supportingFiles.add(new SupportingFile("README.mustache",
"",
"README.md")
);
if (System.getProperty("noservice") == null) { if (System.getProperty("noservice") == null) {
apiTemplateFiles.put( apiTemplateFiles.put(
"service.mustache", // the template to use "service.mustache", // the template to use
@ -191,6 +179,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation"); List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation operation : operations) { for (CodegenOperation operation : operations) {
operation.httpMethod = operation.httpMethod.toLowerCase(); operation.httpMethod = operation.httpMethod.toLowerCase();
List<CodegenParameter> params = operation.allParams; List<CodegenParameter> params = operation.allParams;
if (params != null && params.size() == 0) { if (params != null && params.size() == 0) {
operation.allParams = null; operation.allParams = null;
@ -253,7 +242,6 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public void preprocessSwagger(Swagger swagger) { public void preprocessSwagger(Swagger swagger) {
String host = swagger.getHost(); String host = swagger.getHost();
String port = "8080"; String port = "8080";
if (host != null) { if (host != null) {
@ -273,6 +261,28 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
this.additionalProperties.put("projectName", projectName); this.additionalProperties.put("projectName", projectName);
} }
} }
// need vendor extensions for x-swagger-router-controller
Map<String, Path> paths = swagger.getPaths();
if(paths != null) {
for(String pathname : paths.keySet()) {
Path path = paths.get(pathname);
Map<HttpMethod, Operation> operationMap = path.getOperationMap();
if(operationMap != null) {
for(HttpMethod method : operationMap.keySet()) {
Operation operation = operationMap.get(method);
String tag = "default";
if(operation.getTags() != null && operation.getTags().size() > 0) {
tag = toApiName(operation.getTags().get(0));
}
if(operation.getOperationId() == null) {
operation.setOperationId(getOrGenerateOperationId(operation, pathname, method.toString()));
}
operation.getVendorExtensions().put("x-swagger-router-controller", toApiName(tag));
}
}
}
}
} }
@Override @Override

View File

@ -3,6 +3,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption; import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType; import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen; import io.swagger.codegen.DefaultCodegen;
@ -13,6 +14,8 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -84,6 +87,9 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("List", "NSArray"); typeMapping.put("List", "NSArray");
typeMapping.put("object", "NSObject"); typeMapping.put("object", "NSObject");
typeMapping.put("file", "NSURL"); typeMapping.put("file", "NSURL");
//TODO binary should be mapped to byte array
// mapped to String as a workaround
typeMapping.put("binary", "NSString");
// ref: http://www.tutorialspoint.com/objective_c/objective_c_basic_syntax.htm // ref: http://www.tutorialspoint.com/objective_c/objective_c_basic_syntax.htm
@ -453,6 +459,21 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
this.license = license; this.license = license;
} }
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (!operation.allParams.isEmpty()) {
String firstParamName = operation.allParams.get(0).paramName;
operation.vendorExtensions.put("firstParamAltName", camelize(firstParamName));
}
}
}
return objs;
}
/** /**
* Return the default value of the property * Return the default value of the property
* *

View File

@ -30,6 +30,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code" + File.separatorChar + "perl"; outputFolder = "generated-code" + File.separatorChar + "perl";
modelTemplateFiles.put("object.mustache", ".pm"); modelTemplateFiles.put("object.mustache", ".pm");
apiTemplateFiles.put("api.mustache", ".pm"); apiTemplateFiles.put("api.mustache", ".pm");
modelTestTemplateFiles.put("object_test.mustache", ".t");
apiTestTemplateFiles.put("api_test.mustache", ".t");
embeddedTemplateDir = templateDir = "perl"; embeddedTemplateDir = templateDir = "perl";
@ -142,6 +144,17 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
return (outputFolder + "/lib/" + modulePathPart + modelPackage()).replace('/', File.separatorChar); return (outputFolder + "/lib/" + modulePathPart + modelPackage()).replace('/', File.separatorChar);
} }
@Override
public String apiTestFileFolder() {
return (outputFolder + "/t").replace('/', File.separatorChar);
}
@Override
public String modelTestFileFolder() {
return (outputFolder + "/t").replace('/', File.separatorChar);
}
@Override @Override
public String getTypeDeclaration(Property p) { public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) { if (p instanceof ArrayProperty) {
@ -218,6 +231,16 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
return toModelName(name); return toModelName(name);
} }
@Override
public String toModelTestFilename(String name) {
return toModelFilename(name) + "Test";
}
@Override
public String toApiTestFilename(String name) {
return toApiFilename(name) + "Test";
}
@Override @Override
public String toApiFilename(String name) { public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at // replace - with _ e.g. created-at => created_at

View File

@ -223,6 +223,8 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php")); supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php"));
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
supportingFiles.add(new SupportingFile("README.mustache", getPackagePath(), "README.md"));
supportingFiles.add(new SupportingFile(".travis.yml", getPackagePath(), ".travis.yml"));
} }
@Override @Override

View File

@ -90,6 +90,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("map", "Hash"); typeMapping.put("map", "Hash");
typeMapping.put("object", "Object"); typeMapping.put("object", "Object");
typeMapping.put("file", "File"); typeMapping.put("file", "File");
typeMapping.put("binary", "String");
// remove modelPackage and apiPackage added by default // remove modelPackage and apiPackage added by default
Iterator<CliOption> itr = cliOptions.iterator(); Iterator<CliOption> itr = cliOptions.iterator();
@ -315,7 +316,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
if (type == null) { if (type == null) {
return null; return null;
} }
return type; return toModelName(type);
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType; import io.swagger.codegen.CodegenType;
@ -22,6 +23,11 @@ public class StaticDocCodegen extends DefaultCodegen implements CodegenConfig {
apiTemplateFiles.put("operation.mustache", ".html"); apiTemplateFiles.put("operation.mustache", ".html");
embeddedTemplateDir = templateDir = "swagger-static"; embeddedTemplateDir = templateDir = "swagger-static";
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_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_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage); additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
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

@ -1,5 +1,6 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenOperation;
@ -32,6 +33,17 @@ public class StaticHtmlGenerator extends DefaultCodegen implements CodegenConfig
defaultIncludes = new HashSet<String>(); defaultIncludes = new HashSet<String>();
cliOptions.add(new CliOption("appName", "short name of the application"));
cliOptions.add(new CliOption("appDescription", "description of the application"));
cliOptions.add(new CliOption("infoUrl", "a URL where users can get more information about the application"));
cliOptions.add(new CliOption("infoEmail", "an email address to contact for inquiries about the application"));
cliOptions.add(new CliOption("licenseInfo", "a short description of the 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.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));
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", "https://helloreverb.com"); additionalProperties.put("infoUrl", "https://helloreverb.com");

View File

@ -77,7 +77,8 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
"Bool", "Bool",
"Void", "Void",
"String", "String",
"Character") "Character",
"AnyObject")
); );
defaultIncludes = new HashSet<String>( defaultIncludes = new HashSet<String>(
Arrays.asList( Arrays.asList(
@ -118,7 +119,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("float", "Float"); typeMapping.put("float", "Float");
typeMapping.put("number", "Double"); typeMapping.put("number", "Double");
typeMapping.put("double", "Double"); typeMapping.put("double", "Double");
typeMapping.put("object", "String"); typeMapping.put("object", "AnyObject");
typeMapping.put("file", "NSURL"); typeMapping.put("file", "NSURL");
//TODO binary should be mapped to byte array //TODO binary should be mapped to byte array
// mapped to String as a workaround // mapped to String as a workaround
@ -188,7 +189,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return "Swagger" + name; // add an underscore to the name return "_" + name; // add an underscore to the name
} }
@Override @Override
@ -263,7 +264,11 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
codegenProperty.allowableValues.put("values", swiftEnums); codegenProperty.allowableValues.put("values", swiftEnums);
codegenProperty.datatypeWithEnum = codegenProperty.datatypeWithEnum =
StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length());
if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { // Ensure that the enum type doesn't match a reserved word or
// the variable name doesn't match the generated enum type or the
// Swift compiler will generate an error
if (reservedWords.contains(codegenProperty.datatypeWithEnum) ||
name.equals(codegenProperty.datatypeWithEnum)) {
codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum);
} }
} }
@ -288,6 +293,21 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
return initialCaps(name) + "API"; return initialCaps(name) + "API";
} }
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return camelize(sanitizeName(operationId), true);
}
@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'.

View File

@ -15,6 +15,12 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
return "Generates a TypeScript AngularJS client library."; return "Generates a TypeScript AngularJS client library.";
} }
@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
}
public TypeScriptAngularClientCodegen() { public TypeScriptAngularClientCodegen() {
super(); super();
outputFolder = "generated-code/typescript-angular"; outputFolder = "generated-code/typescript-angular";
@ -23,6 +29,5 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
embeddedTemplateDir = templateDir = "TypeScript-Angular"; embeddedTemplateDir = templateDir = "TypeScript-Angular";
apiPackage = "API.Client"; apiPackage = "API.Client";
modelPackage = "API.Client"; modelPackage = "API.Client";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
} }
} }

View File

@ -14,11 +14,16 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen
return "Generates a TypeScript nodejs client library."; return "Generates a TypeScript nodejs client library.";
} }
@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(new SupportingFile("api.mustache", null, "api.ts"));
}
public TypeScriptNodeClientCodegen() { public TypeScriptNodeClientCodegen() {
super(); super();
outputFolder = "generated-code/typescript-node"; outputFolder = "generated-code/typescript-node";
embeddedTemplateDir = templateDir = "TypeScript-node"; embeddedTemplateDir = templateDir = "TypeScript-node";
supportingFiles.add(new SupportingFile("api.mustache", null, "api.ts"));
} }
} }

View File

@ -1,5 +1,7 @@
apply plugin: 'groovy' apply plugin: 'groovy'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'eclipse'
def artifactory = 'buildserver.supportspace.com' def artifactory = 'buildserver.supportspace.com'
group = 'com.supportspace' group = 'com.supportspace'
archivesBaseName = 'swagger-gen-groovy' archivesBaseName = 'swagger-gen-groovy'

View File

@ -103,7 +103,7 @@
<stringProp name="HTTPSampler.response_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp> <stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">{{vendorExtensions.x-path}}</stringProp> <stringProp name="HTTPSampler.path">{{basePathWithoutHost}}{{vendorExtensions.x-path}}</stringProp>
<stringProp name="HTTPSampler.method">{{httpMethod}}</stringProp> <stringProp name="HTTPSampler.method">{{httpMethod}}</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp>

View File

@ -49,7 +49,7 @@ public class ApiClient {
private int connectionTimeout = 0; private int connectionTimeout = 0;
private Client httpClient; private Client httpClient;
private ObjectMapper mapper; private ObjectMapper objectMapper;
private Map<String, Authentication> authentications; private Map<String, Authentication> authentications;
@ -59,24 +59,16 @@ public class ApiClient {
private DateFormat dateFormat; private DateFormat dateFormat;
public ApiClient() { public ApiClient() {
mapper = new ObjectMapper(); objectMapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
mapper.registerModule(new JodaModule()); objectMapper.registerModule(new JodaModule());
objectMapper.setDateFormat(ApiClient.buildDefaultDateFormat());
httpClient = buildHttpClient(debugging); dateFormat = ApiClient.buildDefaultDateFormat();
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
// Use UTC as the default time zone.
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
this.mapper.setDateFormat((DateFormat) dateFormat.clone());
// Set default User-Agent. // Set default User-Agent.
setUserAgent("Java-Swagger"); setUserAgent("Java-Swagger");
@ -88,6 +80,62 @@ public class ApiClient {
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
// Prevent the authentications from being modified. // Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications); authentications = Collections.unmodifiableMap(authentications);
rebuildHttpClient();
}
public static DateFormat buildDefaultDateFormat() {
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
// Use UTC as the default time zone.
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat;
}
/**
* Build the Client used to make HTTP requests with the latest settings,
* i.e. objectMapper and debugging.
* TODO: better to use the Builder Pattern?
*/
public ApiClient rebuildHttpClient() {
// Add the JSON serialization support to Jersey
JacksonJsonProvider jsonProvider = new JacksonJsonProvider(objectMapper);
DefaultClientConfig conf = new DefaultClientConfig();
conf.getSingletons().add(jsonProvider);
Client client = Client.create(conf);
if (debugging) {
client.addFilter(new LoggingFilter());
}
this.httpClient = client;
return this;
}
/**
* Returns the current object mapper used for JSON serialization/deserialization.
* <p>
* 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.
* </p>
*/
public ObjectMapper getObjectMapper() {
return objectMapper;
}
public ApiClient setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
// Need to rebuild the Client as it depends on object mapper.
rebuildHttpClient();
return this;
}
public Client getHttpClient() {
return httpClient;
}
public ApiClient setHttpClient(Client httpClient) {
this.httpClient = httpClient;
return this;
} }
public String getBasePath() { public String getBasePath() {
@ -228,8 +276,8 @@ public class ApiClient {
*/ */
public ApiClient setDebugging(boolean debugging) { public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging; this.debugging = debugging;
// Rebuild HTTP Client according to the new "debugging" value. // Need to rebuild the Client as it depends on the value of debugging.
this.httpClient = buildHttpClient(debugging); rebuildHttpClient();
return this; return this;
} }
@ -263,8 +311,10 @@ public class ApiClient {
*/ */
public ApiClient setDateFormat(DateFormat dateFormat) { public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat; this.dateFormat = dateFormat;
// also set the date format for model (de)serialization with Date properties // Also set the date format for model (de)serialization with Date properties.
this.mapper.setDateFormat((DateFormat) dateFormat.clone()); this.objectMapper.setDateFormat((DateFormat) dateFormat.clone());
// Need to rebuild the Client as objectMapper changes.
rebuildHttpClient();
return this; return this;
} }
@ -517,7 +567,10 @@ public class ApiClient {
response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType, formParams)); response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType, formParams));
} else if ("DELETE".equals(method)) { } else if ("DELETE".equals(method)) {
response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType, formParams)); response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType, formParams));
} else { } else if ("PATCH".equals(method)) {
response = builder.type(contentType).header("X-HTTP-Method-Override", "PATCH").post(ClientResponse.class, serialize(body, contentType, formParams));
}
else {
throw new ApiException(500, "unknown method type " + method); throw new ApiException(500, "unknown method type " + method);
} }
return response; return response;
@ -608,19 +661,4 @@ public class ApiClient {
return encodedFormParams; return encodedFormParams;
} }
/**
* Build the Client used to make HTTP requests.
*/
private Client buildHttpClient(boolean debugging) {
// Add the JSON serialization support to Jersey
JacksonJsonProvider jsonProvider = new JacksonJsonProvider(mapper);
DefaultClientConfig conf = new DefaultClientConfig();
conf.getSingletons().add(jsonProvider);
Client client = Client.create(conf);
if (debugging) {
client.addFilter(new LoggingFilter());
}
return client;
}
} }

View File

@ -20,7 +20,7 @@ mvn deploy
Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information.
After the client libarary is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*: After the client library is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*:
```xml ```xml
<dependency> <dependency>

View File

@ -1,3 +1,6 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}' group = '{{groupId}}'
version = '{{artifactVersion}}' version = '{{artifactVersion}}'
@ -105,7 +108,9 @@ dependencies {
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version"
compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5" compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5"
compile "joda-time:joda-time:$jodatime_version" compile "joda-time:joda-time:$jodatime_version"
compile "com.brsanthu:migbase64:2.2"
testCompile "junit:junit:$junit_version" testCompile "junit:junit:$junit_version"
} }

View File

@ -1,3 +1,6 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}' group = '{{groupId}}'
version = '{{artifactVersion}}' version = '{{artifactVersion}}'

View File

@ -20,6 +20,9 @@ import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.MultiPart; import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.MultiPartFeature;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -37,6 +40,8 @@ import java.io.UnsupportedEncodingException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import {{invokerPackage}}.auth.Authentication; import {{invokerPackage}}.auth.Authentication;
import {{invokerPackage}}.auth.HttpBasicAuth; import {{invokerPackage}}.auth.HttpBasicAuth;
@ -52,6 +57,7 @@ public class ApiClient {
private Client httpClient; private Client httpClient;
private JSON json; private JSON json;
private String tempFolderPath = null;
private Map<String, Authentication> authentications; private Map<String, Authentication> authentications;
@ -236,8 +242,24 @@ public class ApiClient {
} }
/** /**
* Connect timeout (in milliseconds). * The path of temporary folder used to store downloaded files from endpoints
*/ * with file response. The default value is <code>null</code>, i.e. using
* the system's default tempopary folder.
*
* @see https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File)
*/
public String getTempFolderPath() {
return tempFolderPath;
}
public ApiClient setTempFolderPath(String tempFolderPath) {
this.tempFolderPath = tempFolderPath;
return this;
}
/**
* Connect timeout (in milliseconds).
*/
public int getConnectTimeout() { public int getConnectTimeout() {
return connectionTimeout; return connectionTimeout;
} }
@ -247,11 +269,11 @@ public class ApiClient {
* 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}.
*/ */
public ApiClient setConnectTimeout(int connectionTimeout) { public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout; this.connectionTimeout = connectionTimeout;
httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout); httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout);
return this; return this;
} }
/** /**
* Get the date format used to parse/format date parameters. * Get the date format used to parse/format date parameters.
@ -467,6 +489,13 @@ public class ApiClient {
* Deserialize response body to Java object according to the Content-Type. * Deserialize response body to Java object according to the Content-Type.
*/ */
public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException { public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException {
// Handle file downloading.
if (returnType.equals(File.class)) {
@SuppressWarnings("unchecked")
T file = (T) downloadFileFromResponse(response);
return file;
}
String contentType = null; String contentType = null;
List<Object> contentTypes = response.getHeaders().get("Content-Type"); List<Object> contentTypes = response.getHeaders().get("Content-Type");
if (contentTypes != null && !contentTypes.isEmpty()) if (contentTypes != null && !contentTypes.isEmpty())
@ -477,6 +506,55 @@ public class ApiClient {
return response.readEntity(returnType); return response.readEntity(returnType);
} }
/**
* Download file from the given response.
* @throws ApiException If fail to read file content from response and write to disk
*/
public File downloadFileFromResponse(Response response) throws ApiException {
try {
File file = prepareDownloadFile(response);
Files.copy(response.readEntity(InputStream.class), file.toPath());
return file;
} catch (IOException e) {
throw new ApiException(e);
}
}
public File prepareDownloadFile(Response response) throws IOException {
String filename = null;
String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition");
if (contentDisposition != null && !"".equals(contentDisposition)) {
// Get filename from the Content-Disposition header.
Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
Matcher matcher = pattern.matcher(contentDisposition);
if (matcher.find())
filename = matcher.group(1);
}
String prefix = null;
String suffix = null;
if (filename == null) {
prefix = "download-";
suffix = "";
} else {
int pos = filename.lastIndexOf(".");
if (pos == -1) {
prefix = filename + "-";
} else {
prefix = filename.substring(0, pos) + "-";
suffix = filename.substring(pos);
}
// File.createTempFile requires the prefix to be at least three characters long
if (prefix.length() < 3)
prefix = "download-";
}
if (tempFolderPath == null)
return File.createTempFile(prefix, suffix);
else
return File.createTempFile(prefix, suffix, new File(tempFolderPath));
}
/** /**
* Invoke API by sending HTTP request with the given options. * Invoke API by sending HTTP request with the given options.
* *

View File

@ -1,3 +1,6 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}' group = '{{groupId}}'
version = '{{artifactVersion}}' version = '{{artifactVersion}}'
@ -93,19 +96,21 @@ if(hasProperty('target') && target == 'android') {
ext { ext {
swagger_annotations_version = "1.5.0" swagger_annotations_version = "1.5.0"
jackson_version = "2.4.2" jackson_version = "2.4.2"
jersey_version = "2.6" jersey_version = "2.22"
jodatime_version = "2.3" jodatime_version = "2.3"
junit_version = "4.8.1" junit_version = "4.12"
} }
dependencies { dependencies {
compile "io.swagger:swagger-annotations:$swagger_annotations_version" compile "io.swagger:swagger-annotations:$swagger_annotations_version"
compile "org.glassfish.jersey.core:jersey-client:$jersey_version" compile "org.glassfish.jersey.core:jersey-client:$jersey_version"
compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version"
compile "org.glassfish.jersey.media:jersey-media-json-jackson:2.22.1"
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5" compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5"
compile "joda-time:joda-time:$jodatime_version" compile "joda-time:joda-time:$jodatime_version"
compile "com.brsanthu:migbase64:2.2"
testCompile "junit:junit:$junit_version" testCompile "junit:junit:$junit_version"
} }

View File

@ -104,6 +104,27 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- For testing build.gradle -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>gradle-test</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>gradle</executable>
<arguments>
<argument>check</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
@ -174,10 +195,10 @@
</dependencies> </dependencies>
<properties> <properties>
<swagger-annotations-version>1.5.0</swagger-annotations-version> <swagger-annotations-version>1.5.0</swagger-annotations-version>
<jersey-version>2.12</jersey-version> <jersey-version>2.22</jersey-version>
<jackson-version>2.4.2</jackson-version> <jackson-version>2.4.2</jackson-version>
<jodatime-version>2.3</jodatime-version> <jodatime-version>2.3</jodatime-version>
<maven-plugin-version>1.0.0</maven-plugin-version> <maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.8.1</junit-version> <junit-version>4.12</junit-version>
</properties> </properties>
</project> </project>

View File

@ -1,3 +1,6 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}' group = '{{groupId}}'
version = '{{artifactVersion}}' version = '{{artifactVersion}}'
@ -92,8 +95,8 @@ if(hasProperty('target') && target == 'android') {
dependencies { dependencies {
compile 'io.swagger:swagger-annotations:1.5.0' compile 'io.swagger:swagger-annotations:1.5.0'
compile 'com.squareup.okhttp:okhttp:2.4.0' compile 'com.squareup.okhttp:okhttp:2.7.2'
compile 'com.squareup.okhttp:logging-interceptor:2.7.2'
compile 'com.google.code.gson:gson:2.3.1' compile 'com.google.code.gson:gson:2.3.1'
compile 'com.brsanthu:migbase64:2.2'
testCompile 'junit:junit:4.8.1' testCompile 'junit:junit:4.8.1'
} }

View File

@ -10,9 +10,9 @@ lazy val root = (project in file(".")).
resolvers += Resolver.mavenLocal, resolvers += Resolver.mavenLocal,
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"io.swagger" % "swagger-annotations" % "1.5.0", "io.swagger" % "swagger-annotations" % "1.5.0",
"com.squareup.okhttp" % "okhttp" % "2.4.0", "com.squareup.okhttp" % "okhttp" % "2.7.2",
"com.squareup.okhttp" % "logging-interceptor" % "2.7.2",
"com.google.code.gson" % "gson" % "2.3.1", "com.google.code.gson" % "gson" % "2.3.1",
"com.brsanthu" % "migbase64" % "2.2",
"junit" % "junit" % "4.8.1" % "test" "junit" % "junit" % "4.8.1" % "test"
) )
) )

View File

@ -47,16 +47,17 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
} }
if (o == null || getClass() != o.getClass()) { if (o == null || getClass() != o.getClass()) {
return false; return false;
} }{{#hasVars}}
{{classname}} {{classVarName}} = ({{classname}}) o;{{#hasVars}} {{classname}} {{classVarName}} = ({{classname}}) o;
return {{#vars}}Objects.equals({{name}}, {{classVarName}}.{{name}}){{#hasMore}} && return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
{{/hasMore}}{{^hasMore}};{{/hasMore}}{{/vars}}{{/hasVars}}{{^hasVars}} {{/hasMore}}{{/vars}}{{#parent}} &&
super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
return true;{{/hasVars}} return true;{{/hasVars}}
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}); return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
} }
@Override @Override

View File

@ -104,6 +104,28 @@
<target>1.6</target> <target>1.6</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- For testing build.gradle -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>gradle-test</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>gradle</executable>
<arguments>
<argument>check</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>

View File

@ -1,3 +1,6 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}' group = '{{groupId}}'
version = '{{artifactVersion}}' version = '{{artifactVersion}}'

View File

@ -10,18 +10,18 @@ import java.util.Map;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
import retrofit.Converter; import retrofit2.Converter;
import retrofit.Retrofit; import retrofit2.Retrofit;
import retrofit.GsonConverterFactory; import retrofit2.GsonConverterFactory;
{{#useRxJava}}import retrofit.RxJavaCallAdapterFactory;{{/useRxJava}} {{#useRxJava}}import retrofit2.RxJavaCallAdapterFactory;{{/useRxJava}}
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.squareup.okhttp.Interceptor; import okhttp3.Interceptor;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.RequestBody; import okhttp3.RequestBody;
import com.squareup.okhttp.ResponseBody; import okhttp3.ResponseBody;
import {{invokerPackage}}.auth.HttpBasicAuth; import {{invokerPackage}}.auth.HttpBasicAuth;
@ -284,7 +284,7 @@ public class ApiClient {
* @param okClient * @param okClient
*/ */
public void configureFromOkclient(OkHttpClient okClient) { public void configureFromOkclient(OkHttpClient okClient) {
OkHttpClient clone = okClient.clone(); OkHttpClient clone = okClient.newBuilder().build();
addAuthsToOkClient(clone); addAuthsToOkClient(clone);
adapterBuilder.client(clone); adapterBuilder.client(clone);
} }
@ -330,17 +330,17 @@ class GsonCustomConverterFactory extends Converter.Factory
this.gsonConverterFactory = GsonConverterFactory.create(gson); this.gsonConverterFactory = GsonConverterFactory.create(gson);
} }
@Override @Override
public Converter<ResponseBody, ?> fromResponseBody(Type type, Annotation[] annotations) { public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if(type.equals(String.class)) if(type.equals(String.class))
return new GsonResponseBodyConverterToString<Object>(gson, type); return new GsonResponseBodyConverterToString<Object>(gson, type);
else else
return gsonConverterFactory.fromResponseBody(type, annotations); return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
} }
@Override @Override
public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) { public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return gsonConverterFactory.toRequestBody(type, annotations); return gsonConverterFactory.requestBodyConverter(type, annotations, retrofit);
} }
} }

View File

@ -3,10 +3,10 @@ package {{package}};
import {{invokerPackage}}.CollectionFormats.*; import {{invokerPackage}}.CollectionFormats.*;
{{#useRxJava}}import rx.Observable;{{/useRxJava}} {{#useRxJava}}import rx.Observable;{{/useRxJava}}
{{^useRxJava}}import retrofit.Call;{{/useRxJava}} {{^useRxJava}}import retrofit2.Call;{{/useRxJava}}
import retrofit.http.*; import retrofit2.http.*;
import com.squareup.okhttp.RequestBody; import okhttp3.RequestBody;
{{#imports}}import {{import}}; {{#imports}}import {{import}};
{{/imports}} {{/imports}}

View File

@ -4,9 +4,9 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import com.squareup.okhttp.Interceptor; import okhttp3.Interceptor;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.Response; import okhttp3.Response;
public class ApiKeyAuth implements Interceptor { public class ApiKeyAuth implements Interceptor {
private final String location; private final String location;
@ -41,7 +41,7 @@ public class ApiKeyAuth implements Interceptor {
Request request = chain.request(); Request request = chain.request();
if (location == "query") { if (location == "query") {
String newQuery = request.uri().getQuery(); String newQuery = request.url().uri().getQuery();
paramValue = paramName + "=" + apiKey; paramValue = paramName + "=" + apiKey;
if (newQuery == null) { if (newQuery == null) {
newQuery = paramValue; newQuery = paramValue;
@ -51,8 +51,8 @@ public class ApiKeyAuth implements Interceptor {
URI newUri; URI newUri;
try { try {
newUri = new URI(request.uri().getScheme(), request.uri().getAuthority(), newUri = new URI(request.url().uri().getScheme(), request.url().uri().getAuthority(),
request.uri().getPath(), newQuery, request.uri().getFragment()); request.url().uri().getPath(), newQuery, request.url().uri().getFragment());
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new IOException(e); throw new IOException(e);
} }

View File

@ -2,10 +2,11 @@ package {{invokerPackage}}.auth;
import java.io.IOException; import java.io.IOException;
import com.squareup.okhttp.Credentials; import okhttp3.Interceptor;
import com.squareup.okhttp.Interceptor; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.Response; import okhttp3.Response;
import okhttp3.Credentials;
public class HttpBasicAuth implements Interceptor { public class HttpBasicAuth implements Interceptor {

View File

@ -16,11 +16,11 @@ import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType; import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.oltu.oauth2.common.token.BasicOAuthToken; import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
import com.squareup.okhttp.Interceptor; import okhttp3.Interceptor;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.Request.Builder; import okhttp3.Request.Builder;
import com.squareup.okhttp.Response; import okhttp3.Response;
public class OAuth implements Interceptor { public class OAuth implements Interceptor {
@ -90,9 +90,9 @@ public class OAuth implements Interceptor {
String requestAccessToken = new String(getAccessToken()); String requestAccessToken = new String(getAccessToken());
try { try {
oAuthRequest = new OAuthBearerClientRequest(request.urlString()) oAuthRequest = new OAuthBearerClientRequest(request.url().toString())
.setAccessToken(requestAccessToken) .setAccessToken(requestAccessToken)
.buildHeaderMessage(); .buildHeaderMessage();
} catch (OAuthSystemException e) { } catch (OAuthSystemException e) {
throw new IOException(e); throw new IOException(e);
} }

View File

@ -11,11 +11,14 @@ import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient; import okhttp3.Interceptor;
import com.squareup.okhttp.Request; import okhttp3.OkHttpClient;
import com.squareup.okhttp.RequestBody; import okhttp3.Request;
import com.squareup.okhttp.Response; import okhttp3.Request.Builder;
import okhttp3.Response;
import okhttp3.MediaType;
import okhttp3.RequestBody;
public class OAuthOkHttpClient implements HttpClient { public class OAuthOkHttpClient implements HttpClient {

View File

@ -1,3 +1,6 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = '{{groupId}}' group = '{{groupId}}'
version = '{{artifactVersion}}' version = '{{artifactVersion}}'
@ -71,8 +74,8 @@ if(hasProperty('target') && target == 'android') {
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'maven' apply plugin: 'maven'
sourceCompatibility = JavaVersion.VERSION_1_7 sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7
install { install {
repositories.mavenInstaller { repositories.mavenInstaller {
@ -87,25 +90,25 @@ targetCompatibility = JavaVersion.VERSION_1_7
} }
ext { ext {
okhttp_version = "2.5.0" okhttp_version = "3.0.1"
oltu_version = "1.0.0" oltu_version = "1.0.0"
retrofit_version = "2.0.0-beta2" retrofit_version = "2.0.0-beta3"
gson_version = "2.4" gson_version = "2.4"
swagger_annotations_version = "1.5.0" swagger_annotations_version = "1.5.0"
junit_version = "4.12" junit_version = "4.12"
{{#useRxJava}} {{#useRxJava}}
rx_java_version = "1.0.15" rx_java_version = "1.0.16"
{{/useRxJava}} {{/useRxJava}}
{{^useRxJava}}{{/useRxJava}} {{^useRxJava}}{{/useRxJava}}
} }
dependencies { dependencies {
compile "com.squareup.okhttp:okhttp:$okhttp_version" compile "com.squareup.okhttp3:okhttp:$okhttp_version"
compile "com.squareup.retrofit:retrofit:$retrofit_version" compile "com.squareup.retrofit2:retrofit:$retrofit_version"
compile "com.squareup.retrofit:converter-gson:$retrofit_version" compile "com.squareup.retrofit2:converter-gson:$retrofit_version"
{{#useRxJava}} {{#useRxJava}}
compile "com.squareup.retrofit:adapter-rxjava:$retrofit_version" compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version"
compile "io.reactivex:rxjava:$rx_java_version" compile "io.reactivex:rxjava:$rx_java_version"
{{/useRxJava}} {{/useRxJava}}
{{^useRxJava}}{{/useRxJava}} {{^useRxJava}}{{/useRxJava}}

View File

@ -114,12 +114,12 @@
<version>${swagger-annotations-version}</version> <version>${swagger-annotations-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.retrofit</groupId> <groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId> <artifactId>retrofit</artifactId>
<version>${retrofit-version}</version> <version>${retrofit-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.retrofit</groupId> <groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId> <artifactId>converter-gson</artifactId>
<version>${retrofit-version}</version> <version>${retrofit-version}</version>
</dependency> </dependency>
@ -134,7 +134,7 @@
<version>${oltu-version}</version> <version>${oltu-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
<version>${okhttp-version}</version> <version>${okhttp-version}</version>
</dependency> </dependency>
@ -145,7 +145,7 @@
<version>${rxjava-version}</version> <version>${rxjava-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.retrofit</groupId> <groupId>com.squareup.retrofit2</groupId>
<artifactId>adapter-rxjava</artifactId> <artifactId>adapter-rxjava</artifactId>
<version>${retrofit-version}</version> <version>${retrofit-version}</version>
</dependency> </dependency>
@ -161,9 +161,9 @@
</dependencies> </dependencies>
<properties> <properties>
<swagger-annotations-version>1.5.0</swagger-annotations-version> <swagger-annotations-version>1.5.0</swagger-annotations-version>
<retrofit-version>2.0.0-beta2</retrofit-version> <retrofit-version>2.0.0-beta3</retrofit-version>
{{#useRxJava}}<rxjava-version>1.0.15</rxjava-version>{{/useRxJava}} {{#useRxJava}}<rxjava-version>1.0.16</rxjava-version>{{/useRxJava}}
<okhttp-version>2.5.0</okhttp-version> <okhttp-version>3.0.1</okhttp-version>
<gson-version>2.4</gson-version> <gson-version>2.4</gson-version>
<oltu-version>1.0.0</oltu-version> <oltu-version>1.0.0</oltu-version>
<maven-plugin-version>1.0.0</maven-plugin-version> <maven-plugin-version>1.0.0</maven-plugin-version>

View File

@ -14,8 +14,13 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
* minimum: {{minimum}}{{/minimum}}{{#maximum}} * minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}} * maximum: {{maximum}}{{/maximum}}
**/ **/
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
{{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}} {{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}}
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}") @ApiModelProperty({{#example}}example = "{{example}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
@JsonProperty("{{baseName}}") @JsonProperty("{{baseName}}")
public {{{datatypeWithEnum}}} {{getter}}() { public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}}; return {{name}};
@ -33,17 +38,17 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
} }
if (o == null || getClass() != o.getClass()) { if (o == null || getClass() != o.getClass()) {
return false; return false;
} }{{#hasVars}}
{{classname}} {{classVarName}} = ({{classname}}) o; {{classname}} {{classVarName}} = ({{classname}}) o;
return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
return true {{#hasVars}}&& {{#vars}}Objects.equals({{name}}, {{classVarName}}.{{name}}){{#hasMore}} && {{/hasMore}}{{/vars}}{{#parent}} &&
{{/hasMore}}{{/vars}}{{/hasVars}} super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
{{#parent}}&& super.equals(o){{/parent}}; return true;{{/hasVars}}
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}},{{/hasVars}} super.hashCode(){{/parent}}); return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
} }
@Override @Override

View File

@ -14,8 +14,13 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
* minimum: {{minimum}}{{/minimum}}{{#maximum}} * minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}} * maximum: {{maximum}}{{/maximum}}
**/ **/
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
{{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}} {{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}}
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}") @ApiModelProperty({{#example}}example = "{{example}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
@JsonProperty("{{baseName}}") @JsonProperty("{{baseName}}")
public {{{datatypeWithEnum}}} {{getter}}() { public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}}; return {{name}};

View File

@ -78,12 +78,12 @@
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-inflector</artifactId> <artifactId>swagger-inflector</artifactId>
<version>1.0.0</version> <version>1.0.2</version>
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
<maven-plugin-version>1.0.0</maven-plugin-version> <maven-plugin-version>1.0.0</maven-plugin-version>
<swagger-core-version>1.5.4</swagger-core-version> <swagger-core-version>1.5.7</swagger-core-version>
<jetty-version>9.2.9.v20150224</jetty-version> <jetty-version>9.2.9.v20150224</jetty-version>
<logback-version>1.0.1</logback-version> <logback-version>1.0.1</logback-version>
<junit-version>4.8.2</junit-version> <junit-version>4.8.2</junit-version>

View File

@ -22,13 +22,13 @@ import javax.ws.rs.core.SecurityContext;
{{>generatedAnnotation}} {{>generatedAnnotation}}
{{#operations}} {{#operations}}
public class {{classname}}ServiceImpl extends {{classname}}Service { public class {{classname}}ServiceImpl extends {{classname}}Service {
{{#operation}} {{#operation}}
@Override @Override
public Response {{nickname}}({{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}},{{/allParams}}SecurityContext securityContext) public Response {{nickname}}({{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}, {{/allParams}}SecurityContext securityContext)
throws NotFoundException { throws NotFoundException {
// do some magic! // do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build(); return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
} }
{{/operation}} {{/operation}}
} }
{{/operations}} {{/operations}}

View File

@ -14,8 +14,13 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
* minimum: {{minimum}}{{/minimum}}{{#maximum}} * minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}} * maximum: {{maximum}}{{/maximum}}
**/ **/
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
{{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}} {{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}}
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}") @ApiModelProperty({{#example}}example = "{{example}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
@JsonProperty("{{baseName}}") @JsonProperty("{{baseName}}")
public {{{datatypeWithEnum}}} {{getter}}() { public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}}; return {{name}};

View File

@ -168,7 +168,7 @@
</repository> </repository>
</repositories> </repositories>
<properties> <properties>
<swagger-core-version>1.5.4</swagger-core-version> <swagger-core-version>1.5.7</swagger-core-version>
<jetty-version>9.2.9.v20150224</jetty-version> <jetty-version>9.2.9.v20150224</jetty-version>
<jersey-version>1.18.1</jersey-version> <jersey-version>1.18.1</jersey-version>
<slf4j-version>1.6.3</slf4j-version> <slf4j-version>1.6.3</slf4j-version>

View File

@ -1 +1 @@
{{#isQueryParam}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @DefaultValue("{{defaultValue}}") @QueryParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}} {{#isQueryParam}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, {{> allowableValues }}{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{#defaultValue}} @DefaultValue("{{{defaultValue}}}"){{/defaultValue}} @QueryParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}}

View File

@ -0,0 +1,10 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class ApiException extends Exception{
private int code;
public ApiException (int code, String msg) {
super(msg);
this.code = code;
}
}

View File

@ -0,0 +1,22 @@
package {{apiPackage}};
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
{{>generatedAnnotation}}
public class ApiOriginFilter implements javax.servlet.Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type");
chain.doFilter(request, response);
}
public void destroy() {}
public void init(FilterConfig filterConfig) throws ServletException {}
}

View File

@ -0,0 +1,69 @@
package {{apiPackage}};
import javax.xml.bind.annotation.XmlTransient;
@javax.xml.bind.annotation.XmlRootElement
{{>generatedAnnotation}}
public class ApiResponseMessage {
public static final int ERROR = 1;
public static final int WARNING = 2;
public static final int INFO = 3;
public static final int OK = 4;
public static final int TOO_BUSY = 5;
int code;
String type;
String message;
public ApiResponseMessage(){}
public ApiResponseMessage(int code, String message){
this.code = code;
switch(code){
case ERROR:
setType("error");
break;
case WARNING:
setType("warning");
break;
case INFO:
setType("info");
break;
case OK:
setType("ok");
break;
case TOO_BUSY:
setType("too busy");
break;
default:
setType("unknown");
break;
}
this.message = message;
}
@XmlTransient
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,47 @@
package {{invokerPackage}};
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.ISODateTimeFormat;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {
private final ObjectMapper objectMapper;
public JacksonConfig() throws Exception {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JodaModule() {
{
addSerializer(DateTime.class, new StdSerializer<DateTime>(DateTime.class) {
@Override
public void serialize(DateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
jgen.writeString(ISODateTimeFormat.dateTimeNoMillis().print(value));
}
});
addSerializer(LocalDate.class, new StdSerializer<LocalDate>(LocalDate.class) {
@Override
public void serialize(LocalDate value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
jgen.writeString(ISODateTimeFormat.date().print(value));
}
});
}
});
}
@Override
public ObjectMapper getContext(Class<?> arg0) {
return objectMapper;
}
}

View File

@ -0,0 +1,42 @@
package {{apiPackage}};
import org.joda.time.DateTime;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
@Provider
public class JodaDateTimeProvider implements ParamConverterProvider {
public static class JodaDateTimeConverter implements ParamConverter<DateTime> {
@Override
public DateTime fromString(String string) {
try {
DateTime dateTime = DateTime.parse(string);
return dateTime;
} catch (Exception e) {
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).
entity(string + " must be valid DateTime").build());
}
}
@Override
public String toString(DateTime t) {
return t.toString();
}
}
@Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] antns) {
if (DateTime.class.equals(type)) {
return (ParamConverter<T>) new JodaDateTimeConverter();
}
return null;
}
}

View File

@ -0,0 +1,42 @@
package {{apiPackage}};
import org.joda.time.LocalDate;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
@Provider
public class JodaLocalDateProvider implements ParamConverterProvider {
public static class JodaLocalDateConverter implements ParamConverter<LocalDate> {
@Override
public LocalDate fromString(String string) {
try {
LocalDate localDate = LocalDate.parse(string);
return localDate;
} catch (Exception e) {
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).
entity(string + " must be valid LocalDate").build());
}
}
@Override
public String toString(LocalDate t) {
return t.toString();
}
}
@Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] antns) {
if (LocalDate.class.equals(type)) {
return (ParamConverter<T>) new JodaLocalDateConverter();
}
return null;
}
}

View File

@ -0,0 +1,34 @@
package {{apiPackage}};
import java.time.LocalDate;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
public class LocalDateProvider implements ParamConverterProvider {
public static class LocalDateConverter implements ParamConverter<LocalDate> {
@Override
public LocalDate fromString(String string) {
LocalDate localDate = LocalDate.parse(string);
return localDate;
}
@Override
public String toString(LocalDate t) {
return t.toString();
}
}
@Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] antns) {
if (LocalDate.class.equals(type)) {
return (ParamConverter<T>) new LocalDateConverter();
}
return null;
}
}

View File

@ -0,0 +1,34 @@
package {{apiPackage}};
import java.time.LocalDateTime;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
public class LocalDateTimeProvider implements ParamConverterProvider {
public static class LocalDateTimeConverter implements ParamConverter<LocalDateTime> {
@Override
public LocalDateTime fromString(String string) {
LocalDate localDateTime = LocalDateTime.parse(string);
return localDateTime;
}
@Override
public String toString(LocalDateTime t) {
return t.toString();
}
}
@Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] antns) {
if (LocalDateTime.class.equals(type)) {
return (ParamConverter<T>) new LocalDateTimeConverter();
}
return null;
}
}

View File

@ -0,0 +1,10 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {
super(code, msg);
this.code = code;
}
}

View File

@ -0,0 +1,23 @@
# Swagger generated server
## Overview
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the
[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
is an example of building a swagger-enabled JAX-RS server.
This example uses the [JAX-RS](https://jax-rs-spec.java.net/) framework.
To run the server, please execute the following:
```
mvn clean package jetty:run
```
You can then view the swagger listing here:
```
http://localhost:{{serverPort}}{{contextPath}}/swagger.json
```
Note that if you have configured the `host` to be something other than localhost, the calls through
swagger-ui will be directed to that host and not localhost!

View File

@ -0,0 +1,9 @@
package {{invokerPackage}};
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class RestApplication extends Application {
}

View File

@ -0,0 +1,42 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class StringUtil {
/**
* Check if the given array contains the given value (with case-insensitive comparison).
*
* @param array The array
* @param value The value to search
* @return true if the array contains the value
*/
public static boolean containsIgnoreCase(String[] array, String value) {
for (String str : array) {
if (value == null && str == null) return true;
if (value != null && value.equalsIgnoreCase(str)) return true;
}
return false;
}
/**
* Join an array of strings with the given separator.
* <p>
* Note: This might be replaced by utility method from commons-lang or guava someday
* if one of those libraries is added as dependency.
* </p>
*
* @param array The array of strings
* @param separator The separator
* @return the resulting string
*/
public static String join(String[] array, String separator) {
int len = array.length;
if (len == 0) return "";
StringBuilder out = new StringBuilder();
out.append(array[0]);
for (int i = 1; i < len; i++) {
out.append(separator).append(array[i]);
}
return out.toString();
}
}

View File

@ -0,0 +1 @@
{{#allowableValues}}allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}{{^values}}range=[{{#min}}{{.}}{{/min}}{{^min}}-infinity{{/min}}, {{#max}}{{.}}{{/max}}{{^max}}infinity{{/max}}]{{/values}}"{{/allowableValues}}

View File

@ -0,0 +1,40 @@
package {{package}};
import {{modelPackage}}.*;
import {{package}}.{{classname}}Service;
import {{package}}.factories.{{classname}}ServiceFactory;
{{#imports}}import {{import}};
{{/imports}}
import java.util.List;
import {{package}}.NotFoundException;
import java.io.InputStream;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.*;
{{#operations}}{{#operation}}{{#isMultipart}}import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
{{/isMultipart}}{{/operation}}{{/operations}}
@Path("/{{baseName}}")
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
private final {{classname}}Service delegate = {{classname}}ServiceFactory.get{{classname}}();
{{#operation}}
@{{httpMethod}}
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{^isMultipart}}{{>formParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}@Context SecurityContext securityContext)
throws NotFoundException {
return delegate.{{nickname}}({{#isMultipart}}input,{{/isMultipart}}{{#allParams}}{{^isMultipart}}{{paramName}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}}{{paramName}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}securityContext);
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,27 @@
package {{package}};
import {{package}}.*;
import {{modelPackage}}.*;
{{#operations}}{{#operation}}{{#isMultipart}}import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
{{/isMultipart}}{{/operation}}{{/operations}}
{{#imports}}import {{import}};
{{/imports}}
import java.util.List;
import {{package}}.NotFoundException;
import java.io.InputStream;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
{{>generatedAnnotation}}
{{#operations}}
public abstract class {{classname}}Service {
{{#operation}}
public abstract Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{^isMultipart}}{{>serviceFormParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}SecurityContext securityContext)
throws NotFoundException;
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,15 @@
package {{package}}.factories;
import {{package}}.{{classname}}Service;
import {{package}}.impl.{{classname}}ServiceImpl;
{{>generatedAnnotation}}
public class {{classname}}ServiceFactory {
private final static {{classname}}Service service = new {{classname}}ServiceImpl();
public static {{classname}}Service get{{classname}}()
{
return service;
}
}

View File

@ -0,0 +1,31 @@
package {{package}}.impl;
import {{package}}.*;
import {{modelPackage}}.*;
{{#operations}}{{#operation}}{{#isMultipart}}import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
{{/isMultipart}}{{/operation}}{{/operations}}
{{#imports}}import {{import}};
{{/imports}}
import java.util.List;
import {{package}}.NotFoundException;
import java.io.InputStream;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}}ServiceImpl extends {{classname}}Service {
{{#operation}}
@Override
public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{^isMultipart}}{{>serviceFormParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}SecurityContext securityContext)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1 @@
{{#isBodyParam}} {{{dataType}}} {{paramName}}{{/isBodyParam}}

View File

@ -0,0 +1,17 @@
public enum {{{datatypeWithEnum}}} {
{{#allowableValues}}{{#enumVars}}{{{name}}}("{{{value}}}"){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
private String value;
{{{datatypeWithEnum}}}(String value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return value;
}
}

View File

@ -0,0 +1,3 @@
public enum {{classname}} {
{{#allowableValues}}{{.}}{{^-last}}, {{/-last}}{{/allowableValues}}
}

View File

@ -0,0 +1 @@
{{#isFormParam}}{{#notFile}}@FormParam("{{paramName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{/isFormParam}}

View File

@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@ -0,0 +1,32 @@
apply plugin: 'war'
project.version = "{{artifactVersion}}"
project.group = "{{groupId}}"
repositories {
mavenCentral()
}
dependencies {
providedCompile 'org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final'
providedCompile 'org.jboss.resteasy:jaxrs-api:3.0.11.Final'
providedCompile 'org.jboss.resteasy:resteasy-validator-provider-11:3.0.11.Final'
providedCompile 'org.jboss.resteasy:resteasy-multipart-provider:3.0.11.Final'
providedCompile 'javax.annotation:javax.annotation-api:1.2'
providedCompile 'org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.0.Final'
compile 'org.jboss.resteasy:resteasy-jackson2-provider:3.0.11.Final'
// compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.4.1'
// compile 'joda-time:joda-time:2.7'
testCompile 'junit:junit:4.12',
'org.hamcrest:hamcrest-core:1.3'
}
sourceSets {
main {
java {
srcDir 'src/gen/java'
}
}
}

View File

@ -0,0 +1 @@
{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}}

View File

@ -0,0 +1,3 @@
<jboss-web>
<context-root>{{contextPath}}</context-root>
</jboss-web>

View File

@ -0,0 +1,16 @@
package {{package}};
import java.util.Objects;
{{#imports}}import {{import}};
{{/imports}}
{{#serializableModel}}import java.io.Serializable;{{/serializableModel}}
{{#models}}
{{#model}}{{#description}}
/**
* {{description}}
**/{{/description}}
{{#isEnum}}{{>enumOuterClass}}{{/isEnum}}
{{^isEnum}}{{>pojo}}{{/isEnum}}
{{/model}}
{{/models}}

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