diff --git a/.gitignore b/.gitignore
index 76ede9e0e7a..d55a8014a34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,4 +55,9 @@ samples/client/petstore/python/.projectile
samples/client/petstore/python/.venv/
*/.settings
-modules/*/.settings/
+
+*.mustache~
+*.java~
+*.pm~
+*.xml~
+*.t~
\ No newline at end of file
diff --git a/README.md b/README.md
index a13c194837a..0eeb2a3065e 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
## Overview
This is the swagger codegen project, which allows generation of client libraries automatically from a Swagger-compliant server.
-Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
+Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
# Table of contents
@@ -14,50 +14,37 @@ Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additi
- [Overview](#overview)
- [Table of Contents](#table-of-contents)
- Installation
- - [Build and run using docker](#build-and-run-using-docker)
- - [Build a nodejs server stub](#build-a-nodejs-server-stub)
- [Compatibility](#compatibility)
- [Prerequisites](#prerequisites)
- - [OS X Users](#os-x-users)
- - [Building](#building)
+ - [OS X Users](#os-x-users)
+ - [Building](#building)
+ - [Docker](#docker)
+ - [Build and run](#build-and-run-using-docker)
+ - [Build a Node.js server stub](#build-a-nodejs-server-stub)
+ - [Homebrew](#homebrew)
- Generators
- [To generate a sample client library](#to-generate-a-sample-client-library)
- [Generating libraries from your server](#generating-libraries-from-your-server)
- [Modifying the client library format](#modifying-the-client-library-format)
- [Making your own codegen modules](#making-your-own-codegen-modules)
- [Where is Javascript???](#where-is-javascript)
- - [Generating a client from local files](#generating-a-client-from-local-files)
+ - [Generating a client from local files](#generating-a-client-from-local-files)
- [Customizing the generator](#customizing-the-generator)
- [Validating your swagger spec](#validating-your-swagger-spec)
- [Generating dynamic html api documentation](#generating-dynamic-html-api-documentation)
- [Generating static html api documentation](#generating-static-html-api-documentation)
- [To build a server stub](#to-build-a-server-stub)
- - [node.js](#nodejs)
- - [rails-grape](#rails-grape)
- - [scala scalatra](#scala-scalatra)
- - [java jax-rs](#java-jax-rs)
- - [java spring-mvc](#java-spring-mvc)
+ - [Node.js](#nodejs)
+ - [PHP Silex](#php-silex)
+ - [Ruby Sinatra](#ruby-sinatra)
+ - [Scala Scalatra](#scala-scalatra)
+ - [Java JAX-RS](#java-jax-rs)
+ - [Java Spring MVC](#java-spring-mvc)
- [To build the codegen library](#to-build-the-codegen-library)
+ - [Online Generators](#online-generators)
+ - [Guidelines for Contribution](https://github.com/swagger-api/swagger-codegen/wiki/Guidelines-for-Contribution)
- [License](#license)
-## Build and run using docker
-
-```
-git clone https://github.com/swagger-api/swagger-codegen
-
-cd swagger-codegen
-
-./run-in-docker.sh mvn package
- ```
-
-## Build a nodejs server stub
-
- ```
-./run-in-docker.sh generate \
- -i http://petstore.swagger.io/v2/swagger.json \
- -l nodejs \
- -o samples/server/petstore/nodejs
- ```
## Compatibility
The Swagger Specification has undergone 3 revisions since initial creation in 2010. The swagger-codegen project has the following compatibilies with the swagger specification:
@@ -76,24 +63,52 @@ You need the following installed and available in your $PATH:
* [Java 7](http://java.oracle.com)
* [Apache maven 3.0.3 or greater](http://maven.apache.org/)
-
+
#### OS X Users
Don't forget to install Java 7. You probably have 1.6 or 1.8.
-Export JAVA_HOME in order to user proper Java version:
+Export JAVA_HOME in order to use the supported Java version:
```
export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
export PATH=${JAVA_HOME}/bin:$PATH
```
-#### Building
+### Building
After cloning the project, you can build it from source with this command:
-
```
mvn package
```
+### Docker
+#### Build and run using docker
+
+```
+git clone https://github.com/swagger-api/swagger-codegen
+
+cd swagger-codegen
+
+./run-in-docker.sh mvn package
+ ```
+
+#### Build a Node.js server stub
+
+ ```
+./run-in-docker.sh generate \
+ -i http://petstore.swagger.io/v2/swagger.json \
+ -l nodejs \
+ -o samples/server/petstore/nodejs
+ ```
+
+### Homebrew
+To install, run `brew install swagger-codegen`
+
+Here is an example usage:
+```
+swagger-codegen generate -i http://petstore.swagger.io/v2/swagger.json -l ruby -o /tmp/test/
+```
+
+
### To generate a sample client library
You can build a client against the swagger sample [petstore](http://petstore.swagger.io) API as follows:
@@ -110,7 +125,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/client/petstore/java
```
-With a number of options. You can get the options with the `help generate` command:
+with a number of options. You can get the options with the `help generate` command:
```
NAME
@@ -158,10 +173,10 @@ OPTIONS
-v, --verbose
verbose mode
-
+
-s , --skip-overwrite
- specifies if the existing files should be overwritten during
- the generation
+ 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:
@@ -190,7 +205,7 @@ You can look at `modules/swagger-codegen/src/main/resources/${your-language}` fo
If you're starting a project with a new language and don't see what you need, swagger-codegen can help you create a project to generate your own libraries:
```
-java -jar modules/swagger-codegen-distribution/target/swagger-codegen-cli.jar meta \
+java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar meta \
-o output/myLibrary -n myClientCodegen -p com.my.company.codegen
```
@@ -202,7 +217,7 @@ static code generation.
There is a third-party component called [swagger-js-codegen](https://github.com/wcandillon/swagger-js-codegen) that can generate angularjs or nodejs source code from a swagger specification.
-#### Generating a client from local files
+### Generating a client from local files
If you don't want to call your server, you can save the swagger spec files into a directory and pass an argument
to the code generator like this:
@@ -290,7 +305,8 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/client/petstore/java \
-c path/to/config.json
```
-Supported config options can be different per language. Running `config-help -l {lang}` will show available options.
+Supported config options can be different per language. Running `config-help -l {lang}` will show available options. **These options are applied
+by passing them with `-D{optionName}={optionValue}**.
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar config-help -l java
@@ -336,6 +352,7 @@ CONFIG OPTIONS
jersey2 - HTTP client: Jersey client 2.6
okhttp-gson - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1
retrofit - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)
+ retrofit2 - HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.0-beta2)
```
Your config file for java can look like
@@ -350,7 +367,7 @@ Your config file for java can look like
For all the unspecified options default values will be used.
-Another way to override default options is to extend config class for specific language.
+Another way to override default options is to extend the config class for the specific language.
To change, for example, the prefix for the Objective-C generated files, simply subclass the ObjcClientCodegen.java:
```
@@ -406,7 +423,7 @@ open index.html
You can also use the codegen to generate a server for a couple different frameworks. Take a look here:
-### node.js
+### Node.js
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
@@ -415,11 +432,25 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/server/petstore/nodejs
```
-### rails-grape
+### PHP Silex
-*Not yet migrated to this branch*
+```
+java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i http://petstore.swagger.io/v2/swagger.json \
+ -l silex \
+ -o samples/server/petstore/silex
+```
-### scala scalatra
+### Ruby Sinatra
+
+```
+java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i http://petstore.swagger.io/v2/swagger.json \
+ -l sinatra \
+ -o samples/server/petstore/sinatra
+```
+
+### Scala Scalatra
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-i http://petstore.swagger.io/v2/swagger.json \
@@ -427,7 +458,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/server/petstore/scalatra
```
-### java jax-rs
+### Java JAX-RS
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
@@ -436,7 +467,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/server/petstore/jaxrs
```
-### java spring-mvc
+### Java Spring MVC
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
@@ -444,6 +475,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-l spring-mvc \
-o samples/server/petstore/spring-mvc
```
+
### To build the codegen library
This will create the swagger-codegen library from source.
@@ -454,6 +486,21 @@ mvn package
Note! The templates are included in the library generated. If you want to modify the templates, you'll need to either repackage the library OR specify a path to your scripts
+## Online generators
+
+One can also generate API client or server using the online generators (https://generator.swagger.io)
+
+For example, to generate Ruby API client, simply send the following HTTP request using curl:
+```
+curl -X POST -H "content-type:application/json" -d '{"swaggerUrl":"http://petstore.swagger.io/v2/swagger.json"}' https://generator.swagger.io/api/gen/clients/ruby
+```
+Then you will receieve a JSON response with the URL to download the zipped code.
+
+Guidelines for Contribution
+---------------------------
+
+Please refer to this [page](https://github.com/swagger-api/swagger-codegen/wiki/Guidelines-for-Contribution)
+
License
-------
diff --git a/bin/all-petstore.sh b/bin/all-petstore.sh
index 2f9d4c0c0ff..a439d015337 100755
--- a/bin/all-petstore.sh
+++ b/bin/all-petstore.sh
@@ -20,6 +20,7 @@ fi
cd $APP_DIR
./bin/akka-scala-petstore.sh
./bin/android-java-petstore.sh
+./bin/clojure-petstore.sh
./bin/csharp-petstore.sh
./bin/dynamic-html.sh
./bin/html-petstore.sh
@@ -27,6 +28,7 @@ cd $APP_DIR
./bin/java-petstore-jersey2.sh
./bin/java-petstore-okhttp-gson.sh
./bin/java-petstore-retrofit.sh
++./bin/java-petstore-retrofit2.sh
./bin/jaxrs-petstore-server.sh
./bin/nodejs-petstore-server.sh
./bin/objc-petstore.sh
diff --git a/bin/clojure-petstore.sh b/bin/clojure-petstore.sh
new file mode 100755
index 00000000000..1f53d9d386c
--- /dev/null
+++ b/bin/clojure-petstore.sh
@@ -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 clojure -o samples/client/petstore/clojure"
+
+java $JAVA_OPTS -jar $executable $ags
diff --git a/bin/flaskConnexion.sh b/bin/flaskConnexion.sh
new file mode 100755
index 00000000000..f300d3124b1
--- /dev/null
+++ b/bin/flaskConnexion.sh
@@ -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 flaskConnexion -o samples/server/petstore/flaskConnexion "
+
+java $JAVA_OPTS -Dservice -jar $executable $ags
diff --git a/bin/java-petstore-retrofit2.json b/bin/java-petstore-retrofit2.json
new file mode 100644
index 00000000000..4829fd6dd4b
--- /dev/null
+++ b/bin/java-petstore-retrofit2.json
@@ -0,0 +1,4 @@
+{
+ "library": "retrofit2",
+ "artifactId": "swagger-petstore-retrofit2"
+}
diff --git a/bin/java-petstore-retrofit2.sh b/bin/java-petstore-retrofit2.sh
new file mode 100755
index 00000000000..fbd1f9779e4
--- /dev/null
+++ b/bin/java-petstore-retrofit2.sh
@@ -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 java -c bin/java-petstore-retrofit2.json -o samples/client/petstore/java/retrofit2"
+
+java $JAVA_OPTS -jar $executable $ags
diff --git a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/ConfigHelp.java b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/ConfigHelp.java
index f7a128613b9..eb2f8afea92 100644
--- a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/ConfigHelp.java
+++ b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/ConfigHelp.java
@@ -20,7 +20,7 @@ public class ConfigHelp implements Runnable {
System.out.println("CONFIG OPTIONS");
for (CliOption langCliOption : config.cliOptions()) {
System.out.println("\t" + langCliOption.getOpt());
- System.out.println("\t " + langCliOption.getDescription().replaceAll("\n", "\n\t "));
+ System.out.println("\t " + langCliOption.getOptionHelp().replaceAll("\n", "\n\t "));
System.out.println();
}
}
diff --git a/modules/swagger-codegen/pom.xml b/modules/swagger-codegen/pom.xml
index 116d6c0c986..fc51a41fcdf 100644
--- a/modules/swagger-codegen/pom.xml
+++ b/modules/swagger-codegen/pom.xml
@@ -103,6 +103,18 @@
maven-release-plugin
2.1
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.6
+
+
+
+ test-jar
+
+
+
+
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java
index 2c90f4255ec..d6bbb9fa526 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java
@@ -70,14 +70,29 @@ public abstract class AbstractGenerator {
String libTemplateFile = config.templateDir() + File.separator +
"libraries" + File.separator + library + File.separator +
templateFile;
- if (templateExists(libTemplateFile)) {
+
+ if (new File(libTemplateFile).exists()) {
+ return libTemplateFile;
+ }
+
+ libTemplateFile = config.embeddedTemplateDir() + File.separator +
+ "libraries" + File.separator + library + File.separator +
+ templateFile;
+ if (embeddedTemplateExists(libTemplateFile)) {
+ // Fall back to the template file embedded/packaged in the JAR file...
return libTemplateFile;
}
}
- return config.templateDir() + File.separator + templateFile;
+ String template = config.templateDir() + File.separator + templateFile;
+ if (new File(template).exists()) {
+ return template;
+ } else {
+ // Fall back to the template file embedded/packaged in the JAR file...
+ return config.embeddedTemplateDir() + File.separator + templateFile;
+ }
}
- public boolean templateExists(String name) {
+ public boolean embeddedTemplateExists(String name) {
return this.getClass().getClassLoader().getResource(getCPResourcePath(name)) != null;
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CliOption.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CliOption.java
index 1aa0937b31b..b2732f9cd1e 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CliOption.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CliOption.java
@@ -1,14 +1,31 @@
package io.swagger.codegen;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.models.properties.StringProperty;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
public class CliOption {
private final String opt;
private String description;
+ private String type;
+ private String defaultValue;
+ private Map enumValues;
public CliOption(String opt, String description) {
- this.opt = opt;
- this.description = description;
+ this(opt, description, StringProperty.TYPE);
}
+ public CliOption(String opt, String description, String type) {
+ this.opt = opt;
+ this.description = description;
+ this.type = type;
+ }
+
+ @ApiModelProperty(name = "optionName")
public String getOpt() {
return opt;
}
@@ -20,4 +37,58 @@ public class CliOption {
public void setDescription(String description) {
this.description = description;
}
+
+ @ApiModelProperty(value = "Data type is based on the types supported by the JSON-Schema")
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getDefault() {
+ return defaultValue;
+ }
+
+ public void setDefault(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public CliOption defaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ return this;
+ }
+
+ public CliOption addEnum(String value, String description) {
+ if (this.enumValues == null) {
+ this.enumValues = new LinkedHashMap();
+ }
+ if (!enumValues.containsKey(value)) {
+ enumValues.put(value, description);
+ }
+ return this;
+ }
+
+ public Map getEnum() {
+ return enumValues;
+ }
+
+ public void setEnum(Map enumValues) {
+ this.enumValues = enumValues;
+ }
+
+ @JsonIgnore
+ public String getOptionHelp() {
+ StringBuilder sb = new StringBuilder(description);
+ if(defaultValue != null) {
+ sb.append(" (Default: ").append(defaultValue).append(")");
+ }
+ if (enumValues != null) {
+ for (Map.Entry entry : enumValues.entrySet()) {
+ sb.append("\n ").append(entry.getKey()).append(" - ").append(entry.getValue());
+ }
+ }
+ return sb.toString();
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConfig.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConfig.java
index b50147a6ff3..c111a3af2fc 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConfig.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConfig.java
@@ -29,6 +29,8 @@ public interface CodegenConfig {
String templateDir();
+ String embeddedTemplateDir();
+
String modelFileFolder();
String modelPackage();
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java
index b2ada4a1981..a5bb97e5a93 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java
@@ -38,6 +38,12 @@ public class CodegenConstants {
public static final String LIBRARY_DESC = "library template (sub-template)";
public static final String SORT_PARAMS_BY_REQUIRED_FLAG = "sortParamsByRequiredFlag";
- public static final String SORT_PARAMS_BY_REQUIRED_FLAG_DESC = "Sort method arguments to place required parameters before optional parameters. Default: true";
+ public static final String SORT_PARAMS_BY_REQUIRED_FLAG_DESC = "Sort method arguments to place required parameters before optional parameters.";
+ public static final String ENSURE_UNIQUE_PARAMS = "ensureUniqueParams";
+ public static final String ENSURE_UNIQUE_PARAMS_DESC = "Whether to ensure parameter names are unique in an operation (rename parameters that are not). Default: true";
+
+ public static final String PACKAGE_NAME = "packageName";
+ public static final String PACKAGE_VERSION = "packageVersion";
+ public static final String POD_VERSION = "podVersion";
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java
index 871b3f261c0..c5b9231341e 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java
@@ -10,9 +10,10 @@ import java.util.Set;
public class CodegenOperation {
public final List responseHeaders = new ArrayList();
- public Boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive,
- returnSimpleType, subresourceOperation, isMapContainer, isListContainer,
- hasMore = Boolean.TRUE, isMultipart, isResponseBinary = Boolean.FALSE;
+ public Boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
+ returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMapContainer,
+ isListContainer, isMultipart, hasMore = Boolean.TRUE,
+ isResponseBinary = Boolean.FALSE, hasReference = Boolean.FALSE;
public String path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, notes, baseName, defaultResponse;
public List> consumes, produces;
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
index 1107c4f0c88..8c2d0e72559 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
@@ -78,6 +78,7 @@ public class DefaultCodegen {
protected Map apiTemplateFiles = new HashMap();
protected Map modelTemplateFiles = new HashMap();
protected String templateDir;
+ protected String embeddedTemplateDir;
protected Map additionalProperties = new HashMap();
protected List supportingFiles = new ArrayList();
protected List cliOptions = new ArrayList();
@@ -86,6 +87,7 @@ public class DefaultCodegen {
protected Map supportedLibraries = new LinkedHashMap();
protected String library = null;
protected Boolean sortParamsByRequiredFlag = true;
+ protected Boolean ensureUniqueParams = true;
public List cliOptions() {
return cliOptions;
@@ -105,7 +107,13 @@ public class DefaultCodegen {
}
if (additionalProperties.containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
- this.setSortParamsByRequiredFlag(Boolean.valueOf((String)additionalProperties.get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG).toString()));
+ this.setSortParamsByRequiredFlag(Boolean.valueOf(additionalProperties
+ .get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG).toString()));
+ }
+
+ if (additionalProperties.containsKey(CodegenConstants.ENSURE_UNIQUE_PARAMS)) {
+ this.setEnsureUniqueParams(Boolean.valueOf(additionalProperties
+ .get(CodegenConstants.ENSURE_UNIQUE_PARAMS).toString()));
}
}
@@ -183,6 +191,14 @@ public class DefaultCodegen {
return templateDir;
}
+ public String embeddedTemplateDir() {
+ if (embeddedTemplateDir != null) {
+ return embeddedTemplateDir;
+ } else {
+ return templateDir;
+ }
+ }
+
public Map apiTemplateFiles() {
return apiTemplateFiles;
}
@@ -192,11 +208,11 @@ public class DefaultCodegen {
}
public String apiFileFolder() {
- return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
+ return outputFolder + "/" + apiPackage().replace('.', '/');
}
public String modelFileFolder() {
- return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
+ return outputFolder + "/" + modelPackage().replace('.', '/');
}
public Map additionalProperties() {
@@ -235,6 +251,10 @@ public class DefaultCodegen {
this.sortParamsByRequiredFlag = sortParamsByRequiredFlag;
}
+ public void setEnsureUniqueParams(Boolean ensureUniqueParams) {
+ this.ensureUniqueParams = ensureUniqueParams;
+ }
+
/**
* Return the file name of the Api
*
@@ -423,9 +443,9 @@ public class DefaultCodegen {
importMapping.put("LocalDate", "org.joda.time.*");
importMapping.put("LocalTime", "org.joda.time.*");
- cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
- cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
- cliOptions.add(new CliOption(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
+ CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue("true"));
+ cliOptions.add(new CliOption(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants.ENSURE_UNIQUE_PARAMS_DESC));
}
/**
@@ -804,6 +824,7 @@ public class DefaultCodegen {
LOGGER.error("unexpected missing property for name " + name);
return null;
}
+
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
property.name = toVarName(name);
@@ -1200,6 +1221,7 @@ public class DefaultCodegen {
op.examples = new ExampleGenerator(definitions).generate(methodResponse.getExamples(), operation.getProduces(), responseProperty);
op.defaultResponse = toDefaultValue(responseProperty);
op.returnType = cm.datatype;
+ op.hasReference = definitions != null && definitions.containsKey(op.returnBaseType);
if (cm.isContainer != null) {
op.returnContainer = cm.containerType;
if ("map".equals(cm.containerType)) {
@@ -1233,6 +1255,23 @@ public class DefaultCodegen {
if (parameters != null) {
for (Parameter param : parameters) {
CodegenParameter p = fromParameter(param, imports);
+ // rename parameters to make sure all of them have unique names
+ if (ensureUniqueParams) {
+ while (true) {
+ boolean exists = false;
+ for (CodegenParameter cp : allParams) {
+ if (p.paramName.equals(cp.paramName)) {
+ exists = true;
+ break;
+ }
+ }
+ if (exists) {
+ p.paramName = generateNextName(p.paramName);
+ } else {
+ break;
+ }
+ }
+ }
allParams.add(p);
if (param instanceof QueryParameter) {
p.isQueryParam = new Boolean(true);
@@ -1260,6 +1299,9 @@ public class DefaultCodegen {
p.isFormParam = new Boolean(true);
formParams.add(p.copy());
}
+ if (p.required == null || !p.required) {
+ op.hasOptionalParams = true;
+ }
}
}
for (String i : imports) {
@@ -1271,7 +1313,7 @@ public class DefaultCodegen {
op.httpMethod = httpMethod.toUpperCase();
// move "required" parameters in front of "optional" parameters
- if(sortParamsByRequiredFlag) {
+ if (sortParamsByRequiredFlag) {
Collections.sort(allParams, new Comparator() {
@Override
public int compare(CodegenParameter one, CodegenParameter another) {
@@ -1406,6 +1448,9 @@ public class DefaultCodegen {
}
property = new ArrayProperty(inner);
collectionFormat = qp.getCollectionFormat();
+ if (collectionFormat == null) {
+ collectionFormat = "csv";
+ }
CodegenProperty pr = fromProperty("inner", inner);
p.baseType = pr.datatype;
p.isContainer = true;
@@ -1713,6 +1758,28 @@ public class DefaultCodegen {
return word;
}
+ /**
+ * Generate the next name for the given name, i.e. append "2" to the base name if not ending with a number,
+ * otherwise increase the number by 1. For example:
+ * status => status2
+ * status2 => status3
+ * myName100 => myName101
+ *
+ * @param name The base name
+ * @return The next name for the base name
+ */
+ private String generateNextName(String name) {
+ Pattern pattern = Pattern.compile("\\d+\\z");
+ Matcher matcher = pattern.matcher(name);
+ if (matcher.find()) {
+ String numStr = matcher.group();
+ int num = Integer.parseInt(numStr) + 1;
+ return name.substring(0, name.length() - numStr.length()) + num;
+ } else {
+ return name + "2";
+ }
+ }
+
private void addImport(CodegenModel m, String type) {
if (type != null && needToImport(type)) {
m.imports.add(type);
@@ -1856,7 +1923,7 @@ public class DefaultCodegen {
public String apiFilename(String templateName, String tag) {
String suffix = apiTemplateFiles().get(templateName);
- return apiFileFolder() + File.separator + toApiFilename(tag) + suffix;
+ return apiFileFolder() + '/' + toApiFilename(tag) + suffix;
}
public boolean shouldOverwrite(String filename) {
@@ -1911,6 +1978,12 @@ public class DefaultCodegen {
// character with _ or empty character. Below aims to spell out different cases we've
// encountered so far and hopefully make it easier for others to add more special
// cases in the future.
+
+ // better error handling when map/array type is invalid
+ if (name == null) {
+ LOGGER.error("String to be sanitized is null. Default to ERROR_UNKNOWN");
+ return "ERROR_UNKNOWN";
+ }
// input[] => input
name = name.replaceAll("\\[\\]", "");
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java
index 9a2a47853ea..3623361387e 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java
@@ -1,19 +1,8 @@
package io.swagger.codegen;
-import static org.apache.commons.lang3.StringUtils.capitalize;
-import static org.apache.commons.lang3.StringUtils.isNotEmpty;
-
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
-import io.swagger.models.ComposedModel;
-import io.swagger.models.Contact;
-import io.swagger.models.Info;
-import io.swagger.models.License;
-import io.swagger.models.Model;
-import io.swagger.models.Operation;
-import io.swagger.models.Path;
-import io.swagger.models.SecurityRequirement;
-import io.swagger.models.Swagger;
+import io.swagger.models.*;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
@@ -23,14 +12,12 @@ import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
+import java.io.*;
import java.util.*;
+import static org.apache.commons.lang3.StringUtils.capitalize;
+import static org.apache.commons.lang3.StringUtils.isNotEmpty;
+
public class DefaultGenerator extends AbstractGenerator implements Generator {
Logger LOGGER = LoggerFactory.getLogger(DefaultGenerator.class);
@@ -216,7 +203,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
- return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
+ return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
}
})
.defaultValue("")
@@ -262,6 +249,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
operation.put("classVarName", config.toApiVarName(tag));
operation.put("importPath", config.toApiImport(tag));
+ // Pass sortParamsByRequiredFlag through to the Mustache template...
+ boolean sortParamsByRequiredFlag = true;
+ if (this.config.additionalProperties().containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
+ sortParamsByRequiredFlag = Boolean.valueOf((String)this.config.additionalProperties().get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG).toString());
+ }
+ operation.put("sortParamsByRequiredFlag", sortParamsByRequiredFlag);
+
processMimeTypes(swagger.getConsumes(), operation, "consumes");
processMimeTypes(swagger.getProduces(), operation, "produces");
@@ -285,7 +279,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
- return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
+ return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
}
})
.defaultValue("")
@@ -314,6 +308,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (swagger.getHost() != null) {
bundle.put("host", swagger.getHost());
}
+ bundle.put("swagger", this.swagger);
bundle.put("basePath", basePath);
bundle.put("scheme", scheme);
bundle.put("contextPath", contextPath);
@@ -376,7 +371,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
- return getTemplateReader(config.templateDir() + File.separator + name + ".mustache");
+ return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
}
})
.defaultValue("")
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/SupportingFile.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/SupportingFile.java
index 6be69b85d54..53c6ca5ab9b 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/SupportingFile.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/SupportingFile.java
@@ -10,4 +10,14 @@ public class SupportingFile {
this.folder = folder;
this.destinationFilename = destinationFilename;
}
+
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SupportingFile:").append("\n");
+ builder.append("\ttemplateFile: ").append(templateFile).append("\n");
+ builder.append("\tfolder: ").append(folder).append("\n");
+ builder.append("\tdestinationFilename: ").append(destinationFilename).append("\n");
+
+ return builder.toString();
+ }
}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/config/CodegenConfigurator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/config/CodegenConfigurator.java
index 27a6716eceb..ad892917c70 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/config/CodegenConfigurator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/config/CodegenConfigurator.java
@@ -339,6 +339,9 @@ public class CodegenConfigurator {
if (dynamicProperties.containsKey(opt)) {
codegenConfig.additionalProperties().put(opt, dynamicProperties.get(opt));
}
+ else if(systemProperties.containsKey(opt)) {
+ codegenConfig.additionalProperties().put(opt, systemProperties.get(opt).toString());
+ }
}
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractTypeScriptClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractTypeScriptClientCodegen.java
index 38c0c5307ba..a8d66491851 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractTypeScriptClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractTypeScriptClientCodegen.java
@@ -6,6 +6,8 @@ import io.swagger.models.properties.*;
import java.util.*;
import java.io.File;
+import org.apache.commons.lang.StringUtils;
+
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public CodegenType getTag() {
@@ -15,14 +17,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
public AbstractTypeScriptClientCodegen() {
super();
supportsInheritance = true;
- reservedWords = new HashSet(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"));
+ reservedWords = new HashSet(Arrays.asList("abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
languageSpecificPrimitives = new HashSet(Arrays.asList(
"String",
@@ -79,7 +74,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
return name;
// camelize the variable name
- // pet_id => PetId
+ // pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
@@ -141,4 +136,20 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
type = swaggerType;
return 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
+ // append _ at the beginning, e.g. _return
+ if (reservedWords.contains(operationId)) {
+ return escapeReservedWord(camelize(sanitizeName(operationId), true));
+ }
+
+ return camelize(sanitizeName(operationId), true);
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AkkaScalaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AkkaScalaClientCodegen.java
index c40eb653543..29732f1d45a 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AkkaScalaClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AkkaScalaClientCodegen.java
@@ -3,6 +3,8 @@ package io.swagger.codegen.languages;
import com.google.common.base.CaseFormat;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
+
+import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenOperation;
@@ -68,7 +70,7 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
outputFolder = "generated-code/scala";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
- templateDir = "akka-scala";
+ embeddedTemplateDir = templateDir = "akka-scala";
apiPackage = mainPackage + ".api";
modelPackage = mainPackage + ".model";
@@ -147,6 +149,9 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
);
instantiationTypes.put("array", "ListBuffer");
instantiationTypes.put("map", "Map");
+
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
public CodegenType getTag() {
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java
index 9c55053e59c..7983d83cea1 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java
@@ -17,6 +17,7 @@ import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String USE_ANDROID_MAVEN_GRADLE_PLUGIN = "useAndroidMavenGradlePlugin";
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-android-client";
@@ -30,7 +31,7 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
outputFolder = "generated-code/android";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
- templateDir = "android-java";
+ embeddedTemplateDir = templateDir = "android-java";
apiPackage = "io.swagger.client.api";
modelPackage = "io.swagger.client.model";
@@ -59,12 +60,15 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, "groupId for use in the generated build.gradle and pom.xml"));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, "artifactId for use in the generated build.gradle and pom.xml"));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "artifact version for use in the generated build.gradle and pom.xml"));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
- cliOptions.add(new CliOption("useAndroidMavenGradlePlugin", "A flag to toggle android-maven gradle plugin. Default is true."));
+ cliOptions.add(new CliOption(USE_ANDROID_MAVEN_GRADLE_PLUGIN, "A flag to toggle android-maven gradle plugin.")
+ .defaultValue("true"));
}
public CodegenType getTag() {
@@ -220,14 +224,15 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
}
- if (additionalProperties.containsKey("useAndroidMavenGradlePlugin")) {
- this.setUseAndroidMavenGradlePlugin((Boolean) additionalProperties.get("useAndroidMavenGradlePlugin"));
+ if (additionalProperties.containsKey(USE_ANDROID_MAVEN_GRADLE_PLUGIN)) {
+ this.setUseAndroidMavenGradlePlugin(Boolean.valueOf((String) additionalProperties
+ .get(USE_ANDROID_MAVEN_GRADLE_PLUGIN)));
} else {
- additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin);
+ additionalProperties.put(USE_ANDROID_MAVEN_GRADLE_PLUGIN, useAndroidMavenGradlePlugin);
}
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
- additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin);
+ additionalProperties.put(USE_ANDROID_MAVEN_GRADLE_PLUGIN, useAndroidMavenGradlePlugin);
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AsyncScalaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AsyncScalaClientCodegen.java
index 38e6328a8e5..5e85712ffcd 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AsyncScalaClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AsyncScalaClientCodegen.java
@@ -1,5 +1,6 @@
package io.swagger.codegen.languages;
+import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
@@ -40,7 +41,7 @@ public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenCo
outputFolder = "generated-code/async-scala";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
- templateDir = "asyncscala";
+ embeddedTemplateDir = templateDir = "asyncscala";
apiPackage = "io.swagger.client.api";
modelPackage = "io.swagger.client.model";
@@ -105,6 +106,9 @@ public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenCo
);
instantiationTypes.put("array", "ListBuffer");
instantiationTypes.put("map", "HashMap");
+
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
public CodegenType getTag() {
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java
index bd3487d06df..3ab152cf66d 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java
@@ -1,9 +1,12 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
+import io.swagger.codegen.CodegenProperty;
+import io.swagger.codegen.CodegenModel;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
@@ -13,10 +16,15 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client";
@@ -27,7 +35,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
outputFolder = "generated-code" + File.separator + "csharp";
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
- templateDir = "csharp";
+ embeddedTemplateDir = templateDir = "csharp";
apiPackage = "IO.Swagger.Api";
modelPackage = "IO.Swagger.Model";
@@ -79,28 +87,29 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("object", "Object");
cliOptions.clear();
- cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger"));
- cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0"));
-
+ 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(new CliOption(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC));
}
@Override
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("packageVersion")) {
- packageVersion = (String) additionalProperties.get("packageVersion");
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
+ setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
} else {
- additionalProperties.put("packageVersion", packageVersion);
+ additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
}
- if (additionalProperties.containsKey("packageName")) {
- packageName = (String) additionalProperties.get("packageName");
+ 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("packageName", packageName);
+ additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
additionalProperties.put("clientPackage", clientPackage);
@@ -252,4 +261,29 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
return camelize(sanitizeName(operationId));
}
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public void setPackageVersion(String packageVersion) {
+ this.packageVersion = packageVersion;
+ }
+
+ @Override
+ public Map postProcessModels(Map objs) {
+ List models = (List) objs.get("models");
+ for (Object _mo : models) {
+ Map mo = (Map) _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;
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ClojureClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ClojureClientCodegen.java
new file mode 100644
index 00000000000..0277c2d9077
--- /dev/null
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ClojureClientCodegen.java
@@ -0,0 +1,178 @@
+package io.swagger.codegen.languages;
+
+import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
+import io.swagger.codegen.CodegenOperation;
+import io.swagger.codegen.CodegenType;
+import io.swagger.codegen.DefaultCodegen;
+import io.swagger.codegen.SupportingFile;
+import io.swagger.models.Contact;
+import io.swagger.models.Info;
+import io.swagger.models.License;
+import io.swagger.models.Swagger;
+import org.apache.commons.lang.StringUtils;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.List;
+
+public class ClojureClientCodegen extends DefaultCodegen implements CodegenConfig {
+ private static final String PROJECT_NAME = "projectName";
+ private static final String PROJECT_DESCRIPTION = "projectDescription";
+ private static final String PROJECT_VERSION = "projectVersion";
+ private static final String PROJECT_URL = "projectUrl";
+ private static final String LICENSE_NAME = "licenseName";
+ private static final String LICENSE_URL = "licenseUrl";
+ private static final String BASE_NAMESPACE = "baseNamespace";
+
+ protected String projectName = null;
+ protected String projectDescription = null;
+ protected String projectVersion = null;
+ protected String sourceFolder = "src";
+
+ public ClojureClientCodegen() {
+ super();
+ outputFolder = "generated-code" + File.separator + "clojure";
+ apiTemplateFiles.put("api.mustache", ".clj");
+ embeddedTemplateDir = templateDir = "clojure";
+ }
+
+ @Override
+ public CodegenType getTag() {
+ return CodegenType.CLIENT;
+ }
+
+ @Override
+ public String getName() {
+ return "clojure";
+ }
+
+ @Override
+ public String getHelp() {
+ return "Generates a Clojure client library.";
+ }
+
+ @Override
+ public void preprocessSwagger(Swagger swagger) {
+ super.preprocessSwagger(swagger);
+
+ if (additionalProperties.containsKey(PROJECT_NAME)) {
+ projectName = ((String) additionalProperties.get(PROJECT_NAME));
+ }
+ if (additionalProperties.containsKey(PROJECT_DESCRIPTION)) {
+ projectDescription = ((String) additionalProperties.get(PROJECT_DESCRIPTION));
+ }
+ if (additionalProperties.containsKey(PROJECT_VERSION)) {
+ projectVersion = ((String) additionalProperties.get(PROJECT_VERSION));
+ }
+
+ if (swagger.getInfo() != null) {
+ Info info = swagger.getInfo();
+ if (projectName == null && info.getTitle() != null) {
+ // when projectName is not specified, generate it from info.title
+ projectName = dashize(info.getTitle());
+ }
+ if (projectVersion == null) {
+ // when projectVersion is not specified, use info.version
+ projectVersion = info.getVersion();
+ }
+ if (projectDescription == null) {
+ // when projectDescription is not specified, use info.description
+ projectDescription = info.getDescription();
+ }
+
+ if (info.getContact() != null) {
+ Contact contact = info.getContact();
+ if (additionalProperties.get(PROJECT_URL) == null) {
+ additionalProperties.put(PROJECT_URL, contact.getUrl());
+ }
+ }
+ if (info.getLicense() != null) {
+ License license = info.getLicense();
+ if (additionalProperties.get(LICENSE_NAME) == null) {
+ additionalProperties.put(LICENSE_NAME, license.getName());
+ }
+ if (additionalProperties.get(LICENSE_URL) == null) {
+ additionalProperties.put(LICENSE_URL, license.getUrl());
+ }
+ }
+ }
+
+ // default values
+ if (projectName == null) {
+ projectName = "swagger-clj-client";
+ }
+ if (projectVersion == null) {
+ projectVersion = "1.0.0";
+ }
+ if (projectDescription == null) {
+ projectDescription = "Client library of " + projectName;
+ }
+
+ final String baseNamespace = dashize(projectName);
+ apiPackage = baseNamespace + ".api";
+
+ additionalProperties.put(PROJECT_NAME, projectName);
+ additionalProperties.put(PROJECT_DESCRIPTION, escapeText(projectDescription));
+ additionalProperties.put(PROJECT_VERSION, projectVersion);
+ additionalProperties.put(BASE_NAMESPACE, baseNamespace);
+ additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
+
+ final String baseNamespaceFolder = sourceFolder + File.separator + namespaceToFolder(baseNamespace);
+ supportingFiles.add(new SupportingFile("project.mustache", "", "project.clj"));
+ supportingFiles.add(new SupportingFile("core.mustache", baseNamespaceFolder, "core.clj"));
+ }
+
+ @Override
+ public String apiFileFolder() {
+ return outputFolder + File.separator + sourceFolder + File.separator + namespaceToFolder(apiPackage);
+ }
+
+ @Override
+ public String toOperationId(String operationId) {
+ // throw exception if method name is empty
+ if (StringUtils.isEmpty(operationId)) {
+ throw new RuntimeException("Empty method/operation name (operationId) not allowed");
+ }
+
+ return dashize(sanitizeName(operationId));
+ }
+
+ @Override
+ public String toApiName(String name) {
+ return dashize(name);
+ }
+
+ @Override
+ public String toParamName(String name) {
+ return toVarName(name);
+ }
+
+ @Override
+ public String toVarName(String name) {
+ name = name.replaceAll("[^a-zA-Z0-9_-]+", "");
+ name = dashize(name);
+ return name;
+ }
+
+ @Override
+ public Map postProcessOperations(Map operations) {
+ Map objs = (Map) operations.get("operations");
+ List ops = (List) objs.get("operation");
+ for (CodegenOperation op : ops) {
+ // Convert httpMethod to lower case, e.g. "get", "post"
+ op.httpMethod = op.httpMethod.toLowerCase();
+ }
+ return operations;
+ }
+
+ protected String namespaceToFolder(String ns) {
+ return ns.replace(".", File.separator).replace("-", "_");
+ }
+
+ protected String dashize(String s) {
+ return underscore(s).replaceAll("[_ ]", "-");
+ }
+}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CsharpDotNet2ClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CsharpDotNet2ClientCodegen.java
index 9d9757a9131..7b6bf5e7844 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CsharpDotNet2ClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CsharpDotNet2ClientCodegen.java
@@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
@@ -15,6 +16,7 @@ import java.util.HashMap;
import java.util.HashSet;
public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String CLIENT_PACKAGE = "clientPackage";
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client";
@@ -25,7 +27,7 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
outputFolder = "generated-code" + File.separator + "CsharpDotNet2";
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
- templateDir = "CsharpDotNet2";
+ embeddedTemplateDir = templateDir = "CsharpDotNet2";
apiPackage = "IO.Swagger.Api";
modelPackage = "IO.Swagger.Model";
@@ -77,34 +79,36 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
typeMapping.put("object", "Object");
cliOptions.clear();
- cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger"));
- cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0"));
-
+ 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(new CliOption(CLIENT_PACKAGE, "C# client package name (convention: Camel.Case).")
+ .defaultValue("IO.Swagger.Client"));
}
@Override
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("packageVersion")) {
- packageVersion = (String) additionalProperties.get("packageVersion");
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
+ setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
} else {
- additionalProperties.put("packageVersion", packageVersion);
+ additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
}
- if (additionalProperties.containsKey("packageName")) {
- packageName = (String) additionalProperties.get("packageName");
+ 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("packageName", packageName);
+ additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
- if (additionalProperties.containsKey("clientPackage")) {
- this.setClientPackage((String) additionalProperties.get("clientPackage"));
+ if (additionalProperties.containsKey(CLIENT_PACKAGE)) {
+ this.setClientPackage((String) additionalProperties.get(CLIENT_PACKAGE));
} else {
- additionalProperties.put("clientPackage", clientPackage);
+ additionalProperties.put(CLIENT_PACKAGE, clientPackage);
}
supportingFiles.add(new SupportingFile("Configuration.mustache",
@@ -123,6 +127,14 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
this.clientPackage = clientPackage;
}
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public void setPackageVersion(String packageVersion) {
+ this.packageVersion = packageVersion;
+ }
+
public CodegenType getTag() {
return CodegenType.CLIENT;
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/DartClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/DartClientCodegen.java
index ede4505d4dd..e18b9eac0a2 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/DartClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/DartClientCodegen.java
@@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
@@ -15,6 +16,10 @@ import java.util.HashSet;
import java.util.HashMap;
public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String BROWSER_CLIENT = "browserClient";
+ public static final String PUB_NAME = "pubName";
+ public static final String PUB_VERSION = "pubVersion";
+ public static final String PUB_DESCRIPTION = "pubDescription";
protected boolean browserClient = true;
protected String pubName = "swagger";
protected String pubVersion = "1.0.0";
@@ -26,7 +31,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code/dart";
modelTemplateFiles.put("model.mustache", ".dart");
apiTemplateFiles.put("api.mustache", ".dart");
- templateDir = "dart";
+ embeddedTemplateDir = templateDir = "dart";
apiPackage = "lib.api";
modelPackage = "lib.model";
@@ -72,10 +77,11 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("date", "DateTime");
typeMapping.put("File", "MultipartFile");
- cliOptions.add(new CliOption("browserClient", "Is the client browser based"));
- cliOptions.add(new CliOption("pubName", "Name in generated pubspec"));
- cliOptions.add(new CliOption("pubVersion", "Version in generated pubspec"));
- cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
+ cliOptions.add(new CliOption(BROWSER_CLIENT, "Is the client browser based"));
+ cliOptions.add(new CliOption(PUB_NAME, "Name in generated pubspec"));
+ cliOptions.add(new CliOption(PUB_VERSION, "Version in generated pubspec"));
+ cliOptions.add(new CliOption(PUB_DESCRIPTION, "Description in generated pubspec"));
+ cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code"));
}
public CodegenType getTag() {
@@ -94,37 +100,37 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("browserClient")) {
- this.setBrowserClient(Boolean.parseBoolean((String) additionalProperties.get("browserClient")));
- additionalProperties.put("browserClient", browserClient);
+ if (additionalProperties.containsKey(BROWSER_CLIENT)) {
+ this.setBrowserClient(Boolean.parseBoolean((String) additionalProperties.get(BROWSER_CLIENT)));
+ additionalProperties.put(BROWSER_CLIENT, browserClient);
} else {
//not set, use to be passed to template
- additionalProperties.put("browserClient", browserClient);
+ additionalProperties.put(BROWSER_CLIENT, browserClient);
}
- if (additionalProperties.containsKey("pubName")) {
- this.setPubName((String) additionalProperties.get("pubName"));
+ if (additionalProperties.containsKey(PUB_NAME)) {
+ this.setPubName((String) additionalProperties.get(PUB_NAME));
} else {
//not set, use to be passed to template
- additionalProperties.put("pubName", pubName);
+ additionalProperties.put(PUB_NAME, pubName);
}
- if (additionalProperties.containsKey("pubVersion")) {
- this.setPubVersion((String) additionalProperties.get("pubVersion"));
+ if (additionalProperties.containsKey(PUB_VERSION)) {
+ this.setPubVersion((String) additionalProperties.get(PUB_VERSION));
} else {
//not set, use to be passed to template
- additionalProperties.put("pubVersion", pubVersion);
+ additionalProperties.put(PUB_VERSION, pubVersion);
}
- if (additionalProperties.containsKey("pubDescription")) {
- this.setPubDescription((String) additionalProperties.get("pubDescription"));
+ if (additionalProperties.containsKey(PUB_DESCRIPTION)) {
+ this.setPubDescription((String) additionalProperties.get(PUB_DESCRIPTION));
} else {
//not set, use to be passed to template
- additionalProperties.put("pubDescription", pubDescription);
+ additionalProperties.put(PUB_DESCRIPTION, pubDescription);
}
- if (additionalProperties.containsKey("sourceFolder")) {
- this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
+ if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
+ this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
}
final String libFolder = sourceFolder + File.separator + "lib";
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlashClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlashClientCodegen.java
index 7c484c38a0b..8608cbe8924 100755
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlashClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlashClientCodegen.java
@@ -40,7 +40,7 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
modelTemplateFiles.put("model.mustache", ".as");
modelTemplateFiles.put("modelList.mustache", "List.as");
apiTemplateFiles.put("api.mustache", ".as");
- templateDir = "flash";
+ embeddedTemplateDir = templateDir = "flash";
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("Number");
@@ -68,15 +68,19 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
importMapping.put("File", "flash.filesystem.File");
// from
- reservedWords = new HashSet(
- Arrays.asList(
-"add", "for", "lt", "tellTarget", "and", "function", "ne", "this", "break", "ge", "new", "typeof", "continue", "gt", "not", "var", "delete", "if", "on", "void", "do", "ifFrameLoaded", "onClipEvent", "while", "else", "in", "or", "with", "eq", "le", "return"));
+ reservedWords = new HashSet(Arrays.asList("add", "for", "lt", "tellTarget", "and",
+ "function", "ne", "this", "break", "ge", "new", "typeof", "continue", "gt", "not",
+ "var", "delete", "if", "on", "void", "do", "ifFrameLoaded", "onClipEvent", "while",
+ "else", "in", "or", "with", "eq", "le", "return"));
cliOptions.clear();
- cliOptions.add(new CliOption("packageName", "flash package name (convention: package.name), default: io.swagger"));
- cliOptions.add(new CliOption("packageVersion", "flash package version, default: 1.0.0"));
+ cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "flash package name (convention:" +
+ " package.name)").defaultValue("io.swagger"));
+ cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "flash package version")
+ .defaultValue("1.0.0"));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
- cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code. e.g. src/main/flex"));
+ cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated " +
+ "code. e.g. src/main/flex"));
}
@@ -95,8 +99,8 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
}
- if (additionalProperties.containsKey("packageName")) {
- setPackageName((String) additionalProperties.get("packageName"));
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
+ setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
apiPackage = packageName + ".client.api";
modelPackage = packageName + ".client.model";
}
@@ -104,20 +108,21 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
setPackageName("io.swagger");
}
- if (additionalProperties.containsKey("packageVersion")) {
- setPackageVersion((String) additionalProperties.get("packageVersion"));
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
+ setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
}
else {
setPackageVersion("1.0.0");
}
- additionalProperties.put("packageName", packageName);
- additionalProperties.put("packageVersion", packageVersion);
+ additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
+ additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
//modelPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "model";
//apiPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "api";
- final String invokerFolder = (sourceFolder + File.separator + invokerPackage + File.separator + "swagger" + File.separator).replace(".", File.separator).replace('.', File.separatorChar);
+ final String invokerFolder = (sourceFolder + File.separator + invokerPackage + File.separator
+ + "swagger" + File.separator).replace(".", File.separator).replace('.', File.separatorChar);
supportingFiles.add(new SupportingFile("ApiInvoker.as", invokerFolder + "common", "ApiInvoker.as"));
supportingFiles.add(new SupportingFile("ApiUrlHelper.as", invokerFolder + "common", "ApiUrlHelper.as"));
@@ -131,13 +136,20 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("Response.as", invokerFolder + "event", "Response.as"));
supportingFiles.add(new SupportingFile("build.properties", sourceFolder, "build.properties"));
supportingFiles.add(new SupportingFile("build.xml", sourceFolder, "build.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 + "lib", "ASAXB-0.1.1.swc"));
- supportingFiles.add(new SupportingFile("as3corelib.swc", sourceFolder + File.separatorChar + "lib", "as3corelib.swc"));
- supportingFiles.add(new SupportingFile("flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc"));
- supportingFiles.add(new SupportingFile("flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
- supportingFiles.add(new SupportingFile("flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
- supportingFiles.add(new SupportingFile("flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc"));
+ 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
+ + "lib", "ASAXB-0.1.1.swc"));
+ supportingFiles.add(new SupportingFile("as3corelib.swc", sourceFolder + File.separatorChar
+ + "lib", "as3corelib.swc"));
+ supportingFiles.add(new SupportingFile("flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc", sourceFolder
+ + File.separator + "lib" + File.separator + "ext", "flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc"));
+ supportingFiles.add(new SupportingFile("flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder
+ + File.separator + "lib" + File.separator + "ext", "flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
+ supportingFiles.add(new SupportingFile("flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder
+ + File.separator + "lib" + File.separator + "ext", "flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
+ supportingFiles.add(new SupportingFile("flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc", sourceFolder
+ + File.separator + "lib" + File.separator + "ext", "flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc"));
}
private static String dropDots(String str) {
@@ -163,11 +175,13 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String apiFileFolder() {
- return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
+ return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar
+ + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
}
public String modelFileFolder() {
- return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
+ return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar
+ + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
}
@Override
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java
new file mode 100644
index 00000000000..b3de913501a
--- /dev/null
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java
@@ -0,0 +1,295 @@
+package io.swagger.codegen.languages;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import io.swagger.codegen.*;
+import io.swagger.models.Operation;
+import io.swagger.models.Path;
+import io.swagger.models.Swagger;
+import io.swagger.util.Yaml;
+
+import java.io.File;
+import java.util.*;
+
+public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String CONTROLLER_PACKAGE = "controllerPackage";
+ public static final String DEFAULT_CONTROLLER = "defaultController";
+
+ protected String apiVersion = "1.0.0";
+ protected int serverPort = 8080;
+ protected String projectName = "swagger-server";
+ protected String controllerPackage;
+ protected String defaultController;
+
+ public FlaskConnexionCodegen() {
+ super();
+
+ languageSpecificPrimitives.clear();
+ languageSpecificPrimitives.add("int");
+ languageSpecificPrimitives.add("float");
+ languageSpecificPrimitives.add("list");
+ languageSpecificPrimitives.add("bool");
+ languageSpecificPrimitives.add("str");
+ languageSpecificPrimitives.add("datetime");
+ languageSpecificPrimitives.add("date");
+
+ typeMapping.clear();
+ typeMapping.put("integer", "int");
+ typeMapping.put("float", "float");
+ typeMapping.put("number", "float");
+ typeMapping.put("long", "int");
+ typeMapping.put("double", "float");
+ typeMapping.put("array", "list");
+ typeMapping.put("map", "dict");
+ typeMapping.put("boolean", "bool");
+ typeMapping.put("string", "str");
+ typeMapping.put("date", "date");
+ typeMapping.put("DateTime", "datetime");
+ typeMapping.put("object", "object");
+ typeMapping.put("file", "file");
+
+ // set the output folder here
+ outputFolder = "generated-code/connexion";
+
+ modelTemplateFiles.clear();
+
+ apiTemplateFiles.clear();
+
+ /**
+ * Template Location. This is the location which templates will be read from. The generator
+ * will use the resource stream to attempt to read the templates.
+ */
+ embeddedTemplateDir = templateDir = "flaskConnexion";
+
+ // from https://docs.python.org/release/2.5.4/ref/keywords.html
+ reservedWords = new HashSet(
+ Arrays.asList(
+ "and", "del", "from", "not", "while", "as", "elif", "global", "or", "with",
+ "assert", "else", "if", "pass", "yield", "break", "except", "import",
+ "print", "class", "exec", "in", "raise", "continue", "finally", "is",
+ "return", "def", "for", "lambda", "try"));
+
+ /**
+ * Additional Properties. These values can be passed to the templates and
+ * are available in models, apis, and supporting files
+ */
+ additionalProperties.put("apiVersion", apiVersion);
+ additionalProperties.put("serverPort", serverPort);
+
+ /**
+ * Supporting Files. You can write single files for the generator with the
+ * entire object tree available. If the input file has a suffix of `.mustache
+ * it will be processed by the template engine. Otherwise, it will be copied
+ */
+
+ supportingFiles.add(new SupportingFile("swagger.mustache",
+ "swagger",
+ "swagger.yaml")
+ );
+ supportingFiles.add(new SupportingFile("app.mustache",
+ "",
+ "app.py")
+ );
+ supportingFiles.add(new SupportingFile("README.mustache",
+ "",
+ "README.md")
+ );
+
+ cliOptions.add(new CliOption(CONTROLLER_PACKAGE, "controller package").
+ defaultValue("controllers"));
+ cliOptions.add(new CliOption(DEFAULT_CONTROLLER, "default controller").
+ defaultValue("default_controller"));
+ }
+
+ @Override
+ public void processOpts() {
+ super.processOpts();
+ apiTemplateFiles.clear();
+
+ if (additionalProperties.containsKey(CONTROLLER_PACKAGE)) {
+ this.controllerPackage = additionalProperties.get(CONTROLLER_PACKAGE).toString();
+ }
+ else {
+ this.controllerPackage = "controllers";
+ additionalProperties.put(CONTROLLER_PACKAGE, this.controllerPackage);
+ }
+ if (additionalProperties.containsKey(DEFAULT_CONTROLLER)) {
+ this.defaultController = additionalProperties.get(DEFAULT_CONTROLLER).toString();
+ }
+ else {
+ this.defaultController = "default_controller";
+ additionalProperties.put(DEFAULT_CONTROLLER, this.defaultController);
+ }
+
+ if(!new java.io.File(controllerPackage + File.separator + defaultController + ".py").exists()) {
+ supportingFiles.add(new SupportingFile("controller.mustache",
+ controllerPackage,
+ defaultController + ".py")
+ );
+ }
+ }
+
+ public String apiPackage() {
+ return controllerPackage;
+ }
+
+ /**
+ * 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 "python-flask";
+ }
+
+ /**
+ * 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 python server library using the connexion project. By default, " +
+ "it will also generate service classes--which you can disable with the `-Dnoservice` environment variable.";
+ }
+
+ @Override
+ public String toApiName(String name) {
+ if (name.length() == 0) {
+ return "DefaultController";
+ }
+ return initialCaps(name);
+ }
+
+ @Override
+ public String toApiFilename(String name) {
+ return toApiName(name);
+ }
+
+ /**
+ * Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
+ * those terms here. This logic is only called if a variable matches the reseved words
+ *
+ * @return the escaped term
+ */
+ @Override
+ public String escapeReservedWord(String name) {
+ return "_" + name; // add an underscore to the name
+ }
+
+ /**
+ * Location to write api files. You can use the apiPackage() as defined when the class is
+ * instantiated
+ */
+ @Override
+ public String apiFileFolder() {
+ return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
+ }
+
+ @Override
+ public void preprocessSwagger(Swagger swagger) {
+ 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()) {
+ String operationId = operation.getOperationId();
+ if(operationId != null && operationId.indexOf(".") == -1) {
+ operation.setVendorExtension("x-operationId", underscore(sanitizeName(operationId)));
+ operationId = controllerPackage + "." + defaultController + "." + underscore(sanitizeName(operationId));
+ operation.setOperationId(operationId);
+ }
+ if(operation.getTags() != null) {
+ List> tags = new ArrayList>();
+ for(String tag : operation.getTags()) {
+ Map value = new HashMap();
+ 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);
+ }
+ else {
+ String tag = "default_controller";
+ operation.setTags(Arrays.asList(tag));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private List> getOperations(Map objs) {
+ List> result = new ArrayList>();
+ Map apiInfo = (Map) objs.get("apiInfo");
+ List> apis = (List>) apiInfo.get("apis");
+ for (Map api : apis) {
+ result.add((Map) api.get("operations"));
+ }
+ return result;
+ }
+
+ private List> sortOperationsByPath(List ops) {
+ Multimap opsByPath = ArrayListMultimap.create();
+
+ for (CodegenOperation op : ops) {
+ opsByPath.put(op.path, op);
+ }
+
+ List> opsByPathList = new ArrayList>();
+ for (Map.Entry> entry : opsByPath.asMap().entrySet()) {
+ Map opsByPathEntry = new HashMap();
+ opsByPathList.add(opsByPathEntry);
+ opsByPathEntry.put("path", entry.getKey());
+ opsByPathEntry.put("operation", entry.getValue());
+ List operationsForThisPath = Lists.newArrayList(entry.getValue());
+ operationsForThisPath.get(operationsForThisPath.size() - 1).hasMore = null;
+ if (opsByPathList.size() < opsByPath.asMap().size()) {
+ opsByPathEntry.put("hasMore", "true");
+ }
+ }
+
+ return opsByPathList;
+ }
+
+ @Override
+ public Map postProcessSupportingFileData(Map objs) {
+ Swagger swagger = (Swagger)objs.get("swagger");
+ if(swagger != null) {
+ try {
+ objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ }
+ for (Map operations : getOperations(objs)) {
+ @SuppressWarnings("unchecked")
+ List ops = (List) operations.get("operation");
+
+ List> opsByPathList = sortOperationsByPath(ops);
+ operations.put("operationsByPath", opsByPathList);
+ }
+ return super.postProcessSupportingFileData(objs);
+ }
+}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java
index 658b0ca9602..636f0157a52 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java
@@ -12,9 +12,14 @@ import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Model;
import io.swagger.models.properties.ArrayProperty;
+import io.swagger.models.properties.BooleanProperty;
+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.Property;
+import io.swagger.models.properties.StringProperty;
import java.io.File;
import java.util.ArrayList;
@@ -31,12 +36,15 @@ import org.slf4j.LoggerFactory;
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(JavaClientCodegen.class);
+ public static final String FULL_JAVA_UTIL = "fullJavaUtil";
+ public static final String DEFAULT_LIBRARY = "";
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0";
- protected String sourceFolder = "src/main/java";
+ protected String projectFolder = "src" + File.separator + "main";
+ protected String sourceFolder = projectFolder + File.separator + "java";
protected String localVariablePrefix = "";
protected boolean fullJavaUtil = false;
protected String javaUtilPrefix = "";
@@ -44,10 +52,10 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
public JavaClientCodegen() {
super();
- outputFolder = "generated-code/java";
+ outputFolder = "generated-code" + File.separator + "java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
- templateDir = "Java";
+ embeddedTemplateDir = templateDir = "Java";
apiPackage = "io.swagger.client.api";
modelPackage = "io.swagger.client.model";
@@ -77,6 +85,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
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));
@@ -84,13 +94,19 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
cliOptions.add(new CliOption(CodegenConstants.LOCAL_VARIABLE_PREFIX, CodegenConstants.LOCAL_VARIABLE_PREFIX_DESC));
cliOptions.add(new CliOption(CodegenConstants.SERIALIZABLE_MODEL, CodegenConstants.SERIALIZABLE_MODEL_DESC));
- cliOptions.add(new CliOption("fullJavaUtil", "whether to use fully qualified name for classes under java.util (default to false)"));
+ cliOptions.add(new CliOption(FULL_JAVA_UTIL, "whether to use fully qualified name for classes under java.util")
+ .defaultValue("false"));
- supportedLibraries.put("", "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
+ supportedLibraries.put(DEFAULT_LIBRARY, "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.6");
supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1");
supportedLibraries.put("retrofit", "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)");
- cliOptions.add(buildLibraryCliOption(supportedLibraries));
+ supportedLibraries.put("retrofit2", "HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.0-beta2)");
+ CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
+ library.setDefault(DEFAULT_LIBRARY);
+ library.setEnum(supportedLibraries);
+ library.setDefault(DEFAULT_LIBRARY);
+ cliOptions.add(library);
}
@Override
@@ -150,7 +166,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
}
if (additionalProperties.containsKey(CodegenConstants.SERIALIZABLE_MODEL)) {
- this.setSerializableModel(Boolean.valueOf((String)additionalProperties.get(CodegenConstants.SERIALIZABLE_MODEL).toString()));
+ this.setSerializableModel(Boolean.valueOf(additionalProperties.get(CodegenConstants.SERIALIZABLE_MODEL).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.LIBRARY)) {
@@ -160,13 +176,13 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
// need to put back serializableModel (boolean) into additionalProperties as value in additionalProperties is string
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel);
- if (additionalProperties.containsKey("fullJavaUtil")) {
- fullJavaUtil = Boolean.valueOf(additionalProperties.get("fullJavaUtil").toString());
+ if (additionalProperties.containsKey(FULL_JAVA_UTIL)) {
+ this.setFullJavaUtil(Boolean.valueOf(additionalProperties.get(FULL_JAVA_UTIL).toString()));
}
if (fullJavaUtil) {
javaUtilPrefix = "java.util.";
}
- additionalProperties.put("fullJavaUtil", fullJavaUtil);
+ additionalProperties.put(FULL_JAVA_UTIL, fullJavaUtil);
additionalProperties.put("javaUtilPrefix", javaUtilPrefix);
if (fullJavaUtil) {
@@ -188,21 +204,23 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.sanitizeConfig();
- final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
+ final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
+ supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle"));
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
supportingFiles.add(new SupportingFile("gradle.properties.mustache", "", "gradle.properties"));
+ supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
- final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator);
+ final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
- if (!"retrofit".equals(getLibrary())) {
+ if (!("retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
@@ -216,7 +234,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
// "build.sbt" is for development with SBT
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
- } else if ("retrofit".equals(getLibrary())) {
+ } else if ("retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
supportingFiles.add(new SupportingFile("CollectionFormats.mustache", invokerFolder, "CollectionFormats.java"));
} else {
@@ -251,12 +269,12 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
- return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
+ return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/');
}
@Override
public String modelFileFolder() {
- return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
+ return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/');
}
@Override
@@ -346,12 +364,48 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
pattern = "new HashMap()";
}
return String.format(pattern, getTypeDeclaration(ap.getAdditionalProperties()));
+ } else if (p instanceof IntegerProperty) {
+ IntegerProperty dp = (IntegerProperty) p;
+ if (dp.getDefault() != null) {
+ return dp.getDefault().toString();
+ }
+ return "null";
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString()+"l";
}
return "null";
+ } else if (p instanceof DoubleProperty) {
+ DoubleProperty dp = (DoubleProperty) p;
+ if (dp.getDefault() != null) {
+ return dp.getDefault().toString() + "d";
+ }
+ return "null";
+ } else if (p instanceof FloatProperty) {
+ FloatProperty dp = (FloatProperty) p;
+ if (dp.getDefault() != null) {
+ return dp.getDefault().toString() + "f";
+ }
+ return "null";
+ } else if (p instanceof BooleanProperty) {
+ BooleanProperty bp = (BooleanProperty) p;
+ if (bp.getDefault() != null) {
+ return bp.getDefault().toString();
+ }
+ return "null";
+ } else if (p instanceof StringProperty) {
+ StringProperty sp = (StringProperty) p;
+ if (sp.getDefault() != null) {
+ String _default = sp.getDefault();
+ if (sp.getEnum() == null) {
+ return "\"" + escapeText(_default) + "\"";
+ } else {
+ // convert to enum var name later in postProcessModels
+ return _default;
+ }
+ }
+ return "null";
}
return super.toDefaultValue(p);
}
@@ -444,13 +498,26 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
enumVars.add(enumVar);
}
allowableValues.put("enumVars", enumVars);
+ // handle default value for enum, e.g. available => StatusEnum.AVAILABLE
+ if (var.defaultValue != null) {
+ String enumName = null;
+ for (Map enumVar : enumVars) {
+ if (var.defaultValue.equals(enumVar.get("value"))) {
+ enumName = enumVar.get("name");
+ break;
+ }
+ }
+ if (enumName != null) {
+ var.defaultValue = var.datatypeWithEnum + "." + enumName;
+ }
+ }
}
}
return objs;
}
public Map postProcessOperations(Map objs) {
- if("retrofit".equals(getLibrary())) {
+ if("retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary())) {
Map operations = (Map) objs.get("operations");
if (operations != null) {
List ops = (List) operations.get("operation");
@@ -466,6 +533,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
if (operation.returnType == null) {
operation.returnType = "Void";
}
+ if ("retrofit2".equals(getLibrary()) && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/"))
+ operation.path = operation.path.substring(1);
}
}
}
@@ -582,4 +651,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return packageName;
}
+ public void setFullJavaUtil(boolean fullJavaUtil) {
+ this.fullJavaUtil = fullJavaUtil;
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaInflectorServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaInflectorServerCodegen.java
index d678515f4cb..c0061bf39e7 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaInflectorServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaInflectorServerCodegen.java
@@ -2,7 +2,9 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
+import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
+import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Operation;
@@ -30,7 +32,7 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen implements Cod
sourceFolder = "src/main/java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
- templateDir = "JavaInflector";
+ embeddedTemplateDir = templateDir = "JavaInflector";
invokerPackage = "io.swagger.handler";
artifactId = "swagger-inflector-server";
@@ -121,6 +123,22 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen implements Cod
co.baseName = basePath;
}
+ @Override
+ public Map postProcessModels(Map objs) {
+ List models = (List) objs.get("models");
+ for (Object _mo : models) {
+ Map mo = (Map) _mo;
+ CodegenModel cm = (CodegenModel) mo.get("model");
+ 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;
+ }
+
public Map postProcessOperations(Map objs) {
Map operations = (Map) objs.get("operations");
if (operations != null) {
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JaxRSServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JaxRSServerCodegen.java
index 883b08d8dfa..375f5d72bff 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JaxRSServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JaxRSServerCodegen.java
@@ -1,19 +1,12 @@
package io.swagger.codegen.languages;
-import io.swagger.codegen.CodegenConfig;
-import io.swagger.codegen.CodegenConstants;
-import io.swagger.codegen.CodegenOperation;
-import io.swagger.codegen.CodegenResponse;
-import io.swagger.codegen.CodegenType;
-import io.swagger.codegen.SupportingFile;
+import io.swagger.codegen.*;
import io.swagger.models.Operation;
+import io.swagger.models.Path;
+import io.swagger.models.Swagger;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConfig {
protected String title = "Swagger Server";
@@ -31,7 +24,7 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
apiTemplateFiles.put("apiService.mustache", ".java");
apiTemplateFiles.put("apiServiceImpl.mustache", ".java");
apiTemplateFiles.put("apiServiceFactory.mustache", ".java");
- templateDir = "JavaJaxRS";
+ embeddedTemplateDir = templateDir = "JavaJaxRS";
apiPackage = System.getProperty("swagger.codegen.jaxrs.apipackage", "io.swagger.api");
modelPackage = System.getProperty("swagger.codegen.jaxrs.modelpackage", "io.swagger.model");
@@ -74,13 +67,13 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
- (sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "ApiException.java"));
+ (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiException.java"));
supportingFiles.add(new SupportingFile("ApiOriginFilter.mustache",
- (sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "ApiOriginFilter.java"));
+ (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiOriginFilter.java"));
supportingFiles.add(new SupportingFile("ApiResponseMessage.mustache",
- (sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "ApiResponseMessage.java"));
+ (sourceFolder + '/' + apiPackage).replace(".", "/"), "ApiResponseMessage.java"));
supportingFiles.add(new SupportingFile("NotFoundException.mustache",
- (sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "NotFoundException.java"));
+ (sourceFolder + '/' + apiPackage).replace(".", "/"), "NotFoundException.java"));
supportingFiles.add(new SupportingFile("web.mustache",
("src/main/webapp/WEB-INF"), "web.xml"));
@@ -114,6 +107,52 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
co.baseName = basePath;
}
+ @Override
+ public void preprocessSwagger(Swagger swagger) {
+ 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> tags = new ArrayList>();
+ for(String tag : operation.getTags()) {
+ Map value = new HashMap();
+ 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 postProcessModels(Map objs) {
+ List models = (List) objs.get("models");
+ for (Object _mo : models) {
+ Map mo = (Map) _mo;
+ CodegenModel cm = (CodegenModel) mo.get("model");
+ 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;
+ }
+
public Map postProcessOperations(Map objs) {
Map operations = (Map) objs.get("operations");
if (operations != null) {
@@ -175,9 +214,10 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
result = result.substring(0, ix) + "/impl" + result.substring(ix, result.length() - 5) + "ServiceImpl.java";
String output = System.getProperty("swagger.codegen.jaxrs.impl.source");
- if (output != null) {
- result = result.replace(apiFileFolder(), implFileFolder(output));
+ if(output == null) {
+ output = "src" + File.separator + "main" + File.separator + "java";
}
+ result = result.replace(apiFileFolder(), implFileFolder(output));
} else if (templateName.endsWith("Factory.mustache")) {
int ix = result.lastIndexOf('/');
result = result.substring(0, ix) + "/factories" + result.substring(ix, result.length() - 5) + "ServiceFactory.java";
@@ -195,7 +235,7 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
}
private String implFileFolder(String output) {
- return outputFolder + "/" + output + "/" + apiPackage().replace('.', File.separatorChar);
+ return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
}
public boolean shouldOverwrite(String filename) {
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NodeJSServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NodeJSServerCodegen.java
index 10070ece512..4dee5f6f2df 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NodeJSServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NodeJSServerCodegen.java
@@ -1,27 +1,16 @@
package io.swagger.codegen.languages;
-import io.swagger.codegen.CodegenConfig;
-import io.swagger.codegen.CodegenOperation;
-import io.swagger.codegen.CodegenParameter;
-import io.swagger.codegen.CodegenResponse;
-import io.swagger.codegen.CodegenType;
-import io.swagger.codegen.DefaultCodegen;
-import io.swagger.codegen.SupportingFile;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
+import io.swagger.codegen.*;
+import io.swagger.models.Swagger;
+import io.swagger.util.Yaml;
+
+import java.io.File;
+import java.util.*;
+import java.util.Map.Entry;
public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0";
@@ -55,7 +44,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
* Template Location. This is the location which templates will be read from. The generator
* will use the resource stream to attempt to read the templates.
*/
- templateDir = "nodejs";
+ embeddedTemplateDir = templateDir = "nodejs";
/**
* Reserved words. Override this with reserved words specific to your language
@@ -87,7 +76,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
// );
supportingFiles.add(new SupportingFile("swagger.mustache",
"api",
- "swagger.json")
+ "swagger.yaml")
);
supportingFiles.add(new SupportingFile("index.mustache",
"",
@@ -97,6 +86,10 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
"",
"package.json")
);
+ supportingFiles.add(new SupportingFile("README.mustache",
+ "",
+ "README.md")
+ );
if (System.getProperty("noservice") == null) {
apiTemplateFiles.put(
"service.mustache", // the template to use
@@ -242,6 +235,14 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
@Override
public Map postProcessSupportingFileData(Map objs) {
+ Swagger swagger = (Swagger)objs.get("swagger");
+ if(swagger != null) {
+ try {
+ objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ }
for (Map operations : getOperations(objs)) {
@SuppressWarnings("unchecked")
List ops = (List) operations.get("operation");
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java
index ef369169827..4555aa5f216 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java
@@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
@@ -19,6 +20,12 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String CLASS_PREFIX = "classPrefix";
+ public static final String POD_NAME = "podName";
+ public static final String AUTHOR_NAME = "authorName";
+ public static final String AUTHOR_EMAIL = "authorEmail";
+ public static final String GIT_REPO_URL = "gitRepoURL";
+ public static final String LICENSE = "license";
protected Set foundationClasses = new HashSet();
protected String podName = "SwaggerClient";
protected String podVersion = "1.0.0";
@@ -36,7 +43,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
modelTemplateFiles.put("model-body.mustache", ".m");
apiTemplateFiles.put("api-header.mustache", ".h");
apiTemplateFiles.put("api-body.mustache", ".m");
- templateDir = "objc";
+ embeddedTemplateDir = templateDir = "objc";
defaultIncludes.clear();
defaultIncludes.add("bool");
@@ -113,13 +120,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
instantiationTypes.put("map", "NSMutableDictionary");
cliOptions.clear();
- cliOptions.add(new CliOption("classPrefix", "prefix for generated classes (convention: Abbreviation of pod name e.g. `HN` for `HackerNews`), default: `SWG`"));
- cliOptions.add(new CliOption("podName", "cocoapods package name (convention: CameCase), default: `SwaggerClient`"));
- cliOptions.add(new CliOption("podVersion", "cocoapods package version, default: `1.0.0`"));
- cliOptions.add(new CliOption("authorName", "Name to use in the podspec file, default: `Swagger`"));
- cliOptions.add(new CliOption("authorEmail", "Email to use in the podspec file, default: `apiteam@swagger.io`"));
- cliOptions.add(new CliOption("gitRepoURL", "URL for the git repo where this podspec should point to, default: `https://github.com/swagger-api/swagger-codegen`"));
- cliOptions.add(new CliOption("license", "License to use in the podspec file, default: `MIT`"));
+ cliOptions.add(new CliOption(CLASS_PREFIX, "prefix for generated classes (convention: Abbreviation of pod name e.g. `HN` for `HackerNews`).`")
+ .defaultValue("SWG"));
+ cliOptions.add(new CliOption(POD_NAME, "cocoapods package name (convention: CameCase).")
+ .defaultValue("SwaggerClient"));
+ cliOptions.add(new CliOption(CodegenConstants.POD_VERSION, "cocoapods package version.")
+ .defaultValue("1.0.0"));
+ cliOptions.add(new CliOption(AUTHOR_NAME, "Name to use in the podspec file.").defaultValue("Swagger"));
+ cliOptions.add(new CliOption(AUTHOR_EMAIL, "Email to use in the podspec file.").defaultValue("apiteam@swagger.io"));
+ cliOptions.add(new CliOption(GIT_REPO_URL, "URL for the git repo where this podspec should point to.")
+ .defaultValue("https://github.com/swagger-api/swagger-codegen"));
+ cliOptions.add(new CliOption(LICENSE, "License to use in the podspec file.").defaultValue("MIT"));
}
public CodegenType getTag() {
@@ -138,41 +149,41 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("podName")) {
- setPodName((String) additionalProperties.get("podName"));
+ if (additionalProperties.containsKey(POD_NAME)) {
+ setPodName((String) additionalProperties.get(POD_NAME));
}
- if (additionalProperties.containsKey("podVersion")) {
- setPodVersion((String) additionalProperties.get("podVersion"));
+ if (additionalProperties.containsKey(CodegenConstants.POD_VERSION)) {
+ setPodVersion((String) additionalProperties.get(CodegenConstants.POD_VERSION));
}
- if (additionalProperties.containsKey("classPrefix")) {
- setClassPrefix((String) additionalProperties.get("classPrefix"));
+ if (additionalProperties.containsKey(CLASS_PREFIX)) {
+ setClassPrefix((String) additionalProperties.get(CLASS_PREFIX));
}
- if (additionalProperties.containsKey("authorName")) {
- setAuthorName((String) additionalProperties.get("authorName"));
+ if (additionalProperties.containsKey(AUTHOR_NAME)) {
+ setAuthorName((String) additionalProperties.get(AUTHOR_NAME));
}
- if (additionalProperties.containsKey("authorEmail")) {
- setAuthorEmail((String) additionalProperties.get("authorEmail"));
+ if (additionalProperties.containsKey(AUTHOR_EMAIL)) {
+ setAuthorEmail((String) additionalProperties.get(AUTHOR_EMAIL));
}
- if (additionalProperties.containsKey("gitRepoURL")) {
- setGitRepoURL((String) additionalProperties.get("gitRepoURL"));
+ if (additionalProperties.containsKey(GIT_REPO_URL)) {
+ setGitRepoURL((String) additionalProperties.get(GIT_REPO_URL));
}
- if (additionalProperties.containsKey("license")) {
- setLicense((String) additionalProperties.get("license"));
+ if (additionalProperties.containsKey(LICENSE)) {
+ setLicense((String) additionalProperties.get(LICENSE));
}
- additionalProperties.put("podName", podName);
- additionalProperties.put("podVersion", podVersion);
- additionalProperties.put("classPrefix", classPrefix);
- additionalProperties.put("authorName", authorName);
- additionalProperties.put("authorEmail", authorEmail);
- additionalProperties.put("gitRepoURL", gitRepoURL);
- additionalProperties.put("license", license);
+ additionalProperties.put(POD_NAME, podName);
+ additionalProperties.put(CodegenConstants.POD_VERSION, podVersion);
+ additionalProperties.put(CLASS_PREFIX, classPrefix);
+ additionalProperties.put(AUTHOR_NAME, authorName);
+ additionalProperties.put(AUTHOR_EMAIL, authorEmail);
+ additionalProperties.put(GIT_REPO_URL, gitRepoURL);
+ additionalProperties.put(LICENSE, license);
String swaggerFolder = podName;
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java
index d54c44a9bdd..27f39f11ed0 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java
@@ -4,10 +4,11 @@ import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
+import io.swagger.codegen.CodegenConstants;
+import io.swagger.codegen.CliOption;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
-import io.swagger.codegen.CliOption;
import java.io.File;
import java.util.Arrays;
@@ -16,6 +17,8 @@ import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String MODULE_NAME = "moduleName";
+ public static final String MODULE_VERSION = "moduleVersion";
protected String moduleName = "SwaggerClient";
protected String moduleVersion = "1.0.0";
@@ -25,7 +28,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code" + File.separatorChar + "perl";
modelTemplateFiles.put("object.mustache", ".pm");
apiTemplateFiles.put("api.mustache", ".pm");
- templateDir = "perl";
+ embeddedTemplateDir = templateDir = "perl";
reservedWords = new HashSet(
@@ -68,8 +71,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("object", "object");
cliOptions.clear();
- cliOptions.add(new CliOption("moduleName", "perl module name (convention: CamelCase), default: SwaggerClient"));
- cliOptions.add(new CliOption("moduleVersion", "perl module version, default: 1.0.0"));
+ cliOptions.add(new CliOption(MODULE_NAME, "Perl module name (convention: CamelCase).").defaultValue("SwaggerClient"));
+ cliOptions.add(new CliOption(MODULE_VERSION, "Perl module version.").defaultValue("1.0.0"));
+ cliOptions.add(new CliOption(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants.ENSURE_UNIQUE_PARAMS_DESC));
+
}
@@ -77,21 +83,25 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("moduleVersion")) {
- moduleVersion = (String) additionalProperties.get("moduleVersion");
+ if (additionalProperties.containsKey(MODULE_VERSION)) {
+ setModuleVersion((String) additionalProperties.get(MODULE_VERSION));
} else {
- additionalProperties.put("moduleVersion", moduleVersion);
+ additionalProperties.put(MODULE_VERSION, moduleVersion);
}
- if (additionalProperties.containsKey("moduleName")) {
- moduleName = (String) additionalProperties.get("moduleName");
+ if (additionalProperties.containsKey(MODULE_NAME)) {
+ setModuleName((String) additionalProperties.get(MODULE_NAME));
} else {
- additionalProperties.put("moduleName", moduleName);
+ additionalProperties.put(MODULE_NAME, moduleName);
}
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm"));
+ supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiFactory.pm"));
+ supportingFiles.add(new SupportingFile("Role.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Role.pm"));
+ supportingFiles.add(new SupportingFile("AutoDoc.mustache", ("lib/WWW/" + moduleName + "/Role").replace('/', File.separatorChar), "AutoDoc.pm"));
+ supportingFiles.add(new SupportingFile("autodoc.script.mustache", ("bin/").replace('/', File.separatorChar), "autodoc"));
}
public CodegenType getTag() {
@@ -229,5 +239,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
return underscore(operationId);
}
+ public void setModuleName(String moduleName) {
+ this.moduleName = moduleName;
+ }
+ public void setModuleVersion(String moduleVersion) {
+ this.moduleVersion = moduleVersion;
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java
index 538a5c494a6..5b22fbdbadb 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java
@@ -19,6 +19,11 @@ import java.util.HashSet;
import org.apache.commons.lang3.StringUtils;
public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String VARIABLE_NAMING_CONVENTION = "variableNamingConvention";
+ public static final String PACKAGE_PATH = "packagePath";
+ public static final String SRC_BASE_PATH = "srcBasePath";
+ public static final String COMPOSER_VENDOR_NAME = "composerVendorName";
+ public static final String COMPOSER_PROJECT_NAME = "composerProjectName";
protected String invokerPackage = "Swagger\\Client";
protected String composerVendorName = "swagger";
protected String composerProjectName = "swagger-client";
@@ -33,7 +38,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code" + File.separator + "php";
modelTemplateFiles.put("model.mustache", ".php");
apiTemplateFiles.put("api.mustache", ".php");
- templateDir = "php";
+ embeddedTemplateDir = templateDir = "php";
apiPackage = invokerPackage + "\\Api";
modelPackage = invokerPackage + "\\Model";
@@ -86,12 +91,15 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("object", "object");
typeMapping.put("DateTime", "\\DateTime");
- cliOptions.add(new CliOption("variableNamingConvention", "naming convention of variable name, e.g. camelCase. Default: snake_case"));
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
+ cliOptions.add(new CliOption(VARIABLE_NAMING_CONVENTION, "naming convention of variable name, e.g. camelCase.")
+ .defaultValue("snake_case"));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay\\Pets"));
- cliOptions.add(new CliOption("packagePath", "The main package name for classes. e.g. GeneratedPetstore"));
- cliOptions.add(new CliOption("srcBasePath", "The directory under packagePath to serve as source root."));
- cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets"));
- cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client"));
+ cliOptions.add(new CliOption(PACKAGE_PATH, "The main package name for classes. e.g. GeneratedPetstore"));
+ cliOptions.add(new CliOption(SRC_BASE_PATH, "The directory under packagePath to serve as source root."));
+ cliOptions.add(new CliOption(COMPOSER_VENDOR_NAME, "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets"));
+ cliOptions.add(new CliOption(COMPOSER_PROJECT_NAME, "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client"));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "The version to use in the composer package version field. e.g. 1.2.3"));
}
@@ -144,16 +152,16 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("packagePath")) {
- this.setPackagePath((String) additionalProperties.get("packagePath"));
+ if (additionalProperties.containsKey(PACKAGE_PATH)) {
+ this.setPackagePath((String) additionalProperties.get(PACKAGE_PATH));
} else {
- additionalProperties.put("packagePath", packagePath);
+ additionalProperties.put(PACKAGE_PATH, packagePath);
}
- if (additionalProperties.containsKey("srcBasePath")) {
- this.setSrcBasePath((String) additionalProperties.get("srcBasePath"));
+ if (additionalProperties.containsKey(SRC_BASE_PATH)) {
+ this.setSrcBasePath((String) additionalProperties.get(SRC_BASE_PATH));
} else {
- additionalProperties.put("srcBasePath", srcBasePath);
+ additionalProperties.put(SRC_BASE_PATH, srcBasePath);
}
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
@@ -162,28 +170,24 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
}
- if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
- this.setModelPackage((String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE));
- } else {
+ if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
}
- if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
- this.setApiPackage((String) additionalProperties.get(CodegenConstants.API_PACKAGE));
- } else {
+ if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
}
- if (additionalProperties.containsKey("composerProjectName")) {
- this.setComposerProjectName((String) additionalProperties.get("composerProjectName"));
+ if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
+ this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
} else {
- additionalProperties.put("composerProjectName", composerProjectName);
+ additionalProperties.put(COMPOSER_PROJECT_NAME, composerProjectName);
}
- if (additionalProperties.containsKey("composerVendorName")) {
- this.setComposerVendorName((String) additionalProperties.get("composerVendorName"));
+ if (additionalProperties.containsKey(COMPOSER_VENDOR_NAME)) {
+ this.setComposerVendorName((String) additionalProperties.get(COMPOSER_VENDOR_NAME));
} else {
- additionalProperties.put("composerVendorName", composerVendorName);
+ additionalProperties.put(COMPOSER_VENDOR_NAME, composerVendorName);
}
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
@@ -191,6 +195,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
} else {
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
}
+
+ if (additionalProperties.containsKey(VARIABLE_NAMING_CONVENTION)) {
+ this.setParameterNamingConvention((String) additionalProperties.get(VARIABLE_NAMING_CONVENTION));
+ }
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
@@ -286,7 +294,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
this.variableNamingConvention = variableNamingConvention;
}
- private void setComposerVendorName(String composerVendorName) {
+ public void setComposerVendorName(String composerVendorName) {
this.composerVendorName = composerVendorName;
}
@@ -296,10 +304,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toVarName(String name) {
- if (additionalProperties.containsKey("variableNamingConvention")) {
- this.setParameterNamingConvention((String) additionalProperties.get("variableNamingConvention"));
- }
-
// sanitize name
name = sanitizeName(name);
@@ -333,6 +337,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
// Note: backslash ("\\") is allowed for e.g. "\\DateTime"
name = name.replaceAll("[^\\w\\\\]+", "_");
+ // remove dollar sign
+ name = name.replaceAll("$", "");
+
// model name cannot use reserved keyword
if (reservedWords.contains(name)) {
escapeReservedWord(name); // e.g. return => _return
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java
index 6d9982cf78c..1759e515258 100755
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java
@@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
@@ -27,7 +28,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
outputFolder = "generated-code" + File.separatorChar + "python";
modelTemplateFiles.put("model.mustache", ".py");
apiTemplateFiles.put("api.mustache", ".py");
- templateDir = "python";
+ embeddedTemplateDir = templateDir = "python";
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("int");
@@ -62,30 +63,33 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
"return", "def", "for", "lambda", "try"));
cliOptions.clear();
- cliOptions.add(new CliOption("packageName", "python package name (convention: snake_case), default: swagger_client"));
- cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0"));
+ cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "python package name (convention: snake_case).")
+ .defaultValue("swagger_client"));
+ cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "python package version.")
+ .defaultValue("1.0.0"));
+ cliOptions.add(new CliOption(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC));
}
@Override
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("packageName")) {
- setPackageName((String) additionalProperties.get("packageName"));
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
+ setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
}
else {
setPackageName("swagger_client");
}
- if (additionalProperties.containsKey("packageVersion")) {
- setPackageVersion((String) additionalProperties.get("packageVersion"));
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
+ setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
}
else {
setPackageVersion("1.0.0");
}
- additionalProperties.put("packageName", packageName);
- additionalProperties.put("packageVersion", packageVersion);
+ additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
+ additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
String swaggerFolder = packageName;
@@ -171,6 +175,9 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
// sanitize name
name = sanitizeName(name);
+ // remove dollar sign
+ name = name.replaceAll("$", "");
+
// if it's all uppper case, convert to lower case
if (name.matches("^[A-Z_]*$")) {
name = name.toLowerCase();
@@ -201,6 +208,9 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
public String toModelName(String name) {
name = sanitizeName(name);
+ // remove dollar sign
+ name = name.replaceAll("$", "");
+
// 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");
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Qt5CPPGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Qt5CPPGenerator.java
index ff58dbd9440..2abff5515b0 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Qt5CPPGenerator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Qt5CPPGenerator.java
@@ -71,7 +71,7 @@ public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig {
* Template Location. This is the location which templates will be read from. The generator
* will use the resource stream to attempt to read the templates.
*/
- templateDir = "qt5cpp";
+ embeddedTemplateDir = templateDir = "qt5cpp";
/**
* Reserved words. Override this with reserved words specific to your language
@@ -97,7 +97,9 @@ public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig {
Arrays.asList(
"bool",
"qint32",
- "qint64")
+ "qint64",
+ "float",
+ "double")
);
supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder, PREFIX + "Helpers.h"));
@@ -321,4 +323,4 @@ public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig {
public String toApiName(String type) {
return PREFIX + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java
index 4aac683b6ef..f30b2ef8b85 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java
@@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
@@ -12,10 +13,14 @@ import io.swagger.models.properties.Property;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.Iterator;
import org.apache.commons.lang.StringUtils;
public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
+ public static final String GEM_NAME = "gemName";
+ public static final String MODULE_NAME = "moduleName";
+ public static final String GEM_VERSION = "gemVersion";
protected String gemName = null;
protected String moduleName = null;
protected String gemVersion = "1.0.0";
@@ -28,7 +33,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code" + File.separator + "ruby";
modelTemplateFiles.put("model.mustache", ".rb");
apiTemplateFiles.put("api.mustache", ".rb");
- templateDir = "ruby";
+ embeddedTemplateDir = templateDir = "ruby";
typeMapping.clear();
languageSpecificPrimitives.clear();
@@ -67,21 +72,30 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("file", "File");
// remove modelPackage and apiPackage added by default
- cliOptions.clear();
- cliOptions.add(new CliOption("gemName", "gem name (convention: underscore_case), default: swagger_client"));
- cliOptions.add(new CliOption("moduleName", "top module name (convention: CamelCase, usually corresponding to gem name), default: SwaggerClient"));
- cliOptions.add(new CliOption("gemVersion", "gem version, default: 1.0.0"));
+ Iterator itr = cliOptions.iterator();
+ while (itr.hasNext()) {
+ CliOption opt = itr.next();
+ if (CodegenConstants.MODEL_PACKAGE.equals(opt.getOpt()) ||
+ CodegenConstants.API_PACKAGE.equals(opt.getOpt())) {
+ itr.remove();
+ }
+ }
+ cliOptions.add(new CliOption(GEM_NAME, "gem name (convention: underscore_case).").
+ defaultValue("swagger_client"));
+ cliOptions.add(new CliOption(MODULE_NAME, "top module name (convention: CamelCase, usually corresponding" +
+ " to gem name).").defaultValue("SwaggerClient"));
+ cliOptions.add(new CliOption(GEM_VERSION, "gem version.").defaultValue("1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("gemName")) {
- setGemName((String) additionalProperties.get("gemName"));
+ if (additionalProperties.containsKey(GEM_NAME)) {
+ setGemName((String) additionalProperties.get(GEM_NAME));
}
- if (additionalProperties.containsKey("moduleName")) {
- setModuleName((String) additionalProperties.get("moduleName"));
+ if (additionalProperties.containsKey(MODULE_NAME)) {
+ setModuleName((String) additionalProperties.get(MODULE_NAME));
}
if (gemName == null && moduleName == null) {
@@ -93,14 +107,14 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
setModuleName(generateModuleName(gemName));
}
- additionalProperties.put("gemName", gemName);
- additionalProperties.put("moduleName", moduleName);
+ additionalProperties.put(GEM_NAME, gemName);
+ additionalProperties.put(MODULE_NAME, moduleName);
- if (additionalProperties.containsKey("gemVersion")) {
- setGemVersion((String) additionalProperties.get("gemVersion"));
+ if (additionalProperties.containsKey(GEM_VERSION)) {
+ setGemVersion((String) additionalProperties.get(GEM_VERSION));
} else {
// not set, pass the default value to template
- additionalProperties.put("gemVersion", gemVersion);
+ additionalProperties.put(GEM_VERSION, gemVersion);
}
// use constant model/api package (folder path)
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java
index 003be5ab950..b2f5b9571dd 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java
@@ -1,5 +1,6 @@
package io.swagger.codegen.languages;
+import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
@@ -42,7 +43,7 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
outputFolder = "generated-code/scala";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
- templateDir = "scala";
+ embeddedTemplateDir = templateDir = "scala";
apiPackage = "io.swagger.client.api";
modelPackage = "io.swagger.client.model";
@@ -106,6 +107,9 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
);
instantiationTypes.put("array", "ListBuffer");
instantiationTypes.put("map", "HashMap");
+
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
public CodegenType getTag() {
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalatraServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalatraServerCodegen.java
index 9bab6a6cad0..d50fa867887 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalatraServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalatraServerCodegen.java
@@ -1,5 +1,6 @@
package io.swagger.codegen.languages;
+import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenOperation;
@@ -29,7 +30,7 @@ public class ScalatraServerCodegen extends DefaultCodegen implements CodegenConf
outputFolder = "generated-code/scalatra";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
- templateDir = "scalatra";
+ embeddedTemplateDir = templateDir = "scalatra";
apiPackage = "com.wordnik.client.api";
modelPackage = "com.wordnik.client.model";
@@ -117,6 +118,9 @@ public class ScalatraServerCodegen extends DefaultCodegen implements CodegenConf
importMapping.put("LocalDateTime", "org.joda.time.LocalDateTime");
importMapping.put("LocalDate", "org.joda.time.LocalDate");
importMapping.put("LocalTime", "org.joda.time.LocalTime");
+
+ cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
+ cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
public CodegenType getTag() {
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java
index e25aae15976..2e35f412bbf 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java
@@ -35,7 +35,7 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
modelTemplateFiles.clear();
apiTemplateFiles.clear();
- templateDir = "silex";
+ embeddedTemplateDir = templateDir = "silex";
reservedWords = new HashSet(
Arrays.asList(
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java
index c9d8e550b5d..9bcece87429 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java
@@ -29,7 +29,7 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi
// no model
modelTemplateFiles.clear();
apiTemplateFiles.put("api.mustache", ".rb");
- templateDir = "sinatra";
+ embeddedTemplateDir = templateDir = "sinatra";
typeMapping.clear();
languageSpecificPrimitives.clear();
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringMVCServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringMVCServerCodegen.java
index 30d10073268..446185bcd47 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringMVCServerCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringMVCServerCodegen.java
@@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Iterator;
public class SpringMVCServerCodegen extends JavaClientCodegen implements CodegenConfig {
+ public static final String CONFIG_PACKAGE = "configPackage";
protected String title = "Petstore Server";
protected String configPackage = "";
@@ -23,7 +24,7 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
outputFolder = "generated-code/javaSpringMVC";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
- templateDir = "JavaSpringMVC";
+ embeddedTemplateDir = templateDir = "JavaSpringMVC";
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";
configPackage = "io.swagger.configuration";
@@ -36,7 +37,7 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
additionalProperties.put("title", title);
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
- additionalProperties.put("configPackage", configPackage);
+ additionalProperties.put(CONFIG_PACKAGE, configPackage);
languageSpecificPrimitives = new HashSet(
Arrays.asList(
@@ -49,8 +50,7 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
"Float")
);
- cliOptions.add(new CliOption("configPackage", "configuration package for generated code"));
-
+ cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code"));
}
public CodegenType getTag() {
@@ -69,8 +69,8 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
public void processOpts() {
super.processOpts();
- if (additionalProperties.containsKey("configPackage")) {
- this.setConfigPackage((String) additionalProperties.get("configPackage"));
+ if (additionalProperties.containsKey(CONFIG_PACKAGE)) {
+ this.setConfigPackage((String) additionalProperties.get(CONFIG_PACKAGE));
}
supportingFiles.clear();
@@ -193,6 +193,17 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
String _import = iterator.next().get("import");
if (_import.endsWith(".Object")) iterator.remove();
}
+ List models = (List) objs.get("models");
+ for (Object _mo : models) {
+ Map mo = (Map) _mo;
+ CodegenModel cm = (CodegenModel) mo.get("model");
+ 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;
}
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticDocCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticDocCodegen.java
index c0ccf2a0a6f..b27ba23a4cd 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticDocCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticDocCodegen.java
@@ -20,7 +20,7 @@ public class StaticDocCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "docs";
modelTemplateFiles.put("model.mustache", ".html");
apiTemplateFiles.put("operation.mustache", ".html");
- templateDir = "swagger-static";
+ embeddedTemplateDir = templateDir = "swagger-static";
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticHtmlGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticHtmlGenerator.java
index 29cb5d55eaa..a86c2244995 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticHtmlGenerator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/StaticHtmlGenerator.java
@@ -28,7 +28,7 @@ public class StaticHtmlGenerator extends DefaultCodegen implements CodegenConfig
public StaticHtmlGenerator() {
super();
outputFolder = "docs";
- templateDir = "htmlDocs";
+ embeddedTemplateDir = templateDir = "htmlDocs";
defaultIncludes = new HashSet();
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerGenerator.java
index 94f6279f46f..3241dde7b92 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerGenerator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerGenerator.java
@@ -13,7 +13,7 @@ import java.io.File;
public class SwaggerGenerator extends DefaultCodegen implements CodegenConfig {
public SwaggerGenerator() {
super();
- templateDir = "swagger";
+ embeddedTemplateDir = templateDir = "swagger";
outputFolder = "generated-code/swagger";
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerYamlGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerYamlGenerator.java
index 35874390e0f..8ee1440b17e 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerYamlGenerator.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwaggerYamlGenerator.java
@@ -13,7 +13,7 @@ import java.io.File;
public class SwaggerYamlGenerator extends DefaultCodegen implements CodegenConfig {
public SwaggerYamlGenerator() {
super();
- templateDir = "swagger";
+ embeddedTemplateDir = templateDir = "swagger";
outputFolder = "generated-code/swagger";
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java
index db0b0fc24eb..fffd3aa2aae 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java
@@ -24,13 +24,26 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
- private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
+ public static final String PROJECT_NAME = "projectName";
+ public static final String RESPONSE_AS = "responseAs";
+ public static final String UNWRAP_REQUIRED = "unwrapRequired";
+ public static final String POD_SOURCE = "podSource";
+ public static final String POD_AUTHORS = "podAuthors";
+ public static final String POD_SOCIAL_MEDIA_URL = "podSocialMediaURL";
+ public static final String POD_DOCSET_URL = "podDocsetURL";
+ public static final String POD_LICENSE = "podLicense";
+ public static final String POD_HOMEPAGE = "podHomepage";
+ public static final String POD_SUMMARY = "podSummary";
+ public static final String POD_DESCRIPTION = "podDescription";
+ public static final String POD_SCREENSHOTS = "podScreenshots";
+ public static final String POD_DOCUMENTATION_URL = "podDocumentationURL";
protected static final String LIBRARY_PROMISE_KIT = "PromiseKit";
protected static final String[] RESPONSE_LIBRARIES = { LIBRARY_PROMISE_KIT };
protected String projectName = "SwaggerClient";
protected boolean unwrapRequired = false;
protected String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "Swaggers";
+ private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
public CodegenType getTag() {
return CodegenType.CLIENT;
@@ -49,7 +62,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code" + File.separator + "swift";
modelTemplateFiles.put("model.mustache", ".swift");
apiTemplateFiles.put("api.mustache", ".swift");
- templateDir = "swift";
+ embeddedTemplateDir = templateDir = "swift";
apiPackage = File.separator + "APIs";
modelPackage = File.separator + "Models";
@@ -107,22 +120,22 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
importMapping = new HashMap();
- cliOptions.add(new CliOption("projectName", "Project name in Xcode"));
- cliOptions.add(new CliOption("responseAs", "Optionally use libraries to manage response. Currently " +
+ cliOptions.add(new CliOption(PROJECT_NAME, "Project name in Xcode"));
+ cliOptions.add(new CliOption(RESPONSE_AS, "Optionally use libraries to manage response. Currently " +
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
- cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " +
+ cliOptions.add(new CliOption(UNWRAP_REQUIRED, "Treat 'required' properties in response as non-optional " +
"(which would crash the app if api returns null as opposed to required option specified in json schema"));
- cliOptions.add(new CliOption("podSource", "Source information used for Podspec"));
- cliOptions.add(new CliOption("podVersion", "Version used for Podspec"));
- cliOptions.add(new CliOption("podAuthors", "Authors used for Podspec"));
- cliOptions.add(new CliOption("podSocialMediaURL", "Social Media URL used for Podspec"));
- cliOptions.add(new CliOption("podDocsetURL", "Docset URL used for Podspec"));
- cliOptions.add(new CliOption("podLicense", "License used for Podspec"));
- cliOptions.add(new CliOption("podHomepage", "Homepage used for Podspec"));
- cliOptions.add(new CliOption("podSummary", "Summary used for Podspec"));
- cliOptions.add(new CliOption("podDescription", "Description used for Podspec"));
- cliOptions.add(new CliOption("podScreenshots", "Screenshots used for Podspec"));
- cliOptions.add(new CliOption("podDocumentationURL", "Documentation URL used for Podspec"));
+ cliOptions.add(new CliOption(POD_SOURCE, "Source information used for Podspec"));
+ cliOptions.add(new CliOption(CodegenConstants.POD_VERSION, "Version used for Podspec"));
+ cliOptions.add(new CliOption(POD_AUTHORS, "Authors used for Podspec"));
+ cliOptions.add(new CliOption(POD_SOCIAL_MEDIA_URL, "Social Media URL used for Podspec"));
+ cliOptions.add(new CliOption(POD_DOCSET_URL, "Docset URL used for Podspec"));
+ cliOptions.add(new CliOption(POD_LICENSE, "License used for Podspec"));
+ cliOptions.add(new CliOption(POD_HOMEPAGE, "Homepage used for Podspec"));
+ cliOptions.add(new CliOption(POD_SUMMARY, "Summary used for Podspec"));
+ cliOptions.add(new CliOption(POD_DESCRIPTION, "Description used for Podspec"));
+ cliOptions.add(new CliOption(POD_SCREENSHOTS, "Screenshots used for Podspec"));
+ cliOptions.add(new CliOption(POD_DOCUMENTATION_URL, "Documentation URL used for Podspec"));
}
@Override
@@ -130,29 +143,29 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
super.processOpts();
// Setup project name
- if (additionalProperties.containsKey("projectName")) {
- projectName = (String) additionalProperties.get("projectName");
+ if (additionalProperties.containsKey(PROJECT_NAME)) {
+ setProjectName((String) additionalProperties.get(PROJECT_NAME));
} else {
- additionalProperties.put("projectName", projectName);
+ additionalProperties.put(PROJECT_NAME, projectName);
}
sourceFolder = projectName + File.separator + sourceFolder;
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
- if (additionalProperties.containsKey("unwrapRequired")) {
- unwrapRequired = Boolean.parseBoolean(String.valueOf(additionalProperties.get("unwrapRequired")));
+ if (additionalProperties.containsKey(UNWRAP_REQUIRED)) {
+ setUnwrapRequired(Boolean.parseBoolean(String.valueOf(additionalProperties.get(UNWRAP_REQUIRED))));
}
- additionalProperties.put("unwrapRequired", unwrapRequired);
+ additionalProperties.put(UNWRAP_REQUIRED, unwrapRequired);
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
- if (additionalProperties.containsKey("responseAs")) {
- Object responseAsObject = additionalProperties.get("responseAs");
+ if (additionalProperties.containsKey(RESPONSE_AS)) {
+ Object responseAsObject = additionalProperties.get(RESPONSE_AS);
if (responseAsObject instanceof String) {
- responseAs = ((String)responseAsObject).split(",");
+ setResponseAs(((String)responseAsObject).split(","));
} else {
- responseAs = (String[]) responseAsObject;
+ setResponseAs((String[]) responseAsObject);
}
}
- additionalProperties.put("responseAs", responseAs);
+ additionalProperties.put(RESPONSE_AS, responseAs);
if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) {
additionalProperties.put("usePromiseKit", true);
}
@@ -308,4 +321,16 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
return builder.toString();
}
+
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+ public void setUnwrapRequired(boolean unwrapRequired) {
+ this.unwrapRequired = unwrapRequired;
+ }
+
+ public void setResponseAs(String[] responseAs) {
+ this.responseAs = responseAs;
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TizenClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TizenClientCodegen.java
index 7dc0b8ec3bd..8efb5276cff 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TizenClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TizenClientCodegen.java
@@ -40,7 +40,7 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
modelTemplateFiles.put("model-body.mustache", ".cpp");
apiTemplateFiles.put("api-header.mustache", ".h");
apiTemplateFiles.put("api-body.mustache", ".cpp");
- templateDir = "tizen";
+ embeddedTemplateDir = templateDir = "tizen";
modelPackage = "";
defaultIncludes = new HashSet(
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java
index d145760d2cc..6c9b615476d 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java
@@ -4,7 +4,7 @@ import io.swagger.codegen.SupportingFile;
import java.io.File;
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
-
+
@Override
public String getName() {
return "typescript-angular";
@@ -19,7 +19,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
outputFolder = "generated-code/typescript-angular";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
- templateDir = "TypeScript-Angular";
+ embeddedTemplateDir = templateDir = "TypeScript-Angular";
apiPackage = "API.Client";
modelPackage = "API.Client";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java
index b92598b1fb6..b4de0f7ed0c 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java
@@ -17,7 +17,7 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen
public TypeScriptNodeClientCodegen() {
super();
outputFolder = "generated-code/typescript-node";
- templateDir = "TypeScript-node";
+ embeddedTemplateDir = templateDir = "TypeScript-node";
supportingFiles.add(new SupportingFile("api.mustache", null, "api.ts"));
}
diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache
index 18d27ede7c3..91d1eb93daf 100644
--- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache
@@ -55,13 +55,15 @@ public class ApiClient {
private DateFormat dateFormat;
public ApiClient() {
- // Use ISO 8601 format for date and datetime.
- // See https://en.wikipedia.org/wiki/ISO_8601
- this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ // 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.json.setDateFormat((DateFormat) dateFormat.clone());
+
// Set default User-Agent.
setUserAgent("Java-Swagger");
@@ -74,6 +76,13 @@ public class ApiClient {
authentications = Collections.unmodifiableMap(authentications);
}
+ /**
+ * Gets the JSON instance to do JSON serialization and deserialization.
+ */
+ public JSON getJSON() {
+ return json;
+ }
+
public String getBasePath() {
return basePath;
}
@@ -166,6 +175,19 @@ public class ApiClient {
throw new RuntimeException("No API key authentication configured!");
}
+ /**
+ * Helper method to set access token for the first OAuth2 authentication.
+ */
+ public void setAccessToken(String accessToken) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof OAuth) {
+ ((OAuth) auth).setAccessToken(accessToken);
+ return;
+ }
+ }
+ throw new RuntimeException("No OAuth2 authentication configured!");
+ }
+
/**
* Set the User-Agent header's value (by adding to the default header map).
*/
@@ -214,6 +236,8 @@ public class ApiClient {
*/
public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
+ // also set the date format for model (de)serialization with Date properties
+ this.json.setDateFormat((DateFormat) dateFormat.clone());
return this;
}
diff --git a/modules/swagger-codegen/src/main/resources/Java/JSON.mustache b/modules/swagger-codegen/src/main/resources/Java/JSON.mustache
index 43b38f6e21d..54faed8dcb3 100644
--- a/modules/swagger-codegen/src/main/resources/Java/JSON.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/JSON.mustache
@@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.joda.*;
+import java.text.DateFormat;
+
import java.io.IOException;
{{>generatedAnnotation}}
@@ -20,6 +22,13 @@ public class JSON {
mapper.registerModule(new JodaModule());
}
+ /**
+ * Set the date format for JSON (de)serialization with Date properties.
+ */
+ public void setDateFormat(DateFormat dateFormat) {
+ mapper.setDateFormat(dateFormat);
+ }
+
/**
* Serialize the given Java object into JSON string.
*/
diff --git a/modules/swagger-codegen/src/main/resources/Java/README.mustache b/modules/swagger-codegen/src/main/resources/Java/README.mustache
new file mode 100644
index 00000000000..7ce9bac3ca0
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/README.mustache
@@ -0,0 +1,43 @@
+# {{artifactId}}
+
+## Requirements
+
+Building the API client library requires [Maven](https://maven.apache.org/) to be installed.
+
+## Installation & Usage
+
+To install the API client library to your local Maven repository, simply execute:
+
+```shell
+mvn install
+```
+
+To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
+
+```shell
+mvn deploy
+```
+
+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*:
+
+```xml
+
+ {{groupId}}
+ {{artifactId}}
+ {{artifactVersion}}
+ compile
+
+
+```
+
+## Recommendation
+
+It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issue.
+
+## Author
+
+{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
+{{/hasMore}}{{/apis}}{{/apiInfo}}
+
diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache
index 08d28ebd51b..3ac280b2d70 100644
--- a/modules/swagger-codegen/src/main/resources/Java/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache
@@ -64,7 +64,7 @@ public class {{classname}} {
{{/queryParams}}
{{#headerParams}}if ({{paramName}} != null)
- {{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));
+ {{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));
{{/headerParams}}
{{#formParams}}if ({{paramName}} != null)
diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache
index a1f1b6a827c..902f54a2e3a 100644
--- a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache
@@ -7,8 +7,20 @@ import java.util.List;
{{>generatedAnnotation}}
public class OAuth implements Authentication {
+ private String accessToken;
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
@Override
public void applyToParams(List queryParams, Map headerParams) {
- // TODO: support oauth
+ if (accessToken != null) {
+ headerParams.put("Authorization", "Bearer " + accessToken);
+ }
}
}
diff --git a/modules/swagger-codegen/src/main/resources/Java/build.gradle.mustache b/modules/swagger-codegen/src/main/resources/Java/build.gradle.mustache
index 971dcd816a4..2725cbe1f86 100644
--- a/modules/swagger-codegen/src/main/resources/Java/build.gradle.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/build.gradle.mustache
@@ -18,72 +18,76 @@ repositories {
if(hasProperty('target') && target == 'android') {
- apply plugin: 'com.android.library'
- apply plugin: 'com.github.dcendents.android-maven'
-
- android {
- compileSdkVersion 22
- buildToolsVersion '22.0.0'
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 22
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
- // Rename the aar correctly
- libraryVariants.all { variant ->
- variant.outputs.each { output ->
- def outputFile = output.outputFile
- if (outputFile != null && outputFile.name.endsWith('.aar')) {
- def fileName = "${project.name}-${variant.baseName}-${version}.aar"
- output.outputFile = new File(outputFile.parent, fileName)
- }
- }
- }
- }
-
- afterEvaluate {
- android.libraryVariants.all { variant ->
- def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
- task.description = "Create jar artifact for ${variant.name}"
- task.dependsOn variant.javaCompile
- task.from variant.javaCompile.destinationDir
- task.destinationDir = project.file("${project.buildDir}/outputs/jar")
- task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
- artifacts.add('archives', task);
- }
- }
-
- task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
- }
-
- artifacts {
- archives sourcesJar
- }
+ apply plugin: 'com.android.library'
+ apply plugin: 'com.github.dcendents.android-maven'
+
+ android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.0'
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 22
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ // Rename the aar correctly
+ libraryVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = output.outputFile
+ if (outputFile != null && outputFile.name.endsWith('.aar')) {
+ def fileName = "${project.name}-${variant.baseName}-${version}.aar"
+ output.outputFile = new File(outputFile.parent, fileName)
+ }
+ }
+ }
+
+ dependencies {
+ provided 'javax.annotation:jsr250-api:1.0'
+ }
+ }
+
+ afterEvaluate {
+ android.libraryVariants.all { variant ->
+ def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
+ task.description = "Create jar artifact for ${variant.name}"
+ task.dependsOn variant.javaCompile
+ task.from variant.javaCompile.destinationDir
+ task.destinationDir = project.file("${project.buildDir}/outputs/jar")
+ task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
+ artifacts.add('archives', task);
+ }
+ }
+
+ task sourcesJar(type: Jar) {
+ from android.sourceSets.main.java.srcDirs
+ classifier = 'sources'
+ }
+
+ artifacts {
+ archives sourcesJar
+ }
} else {
- apply plugin: 'java'
- apply plugin: 'maven'
-
- sourceCompatibility = JavaVersion.VERSION_1_7
- targetCompatibility = JavaVersion.VERSION_1_7
-
- install {
- repositories.mavenInstaller {
- pom.artifactId = '{{artifactId}}'
- }
- }
-
- task execute(type:JavaExec) {
- main = System.getProperty('mainClass')
- classpath = sourceSets.main.runtimeClasspath
- }
+ apply plugin: 'java'
+ apply plugin: 'maven'
+
+ sourceCompatibility = JavaVersion.VERSION_1_7
+ targetCompatibility = JavaVersion.VERSION_1_7
+
+ install {
+ repositories.mavenInstaller {
+ pom.artifactId = '{{artifactId}}'
+ }
+ }
+
+ task execute(type:JavaExec) {
+ main = System.getProperty('mainClass')
+ classpath = sourceSets.main.runtimeClasspath
+ }
}
ext {
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache
index fffd5fc824f..bd64a6fe659 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache
@@ -45,6 +45,7 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
+ private Client client;
private Map hostMap = new HashMap();
private Map defaultHeaderMap = new HashMap();
private boolean debugging = false;
@@ -59,16 +60,20 @@ public class ApiClient {
private DateFormat dateFormat;
public ApiClient() {
- // Use ISO 8601 format for date and datetime.
- // See https://en.wikipedia.org/wiki/ISO_8601
- this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ // 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.json.setDateFormat((DateFormat) dateFormat.clone());
+
// Set default User-Agent.
setUserAgent("Java-Swagger");
+ buildClient();
+
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap();{{#authMethods}}{{#isBasic}}
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
@@ -78,6 +83,13 @@ public class ApiClient {
authentications = Collections.unmodifiableMap(authentications);
}
+ /**
+ * Gets the JSON instance to do JSON serialization and deserialization.
+ */
+ public JSON getJSON() {
+ return json;
+ }
+
public String getBasePath() {
return basePath;
}
@@ -170,6 +182,19 @@ public class ApiClient {
throw new RuntimeException("No API key authentication configured!");
}
+ /**
+ * Helper method to set access token for the first OAuth2 authentication.
+ */
+ public void setAccessToken(String accessToken) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof OAuth) {
+ ((OAuth) auth).setAccessToken(accessToken);
+ return;
+ }
+ }
+ throw new RuntimeException("No OAuth2 authentication configured!");
+ }
+
/**
* Set the User-Agent header's value (by adding to the default header map).
*/
@@ -203,6 +228,7 @@ public class ApiClient {
*/
public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging;
+ buildClient();
return this;
}
@@ -218,6 +244,8 @@ public class ApiClient {
*/
public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
+ // also set the date format for model (de)serialization with Date properties
+ this.json.setDateFormat((DateFormat) dateFormat.clone());
return this;
}
@@ -419,13 +447,6 @@ public class ApiClient {
public T invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames, TypeRef returnType) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);
- final ClientConfig clientConfig = new ClientConfig();
- clientConfig.register(MultiPartFeature.class);
- if (debugging) {
- clientConfig.register(LoggingFilter.class);
- }
- Client client = ClientBuilder.newClient(clientConfig);
-
WebTarget target = client.target(this.basePath).path(path);
if (queryParams != null) {
@@ -537,6 +558,15 @@ public class ApiClient {
}
}
+ private void buildClient() {
+ final ClientConfig clientConfig = new ClientConfig();
+ clientConfig.register(MultiPartFeature.class);
+ if (debugging) {
+ clientConfig.register(LoggingFilter.class);
+ }
+ this.client = ClientBuilder.newClient(clientConfig);
+ }
+
private Map> buildResponseHeaders(Response response) {
Map> responseHeaders = new HashMap>();
for (Entry> entry: response.getHeaders().entrySet()) {
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/build.gradle.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/build.gradle.mustache
index 548c1854e5e..09262af0d63 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/build.gradle.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/build.gradle.mustache
@@ -18,72 +18,76 @@ repositories {
if(hasProperty('target') && target == 'android') {
- apply plugin: 'com.android.library'
- apply plugin: 'com.github.dcendents.android-maven'
-
- android {
- compileSdkVersion 22
- buildToolsVersion '22.0.0'
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 22
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
- // Rename the aar correctly
- libraryVariants.all { variant ->
- variant.outputs.each { output ->
- def outputFile = output.outputFile
- if (outputFile != null && outputFile.name.endsWith('.aar')) {
- def fileName = "${project.name}-${variant.baseName}-${version}.aar"
- output.outputFile = new File(outputFile.parent, fileName)
- }
- }
- }
- }
-
- afterEvaluate {
- android.libraryVariants.all { variant ->
- def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
- task.description = "Create jar artifact for ${variant.name}"
- task.dependsOn variant.javaCompile
- task.from variant.javaCompile.destinationDir
- task.destinationDir = project.file("${project.buildDir}/outputs/jar")
- task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
- artifacts.add('archives', task);
- }
- }
-
- task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
- }
-
- artifacts {
- archives sourcesJar
- }
+ apply plugin: 'com.android.library'
+ apply plugin: 'com.github.dcendents.android-maven'
+
+ android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.0'
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 22
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ // Rename the aar correctly
+ libraryVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = output.outputFile
+ if (outputFile != null && outputFile.name.endsWith('.aar')) {
+ def fileName = "${project.name}-${variant.baseName}-${version}.aar"
+ output.outputFile = new File(outputFile.parent, fileName)
+ }
+ }
+ }
+
+ dependencies {
+ provided 'javax.annotation:jsr250-api:1.0'
+ }
+ }
+
+ afterEvaluate {
+ android.libraryVariants.all { variant ->
+ def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
+ task.description = "Create jar artifact for ${variant.name}"
+ task.dependsOn variant.javaCompile
+ task.from variant.javaCompile.destinationDir
+ task.destinationDir = project.file("${project.buildDir}/outputs/jar")
+ task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
+ artifacts.add('archives', task);
+ }
+ }
+
+ task sourcesJar(type: Jar) {
+ from android.sourceSets.main.java.srcDirs
+ classifier = 'sources'
+ }
+
+ artifacts {
+ archives sourcesJar
+ }
} else {
- apply plugin: 'java'
- apply plugin: 'maven'
-
- sourceCompatibility = JavaVersion.VERSION_1_7
- targetCompatibility = JavaVersion.VERSION_1_7
-
- install {
- repositories.mavenInstaller {
- pom.artifactId = '{{artifactId}}'
- }
- }
-
- task execute(type:JavaExec) {
- main = System.getProperty('mainClass')
- classpath = sourceSets.main.runtimeClasspath
- }
+ apply plugin: 'java'
+ apply plugin: 'maven'
+
+ sourceCompatibility = JavaVersion.VERSION_1_7
+ targetCompatibility = JavaVersion.VERSION_1_7
+
+ install {
+ repositories.mavenInstaller {
+ pom.artifactId = '{{artifactId}}'
+ }
+ }
+
+ task execute(type:JavaExec) {
+ main = System.getProperty('mainClass')
+ classpath = sourceSets.main.runtimeClasspath
+ }
}
ext {
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache
index e2d0f73d408..c8d2145bc6e 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache
@@ -162,7 +162,7 @@
1.5.0
- 2.6
+ 2.12
2.4.2
2.3
1.0.0
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache
index df36a8b5483..f238c37fb47 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache
@@ -75,13 +75,11 @@ public class ApiClient {
private int statusCode;
private Map> responseHeaders;
- private String dateFormat;
- private DateFormat dateFormatter;
+ private DateFormat dateFormat;
+ private DateFormat datetimeFormat;
+ private boolean lenientDatetimeFormat;
private int dateLength;
- private String datetimeFormat;
- private DateFormat datetimeFormatter;
-
private InputStream sslCaCert;
private boolean verifyingSsl;
@@ -95,10 +93,19 @@ public class ApiClient {
json = new JSON(this);
- // Use ISO 8601 format for date and datetime.
- // See https://en.wikipedia.org/wiki/ISO_8601
- setDateFormat("yyyy-MM-dd");
- setDatetimeFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ /*
+ * 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");
+ // Always use UTC as the default time zone when dealing with date (without time).
+ this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ // Use the system's default time zone when dealing with datetime (mainly formatting).
+ this.datetimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+ // Be lenient on datetime formats when parsing datetime from string.
+ // See parseDatetime
.
+ this.lenientDatetimeFormat = true;
// Set default User-Agent.
setUserAgent("Java-Swagger");
@@ -186,32 +193,35 @@ public class ApiClient {
return this;
}
- public String getDateFormat() {
+ public DateFormat getDateFormat() {
return dateFormat;
}
- public ApiClient setDateFormat(String dateFormat) {
+ public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
-
- this.dateFormatter = new SimpleDateFormat(dateFormat);
- // Use UTC as the default time zone.
- this.dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
-
- this.dateLength = this.dateFormatter.format(new Date()).length();
-
+ this.dateLength = this.dateFormat.format(new Date()).length();
return this;
}
- public String getDatetimeFormat() {
+ public DateFormat getDatetimeFormat() {
return datetimeFormat;
}
- public ApiClient setDatetimeFormat(String datetimeFormat) {
+ public ApiClient setDatetimeFormat(DateFormat datetimeFormat) {
this.datetimeFormat = datetimeFormat;
+ return this;
+ }
- this.datetimeFormatter = new SimpleDateFormat(datetimeFormat);
- // Note: The datetime formatter uses the system's default time zone.
+ /**
+ * Whether to allow various ISO 8601 datetime formats when parsing a datetime string.
+ * @see #parseDatetime(String)
+ */
+ public boolean isLenientDatetimeFormat() {
+ return lenientDatetimeFormat;
+ }
+ public ApiClient setLenientDatetimeFormat(boolean lenientDatetimeFormat) {
+ this.lenientDatetimeFormat = lenientDatetimeFormat;
return this;
}
@@ -225,15 +235,15 @@ public class ApiClient {
if (str == null)
return null;
try {
- return dateFormatter.parse(str);
+ return dateFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
- * Parse the given date-time string into Date object.
- * The default datetimeFormat
supports these ISO 8601 datetime formats:
+ * Parse the given datetime string into Date object.
+ * When lenientDatetimeFormat
is enabled, the following ISO 8601 datetime formats are supported:
* 2015-08-16T08:20:05Z
* 2015-8-16T8:20:05Z
* 2015-08-16T08:20:05+00:00
@@ -253,25 +263,25 @@ public class ApiClient {
if (str == null)
return null;
- if ("yyyy-MM-dd'T'HH:mm:ss.SSSZ".equals(datetimeFormat)) {
+ if (lenientDatetimeFormat) {
/*
- * When the default datetime format is used, process the given string
+ * When lenientDatetimeFormat is enabled, process the given string
* to support various formats defined by ISO 8601.
*/
// normalize time zone
- // trailing "Z": 2015-08-16T08:20:05Z => 2015-08-16T08:20:05+0000
- str = str.replaceAll("[zZ]\\z", "+0000");
- // remove colon: 2015-08-16T08:20:05+00:00 => 2015-08-16T08:20:05+0000
- str = str.replaceAll("([+-]\\d{2}):(\\d{2})\\z", "$1$2");
- // expand time zone: 2015-08-16T08:20:05+00 => 2015-08-16T08:20:05+0000
- str = str.replaceAll("([+-]\\d{2})\\z", "$100");
+ // trailing "Z": 2015-08-16T08:20:05Z => 2015-08-16T08:20:05+00:00
+ str = str.replaceAll("[zZ]\\z", "+00:00");
+ // add colon: 2015-08-16T08:20:05+0000 => 2015-08-16T08:20:05+00:00
+ str = str.replaceAll("([+-]\\d{2})(\\d{2})\\z", "$1:$2");
+ // expand time zone: 2015-08-16T08:20:05+00 => 2015-08-16T08:20:05+00:00
+ str = str.replaceAll("([+-]\\d{2})\\z", "$1:00");
// add milliseconds when missing
- // 2015-08-16T08:20:05+0000 => 2015-08-16T08:20:05.000+0000
- str = str.replaceAll("(:\\d{1,2})([+-]\\d{4})\\z", "$1.000$2");
+ // 2015-08-16T08:20:05+00:00 => 2015-08-16T08:20:05.000+00:00
+ str = str.replaceAll("(:\\d{1,2})([+-]\\d{2}:\\d{2})\\z", "$1.000$2");
}
try {
- return datetimeFormatter.parse(str);
+ return datetimeFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
@@ -290,14 +300,14 @@ public class ApiClient {
* Format the given Date object into string.
*/
public String formatDate(Date date) {
- return dateFormatter.format(date);
+ return dateFormat.format(date);
}
/**
* Format the given Date object into string.
*/
public String formatDatetime(Date date) {
- return datetimeFormatter.format(date);
+ return datetimeFormat.format(date);
}
/**
@@ -369,6 +379,19 @@ public class ApiClient {
throw new RuntimeException("No API key authentication configured!");
}
+ /**
+ * Helper method to set access token for the first OAuth2 authentication.
+ */
+ public void setAccessToken(String accessToken) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof OAuth) {
+ ((OAuth) auth).setAccessToken(accessToken);
+ return;
+ }
+ }
+ throw new RuntimeException("No OAuth2 authentication configured!");
+ }
+
/**
* Set the User-Agent header's value (by adding to the default header map).
*/
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/build.gradle.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/build.gradle.mustache
index 289f9a6df72..9741cb13d10 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/build.gradle.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/okhttp-gson/build.gradle.mustache
@@ -18,72 +18,76 @@ repositories {
if(hasProperty('target') && target == 'android') {
- apply plugin: 'com.android.library'
- apply plugin: 'com.github.dcendents.android-maven'
-
- android {
- compileSdkVersion 22
- buildToolsVersion '22.0.0'
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 22
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
- // Rename the aar correctly
- libraryVariants.all { variant ->
- variant.outputs.each { output ->
- def outputFile = output.outputFile
- if (outputFile != null && outputFile.name.endsWith('.aar')) {
- def fileName = "${project.name}-${variant.baseName}-${version}.aar"
- output.outputFile = new File(outputFile.parent, fileName)
- }
- }
- }
- }
-
- afterEvaluate {
- android.libraryVariants.all { variant ->
- def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
- task.description = "Create jar artifact for ${variant.name}"
- task.dependsOn variant.javaCompile
- task.from variant.javaCompile.destinationDir
- task.destinationDir = project.file("${project.buildDir}/outputs/jar")
- task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
- artifacts.add('archives', task);
- }
- }
-
- task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
- }
-
- artifacts {
- archives sourcesJar
- }
+ apply plugin: 'com.android.library'
+ apply plugin: 'com.github.dcendents.android-maven'
+
+ android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.0'
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 22
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ // Rename the aar correctly
+ libraryVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = output.outputFile
+ if (outputFile != null && outputFile.name.endsWith('.aar')) {
+ def fileName = "${project.name}-${variant.baseName}-${version}.aar"
+ output.outputFile = new File(outputFile.parent, fileName)
+ }
+ }
+ }
+
+ dependencies {
+ provided 'javax.annotation:jsr250-api:1.0'
+ }
+ }
+
+ afterEvaluate {
+ android.libraryVariants.all { variant ->
+ def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
+ task.description = "Create jar artifact for ${variant.name}"
+ task.dependsOn variant.javaCompile
+ task.from variant.javaCompile.destinationDir
+ task.destinationDir = project.file("${project.buildDir}/outputs/jar")
+ task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
+ artifacts.add('archives', task);
+ }
+ }
+
+ task sourcesJar(type: Jar) {
+ from android.sourceSets.main.java.srcDirs
+ classifier = 'sources'
+ }
+
+ artifacts {
+ archives sourcesJar
+ }
} else {
- apply plugin: 'java'
- apply plugin: 'maven'
-
- sourceCompatibility = JavaVersion.VERSION_1_7
- targetCompatibility = JavaVersion.VERSION_1_7
-
- install {
- repositories.mavenInstaller {
- pom.artifactId = '{{artifactId}}'
- }
- }
-
- task execute(type:JavaExec) {
- main = System.getProperty('mainClass')
- classpath = sourceSets.main.runtimeClasspath
- }
+ apply plugin: 'java'
+ apply plugin: 'maven'
+
+ sourceCompatibility = JavaVersion.VERSION_1_7
+ targetCompatibility = JavaVersion.VERSION_1_7
+
+ install {
+ repositories.mavenInstaller {
+ pom.artifactId = '{{artifactId}}'
+ }
+ }
+
+ task execute(type:JavaExec) {
+ main = System.getProperty('mainClass')
+ classpath = sourceSets.main.runtimeClasspath
+ }
}
dependencies {
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/ApiClient.mustache
index eaca662c583..183fb5f27ce 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/ApiClient.mustache
@@ -28,6 +28,7 @@ import com.squareup.okhttp.OkHttpClient;
import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.OAuth;
+import {{invokerPackage}}.auth.OAuth.AccessTokenListener;
import {{invokerPackage}}.auth.OAuthFlow;
@@ -44,12 +45,7 @@ public class ApiClient {
public ApiClient(String[] authNames) {
this();
- okClient = new OkHttpClient();
- adapterBuilder.setClient(new OkClient(okClient));
- for(String authName : authNames) {
- if (apiAuthorizations.containsKey(authName)) {
- throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
- }{{#hasAuthMethods}}
+ for(String authName : authNames) { {{#hasAuthMethods}}
Interceptor auth;
{{#authMethods}}if (authName == "{{name}}") { {{#isBasic}}
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
@@ -58,10 +54,9 @@ public class ApiClient {
} else {{/authMethods}}{
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
- apiAuthorizations.put(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
+ addAuthorization(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");{{/hasAuthMethods}}
}
- addAuthsToOkClient(okClient);
}
/**
@@ -115,9 +110,12 @@ public class ApiClient {
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.create();
+ okClient = new OkHttpClient();
+
adapterBuilder = new RestAdapter
.Builder()
.setEndpoint("{{basePath}}")
+ .setClient(new OkClient(okClient))
.setConverter(new GsonConverterWrapper(gson));
}
@@ -224,6 +222,33 @@ public class ApiClient {
}
}
+ /**
+ * Configures a listener which is notified when a new access token is received.
+ * @param accessTokenListener
+ */
+ public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ oauth.registerAccessTokenListener(accessTokenListener);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Adds an authorization to be used by the client
+ * @param authName
+ * @param authorization
+ */
+ public void addAuthorization(String authName, Interceptor authorization) {
+ if (apiAuthorizations.containsKey(authName)) {
+ throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
+ }
+ apiAuthorizations.put(authName, authorization);
+ okClient.interceptors().add(authorization);
+ }
+
public Map getApiAuthorizations() {
return apiAuthorizations;
}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/auth/OAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/auth/OAuth.mustache
index e6179d6c690..647ff141329 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/auth/OAuth.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/auth/OAuth.mustache
@@ -1,6 +1,7 @@
package {{invokerPackage}}.auth;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
import java.io.IOException;
import java.util.Map;
@@ -14,6 +15,7 @@ import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
+import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
@@ -23,12 +25,18 @@ import com.squareup.okhttp.Response;
public class OAuth implements Interceptor {
+ public interface AccessTokenListener {
+ public void notify(BasicOAuthToken token);
+ }
+
private volatile String accessToken;
private OAuthClient oauthClient;
private TokenRequestBuilder tokenRequestBuilder;
private AuthenticationRequestBuilder authenticationRequestBuilder;
+ private AccessTokenListener accessTokenListener;
+
public OAuth( OkHttpClient client, TokenRequestBuilder requestBuilder ) {
this.oauthClient = new OAuthClient(new OAuthOkHttpClient(client));
this.tokenRequestBuilder = requestBuilder;
@@ -78,47 +86,67 @@ public class OAuth implements Interceptor {
updateAccessToken(null);
}
- // Build the request
- Builder rb = request.newBuilder();
-
- String requestAccessToken = new String(getAccessToken());
- try {
- oAuthRequest = new OAuthBearerClientRequest(request.urlString())
- .setAccessToken(requestAccessToken)
- .buildHeaderMessage();
- } catch (OAuthSystemException e) {
- throw new IOException(e);
+ if (getAccessToken() != null) {
+ // Build the request
+ Builder rb = request.newBuilder();
+
+ String requestAccessToken = new String(getAccessToken());
+ try {
+ oAuthRequest = new OAuthBearerClientRequest(request.urlString())
+ .setAccessToken(requestAccessToken)
+ .buildHeaderMessage();
+ } catch (OAuthSystemException e) {
+ throw new IOException(e);
+ }
+
+ for ( Map.Entry header : oAuthRequest.getHeaders().entrySet() ) {
+ rb.addHeader(header.getKey(), header.getValue());
+ }
+ rb.url( oAuthRequest.getLocationUri());
+
+ //Execute the request
+ Response response = chain.proceed(rb.build());
+
+ // 401 most likely indicates that access token has expired.
+ // Time to refresh and resend the request
+ if ( response != null && (response.code() == HTTP_UNAUTHORIZED | response.code() == HTTP_FORBIDDEN) ) {
+ if (updateAccessToken(requestAccessToken)) {
+ return intercept( chain );
+ }
+ }
+ return response;
+ } else {
+ return chain.proceed(chain.request());
}
-
- for ( Map.Entry header : oAuthRequest.getHeaders().entrySet() ) {
- rb.addHeader(header.getKey(), header.getValue());
- }
- rb.url( oAuthRequest.getLocationUri());
-
- //Execute the request
- Response response = chain.proceed(rb.build());
-
- // 401 most likely indicates that access token has expired.
- // Time to refresh and resend the request
- if ( response.code() == HTTP_UNAUTHORIZED ) {
- updateAccessToken(requestAccessToken);
- return intercept( chain );
- }
- return response;
}
- public synchronized void updateAccessToken(String requestAccessToken) throws IOException {
+ /*
+ * Returns true if the access token has been updated
+ */
+ public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException {
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
try {
- OAuthJSONAccessTokenResponse accessTokenResponse;
- accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage());
- setAccessToken(accessTokenResponse.getAccessToken());
+ OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage());
+ if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
+ setAccessToken(accessTokenResponse.getAccessToken());
+ if (accessTokenListener != null) {
+ accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
+ }
+ return getAccessToken().equals(requestAccessToken);
+ } else {
+ return false;
+ }
} catch (OAuthSystemException e) {
throw new IOException(e);
} catch (OAuthProblemException e) {
throw new IOException(e);
}
}
+ return true;
+ }
+
+ public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
+ this.accessTokenListener = accessTokenListener;
}
public synchronized String getAccessToken() {
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/build.gradle.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/build.gradle.mustache
index a285745505a..7072c8752f5 100644
--- a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/build.gradle.mustache
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit/build.gradle.mustache
@@ -18,72 +18,76 @@ repositories {
if(hasProperty('target') && target == 'android') {
- apply plugin: 'com.android.library'
- apply plugin: 'com.github.dcendents.android-maven'
-
- android {
- compileSdkVersion 22
- buildToolsVersion '22.0.0'
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 22
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
- // Rename the aar correctly
- libraryVariants.all { variant ->
- variant.outputs.each { output ->
- def outputFile = output.outputFile
- if (outputFile != null && outputFile.name.endsWith('.aar')) {
- def fileName = "${project.name}-${variant.baseName}-${version}.aar"
- output.outputFile = new File(outputFile.parent, fileName)
- }
- }
- }
- }
-
- afterEvaluate {
- android.libraryVariants.all { variant ->
- def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
- task.description = "Create jar artifact for ${variant.name}"
- task.dependsOn variant.javaCompile
- task.from variant.javaCompile.destinationDir
- task.destinationDir = project.file("${project.buildDir}/outputs/jar")
- task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
- artifacts.add('archives', task);
- }
- }
-
- task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
- }
-
- artifacts {
- archives sourcesJar
- }
+ apply plugin: 'com.android.library'
+ apply plugin: 'com.github.dcendents.android-maven'
+
+ android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.0'
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 22
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ // Rename the aar correctly
+ libraryVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = output.outputFile
+ if (outputFile != null && outputFile.name.endsWith('.aar')) {
+ def fileName = "${project.name}-${variant.baseName}-${version}.aar"
+ output.outputFile = new File(outputFile.parent, fileName)
+ }
+ }
+ }
+
+ dependencies {
+ provided 'javax.annotation:jsr250-api:1.0'
+ }
+ }
+
+ afterEvaluate {
+ android.libraryVariants.all { variant ->
+ def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
+ task.description = "Create jar artifact for ${variant.name}"
+ task.dependsOn variant.javaCompile
+ task.from variant.javaCompile.destinationDir
+ task.destinationDir = project.file("${project.buildDir}/outputs/jar")
+ task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
+ artifacts.add('archives', task);
+ }
+ }
+
+ task sourcesJar(type: Jar) {
+ from android.sourceSets.main.java.srcDirs
+ classifier = 'sources'
+ }
+
+ artifacts {
+ archives sourcesJar
+ }
} else {
- apply plugin: 'java'
- apply plugin: 'maven'
-
- sourceCompatibility = JavaVersion.VERSION_1_7
- targetCompatibility = JavaVersion.VERSION_1_7
-
- install {
- repositories.mavenInstaller {
- pom.artifactId = '{{artifactId}}'
- }
- }
-
- task execute(type:JavaExec) {
- main = System.getProperty('mainClass')
- classpath = sourceSets.main.runtimeClasspath
- }
+ apply plugin: 'java'
+ apply plugin: 'maven'
+
+ sourceCompatibility = JavaVersion.VERSION_1_7
+ targetCompatibility = JavaVersion.VERSION_1_7
+
+ install {
+ repositories.mavenInstaller {
+ pom.artifactId = '{{artifactId}}'
+ }
+ }
+
+ task execute(type:JavaExec) {
+ main = System.getProperty('mainClass')
+ classpath = sourceSets.main.runtimeClasspath
+ }
}
ext {
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/ApiClient.mustache
new file mode 100644
index 00000000000..56e83f7d915
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/ApiClient.mustache
@@ -0,0 +1,343 @@
+package {{invokerPackage}};
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
+
+import retrofit.Converter;
+import retrofit.Retrofit;
+import retrofit.GsonConverterFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonParseException;
+import com.squareup.okhttp.Interceptor;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.RequestBody;
+import com.squareup.okhttp.ResponseBody;
+
+import {{invokerPackage}}.auth.HttpBasicAuth;
+import {{invokerPackage}}.auth.ApiKeyAuth;
+import {{invokerPackage}}.auth.OAuth;
+import {{invokerPackage}}.auth.OAuth.AccessTokenListener;
+import {{invokerPackage}}.auth.OAuthFlow;
+
+
+public class ApiClient {
+
+ private Map apiAuthorizations;
+ private OkHttpClient okClient;
+ private Retrofit.Builder adapterBuilder;
+
+ public ApiClient() {
+ apiAuthorizations = new LinkedHashMap();
+ createDefaultAdapter();
+ }
+
+ public ApiClient(String[] authNames) {
+ this();
+ for(String authName : authNames) { {{#hasAuthMethods}}
+ Interceptor auth;
+ {{#authMethods}}if (authName == "{{name}}") { {{#isBasic}}
+ auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
+ auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
+ auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
+ } else {{/authMethods}}{
+ throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
+ }
+ addAuthorization(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
+ throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");{{/hasAuthMethods}}
+ }
+ }
+
+ /**
+ * Basic constructor for single auth name
+ * @param authName
+ */
+ public ApiClient(String authName) {
+ this(new String[]{authName});
+ }
+
+ /**
+ * Helper constructor for single api key
+ * @param authName
+ * @param apiKey
+ */
+ public ApiClient(String authName, String apiKey) {
+ this(authName);
+ this.setApiKey(apiKey);
+ }
+
+ /**
+ * Helper constructor for single basic auth or password oauth2
+ * @param authName
+ * @param username
+ * @param password
+ */
+ public ApiClient(String authName, String username, String password) {
+ this(authName);
+ this.setCredentials(username, password);
+ }
+
+ /**
+ * Helper constructor for single password oauth2
+ * @param authName
+ * @param clientId
+ * @param secret
+ * @param username
+ * @param password
+ */
+ public ApiClient(String authName, String clientId, String secret, String username, String password) {
+ this(authName);
+ this.getTokenEndPoint()
+ .setClientId(clientId)
+ .setClientSecret(secret)
+ .setUsername(username)
+ .setPassword(password);
+ }
+
+ public void createDefaultAdapter() {
+ Gson gson = new GsonBuilder()
+ .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
+ .create();
+
+ okClient = new OkHttpClient();
+
+ String baseUrl = "{{basePath}}";
+ if(!baseUrl.endsWith("/"))
+ baseUrl = baseUrl + "/";
+
+ adapterBuilder = new Retrofit
+ .Builder()
+ .baseUrl(baseUrl)
+ .client(okClient)
+ .addConverterFactory(GsonCustomConverterFactory.create(gson));
+ }
+
+ public S createService(Class serviceClass) {
+ return adapterBuilder.build().create(serviceClass);
+
+ }
+
+ /**
+ * Helper method to configure the first api key found
+ * @param apiKey
+ */
+ private void setApiKey(String apiKey) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof ApiKeyAuth) {
+ ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
+ keyAuth.setApiKey(apiKey);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Helper method to configure the username/password for basic auth or password oauth
+ * @param username
+ * @param password
+ */
+ private void setCredentials(String username, String password) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof HttpBasicAuth) {
+ HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
+ basicAuth.setCredentials(username, password);
+ return;
+ }
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
+ * @return
+ */
+ public TokenRequestBuilder getTokenEndPoint() {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ return oauth.getTokenRequestBuilder();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
+ * @return
+ */
+ public AuthenticationRequestBuilder getAuthorizationEndPoint() {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ return oauth.getAuthenticationRequestBuilder();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
+ * @param accessToken
+ */
+ public void setAccessToken(String accessToken) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ oauth.setAccessToken(accessToken);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Helper method to configure the oauth accessCode/implicit flow parameters
+ * @param clientId
+ * @param clientSecret
+ * @param redirectURI
+ */
+ public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ oauth.getTokenRequestBuilder()
+ .setClientId(clientId)
+ .setClientSecret(clientSecret)
+ .setRedirectURI(redirectURI);
+ oauth.getAuthenticationRequestBuilder()
+ .setClientId(clientId)
+ .setRedirectURI(redirectURI);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Configures a listener which is notified when a new access token is received.
+ * @param accessTokenListener
+ */
+ public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ if (apiAuthorization instanceof OAuth) {
+ OAuth oauth = (OAuth) apiAuthorization;
+ oauth.registerAccessTokenListener(accessTokenListener);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Adds an authorization to be used by the client
+ * @param authName
+ * @param authorization
+ */
+ public void addAuthorization(String authName, Interceptor authorization) {
+ if (apiAuthorizations.containsKey(authName)) {
+ throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
+ }
+ apiAuthorizations.put(authName, authorization);
+ okClient.interceptors().add(authorization);
+ }
+
+ public Map getApiAuthorizations() {
+ return apiAuthorizations;
+ }
+
+ public void setApiAuthorizations(Map apiAuthorizations) {
+ this.apiAuthorizations = apiAuthorizations;
+ }
+
+ public Retrofit.Builder getAdapterBuilder() {
+ return adapterBuilder;
+ }
+
+ public void setAdapterBuilder(Retrofit.Builder adapterBuilder) {
+ this.adapterBuilder = adapterBuilder;
+ }
+
+ public OkHttpClient getOkClient() {
+ return okClient;
+ }
+
+ public void addAuthsToOkClient(OkHttpClient okClient) {
+ for(Interceptor apiAuthorization : apiAuthorizations.values()) {
+ okClient.interceptors().add(apiAuthorization);
+ }
+ }
+
+ /**
+ * Clones the okClient given in parameter, adds the auth interceptors and uses it to configure the Retrofit
+ * @param okClient
+ */
+ public void configureFromOkclient(OkHttpClient okClient) {
+ OkHttpClient clone = okClient.clone();
+ addAuthsToOkClient(clone);
+ adapterBuilder.client(clone);
+ }
+}
+
+/**
+ * This wrapper is to take care of this case:
+ * when the deserialization fails due to JsonParseException and the
+ * expected type is String, then just return the body string.
+ */
+class GsonResponseBodyConverterToString implements Converter {
+ private final Gson gson;
+ private final Type type;
+
+ GsonResponseBodyConverterToString(Gson gson, Type type) {
+ this.gson = gson;
+ this.type = type;
+ }
+
+ @Override public T convert(ResponseBody value) throws IOException {
+ String returned = value.string();
+ try {
+ return gson.fromJson(returned, type);
+ }
+ catch (JsonParseException e) {
+ return (T) returned;
+ }
+ }
+}
+
+class GsonCustomConverterFactory extends Converter.Factory
+{
+ public static GsonCustomConverterFactory create(Gson gson) {
+ return new GsonCustomConverterFactory(gson);
+ }
+
+ private final Gson gson;
+ private final GsonConverterFactory gsonConverterFactory;
+
+ private GsonCustomConverterFactory(Gson gson) {
+ if (gson == null) throw new NullPointerException("gson == null");
+ this.gson = gson;
+ this.gsonConverterFactory = GsonConverterFactory.create(gson);
+ }
+
+ @Override
+ public Converter fromResponseBody(Type type, Annotation[] annotations) {
+ if(type.equals(String.class))
+ return new GsonResponseBodyConverterToString(gson, type);
+ else
+ return gsonConverterFactory.fromResponseBody(type, annotations);
+ }
+
+ @Override
+ public Converter, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
+ return gsonConverterFactory.toRequestBody(type, annotations);
+ }
+}
+
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/CollectionFormats.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/CollectionFormats.mustache
new file mode 100644
index 00000000000..a549ea59d1c
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/CollectionFormats.mustache
@@ -0,0 +1,95 @@
+package {{invokerPackage}};
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CollectionFormats {
+
+ public static class CSVParams {
+
+ protected List params;
+
+ public CSVParams() {
+ }
+
+ public CSVParams(List params) {
+ this.params = params;
+ }
+
+ public CSVParams(String... params) {
+ this.params = Arrays.asList(params);
+ }
+
+ public List getParams() {
+ return params;
+ }
+
+ public void setParams(List params) {
+ this.params = params;
+ }
+
+ @Override
+ public String toString() {
+ return StringUtil.join(params.toArray(new String[0]), ",");
+ }
+
+ }
+
+ public static class SSVParams extends CSVParams {
+
+ public SSVParams() {
+ }
+
+ public SSVParams(List params) {
+ super(params);
+ }
+
+ public SSVParams(String... params) {
+ super(params);
+ }
+
+ @Override
+ public String toString() {
+ return StringUtil.join(params.toArray(new String[0]), " ");
+ }
+ }
+
+ public static class TSVParams extends CSVParams {
+
+ public TSVParams() {
+ }
+
+ public TSVParams(List params) {
+ super(params);
+ }
+
+ public TSVParams(String... params) {
+ super(params);
+ }
+
+ @Override
+ public String toString() {
+ return StringUtil.join( params.toArray(new String[0]), "\t");
+ }
+ }
+
+ public static class PIPESParams extends CSVParams {
+
+ public PIPESParams() {
+ }
+
+ public PIPESParams(List params) {
+ super(params);
+ }
+
+ public PIPESParams(String... params) {
+ super(params);
+ }
+
+ @Override
+ public String toString() {
+ return StringUtil.join(params.toArray(new String[0]), "|");
+ }
+ }
+
+}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/api.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/api.mustache
new file mode 100644
index 00000000000..d0205c3d0b1
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/api.mustache
@@ -0,0 +1,34 @@
+package {{package}};
+
+import {{invokerPackage}}.CollectionFormats.*;
+
+import retrofit.Call;
+import retrofit.http.*;
+import com.squareup.okhttp.RequestBody;
+
+{{#imports}}import {{import}};
+{{/imports}}
+
+{{^fullJavaUtil}}
+import java.util.*;
+{{/fullJavaUtil}}
+
+{{#operations}}
+public interface {{classname}} {
+ {{#operation}}
+ /**
+ * {{summary}}
+ * {{notes}}
+{{#allParams}} * @param {{paramName}} {{description}}
+{{/allParams}} * @return Call<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>
+ */
+ {{#formParams}}{{#-first}}
+ {{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
+ @{{httpMethod}}("{{path}}")
+ Call<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{nickname}}({{^allParams}});{{/allParams}}
+ {{#allParams}}{{>libraries/retrofit2/queryParams}}{{>libraries/retrofit2/pathParams}}{{>libraries/retrofit2/headerParams}}{{>libraries/retrofit2/bodyParams}}{{>libraries/retrofit2/formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}
+ );{{/hasMore}}{{/allParams}}
+
+ {{/operation}}
+}
+{{/operations}}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/ApiKeyAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/ApiKeyAuth.mustache
new file mode 100644
index 00000000000..fec45262e93
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/ApiKeyAuth.mustache
@@ -0,0 +1,68 @@
+package {{invokerPackage}}.auth;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import com.squareup.okhttp.Interceptor;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+public class ApiKeyAuth implements Interceptor {
+ private final String location;
+ private final String paramName;
+
+ private String apiKey;
+
+ public ApiKeyAuth(String location, String paramName) {
+ this.location = location;
+ this.paramName = paramName;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String getParamName() {
+ return paramName;
+ }
+
+ public String getApiKey() {
+ return apiKey;
+ }
+
+ public void setApiKey(String apiKey) {
+ this.apiKey = apiKey;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ String paramValue;
+ Request request = chain.request();
+
+ if (location == "query") {
+ String newQuery = request.uri().getQuery();
+ paramValue = paramName + "=" + apiKey;
+ if (newQuery == null) {
+ newQuery = paramValue;
+ } else {
+ newQuery += "&" + paramValue;
+ }
+
+ URI newUri;
+ try {
+ newUri = new URI(request.uri().getScheme(), request.uri().getAuthority(),
+ request.uri().getPath(), newQuery, request.uri().getFragment());
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+
+ request = request.newBuilder().url(newUri.toURL()).build();
+ } else if (location == "header") {
+ request = request.newBuilder()
+ .addHeader(paramName, apiKey)
+ .build();
+ }
+ return chain.proceed(request);
+ }
+}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/HttpBasicAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/HttpBasicAuth.mustache
new file mode 100644
index 00000000000..394592f64d9
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/HttpBasicAuth.mustache
@@ -0,0 +1,49 @@
+package {{invokerPackage}}.auth;
+
+import java.io.IOException;
+
+import com.squareup.okhttp.Credentials;
+import com.squareup.okhttp.Interceptor;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+public class HttpBasicAuth implements Interceptor {
+
+ private String username;
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setCredentials(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+
+ // If the request already have an authorization (eg. Basic auth), do nothing
+ if (request.header("Authorization") == null) {
+ String credentials = Credentials.basic(username, password);
+ request = request.newBuilder()
+ .addHeader("Authorization", credentials)
+ .build();
+ }
+ return chain.proceed(request);
+ }
+}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/OAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/OAuth.mustache
new file mode 100644
index 00000000000..68ee918601e
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/OAuth.mustache
@@ -0,0 +1,161 @@
+package {{invokerPackage}}.auth;
+
+import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.oltu.oauth2.client.OAuthClient;
+import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
+import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.apache.oltu.oauth2.common.message.types.GrantType;
+import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
+
+import com.squareup.okhttp.Interceptor;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Request.Builder;
+import com.squareup.okhttp.Response;
+
+public class OAuth implements Interceptor {
+
+ public interface AccessTokenListener {
+ public void notify(BasicOAuthToken token);
+ }
+
+ private volatile String accessToken;
+ private OAuthClient oauthClient;
+
+ private TokenRequestBuilder tokenRequestBuilder;
+ private AuthenticationRequestBuilder authenticationRequestBuilder;
+
+ private AccessTokenListener accessTokenListener;
+
+ public OAuth( OkHttpClient client, TokenRequestBuilder requestBuilder ) {
+ this.oauthClient = new OAuthClient(new OAuthOkHttpClient(client));
+ this.tokenRequestBuilder = requestBuilder;
+ }
+
+ public OAuth(TokenRequestBuilder requestBuilder ) {
+ this(new OkHttpClient(), requestBuilder);
+ }
+
+ public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
+ this(OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
+ setFlow(flow);
+ authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
+ }
+
+ public void setFlow(OAuthFlow flow) {
+ switch(flow) {
+ case accessCode:
+ case implicit:
+ tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
+ break;
+ case password:
+ tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
+ break;
+ case application:
+ tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public Response intercept(Chain chain)
+ throws IOException {
+
+ Request request = chain.request();
+
+ // If the request already have an authorization (eg. Basic auth), do nothing
+ if (request.header("Authorization") != null) {
+ return chain.proceed(request);
+ }
+
+ // If first time, get the token
+ OAuthClientRequest oAuthRequest;
+ if (getAccessToken() == null) {
+ updateAccessToken(null);
+ }
+
+ // Build the request
+ Builder rb = request.newBuilder();
+
+ String requestAccessToken = new String(getAccessToken());
+ try {
+ oAuthRequest = new OAuthBearerClientRequest(request.urlString())
+ .setAccessToken(requestAccessToken)
+ .buildHeaderMessage();
+ } catch (OAuthSystemException e) {
+ throw new IOException(e);
+ }
+
+ for ( Map.Entry header : oAuthRequest.getHeaders().entrySet() ) {
+ rb.addHeader(header.getKey(), header.getValue());
+ }
+ rb.url( oAuthRequest.getLocationUri());
+
+ //Execute the request
+ Response response = chain.proceed(rb.build());
+
+ // 401 most likely indicates that access token has expired.
+ // Time to refresh and resend the request
+ if ( response.code() == HTTP_UNAUTHORIZED ) {
+ updateAccessToken(requestAccessToken);
+ return intercept( chain );
+ }
+ return response;
+ }
+
+ public synchronized void updateAccessToken(String requestAccessToken) throws IOException {
+ if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
+ try {
+ OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage());
+ setAccessToken(accessTokenResponse.getAccessToken());
+ if (accessTokenListener != null) {
+ accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
+ }
+ } catch (OAuthSystemException e) {
+ throw new IOException(e);
+ } catch (OAuthProblemException e) {
+ throw new IOException(e);
+ }
+ }
+ }
+
+ public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
+ this.accessTokenListener = accessTokenListener;
+ }
+
+ public synchronized String getAccessToken() {
+ return accessToken;
+ }
+
+ public synchronized void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ public TokenRequestBuilder getTokenRequestBuilder() {
+ return tokenRequestBuilder;
+ }
+
+ public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
+ this.tokenRequestBuilder = tokenRequestBuilder;
+ }
+
+ public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
+ return authenticationRequestBuilder;
+ }
+
+ public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
+ this.authenticationRequestBuilder = authenticationRequestBuilder;
+ }
+
+}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/OAuthOkHttpClient.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/OAuthOkHttpClient.mustache
new file mode 100644
index 00000000000..ea195f7df04
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/auth/OAuthOkHttpClient.mustache
@@ -0,0 +1,69 @@
+package {{invokerPackage}}.auth;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.oltu.oauth2.client.HttpClient;
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
+import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
+import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+
+import com.squareup.okhttp.MediaType;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.RequestBody;
+import com.squareup.okhttp.Response;
+
+
+public class OAuthOkHttpClient implements HttpClient {
+
+ private OkHttpClient client;
+
+ public OAuthOkHttpClient() {
+ this.client = new OkHttpClient();
+ }
+
+ public OAuthOkHttpClient(OkHttpClient client) {
+ this.client = client;
+ }
+
+ public T execute(OAuthClientRequest request, Map headers,
+ String requestMethod, Class responseClass)
+ throws OAuthSystemException, OAuthProblemException {
+
+ MediaType mediaType = MediaType.parse("application/json");
+ Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
+
+ if(headers != null) {
+ for (Entry entry : headers.entrySet()) {
+ if (entry.getKey().equalsIgnoreCase("Content-Type")) {
+ mediaType = MediaType.parse(entry.getValue());
+ } else {
+ requestBuilder.addHeader(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null;
+ requestBuilder.method(requestMethod, body);
+
+ try {
+ Response response = client.newCall(requestBuilder.build()).execute();
+ return OAuthClientResponseFactory.createCustomResponse(
+ response.body().string(),
+ response.body().contentType().toString(),
+ response.code(),
+ responseClass);
+ } catch (IOException e) {
+ throw new OAuthSystemException(e);
+ }
+ }
+
+ public void shutdown() {
+ // Nothing to do here
+ }
+
+}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/bodyParams.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/bodyParams.mustache
new file mode 100644
index 00000000000..f8788583db5
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/bodyParams.mustache
@@ -0,0 +1 @@
+{{#isBodyParam}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/build.gradle.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/build.gradle.mustache
new file mode 100644
index 00000000000..b1efe3911a8
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/build.gradle.mustache
@@ -0,0 +1,106 @@
+group = '{{groupId}}'
+version = '{{artifactVersion}}'
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.2.2'
+ classpath 'com.github.dcendents:android-maven-plugin:1.2'
+ }
+}
+
+repositories {
+ jcenter()
+}
+
+
+if(hasProperty('target') && target == 'android') {
+
+ apply plugin: 'com.android.library'
+ apply plugin: 'com.github.dcendents.android-maven'
+
+ android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.0'
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 22
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ // Rename the aar correctly
+ libraryVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = output.outputFile
+ if (outputFile != null && outputFile.name.endsWith('.aar')) {
+ def fileName = "${project.name}-${variant.baseName}-${version}.aar"
+ output.outputFile = new File(outputFile.parent, fileName)
+ }
+ }
+ }
+ }
+
+ afterEvaluate {
+ android.libraryVariants.all { variant ->
+ def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
+ task.description = "Create jar artifact for ${variant.name}"
+ task.dependsOn variant.javaCompile
+ task.from variant.javaCompile.destinationDir
+ task.destinationDir = project.file("${project.buildDir}/outputs/jar")
+ task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
+ artifacts.add('archives', task);
+ }
+ }
+
+ task sourcesJar(type: Jar) {
+ from android.sourceSets.main.java.srcDirs
+ classifier = 'sources'
+ }
+
+ artifacts {
+ archives sourcesJar
+ }
+
+} else {
+
+ apply plugin: 'java'
+ apply plugin: 'maven'
+
+ sourceCompatibility = JavaVersion.VERSION_1_7
+ targetCompatibility = JavaVersion.VERSION_1_7
+
+ install {
+ repositories.mavenInstaller {
+ pom.artifactId = '{{artifactId}}'
+ }
+ }
+
+ task execute(type:JavaExec) {
+ main = System.getProperty('mainClass')
+ classpath = sourceSets.main.runtimeClasspath
+ }
+}
+
+ext {
+ okhttp_version = "2.5.0"
+ oltu_version = "1.0.0"
+ retrofit_version = "2.0.0-beta2"
+ gson_version = "2.4"
+ swagger_annotations_version = "1.5.0"
+ junit_version = "4.12"
+}
+
+dependencies {
+ compile "com.squareup.okhttp:okhttp:$okhttp_version"
+ compile "com.squareup.retrofit:retrofit:$retrofit_version"
+ compile 'com.google.code.gson:gson:$gson_version'
+ compile 'com.squareup.retrofit:converter-gson:$retrofit_version'
+ compile "io.swagger:swagger-annotations:$swagger_annotations_version"
+ compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"
+ testCompile "junit:junit:$junit_version"
+}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/formParams.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/formParams.mustache
new file mode 100644
index 00000000000..8d9208978b5
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/formParams.mustache
@@ -0,0 +1 @@
+{{#isFormParam}}{{#notFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{baseName}}\"; filename=\"{{baseName}}\"") RequestBody {{paramName}}{{/isFile}}{{/isFormParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/headerParams.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/headerParams.mustache
new file mode 100644
index 00000000000..29206e1546b
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/headerParams.mustache
@@ -0,0 +1 @@
+{{#isHeaderParam}}@Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/model.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/model.mustache
new file mode 100644
index 00000000000..0987aa68f34
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/model.mustache
@@ -0,0 +1,58 @@
+package {{package}};
+
+import {{invokerPackage}}.StringUtil;
+{{#imports}}import {{import}};
+{{/imports}}
+
+import com.google.gson.annotations.SerializedName;
+
+{{#serializableModel}}
+import java.io.Serializable;{{/serializableModel}}
+
+import io.swagger.annotations.*;
+
+{{#models}}
+
+{{#model}}{{#description}}
+/**
+ * {{description}}
+ **/{{/description}}
+@ApiModel(description = "{{{description}}}")
+public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
+ {{#vars}}{{#isEnum}}
+
+{{>libraries/okhttp-gson/enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}
+
+{{>libraries/okhttp-gson/enumClass}}{{/items}}{{/items.isEnum}}
+ @SerializedName("{{baseName}}")
+ private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
+ {{/vars}}
+
+ {{#vars}}
+ /**{{#description}}
+ * {{{description}}}{{/description}}{{#minimum}}
+ * minimum: {{minimum}}{{/minimum}}{{#maximum}}
+ * maximum: {{maximum}}{{/maximum}}
+ **/
+ @ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
+ public {{{datatypeWithEnum}}} {{getter}}() {
+ return {{name}};
+ }
+ public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
+ this.{{name}} = {{name}};
+ }
+
+ {{/vars}}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class {{classname}} {\n");
+ {{#parent}}sb.append(" ").append(StringUtil.toIndentedString(super.toString())).append("\n");{{/parent}}
+ {{#vars}}sb.append(" {{name}}: ").append(StringUtil.toIndentedString({{name}})).append("\n");
+ {{/vars}}sb.append("}");
+ return sb.toString();
+ }
+}
+{{/model}}
+{{/models}}
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pathParams.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pathParams.mustache
new file mode 100644
index 00000000000..8a8bdc74c88
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pathParams.mustache
@@ -0,0 +1 @@
+{{#isPathParam}}@Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pom.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pom.mustache
new file mode 100644
index 00000000000..a155d04ef88
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/pom.mustache
@@ -0,0 +1,158 @@
+
+ 4.0.0
+ {{groupId}}
+ {{artifactId}}
+ jar
+ {{artifactId}}
+ {{artifactVersion}}
+
+ scm:git:git@github.com:swagger-api/swagger-mustache.git
+ scm:git:git@github.com:swagger-api/swagger-codegen.git
+ https://github.com/swagger-api/swagger-codegen
+
+
+ 2.2.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.12
+
+
+
+ loggerPath
+ conf/log4j.properties
+
+
+ -Xms512m -Xmx1500m
+ methods
+ pertest
+
+
+
+ maven-dependency-plugin
+
+
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/lib
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.2
+
+
+
+ jar
+ test-jar
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ add_sources
+ generate-sources
+
+ add-source
+
+
+
+ src/main/java
+
+
+
+
+ add_test_sources
+ generate-test-sources
+
+ add-test-source
+
+
+
+ src/test/java
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.6
+ 1.6
+
+
+
+
+
+
+ io.swagger
+ swagger-annotations
+ ${swagger-annotations-version}
+
+
+ com.squareup.retrofit
+ retrofit
+ ${retrofit-version}
+
+
+ com.squareup.retrofit
+ converter-gson
+ ${retrofit-version}
+
+
+ com.google.code.gson
+ gson
+ ${gson-version}
+
+
+ org.apache.oltu.oauth2
+ org.apache.oltu.oauth2.client
+ ${oltu-version}
+
+
+ com.squareup.okhttp
+ okhttp
+ ${okhttp-version}
+
+
+
+
+ junit
+ junit
+ ${junit-version}
+ test
+
+
+
+ 1.5.0
+ 2.0.0-beta2
+ 2.5.0
+ 2.4
+ 1.0.0
+ 1.0.0
+ 4.12
+
+
diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/queryParams.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/queryParams.mustache
new file mode 100644
index 00000000000..3c5b1bb7e69
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/libraries/retrofit2/queryParams.mustache
@@ -0,0 +1 @@
+{{#isQueryParam}}@Query("{{baseName}}") {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}} {{paramName}}{{/isQueryParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/Java/manifest.mustache b/modules/swagger-codegen/src/main/resources/Java/manifest.mustache
new file mode 100644
index 00000000000..f44bd07d0a0
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/Java/manifest.mustache
@@ -0,0 +1,3 @@
+
+
+
diff --git a/modules/swagger-codegen/src/main/resources/JavaJaxRS/api.mustache b/modules/swagger-codegen/src/main/resources/JavaJaxRS/api.mustache
index e919fa7ce71..ea9f2518b01 100644
--- a/modules/swagger-codegen/src/main/resources/JavaJaxRS/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaJaxRS/api.mustache
@@ -22,14 +22,13 @@ import com.sun.jersey.multipart.FormDataParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.*;
-@Path("{{basePathWithoutHost}}/{{baseName}}")
+@Path("/{{baseName}}")
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
-@io.swagger.annotations.Api(value = "/{{baseName}}", description = "the {{baseName}} API")
+@io.swagger.annotations.Api(description = "the {{baseName}} API")
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
-
private final {{classname}}Service delegate = {{classname}}ServiceFactory.get{{classname}}();
{{#operation}}
@@ -43,7 +42,7 @@ public class {{classname}} {
{{/hasMore}}{{/scopes}}
}{{/isOAuth}}){{#hasMore}},
{{/hasMore}}{{/authMethods}}
- }{{/hasAuthMethods}})
+ }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{#hasMore}}, {{/hasMore}}{{/vendorExtensions.x-tags}} })
@io.swagger.annotations.ApiResponses(value = { {{#responses}}
@io.swagger.annotations.ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}){{#hasMore}},
{{/hasMore}}{{/responses}} })
diff --git a/modules/swagger-codegen/src/main/resources/JavaJaxRS/web.mustache b/modules/swagger-codegen/src/main/resources/JavaJaxRS/web.mustache
index ae6f6d4d692..8cd666106f9 100644
--- a/modules/swagger-codegen/src/main/resources/JavaJaxRS/web.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaJaxRS/web.mustache
@@ -34,14 +34,14 @@
swagger.api.basepath
- http://localhost:8080
+ {{basePath}}
2
jersey
- /*
+ {{contextPath}}/*
ApiOriginFilter
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpringMVC/bodyParams.mustache b/modules/swagger-codegen/src/main/resources/JavaSpringMVC/bodyParams.mustache
index 86546afb9ca..f1137ba7073 100644
--- a/modules/swagger-codegen/src/main/resources/JavaSpringMVC/bodyParams.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaSpringMVC/bodyParams.mustache
@@ -1 +1 @@
-{{#isBodyParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}} {{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/isBodyParam}}
\ No newline at end of file
+{{#isBodyParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}} {{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @RequestBody {{{dataType}}} {{paramName}}{{/isBodyParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
index 4cf785abbd8..5c607488d9b 100644
--- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
+++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
@@ -3,6 +3,7 @@ io.swagger.codegen.languages.AsyncScalaClientCodegen
io.swagger.codegen.languages.CSharpClientCodegen
io.swagger.codegen.languages.DartClientCodegen
io.swagger.codegen.languages.FlashClientCodegen
+io.swagger.codegen.languages.FlaskConnexionCodegen
io.swagger.codegen.languages.JavaClientCodegen
io.swagger.codegen.languages.JaxRSServerCodegen
io.swagger.codegen.languages.JavaInflectorServerCodegen
@@ -28,3 +29,4 @@ io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen
io.swagger.codegen.languages.AkkaScalaClientCodegen
io.swagger.codegen.languages.CsharpDotNet2ClientCodegen
+io.swagger.codegen.languages.ClojureClientCodegen
diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache
index 9681634a765..9efea198f36 100644
--- a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache
@@ -12,26 +12,38 @@ namespace {{package}} {
*/
{{/description}}
export class {{classname}} {
- private basePath = '{{basePath}}';
+ protected basePath = '{{basePath}}';
+ public defaultHeaders : any = {};
static $inject: string[] = ['$http', '$httpParamSerializer'];
- constructor(private $http: ng.IHttpService, basePath?: string, private $httpParamSerializer?: (d: any) => any) {
+ constructor(protected $http: ng.IHttpService, protected $httpParamSerializer?: (d: any) => any, basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
+
+ private extendObj(objA: T1, objB: T2) {
+ for(let key in objB){
+ if(objB.hasOwnProperty(key)){
+ objA[key] = objB[key];
+ }
+ }
+ return objA;
+ }
+
{{#operation}}
-
+ /**
+ * {{summary}}
+ * {{notes}}
+ {{#allParams}}* @param {{paramName}} {{description}}
+ {{/allParams}}*/
public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
- let path = this.basePath + '{{path}}';
+ const path = this.basePath + '{{path}}'{{#pathParams}}
+ .replace('{' + '{{baseName}}' + '}', String({{paramName}})){{/pathParams}};
-{{#pathParams}}
- path = path.replace('{' + '{{baseName}}' + '}', String({{paramName}}));
-
-{{/pathParams}}
let queryParameters: any = {};
- let headerParams: any = {};
+ let headerParams: any = this.extendObj({}, this.defaultHeaders);
{{#hasFormParams}}
let formParams: any = {};
@@ -42,7 +54,6 @@ namespace {{package}} {
if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
}
-
{{/required}}
{{/allParams}}
{{#queryParams}}
@@ -61,7 +72,7 @@ namespace {{package}} {
{{/hasFormParams}}
{{#formParams}}
formParams['{{baseName}}'] = {{paramName}};
-
+
{{/formParams}}
let httpRequestParams: any = {
method: '{{httpMethod}}',
@@ -76,11 +87,7 @@ namespace {{package}} {
};
if (extraHttpRequestParams) {
- for (let k in extraHttpRequestParams) {
- if (extraHttpRequestParams.hasOwnProperty(k)) {
- httpRequestParams[k] = extraHttpRequestParams[k];
- }
- }
+ httpRequestParams = this.extendObj(httpRequestParams, extraHttpRequestParams);
}
return this.$http(httpRequestParams);
diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache
index 5b57ed4dc94..f4cfe923baa 100644
--- a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache
+++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache
@@ -18,7 +18,7 @@ namespace {{package}} {
* {{{description}}}
*/
{{/description}}
- {{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
+ {{name}}{{^required}}?{{/required}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
@@ -27,7 +27,7 @@ namespace {{package}} {
{{#vars}}
{{#isEnum}}
- export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
+ export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = '{{.}}',{{/values}}{{/allowableValues}}
}
{{/isEnum}}
@@ -36,4 +36,4 @@ namespace {{package}} {
{{/hasEnums}}
{{/model}}
{{/models}}
-}
\ No newline at end of file
+}
diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache
index 4d03ae0f424..c1f311fec19 100644
--- a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache
@@ -95,7 +95,11 @@ class VoidAuth implements Authentication {
*/
{{/description}}
export class {{classname}} {
- private basePath = '{{basePath}}';
+ protected basePath = '{{basePath}}';
+ protected defaultHeaders : any = {};
+
+
+
public authentications = {
'default': new VoidAuth(),
{{#authMethods}}
@@ -154,17 +158,25 @@ export class {{classname}} {
{{#isOAuth}}
{{/isOAuth}}
{{/authMethods}}
+ private extendObj(objA: T1, objB: T2) {
+ for(let key in objB){
+ if(objB.hasOwnProperty(key)){
+ objA[key] = objB[key];
+ }
+ }
+ return objA;
+ }
{{#operation}}
-
- public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> {
- let path = this.url + this.basePath + '{{path}}';
-
-{{#pathParams}}
- path = path.replace('{' + '{{baseName}}' + '}', String({{paramName}}));
-
-{{/pathParams}}
+ /**
+ * {{summary}}
+ * {{notes}}
+ {{#allParams}}* @param {{paramName}} {{description}}
+ {{/allParams}}*/
+ public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}}{{^returnType}}body?: any; {{/returnType}} }> {
+ const path = this.url + this.basePath + '{{path}}'{{#pathParams}}
+ .replace('{' + '{{baseName}}' + '}', String({{paramName}})){{/pathParams}};
let queryParameters: any = {};
- let headerParams: any = {};
+ let headerParams: any = this.extendObj({}, this.defaultHeaders);
let formParams: any = {};
{{#allParams}}{{#required}}
@@ -194,7 +206,7 @@ export class {{classname}} {
{{/isFile}}
{{/formParams}}
- let deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>();
+ let deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}}{{^returnType}}body?: any; {{/returnType}} }>();
let requestOptions: request.Options = {
method: '{{httpMethod}}',
diff --git a/modules/swagger-codegen/src/main/resources/clojure/api.mustache b/modules/swagger-codegen/src/main/resources/clojure/api.mustache
new file mode 100644
index 00000000000..a4425280f1b
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/clojure/api.mustache
@@ -0,0 +1,19 @@
+{{=< >=}}(ns .
+ (:require [.core :refer [call-api check-required-params]])
+ (:import (java.io File)))
+<#operations><#operation>
+(defn
+ "<&summary><#notes>
+ <¬es>"<#hasOptionalParams>
+ ([<#allParams><#required><#isFile>^File ] (<#allParams><#required> nil))
+ <#hasOptionalParams>([<#allParams><#required><#isFile>^File <#hasOptionalParams>{:keys [<#allParams><^required><#isFile>^File ]}]<#hasRequiredParams>
+ <#hasOptionalParams> (check-required-params<#allParams><#required> )
+ <#hasOptionalParams> (call-api "" :
+ <#hasOptionalParams> {:path-params {<#pathParams>"" }
+ <#hasOptionalParams> :header-params {<#headerParams>"" }
+ <#hasOptionalParams> :query-params {<#queryParams>"" }
+ <#hasOptionalParams> :form-params {<#formParams>"" }<#bodyParam>
+ <#hasOptionalParams> :body-param
+ <#hasOptionalParams> :content-types [<#consumes>""<#hasMore> ]
+ <#hasOptionalParams> :accepts [<#produces>""<#hasMore> ]}))<#hasOptionalParams>)
+
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/clojure/core.mustache b/modules/swagger-codegen/src/main/resources/clojure/core.mustache
new file mode 100644
index 00000000000..32aa8a6bc0d
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/clojure/core.mustache
@@ -0,0 +1,178 @@
+(ns {{{baseNamespace}}}.core
+ (:require [cheshire.core :refer [generate-string parse-string]]
+ [clojure.string :as str]
+ [clj-http.client :as client])
+ (:import (com.fasterxml.jackson.core JsonParseException)
+ (java.io File)
+ (java.util Date TimeZone)
+ (java.text SimpleDateFormat)))
+
+(def default-api-context
+ "Default API context."
+ {:base-url "http://petstore.swagger.io/v2"
+ :date-format "yyyy-MM-dd"
+ :datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
+ :debug false})
+
+(def ^:dynamic *api-context*
+ "Dynamic API context to be applied in API calls."
+ default-api-context)
+
+(defmacro with-api-context
+ "A helper macro to wrap *api-context* with default values."
+ [context & body]
+ `(binding [*api-context* (merge *api-context* ~context)]
+ ~@body))
+
+(defmacro check-required-params
+ "Throw exception if the given parameter value is nil."
+ [& params]
+ (->> params
+ (map (fn [p]
+ `(if (nil? ~p)
+ (throw (IllegalArgumentException. ~(str "The parameter \"" p "\" is required"))))))
+ (list* 'do)))
+
+(defn- make-date-format
+ ([format-str] (make-date-format format-str nil))
+ ([format-str time-zone]
+ (let [date-format (SimpleDateFormat. format-str)]
+ (when time-zone
+ (.setTimeZone date-format (TimeZone/getTimeZone time-zone)))
+ date-format)))
+
+(defn format-date
+ "Format the given Date object with the :date-format defined in *api-options*.
+ NOTE: The UTC time zone is used."
+ [^Date date]
+ (let [{:keys [date-format]} *api-context*]
+ (-> (make-date-format date-format "UTC")
+ (.format date))))
+
+(defn parse-date
+ "Parse the given string to a Date object with the :date-format defined in *api-options*.
+ NOTE: The UTC time zone is used."
+ [^String s]
+ (let [{:keys [date-format]} *api-context*]
+ (-> (make-date-format date-format "UTC")
+ (.parse s))))
+
+(defn format-datetime
+ "Format the given Date object with the :datetime-format defined in *api-options*.
+ NOTE: The system's default time zone is used when not provided."
+ ([^Date date] (format-datetime date nil))
+ ([^Date date ^String time-zone]
+ (let [{:keys [datetime-format]} *api-context*]
+ (-> (make-date-format datetime-format time-zone)
+ (.format date)))))
+
+(defn parse-datetime
+ "Parse the given string to a Date object with the :datetime-format defined in *api-options*.
+ NOTE: The system's default time zone is used when not provided."
+ ([^String s] (parse-datetime s nil))
+ ([^String s ^String time-zone]
+ (let [{:keys [datetime-format]} *api-context*]
+ (-> (make-date-format datetime-format time-zone)
+ (.parse s)))))
+
+(defn param-to-str [param]
+ "Format the given parameter value to string."
+ (cond
+ (instance? Date param) (format-datetime param)
+ (sequential? param) (str/join "," param)
+ :else (str param)))
+
+(defn make-url
+ "Make full URL by adding base URL and filling path parameters."
+ [path path-params]
+ (let [path (reduce (fn [p [k v]]
+ (str/replace p (re-pattern (str "\\{" k "\\}")) (param-to-str v)))
+ path
+ path-params)]
+ (str (:base-url *api-context*) path)))
+
+(defn normalize-param
+ "Normalize parameter value, handling three cases:
+ for sequential value, normalize each elements of it;
+ for File value, do nothing with it;
+ otherwise, call `param-to-string`."
+ [param]
+ (cond
+ (sequential? param) (map normalize-param param)
+ (instance? File param) param
+ :else (param-to-str param)))
+
+(defn normalize-params
+ "Normalize parameters values: remove nils, format to string with `param-to-str`."
+ [params]
+ (->> params
+ (remove (comp nil? second))
+ (map (fn [[k v]] [k (normalize-param v)]))
+ (into {})))
+
+(defn json-mime? [mime]
+ "Check if the given MIME is a standard JSON MIME or :json."
+ (if mime
+ (or (= :json mime)
+ (re-matches #"application/json(;.*)?" (name mime)))))
+
+(defn json-preferred-mime [mimes]
+ "Choose a MIME from the given MIMEs with JSON preferred,
+ i.e. return JSON if included, otherwise return the first one."
+ (-> (filter json-mime? mimes)
+ first
+ (or (first mimes))))
+
+(defn serialize
+ "Serialize the given data according to content-type.
+ Only JSON is supported for now."
+ [data content-type]
+ (if (json-mime? content-type)
+ (generate-string data {:date-format (:datetime-format *api-context*)})
+ (throw (IllegalArgumentException. (str "Content type \"" content-type "\" is not support for serialization")))))
+
+(defn deserialize
+ "Deserialize the given HTTP response according to the Content-Type header."
+ [{:keys [body] {:keys [content-type]} :headers}]
+ (cond
+ (json-mime? content-type)
+ (try
+ (parse-string body true)
+ (catch JsonParseException e
+ ;; return the body string directly on JSON parsing error
+ body))
+ ;; for non-JSON response, return the body string directly
+ :else body))
+
+(defn form-params-to-multipart
+ "Convert the given form parameters map into a vector as clj-http's :multipart option."
+ [form-params]
+ (->> form-params
+ (map (fn [[k v]] (array-map :name k :content v)))
+ vec))
+
+(defn call-api
+ "Call an API by making HTTP request and return its response."
+ [path method {:keys [path-params query-params header-params form-params body-param content-types accepts]}]
+ (let [{:keys [debug]} *api-context*
+ url (make-url path path-params)
+ content-type (or (json-preferred-mime content-types)
+ (and body-param :json))
+ accept (or (json-preferred-mime accepts) :json)
+ multipart? (= "multipart/form-data" content-type)
+ opts (cond-> {:url url :method method}
+ accept (assoc :accept accept)
+ (seq query-params) (assoc :query-params (normalize-params query-params))
+ (seq header-params) (assoc :header-params (normalize-params header-params))
+ (and content-type (not multipart?)) (assoc :content-type content-type)
+ multipart? (assoc :multipart (-> form-params
+ normalize-params
+ form-params-to-multipart))
+ (and (not multipart?) (seq form-params)) (assoc :form-params (normalize-params form-params))
+ body-param (assoc :body (serialize body-param content-type))
+ debug (assoc :debug true :debug-body true))
+ resp (client/request opts)]
+ (when debug
+ (println "Response:")
+ (println resp))
+ (deserialize resp)))
diff --git a/modules/swagger-codegen/src/main/resources/clojure/project.mustache b/modules/swagger-codegen/src/main/resources/clojure/project.mustache
new file mode 100644
index 00000000000..c403c9c43c6
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/clojure/project.mustache
@@ -0,0 +1,8 @@
+{{=< >=}}(defproject <&projectName> "<&projectVersion>"
+ :description "<&projectDescription>"<#projectUrl>
+ :url "<&projectUrl>"<#licenseName>
+ :license {:name "<&licenseName>"<#licenseUrl>
+ :url "<&licenseUrl>"}
+ :dependencies [[org.clojure/clojure "1.7.0"]
+ [clj-http "2.0.0"]
+ [cheshire "5.5.0"]])
diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache
index f6dd2933331..87d55ab3f6e 100644
--- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache
@@ -10,7 +10,6 @@ using System.Net;
using System.Text;
using Newtonsoft.Json;
using RestSharp;
-using RestSharp.Extensions;
namespace {{packageName}}.Client
{
@@ -171,7 +170,7 @@ namespace {{packageName}}.Client
/// Escaped string.
public string EscapeString(string str)
{
- return RestSharp.Extensions.StringExtensions.UrlEncode(str);
+ return UrlEncode(str);
}
///
@@ -183,9 +182,9 @@ namespace {{packageName}}.Client
public FileParameter ParameterToFile(string name, Stream stream)
{
if (stream is FileStream)
- return FileParameter.Create(name, stream.ReadAsBytes(), Path.GetFileName(((FileStream)stream).Name));
+ return FileParameter.Create(name, ReadAsBytes(stream), Path.GetFileName(((FileStream)stream).Name));
else
- return FileParameter.Create(name, stream.ReadAsBytes(), "no_file_name_provided");
+ return FileParameter.Create(name, ReadAsBytes(stream), "no_file_name_provided");
}
///
@@ -319,8 +318,7 @@ namespace {{packageName}}.Client
{
{{#authMethods}}
case "{{name}}":
- {{#isApiKey}}{{#isKeyInHeader}}headerParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInHeader}}{{#isKeyInQuery}}queryParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}headerParams["Authorization"] = "Basic " + Base64Encode(Configuration.Username + ":" + Configuration.Password);{{/isBasic}}
- {{#isOAuth}}//TODO support oauth{{/isOAuth}}
+ {{#isApiKey}}{{#isKeyInHeader}}headerParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInHeader}}{{#isKeyInQuery}}queryParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}headerParams["Authorization"] = "Basic " + Base64Encode(Configuration.Username + ":" + Configuration.Password);{{/isBasic}}{{#isOAuth}}headerParams["Authorization"] = "Bearer " + Configuration.AccessToken;{{/isOAuth}}
break;
{{/authMethods}}
default:
@@ -366,6 +364,62 @@ namespace {{packageName}}.Client
public static dynamic ConvertType(dynamic source, Type dest) {
return Convert.ChangeType(source, dest);
}
+
+ ///
+ /// Convert stream to byte array
+ /// Credit/Ref: http://stackoverflow.com/a/221941/677735
+ ///
+ /// Input stream to be converted
+ /// Byte array
+ public static byte[] ReadAsBytes(Stream input)
+ {
+ byte[] buffer = new byte[16*1024];
+ using (MemoryStream ms = new MemoryStream())
+ {
+ int read;
+ while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ ms.Write(buffer, 0, read);
+ }
+ return ms.ToArray();
+ }
+ }
+
+ ///
+ /// URL encode a string
+ /// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50
+ ///
+ /// String to be URL encoded
+ /// Byte array
+ public static string UrlEncode(string input)
+ {
+ const int maxLength = 32766;
+
+ if (input == null)
+ {
+ throw new ArgumentNullException("input");
+ }
+
+ if (input.Length <= maxLength)
+ {
+ return Uri.EscapeDataString(input);
+ }
+
+ StringBuilder sb = new StringBuilder(input.Length * 2);
+ int index = 0;
+
+ while (index < input.Length)
+ {
+ int length = Math.Min(input.Length - index, maxLength);
+ string subString = input.Substring(index, length);
+
+ sb.Append(Uri.EscapeDataString(subString));
+ index += subString.Length;
+ }
+
+ return sb.ToString();
+ }
+
}
}
diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache
index 67b07069e2f..79b20c6062c 100644
--- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache
+++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache
@@ -37,6 +37,12 @@ namespace {{packageName}}.Client
/// The password.
public static String Password { get; set; }
+ ///
+ /// Gets or sets the access token for OAuth2 authentication.
+ ///
+ /// The access token.
+ public static String AccessToken { get; set; }
+
///
/// Gets or sets the API key based on the authentication name.
///
diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache
index 89594091dfb..6708fa1e16d 100644
--- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache
@@ -102,7 +102,7 @@ namespace {{packageName}}.Api
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
{{/required}}{{/allParams}}
- var path = "{{path}}";
+ var path_ = "{{path}}";
var pathParams = new Dictionary();
var queryParams = new Dictionary();
@@ -137,7 +137,7 @@ namespace {{packageName}}.Api
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
// make the HTTP request
- IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams, authSettings);
+ IRestResponse response = (IRestResponse) ApiClient.CallApi(path_, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams, authSettings);
if (((int)response.StatusCode) >= 400)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
@@ -158,7 +158,7 @@ namespace {{packageName}}.Api
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
{{/required}}{{/allParams}}
- var path = "{{path}}";
+ var path_ = "{{path}}";
var pathParams = new Dictionary();
var queryParams = new Dictionary();
@@ -193,7 +193,7 @@ namespace {{packageName}}.Api
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
// make the HTTP request
- IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams, authSettings);
+ IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path_, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams, authSettings);
if (((int)response.StatusCode) >= 400)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
diff --git a/modules/swagger-codegen/src/main/resources/csharp/model.mustache b/modules/swagger-codegen/src/main/resources/csharp/model.mustache
index 99da4f8302a..d40ece4cc02 100644
--- a/modules/swagger-codegen/src/main/resources/csharp/model.mustache
+++ b/modules/swagger-codegen/src/main/resources/csharp/model.mustache
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache
new file mode 100644
index 00000000000..ed64b667558
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/README.mustache
@@ -0,0 +1,27 @@
+# Swagger generated server
+
+## Overview
+This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the
+[swagger-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 flask server.
+
+This example uses the [connexion](https://github.com/zalando/connexion) library on top of Flask.
+
+To run the server, please execute the following:
+
+```
+python3 app.py
+```
+
+and open your browser to here:
+
+```
+http://localhost:{{serverPort}}/ui
+```
+
+Your swagger definition lives here:
+
+```
+http://localhost:{{serverPort}}{{basePathWithoutHost}}/swagger.json
+```
+
diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache
new file mode 100644
index 00000000000..14af64be6f9
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/app.mustache
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import connexion
+
+if __name__ == '__main__':
+ app = connexion.App(__name__, {{serverPort}},
+ specification_dir='./swagger/')
+ app.add_api('swagger.yaml', arguments={'title': '{{appDescription}}'})
+ app.run()
diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache
new file mode 100644
index 00000000000..cb8544aa1b4
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache
@@ -0,0 +1,11 @@
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+{{#operation}}
+
+def {{vendorExtensions.x-operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> str:
+ return 'do some magic!'
+{{/operation}}
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/flaskConnexion/swagger.mustache b/modules/swagger-codegen/src/main/resources/flaskConnexion/swagger.mustache
new file mode 100644
index 00000000000..51560926bba
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/flaskConnexion/swagger.mustache
@@ -0,0 +1 @@
+{{{swagger-yaml}}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/htmlDocs/index.mustache b/modules/swagger-codegen/src/main/resources/htmlDocs/index.mustache
index 9473309ff83..83cd24e72d0 100644
--- a/modules/swagger-codegen/src/main/resources/htmlDocs/index.mustache
+++ b/modules/swagger-codegen/src/main/resources/htmlDocs/index.mustache
@@ -94,17 +94,15 @@
{{/hasFormParams}}
-
+
{{#hasExamples}}
{{#examples}}
diff --git a/modules/swagger-codegen/src/main/resources/nodejs/controller.mustache b/modules/swagger-codegen/src/main/resources/nodejs/controller.mustache
index 85d1f3211a1..0f0c35bc0ee 100644
--- a/modules/swagger-codegen/src/main/resources/nodejs/controller.mustache
+++ b/modules/swagger-codegen/src/main/resources/nodejs/controller.mustache
@@ -9,17 +9,7 @@ var {{classname}} = require('./{{classname}}Service');
{{#operation}}
module.exports.{{nickname}} = function {{nickname}} (req, res, next) {
- {{#allParams}}var {{paramName}} = req.swagger.params['{{baseName}}'].value;
- {{/allParams}}
-
- var result = {{classname}}.{{nickname}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
-
- if(typeof result !== 'undefined') {
- res.setHeader('Content-Type', 'application/json');
- res.end(JSON.stringify(result || {}, null, 2));
- }
- else
- res.end();
+ {{classname}}.{{nickname}}(req.swagger.params, res, next);
};
{{/operation}}
{{/operations}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/nodejs/index.mustache b/modules/swagger-codegen/src/main/resources/nodejs/index.mustache
index 419b3fb5e63..397661d4d52 100644
--- a/modules/swagger-codegen/src/main/resources/nodejs/index.mustache
+++ b/modules/swagger-codegen/src/main/resources/nodejs/index.mustache
@@ -3,7 +3,8 @@
var app = require('connect')();
var http = require('http');
var swaggerTools = require('swagger-tools');
-
+var jsyaml = require('js-yaml');
+var fs = require('fs');
var serverPort = {{serverPort}};
// swaggerRouter configuration
@@ -14,7 +15,8 @@ var options = {
};
// The Swagger document (require it, build it programmatically, fetch it from a URL, ...)
-var swaggerDoc = require('./api/swagger.json');
+var spec = fs.readFileSync('./api/swagger.yaml', 'utf8');
+var swaggerDoc = jsyaml.safeLoad(spec);
// Initialize the Swagger middleware
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
diff --git a/modules/swagger-codegen/src/main/resources/nodejs/package.mustache b/modules/swagger-codegen/src/main/resources/nodejs/package.mustache
index 89db4c0b91e..86aa21af635 100644
--- a/modules/swagger-codegen/src/main/resources/nodejs/package.mustache
+++ b/modules/swagger-codegen/src/main/resources/nodejs/package.mustache
@@ -10,6 +10,7 @@
"private": true,
"dependencies": {
"connect": "^3.2.0",
- "swagger-tools": "0.8.*"
+ "js-yaml": "^3.3.0",
+ "swagger-tools": "0.9.*"
}
}
diff --git a/modules/swagger-codegen/src/main/resources/nodejs/service.mustache b/modules/swagger-codegen/src/main/resources/nodejs/service.mustache
index d7c2ade5079..5073d249275 100644
--- a/modules/swagger-codegen/src/main/resources/nodejs/service.mustache
+++ b/modules/swagger-codegen/src/main/resources/nodejs/service.mustache
@@ -2,17 +2,27 @@
{{#operations}}
{{#operation}}
-exports.{{nickname}} = function({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
+exports.{{nickname}} = function(args, res, next) {
+ /**
+ * parameters expected in the args:
+ {{#allParams}}* {{paramName}} ({{dataType}})
+ {{/allParams}}**/
- var examples = {};
+var examples = {};
{{#examples}}
examples['{{contentType}}'] = {{{example}}};
{{/examples}}
{{#returnType}}
- if(Object.keys(examples).length > 0)
- return examples[Object.keys(examples)[0]];
+ if(Object.keys(examples).length > 0) {
+ res.setHeader('Content-Type', 'application/json');
+ res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2));
+ }
+ else {
+ res.end();
+ }
{{/returnType}}
+ {{^returnType}}res.end();{{/returnType}}
}
{{/operation}}
{{/operations}}
diff --git a/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache b/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache
index 1d0f7d78162..51560926bba 100644
--- a/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache
+++ b/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache
@@ -1,43 +1 @@
-{
- "swagger": "2.0",
- "info": {
- "title": "{{appName}}",
- "description": "{{{appDescription}}}",
- "version": "{{apiVersion}}"
- },
-{{#apiInfo}}
- "produces": ["application/json"],
- "host": "localhost:{{serverPort}}",
- "basePath": "{{contextPath}}",
- "paths": {
-{{#apis}}
-{{#operations}}
- {{#operationsByPath}}
- "{{{path}}}": {
- {{#operation}}
- "{{httpMethod}}": {
- "summary": "{{summary}}",
- "description":"{{notes}}",
- "x-swagger-router-controller": "{{classname}}",
- "tags": ["{{baseName}}"],
- "operationId": "{{operationId}}",{{#hasParams}}
- "parameters": [
- {{#allParams}}{{{jsonSchema}}}{{#hasMore}},{{/hasMore}}
- {{/allParams}}
- ],{{/hasParams}}
- "responses": {
- {{#responses}}"{{code}}": {{{jsonSchema}}}
- {{#hasMore}},{{/hasMore}}
- {{/responses}}
- }
- } {{#hasMore}},{{/hasMore}}
- {{/operation}}
- } {{#hasMore}},{{/hasMore}}
- {{/operationsByPath}}
-{{/operations}}
-{{/apis}}
-{{/apiInfo}}
- }, "definitions": {
- {{#models}}{{#model}}"{{classVarName}}": {{{modelJson}}}{{#hasMoreModels}},{{/hasMoreModels}}{{/model}}{{/models}}
- }
-}
+{{{swagger-yaml}}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache
index fa88dbd0333..bf1220912d2 100644
--- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache
@@ -20,7 +20,9 @@ use Module::Runtime qw(use_module);
use WWW::{{moduleName}}::Configuration;
-sub new
+use base 'Class::Singleton';
+
+sub _new_instance
{
my $class = shift;
my (%args) = (
@@ -32,6 +34,8 @@ sub new
return bless \%args, $class;
}
+sub _cfg {'WWW::{{moduleName}}::Configuration'}
+
# Set the user agent of the API client
#
# @param string $user_agent The user agent of the API client
@@ -118,10 +122,12 @@ sub call_api {
$self->{ua}->timeout($self->{http_timeout} || $WWW::{{moduleName}}::Configuration::http_timeout);
$self->{ua}->agent($self->{http_user_agent} || $WWW::{{moduleName}}::Configuration::http_user_agent);
+ $log->debugf("REQUEST: %s", $_request->as_string);
my $_response = $self->{ua}->request($_request);
+ $log->debugf("RESPONSE: %s", $_response->as_string);
unless ($_response->is_success) {
- croak("API Exception(".$_response->code."): ".$_response->message);
+ croak(sprintf "API Exception(%s): %s\n%s", $_response->code, $_response->message, $_response->content);
}
return $_response->content;
@@ -146,8 +152,8 @@ sub to_path_value {
# @return string the serialized object
sub to_query_value {
my ($self, $object) = @_;
- if (is_array($object)) {
- return implode(',', $object);
+ if (ref($object) eq 'ARRAY') {
+ return join(',', @$object);
} else {
return $self->to_string($object);
}
@@ -286,23 +292,26 @@ sub select_header_content_type
# @return string API key with the prefix
sub get_api_key_with_prefix
{
- my ($self, $api_key) = @_;
- if ($WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}) {
- return $WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{moduleName}}::Configuration::api_key->{$api_key};
- } else {
- return $WWW::{{moduleName}}::Configuration::api_key->{$api_key};
- }
-}
+ my ($self, $key_name) = @_;
-# update hearder and query param based on authentication setting
+ my $api_key = $WWW::{{moduleName}}::Configuration::api_key->{$key_name};
+
+ return unless $api_key;
+
+ my $prefix = $WWW::{{moduleName}}::Configuration::api_key_prefix->{$key_name};
+ return $prefix ? "$prefix $api_key" : $api_key;
+}
+
+# update header and query param based on authentication setting
#
# @param array $headerParams header parameters (by ref)
# @param array $queryParams query parameters (by ref)
# @param array $authSettings array of authentication scheme (e.g ['api_key'])
sub update_params_for_auth {
my ($self, $header_params, $query_params, $auth_settings) = @_;
-
- return if (!defined($auth_settings) || scalar(@$auth_settings) == 0);
+
+ return $self->_global_auth_setup($header_params, $query_params)
+ unless $auth_settings && @$auth_settings;
# one endpoint can have more than 1 auth settings
foreach my $auth (@$auth_settings) {
@@ -311,14 +320,51 @@ sub update_params_for_auth {
}
{{#authMethods}}elsif ($auth eq '{{name}}') {
{{#isApiKey}}{{#isKeyInHeader}}$header_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$query_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$header_params->{'Authorization'} = 'Basic '.encode_base64($WWW::{{moduleName}}::Configuration::username.":".$WWW::{{moduleName}}::Configuration::password);{{/isBasic}}
- {{#isOAuth}}# TODO support oauth{{/isOAuth}}
+ {{#isOAuth}}$header_params->{'Authorization'} = 'Bearer ' . $WWW::{{moduleName}}::Configuration::access_token;{{/isOAuth}}
}
{{/authMethods}}
else {
- # TODO show warning about security definition not found
+ # TODO show warning about security definition not found
}
}
}
+# The endpoint API class has not found any settings for auth. This may be deliberate,
+# in which case update_params_for_auth() will be a no-op. But it may also be that the
+# swagger spec does not describe the intended authorization. So we check in the config for any
+# auth tokens and if we find any, we use them for all endpoints;
+sub _global_auth_setup {
+ my ($self, $header_params, $query_params) = @_;
+
+ my $tokens = $self->_cfg->get_tokens;
+ return unless keys %$tokens;
+
+ # basic
+ if (my $uname = delete $tokens->{username}) {
+ my $pword = delete $tokens->{password};
+ $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword);
+ }
+
+ # oauth
+ if (my $access_token = delete $tokens->{access_token}) {
+ $header_params->{'Authorization'} = 'Bearer ' . $access_token;
+ }
+
+ # other keys
+ foreach my $token_name (keys %$tokens) {
+ my $in = $tokens->{$token_name}->{in};
+ my $token = $self->get_api_key_with_prefix($token_name);
+ if ($in eq 'head') {
+ $header_params->{$token_name} = $token;
+ }
+ elsif ($in eq 'query') {
+ $query_params->{$token_name} = $token;
+ }
+ else {
+ die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')";
+ }
+ }
+}
+
1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache
new file mode 100644
index 00000000000..fc119f7a902
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache
@@ -0,0 +1,100 @@
+package WWW::{{moduleName}}::ApiFactory;
+
+use strict;
+use warnings;
+use utf8;
+
+use Carp;
+use Module::Find;
+
+usesub WWW::{{moduleName}}::Object;
+
+use WWW::{{moduleName}}::ApiClient;
+
+=head1 Name
+
+ WWW::{{moduleName}}::ApiFactory - constructs APIs to retrieve {{moduleName}} objects
+
+=head1 Synopsis
+
+ package My::Petstore::App;
+
+ use WWW::{{moduleName}}::ApiFactory;
+
+ my $api_factory = WWW::{{moduleName}}::ApiFactory->new( ... ); # any args for ApiClient constructor
+
+ # later...
+ my $pet_api = $api_factory->get_api('Pet');
+
+ # $pet_api isa WWW::{{moduleName}}::PetApi
+
+ my $pet = $pet_api->get_pet_by_id(pet_id => $pet_id);
+
+ # object attributes have proper accessors:
+ printf "Pet's name is %s", $pet->name;
+
+ # change the value stored on the object:
+ $pet->name('Dave');
+
+=cut
+
+# Load all the API classes and construct a lookup table at startup time
+my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ }
+ grep {$_ =~ /Api$/}
+ usesub 'WWW::{{moduleName}}';
+
+=head1 new()
+
+ Any parameters are optional, and are passed to and stored on the api_client object.
+
+ base_url: (optional)
+ supply this to change the default base URL taken from the Swagger definition.
+
+=cut
+
+sub new {
+ my ($class, %p) = (shift, @_);
+ $p{api_client} = WWW::{{moduleName}}::ApiClient->instance(%p);
+ return bless \%p, $class;
+}
+
+=head1 get_api($which)
+
+ Returns an API object of the requested type.
+
+ $which is a nickname for the class:
+
+ WWW::FooBarClient::BazApi has nickname 'Baz'
+
+=cut
+
+sub get_api {
+ my ($self, $which) = @_;
+ croak "API not specified" unless $which;
+ my $api_class = $_apis{"${which}Api"} || croak "No known API for '$which'";
+ return $api_class->new(api_client => $self->api_client);
+}
+
+=head1 api_client()
+
+ Returns the api_client object, should you ever need it.
+
+=cut
+
+sub api_client { $_[0]->{api_client} }
+
+=head1 apis_available()
+=cut
+
+sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis }
+
+=head1 classname_for()
+=cut
+
+sub classname_for {
+ my ($self, $api_name) = @_;
+ return $_apis{"${api_name}Api"};
+}
+
+
+1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache
new file mode 100644
index 00000000000..76da048b069
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache
@@ -0,0 +1,427 @@
+package WWW::{{moduleName}}::Role::AutoDoc;
+use List::MoreUtils qw(uniq);
+
+use Moose::Role;
+
+sub autodoc {
+ my ($self, $how) = @_;
+
+ die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/;
+
+ $self->_printisa($how);
+ $self->_printmethods($how);
+ $self->_printattrs($how);
+ print "\n";
+}
+
+sub _printisa {
+ my ($self, $how) = @_;
+ my $meta = $self->meta;
+
+ my $myclass = ref $self;
+
+ my $super = join ', ', $meta->superclasses;
+ my @roles = $meta->calculate_all_roles;
+ #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles
+
+ my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa;
+ my $sub = join ', ', $meta->subclasses;
+ my $dsub = join ', ', $meta->direct_subclasses;
+
+ my $app_name = $self->version_info->{app_name};
+ my $app_version = $self->version_info->{app_version};
+ my $generated_date = $self->version_info->{generated_date};
+ my $generator_class = $self->version_info->{generator_class};
+
+ $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT';
+ write;
+
+ my ($rolepkg, $role_reqs);
+
+ foreach my $role (@roles) {
+ $rolepkg = $role->{package} || next; # some are anonymous, or something
+ next if $rolepkg eq 'WWW::{{moduleName}}::Role::AutoDoc';
+ $role_reqs = join ', ', keys %{$role->{required_methods}};
+ $role_reqs ||= '';
+ $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES';
+ write;
+ }
+
+ if ($how eq 'pod') {
+ $~ = 'ROLES_POD_CLOSE';
+ write;
+ }
+
+# ----- format specs -----
+ format INHERIT =
+
+@* -
+$myclass
+ ISA: @*
+ $isa
+ Direct subclasses: @*
+ $dsub
+ All subclasses: @*
+ $sub
+
+ Target API: @* @*
+ $app_name, $app_version
+ Generated on: @*
+ $generated_date
+ Generator class: @*
+ $generator_class
+
+.
+ format ROLES =
+ Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~
+ $rolepkg
+ requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~
+ $role_reqs
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $role_reqs
+.
+
+ format INHERIT_POD =
+=head1 NAME
+
+@*
+$myclass
+
+=head1 VERSION
+
+=head2 @* version: @*
+ $app_name, $app_version
+
+Automatically generated by the Perl Swagger Codegen project:
+
+=over 4
+
+=item Build date: @*
+ $generated_date
+
+=item Build package: @*
+ $generator_class
+
+=item Codegen version:
+
+
+=back
+
+=head1 INHERITANCE
+
+=head2 Base class(es)
+
+@*
+$isa
+
+=head2 Direct subclasses
+
+@*
+$dsub
+
+=head2 All subclasses
+
+@*
+$sub
+
+
+=head1 COMPOSITION
+
+@* composes the following roles:
+$myclass
+
+
+.
+ format ROLES_POD =
+=head2 C<@*>
+ $rolepkg
+
+Requires:
+
+@*
+$role_reqs
+
+.
+ format ROLES_POD_CLOSE =
+
+
+.
+# ----- / format specs -----
+}
+
+sub _printmethods {
+ my ($self, $how) = @_;
+
+ if ($how eq 'narrow') {
+ print <_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list,
+
+ if ($how eq 'pod') {
+ $~ = 'METHOD_POD_CLOSE';
+ write;
+ }
+
+
+}
+
+sub _printmethod {
+ my ($self, $methodname, $how) = @_;
+ return if $methodname =~ /^_/;
+ return if $self->meta->has_attribute($methodname);
+ my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY
+ DOES isa BUILDALL does VERSION dump
+ );
+ return if $internal{$methodname};
+ my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose
+
+ return if $method->original_package_name eq __PACKAGE__;
+
+ my $delegate_to = '';
+ my $via = '';
+ my $on = '';
+ my $doc = '';
+ my $original_pkg = $method->original_package_name;
+ if ($method->can('associated_attribute')) {
+ $delegate_to = $method->delegate_to_method;
+ my $aa = $method->associated_attribute;
+ $on = $aa->{isa};
+ $via = $aa->{name};
+ $original_pkg = $on;
+ $doc = $original_pkg->method_documentation->{$delegate_to}->{summary};
+ }
+ else {
+ $doc = $method->documentation;
+ }
+
+ if ($how eq 'narrow') {
+ $~ = 'METHOD_NARROW';
+ write;
+ }
+ elsif ($how eq 'pod' and $delegate_to) {
+ $~ = 'METHOD_POD_DELEGATED';
+ write;
+ }
+ elsif ($how eq 'pod') {
+ $~ = 'METHOD_POD';
+ write;
+ }
+ else {
+ $~ = 'METHOD';
+ write;
+ }
+
+# ----- format specs -----
+ format METHODHEAD =
+
+METHODS
+-------
+Name delegates to on via
+===========================================================================================================================================================================
+.
+ format METHOD =
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<...
+$methodname, $delegate_to, $on, $via
+.
+
+ format METHOD_NARROW =
+@*
+$methodname
+ original pkg: @*
+ $original_pkg
+ delegates to: @*
+ $delegate_to
+ on: @*
+ $on
+ via: @*
+ $via
+
+.
+
+ format METHODHEAD_POD =
+
+=head1 METHODS
+
+.
+
+ format METHOD_POD =
+
+=head2 C<@*()>
+ $methodname
+
+ Defined in: @*
+ $original_pkg
+
+
+.
+ format METHOD_POD_DELEGATED =
+
+=head2 C<@*()>
+ $methodname
+
+ Defined in: @*
+ $original_pkg
+ Delegates to: @*()
+ $delegate_to
+ On: @*
+ $on
+ Via: @*()
+ $via
+ Doc: @*
+ $doc
+ Same as: $self->@*->@*()
+ $via, $delegate_to
+
+.
+ format METHOD_POD_CLOSE =
+
+.
+# ----- / format specs -----
+}
+
+sub _printattrs {
+ my ($self, $how) = @_;
+
+ if ($how eq 'narrow') {
+ print <_printattr($_, $how) for sort $self->meta->get_attribute_list;
+
+ if ($how eq 'pod') {
+ $~ = 'ATTR_POD_CLOSE';
+ write;
+ }
+}
+
+sub _printattr {
+ my ($self, $attrname, $how) = @_;
+ return if $attrname =~ /^_/;
+ my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname";
+
+ my $is;
+ $is = 'rw' if $attr->get_read_method && $attr->get_write_method;
+ $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method;
+ $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method;
+ $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method;
+ $is or die "No \$is for $attrname";
+
+ my $tc = $attr->type_constraint || '';
+ my $from = $attr->associated_class->name || '';
+ my $reqd = $attr->is_required ? 'yes' : 'no';
+ my $lazy = $attr->is_lazy ? 'yes' : 'no';
+ my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have
+ my $doc = $attr->documentation || '';
+ my $handles = join ', ', sort @{$attr->handles || []};
+ $handles ||= '';
+
+ if ($how eq 'narrow') {
+ $~ = 'ATTR_NARROW';
+ }
+ elsif ($how eq 'pod') {
+ $~ = 'ATTR_POD';
+ }
+ else {
+ $~ = 'ATTR';
+ }
+
+ write;
+
+# ----- format specs -----
+ format ATTRHEAD =
+
+ATTRIBUTES
+----------
+Name is isa reqd lazy doc handles
+==============================================================================================================
+.
+ format ATTR =
+@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+.
+
+ format ATTR_NARROW =
+@*
+$attrname
+ is: @*
+ $is
+ isa: @*
+ $tc
+ reqd: @*
+ $reqd
+ lazy: @*
+ $lazy
+ doc: @*
+ $doc
+ handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+
+.
+ format ATTRHEAD_POD =
+=head1 ATTRIBUTES
+
+.
+ format ATTR_POD =
+
+=head2 C<@*>
+ $attrname
+
+ is: @*
+ $is
+ isa: @*
+ $tc
+ reqd: @*
+ $reqd
+ lazy: @*
+ $lazy
+ doc: @*
+ $doc
+ handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $handles
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $handles
+
+.
+ format ATTR_POD_CLOSE =
+
+
+.
+# ----- / format specs -----
+}
+
+
+
+1;
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache
index e740ea593ab..a41931940ba 100644
--- a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache
@@ -11,6 +11,8 @@ use Log::Any qw($log);
use Date::Parse;
use DateTime;
+use base ("Class::Accessor", "Class::Data::Inheritable");
+
#
#
@@ -18,8 +20,26 @@ use DateTime;
#NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
#
+__PACKAGE__->mk_classdata('attribute_map' => {});
+__PACKAGE__->mk_classdata('swagger_types' => {});
+__PACKAGE__->mk_classdata('method_documentation' => {});
+__PACKAGE__->mk_classdata('class_documentation' => {});
-# return json string
+# new object
+sub new {
+ my ($class, %args) = @_;
+
+ my $self = bless {}, $class;
+
+ foreach my $attribute (keys %{$class->attribute_map}) {
+ my $args_key = $class->attribute_map->{$attribute};
+ $self->$attribute( $args{ $args_key } );
+ }
+
+ return $self;
+}
+
+# return perl hash
sub to_hash {
return decode_json(JSON->new->convert_blessed->encode( shift ));
}
@@ -28,36 +48,38 @@ sub to_hash {
sub TO_JSON {
my $self = shift;
my $_data = {};
- foreach my $_key (keys %{$self->get_attribute_map}) {
+ foreach my $_key (keys %{$self->attribute_map}) {
if (defined $self->{$_key}) {
- $_data->{$self->get_attribute_map->{$_key}} = $self->{$_key};
+ $_data->{$self->attribute_map->{$_key}} = $self->{$_key};
}
}
return $_data;
}
-# from json string
+# from Perl hashref
sub from_hash {
my ($self, $hash) = @_;
+
# loop through attributes and use swagger_types to deserialize the data
- while ( my ($_key, $_type) = each %{$self->get_swagger_types} ) {
+ while ( my ($_key, $_type) = each %{$self->swagger_types} ) {
+ my $_json_attribute = $self->attribute_map->{$_key};
if ($_type =~ /^array\[/i) { # array
my $_subclass = substr($_type, 6, -1);
my @_array = ();
- foreach my $_element (@{$hash->{$self->get_attribute_map->{$_key}}}) {
+ foreach my $_element (@{$hash->{$_json_attribute}}) {
push @_array, $self->_deserialize($_subclass, $_element);
}
$self->{$_key} = \@_array;
- } elsif (defined $hash->{$_key}) { #hash(model), primitive, datetime
- $self->{$_key} = $self->_deserialize($_type, $hash->{$_key});
+ } elsif (exists $hash->{$_json_attribute}) { #hash(model), primitive, datetime
+ $self->{$_key} = $self->_deserialize($_type, $hash->{$_json_attribute});
} else {
- $log->debugf("warning: %s not defined\n", $_key);
+ $log->debugf("Warning: %s (%s) does not exist in input hash\n", $_key, $_json_attribute);
}
}
return $self;
}
-
+
# deserialize non-array data
sub _deserialize {
my ($self, $type, $data) = @_;
diff --git a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache
index 0a097dda7bd..75a1ba7f61a 100644
--- a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache
@@ -10,15 +10,71 @@ use Carp;
use constant VERSION => '{{moduleVersion}}';
# class/static variables
-our $api_client;
our $http_timeout = 180;
our $http_user_agent = 'Perl-Swagger';
# authenticaiton setting
our $api_key = {};
our $api_key_prefix = {};
-our $username;
-our $password;
+our $api_key_in = {};
+# username and password for HTTP basic authentication
+our $username = '';
+our $password = '';
+
+# access token for OAuth
+our $access_token = '';
+
+sub get_tokens {
+ my $class = shift;
+
+ my $tokens = {};
+ $tokens->{username} = $username if $username;
+ $tokens->{password} = $password if $password;
+ $tokens->{access_token} = $access_token if $access_token;
+
+ foreach my $token_name (keys %{ $api_key }) {
+ $tokens->{$token_name}->{token} = $api_key->{$token_name};
+ $tokens->{$token_name}->{prefix} = $api_key_prefix->{$token_name};
+ $tokens->{$token_name}->{in} = $api_key_in->{$token_name};
+ }
+
+ return $tokens;
+}
+
+sub clear_tokens {
+ my $class = shift;
+ my %tokens = %{$class->get_tokens}; # copy
+
+ $username = undef;
+ $password = undef;
+ $access_token = undef;
+
+ $api_key = {};
+ $api_key_prefix = {};
+ $api_key_in = {};
+
+ return \%tokens;
+}
+
+sub accept_tokens {
+ my ($class, $tokens) = @_;
+
+ foreach my $known_name (qw(username password access_token)) {
+ next unless $tokens->{$known_name};
+ eval "\$$known_name = delete \$tokens->{\$known_name}";
+ die $@ if $@;
+ }
+
+ foreach my $token_name (keys %$tokens) {
+ $api_key->{$token_name} = $tokens->{$token_name}->{token};
+ if ($tokens->{$token_name}->{prefix}) {
+ $api_key_prefix->{$token_name} = $tokens->{$token_name}->{prefix};
+ }
+ my $in = $tokens->{$token_name}->{in} || 'head';
+ croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/;
+ $api_key_in->{$token_name} = $in;
+ }
+}
1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md
new file mode 100644
index 00000000000..8d0b7695c15
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/README.md
@@ -0,0 +1,219 @@
+# NAME
+
+WWW::{{moduleName}}::Role - a Moose role for the {{appName}}
+
+## {{appName}} version: {{appVersion}}
+
+# VERSION
+
+Automatically generated by the Perl Swagger Codegen project:
+
+- Build date: {{generatedDate}}
+- Build package: {{generatorClass}}
+- Codegen version:
+
+## A note on Moose
+
+This role is the only component of the library that uses Moose. See
+WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
+
+# SYNOPSIS
+
+The Perl Swagger Codegen project builds a library of Perl modules to interact with
+a web service defined by a Swagger specification. See below for how to build the
+library.
+
+This module provides an interface to the generated library. All the classes,
+objects, and methods (well, not quite \*all\*, see below) are flattened into this
+role.
+
+ package MyApp;
+ use Moose;
+ with 'WWW::{{moduleName}}::Role';
+
+ package main;
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+ my $pet = $api->get_pet_by_id(pet_id => $pet_id);
+
+
+## Structure of the library
+
+The library consists of a set of API classes, one for each endpoint. These APIs
+implement the method calls available on each endpoint.
+
+Additionally, there is a set of "object" classes, which represent the objects
+returned by and sent to the methods on the endpoints.
+
+An API factory class is provided, which builds instances of each endpoint API.
+
+This Moose role flattens all the methods from the endpoint APIs onto the consuming
+class. It also provides methods to retrieve the endpoint API objects, and the API
+factory object, should you need it.
+
+For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
+
+## Configuring authentication
+
+In the normal case, the Swagger spec will describe what parameters are
+required and where to put them. You just need to supply the tokens.
+
+ my $tokens = {
+ # basic
+ username => $username,
+ password => $password,
+
+ # oauth
+ access_token => $oauth_token,
+
+ # keys
+ $some_key => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+
+ $another => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+ ...,
+
+ };
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+Note these are all optional, as are `prefix` and `in`, and depend on the API
+you are accessing. Usually `prefix` and `in` will be determined by the code generator from
+the spec and you will not need to set them at run time. If not, `in` will
+default to 'head' and `prefix` to the empty string.
+
+The tokens will be placed in the `WWW::{{moduleName}}::Configuration` namespace
+as follows, but you don't need to know about this.
+
+- `$WWW::{{moduleName}}::Configuration::username`
+
+ String. The username for basic auth.
+
+- `$WWW::{{moduleName}}::Configuration::password`
+
+ String. The password for basic auth.
+
+- `$WWW::{{moduleName}}::Configuration::api_key`
+
+ Hashref. Keyed on the name of each key (there can be multiple tokens).
+
+ $WWW::{{moduleName}}::Configuration::api_key = {
+ secretKey => 'aaaabbbbccccdddd',
+ anotherKey => '1111222233334444',
+ };
+
+- `$WWW::{{moduleName}}::Configuration::api_key_prefix`
+
+ Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
+ all api keys require a prefix.
+
+ $WWW::{{moduleName}}::Configuration::api_key_prefix = {
+ secretKey => 'string',
+ anotherKey => 'same or some other string',
+ };
+
+- `$WWW::{{moduleName}}::Configuration::access_token`
+
+ String. The OAuth access token.
+
+# METHODS
+
+## `base_url`
+
+The generated code has the `base_url` already set as a default value. This method
+returns (and optionally sets, but only if the API client has not been
+created yet) the current value of `base_url`.
+
+## `api_factory`
+
+Returns an API factory object. You probably won't need to call this directly.
+
+ $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
+
+ $self->pet_api; # the same
+
+# MISSING METHODS
+
+Most of the methods on the API are delegated to individual endpoint API objects
+(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the
+same method name (e.g. `new()`), these methods can't be delegated. So you need
+to call `$api->pet_api->new()`.
+
+In principle, every API is susceptible to the presence of a few, random, undelegatable
+method names. In practice, because of the way method names are constructed, it's
+unlikely in general that any methods will be undelegatable, except for:
+
+ new()
+ class_documentation()
+ method_documentation()
+
+To call these methods, you need to get a handle on the relevant object, either
+by calling `$api->foo_api` or by retrieving an object, e.g.
+`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so
+you could also call them on class names.
+
+# BUILDING YOUR LIBRARY
+
+See the homepage `https://github.com/swagger-api/swagger-codegen` for full details.
+But briefly, clone the git repository, build the codegen codebase, set up your build
+config file, then run the API build script. You will need git, Java 7 and Apache
+maven 3.0.3 or better already installed.
+
+The config file should specify the project name for the generated library:
+
+ {"moduleName":"MyProjectName"}
+
+Your library files will be built under `WWW::MyProjectName`.
+
+ $ git clone https://github.com/swagger-api/swagger-codegen.git
+ $ cd swagger-codegen
+ $ mvn package
+ $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i [URL or file path to JSON swagger API spec] \
+ -l perl \
+ -c /path/to/config/file.json \
+ -o /path/to/output/folder
+
+Bang, all done. Run the `autodoc` script in the `bin` directory to see the API
+you just built.
+
+# AUTOMATIC DOCUMENTATION
+
+You can print out a summary of the generated API by running the included
+`autodoc` script in the `bin` directory of your generated library. A few
+output formats are supported:
+
+ Usage: autodoc [OPTION]
+
+ -w wide format (default)
+ -n narrow format
+ -p POD format
+ -H HTML format
+ -m Markdown format
+ -h print this help message
+ -c your application class
+
+
+The `-c` option allows you to load and inspect your own application. A dummy
+namespace is used if you don't supply your own class.
+
+# DOCUMENTATION FROM THE SWAGGER SPEC
+
+Additional documentation for each class and method may be provided by the Swagger
+spec. If so, this is available via the `class_documentation()` and
+`method_documentation()` methods on each generated object class, and the
+`method_documentation()` method on the endpoint API classes:
+
+ my $cmdoc = $api->pet_api->method_documentation->{$method_name};
+
+ my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
+ my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
+
+
+Each of these calls returns a hashref with various useful pieces of information.
diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache
new file mode 100644
index 00000000000..7bca8cca78d
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache
@@ -0,0 +1,323 @@
+package WWW::{{moduleName}}::Role;
+use utf8;
+
+use Moose::Role;
+use namespace::autoclean;
+use Class::Inspector;
+use Log::Any qw($log);
+use WWW::{{moduleName}}::ApiFactory;
+
+has base_url => ( is => 'ro',
+ required => 0,
+ isa => 'Str',
+ documentation => 'Root of the server that requests are sent to',
+ );
+
+has api_factory => ( is => 'ro',
+ isa => 'WWW::{{moduleName}}::ApiFactory',
+ builder => '_build_af',
+ lazy => 1,
+ documentation => 'Builds an instance of the endpoint API class',
+ );
+
+has tokens => ( is => 'ro',
+ isa => 'HashRef',
+ required => 0,
+ default => sub { {} },
+ documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)',
+ );
+
+has _cfg => ( is => 'ro',
+ isa => 'Str',
+ default => 'WWW::{{moduleName}}::Configuration',
+ );
+
+has version_info => ( is => 'ro',
+ isa => 'HashRef',
+ default => sub { {
+ app_name => '{{appName}}',
+ app_version => '{{appVersion}}',
+ generated_date => '{{generatedDate}}',
+ generator_class => '{{generatorClass}}',
+ } },
+ documentation => 'Information about the application version and the codegen codebase version'
+ );
+
+sub BUILD {
+ my $self = shift;
+
+ $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens};
+
+ # ignore these symbols imported into API namespaces
+ my %outsiders = map {$_ => 1} qw( croak );
+
+ my %delegates;
+
+ # collect the methods callable on each API
+ foreach my $api_name ($self->api_factory->apis_available) {
+ my $api_class = $self->api_factory->classname_for($api_name);
+ my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead
+ my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods;
+ push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods;
+ }
+
+ # remove clashes
+ foreach my $method (keys %delegates) {
+ if ( @{$delegates{$method}} > 1 ) {
+ my ($apis) = delete $delegates{$method};
+ }
+ }
+
+ # build the flattened API
+ foreach my $api_name ($self->api_factory->apis_available) {
+ my $att_name = sprintf "%s_api", lc($api_name);
+ my $api_class = $self->api_factory->classname_for($api_name);
+ my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates;
+ $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated);
+ $self->meta->add_attribute( $att_name => (
+ is => 'ro',
+ isa => $api_class,
+ default => sub {$self->api_factory->get_api($api_name)},
+ lazy => 1,
+ handles => \@delegated,
+ ) );
+ }
+}
+
+sub _build_af {
+ my $self = shift;
+ my %args;
+ $args{base_url} = $self->base_url if $self->base_url;
+ return WWW::{{moduleName}}::ApiFactory->new(%args);
+}
+
+=head1 NAME
+
+WWW::{{moduleName}}::Role - a Moose role for the {{appName}}
+
+=head2 {{appName}} version: {{appVersion}}
+
+=head1 VERSION
+
+Automatically generated by the Perl Swagger Codegen project:
+
+=over 4
+
+=item Build date: {{generatedDate}}
+
+=item Build package: {{generatorClass}}
+
+=item Codegen version:
+
+=back
+
+=head2 A note on Moose
+
+This role is the only component of the library that uses Moose. See
+WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
+
+=head1 SYNOPSIS
+
+The Perl Swagger Codegen project builds a library of Perl modules to interact with
+a web service defined by a Swagger specification. See below for how to build the
+library.
+
+This module provides an interface to the generated library. All the classes,
+objects, and methods (well, not quite *all*, see below) are flattened into this
+role.
+
+ package MyApp;
+ use Moose;
+ with 'WWW::{{moduleName}}::Role';
+
+ package main;
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+ my $pet = $api->get_pet_by_id(pet_id => $pet_id);
+
+=head2 Structure of the library
+
+The library consists of a set of API classes, one for each endpoint. These APIs
+implement the method calls available on each endpoint.
+
+Additionally, there is a set of "object" classes, which represent the objects
+returned by and sent to the methods on the endpoints.
+
+An API factory class is provided, which builds instances of each endpoint API.
+
+This Moose role flattens all the methods from the endpoint APIs onto the consuming
+class. It also provides methods to retrieve the endpoint API objects, and the API
+factory object, should you need it.
+
+For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
+
+=head2 Configuring authentication
+
+In the normal case, the Swagger spec will describe what parameters are
+required and where to put them. You just need to supply the tokens.
+
+ my $tokens = {
+ # basic
+ username => $username,
+ password => $password,
+
+ # oauth
+ access_token => $oauth_token,
+
+ # keys
+ $some_key => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+
+ $another => { token => $token,
+ prefix => $prefix,
+ in => $in, # 'head||query',
+ },
+ ...,
+
+ };
+
+ my $api = MyApp->new({ tokens => $tokens });
+
+Note these are all optional, as are C and C, and depend on the API
+you are accessing. Usually C and C will be determined by the code generator from
+the spec and you will not need to set them at run time. If not, C will
+default to 'head' and C to the empty string.
+
+The tokens will be placed in the C namespace
+as follows, but you don't need to know about this.
+
+=over 4
+
+=item C<$WWW::{{moduleName}}::Configuration::username>
+
+String. The username for basic auth.
+
+=item C<$WWW::{{moduleName}}::Configuration::password>
+
+String. The password for basic auth.
+
+=item C<$WWW::{{moduleName}}::Configuration::api_key>
+
+Hashref. Keyed on the name of each key (there can be multiple tokens).
+
+ $WWW::{{moduleName}}::Configuration::api_key = {
+ secretKey => 'aaaabbbbccccdddd',
+ anotherKey => '1111222233334444',
+ };
+
+=item C<$WWW::{{moduleName}}::Configuration::api_key_prefix>
+
+Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
+all api keys require a prefix.
+
+ $WWW::{{moduleName}}::Configuration::api_key_prefix = {
+ secretKey => 'string',
+ anotherKey => 'same or some other string',
+ };
+
+=item C<$WWW::{{moduleName}}::Configuration::access_token>
+
+String. The OAuth access token.
+
+=back
+
+=head1 METHODS
+
+=head2 C
+
+The generated code has the C already set as a default value. This method
+returns (and optionally sets, but only if the API client has not been
+created yet) the current value of C.
+
+=head2 C
+
+Returns an API factory object. You probably won't need to call this directly.
+
+ $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
+
+ $self->pet_api; # the same
+
+=head1 MISSING METHODS
+
+Most of the methods on the API are delegated to individual endpoint API objects
+(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the
+same method name (e.g. C), these methods can't be delegated. So you need
+to call C<$api-Epet_api-Enew()>.
+
+In principle, every API is susceptible to the presence of a few, random, undelegatable
+method names. In practice, because of the way method names are constructed, it's
+unlikely in general that any methods will be undelegatable, except for:
+
+ new()
+ class_documentation()
+ method_documentation()
+
+To call these methods, you need to get a handle on the relevant object, either
+by calling C<$api-Efoo_api> or by retrieving an object, e.g.
+C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so
+you could also call them on class names.
+
+=head1 BUILDING YOUR LIBRARY
+
+See the homepage C for full details.
+But briefly, clone the git repository, build the codegen codebase, set up your build
+config file, then run the API build script. You will need git, Java 7 and Apache
+maven 3.0.3 or better already installed.
+
+The config file should specify the project name for the generated library:
+
+ {"moduleName":"MyProjectName"}
+
+Your library files will be built under C.
+
+ $ git clone https://github.com/swagger-api/swagger-codegen.git
+ $ cd swagger-codegen
+ $ mvn package
+ $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
+ -i [URL or file path to JSON swagger API spec] \
+ -l perl \
+ -c /path/to/config/file.json \
+ -o /path/to/output/folder
+
+Bang, all done. Run the C script in the C directory to see the API
+you just built.
+
+=head1 AUTOMATIC DOCUMENTATION
+
+You can print out a summary of the generated API by running the included
+C script in the C directory of your generated library. A few
+output formats are supported:
+
+ Usage: autodoc [OPTION]
+
+ -w wide format (default)
+ -n narrow format
+ -p POD format
+ -H HTML format
+ -m Markdown format
+ -h print this help message
+ -c your application class
+
+The C<-c> option allows you to load and inspect your own application. A dummy
+namespace is used if you don't supply your own class.
+
+=head1 DOCUMENTATION FROM THE SWAGGER SPEC
+
+Additional documentation for each class and method may be provided by the Swagger
+spec. If so, this is available via the C and
+C methods on each generated object class, and the
+C method on the endpoint API classes:
+
+ my $cmdoc = $api->pet_api->method_documentation->{$method_name};
+
+ my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
+ my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
+
+Each of these calls returns a hashref with various useful pieces of information.
+
+=cut
+
+1;
diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache
index e69e4e3066f..f25c63a528c 100644
--- a/modules/swagger-codegen/src/main/resources/perl/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache
@@ -30,11 +30,14 @@ use Log::Any qw($log);
use WWW::{{moduleName}}::ApiClient;
use WWW::{{moduleName}}::Configuration;
+use base "Class::Data::Inheritable";
+
+__PACKAGE__->mk_classdata('method_documentation' => {});
+
sub new {
my $class = shift;
- my $default_api_client = $WWW::{{moduleName}}::Configuration::api_client ? $WWW::{{moduleName}}::Configuration::api_client : WWW::{{moduleName}}::ApiClient->new;
my (%self) = (
- 'api_client' => $default_api_client,
+ 'api_client' => WWW::{{moduleName}}::ApiClient->instance,
@_
);
@@ -49,13 +52,31 @@ sub new {
{{#operations}}
{{#operation}}
+
#
# {{{nickname}}}
#
# {{{summary}}}
#
{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
-{{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
+{{/allParams}}
+{
+ my $params = {
+{{#allParams}}
+ '{{paramName}}' => {
+ data_type => '{{dataType}}',
+ description => '{{description}}',
+ required => {{#required}}'1'{{/required}}{{^required}}'0'{{/required}},
+ },
+{{/allParams}}
+ };
+ __PACKAGE__->method_documentation->{ {{nickname}} } = {
+ summary => '{{summary}}',
+ params => $params,
+ returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}},
+ };
+}
+# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
#
sub {{nickname}} {
my ($self, %args) = @_;
@@ -100,7 +121,7 @@ sub {{nickname}} {
{{#formParams}}# form params
if ( exists $args{'{{paramName}}'} ) {
{{#isFile}}$form_params->{'{{baseName}}'} = [] unless defined $form_params->{'{{baseName}}'};
- push $form_params->{'{{baseName}}'}, $args{'{{paramName}}'};
+ push @{$form_params->{'{{baseName}}'}}, $args{'{{paramName}}'};
{{/isFile}}
{{^isFile}}$form_params->{'{{baseName}}'} = $self->{api_client}->to_form_value($args{'{{paramName}}'});
{{/isFile}}
@@ -112,7 +133,7 @@ sub {{nickname}} {
}{{/bodyParams}}
# authentication setting, if any
- my $auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}];
+ my $auth_settings = [qw({{#authMethods}}{{name}} {{/authMethods}})];
# make the API Call
{{#returnType}}my $response = $self->{api_client}->call_api($_resource_path, $_method,
diff --git a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache
new file mode 100644
index 00000000000..240936d9b51
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+use FindBin;
+use File::Spec;
+use lib File::Spec->catdir($FindBin::Bin, '..', 'lib');
+
+use Moose::Util qw(apply_all_roles);
+use Getopt::Std;
+
+my %options=();
+getopts("wnphmHc:", \%options);
+help if $options{h};
+
+my $my_app = $options{c} || 'My::App';
+
+if ($options{c}) {
+ eval <new;
+
+if ($options{H}) {
+ my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3";
+ open STDOUT, "| $pod2html" or die "Can't fork: $!";
+ $api->autodoc($opt);
+ close STDOUT or die "Can't close: $!";
+}
+elsif ($options{m}) {
+ my $pod2markdown = "pod2markdown --html-encode-chars 1";
+ open STDOUT, "| $pod2markdown" or die "Can't fork: $!";
+ $api->autodoc($opt);
+ close STDOUT or die "Can't close: $!";
+}
+else {
+ $api->autodoc($opt);
+}
+
+exit(0);
+
+# --------------------
+sub help {
+ print <class_documentation({description => '{{description}}',
+ class => '{{classname}}',
+ required => [], # TODO
+} );
+
+__PACKAGE__->method_documentation({
+ {{#vars}}'{{name}}' => {
+ datatype => '{{datatype}}',
+ base_name => '{{baseName}}',
+ description => '{{description}}',
+ format => '{{format}}',
+ read_only => '{{readOnly}}',
+ },
+ {{/vars}}
+});
+
+__PACKAGE__->swagger_types( {
{{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
-};
+} );
-my $attribute_map = {
+__PACKAGE__->attribute_map( {
{{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
-};
+} );
-# new object
-sub new {
- my ($class, %args) = @_;
- my $self = {
- {{#vars}}#{{#description}}{{{description}}}{{/description}}
- '{{name}}' => $args{'{{baseName}}'}{{#hasMore}},
- {{/hasMore}}{{/vars}}
- };
-
- return bless $self, $class;
-}
-
-# get swagger type of the attribute
-sub get_swagger_types {
- return $swagger_types;
-}
-
-# get attribute mappping
-sub get_attribute_map {
- return $attribute_map;
-}
+__PACKAGE__->mk_accessors(keys %{__PACKAGE__->attribute_map});
1;
{{/model}}
diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache
index e2193b1d754..11fe3827d48 100644
--- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache
+++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache
@@ -69,7 +69,7 @@ class ApiClient
* Constructor of the class
* @param Configuration $config config for this ApiClient
*/
- function __construct(Configuration $config = null)
+ public function __construct(Configuration $config = null)
{
if ($config == null) {
$config = Configuration::getDefaultConfiguration();
diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache
index db1d4c8cb4f..e3a9749c423 100644
--- a/modules/swagger-codegen/src/main/resources/php/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/php/api.mustache
@@ -140,7 +140,18 @@ use \{{invokerPackage}}\ObjectSerializer;
}{{/pathParams}}
{{#formParams}}// form params
if (${{paramName}} !== null) {
- $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->getSerializer()->toFormValue(${{paramName}});
+ {{#isFile}}
+ // PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax
+ // See: https://wiki.php.net/rfc/curl-file-upload
+ if (function_exists('curl_file_create')) {
+ $formParams['{{baseName}}'] = curl_file_create($this->apiClient->getSerializer()->toFormValue(${{paramName}}));
+ } else {
+ $formParams['{{baseName}}'] = '@' . $this->apiClient->getSerializer()->toFormValue(${{paramName}});
+ }
+ {{/isFile}}
+ {{^isFile}}
+ $formParams['{{baseName}}'] = $this->apiClient->getSerializer()->toFormValue(${{paramName}});
+ {{/isFile}}
}{{/formParams}}
{{#bodyParams}}// body params
$_tempBody = null;
@@ -159,8 +170,8 @@ use \{{invokerPackage}}\ObjectSerializer;
if (isset($apiKey)) {
{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $apiKey;{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $apiKey;{{/isKeyInQuery}}
}{{/isApiKey}}
- {{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode($this->apiClient->getConfig()->getUsername().":".$this->apiClient->getConfig()->getPassword());{{/isBasic}}
- {{#isOAuth}}//TODO support oauth{{/isOAuth}}
+ {{#isBasic}}$headerParams['Authorization'] = 'Basic ' . base64_encode($this->apiClient->getConfig()->getUsername() . ":" . $this->apiClient->getConfig()->getPassword());{{/isBasic}}
+ {{#isOAuth}}$headerParams['Authorization'] = 'Bearer ' . $this->apiClient->getConfig()->getAccessToken();{{/isOAuth}}
{{/authMethods}}
// make the API Call
try
diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/configuration.mustache
index 96bc8a1b660..14d7957fe54 100644
--- a/modules/swagger-codegen/src/main/resources/php/configuration.mustache
+++ b/modules/swagger-codegen/src/main/resources/php/configuration.mustache
@@ -63,6 +63,13 @@ class Configuration
*/
protected $apiKeyPrefixes = array();
+ /**
+ * Access token for OAuth
+ *
+ * @var string
+ */
+ protected $accessToken = '';
+
/**
* Username for HTTP basic authentication
*
@@ -195,6 +202,29 @@ class Configuration
return isset($this->apiKeyPrefixes[$apiKeyIdentifier]) ? $this->apiKeyPrefixes[$apiKeyIdentifier] : null;
}
+ /**
+ * Sets the access token for OAuth
+ *
+ * @param string $accessToken Token for OAuth
+ *
+ * @return Configuration
+ */
+ public function setAccessToken($accessToken)
+ {
+ $this->$accessToken = $accessToken;
+ return $this;
+ }
+
+ /**
+ * Gets the access token for OAuth
+ *
+ * @return string Access token for OAuth
+ */
+ public function getAccessToken()
+ {
+ return $this->accessToken;
+ }
+
/**
* Sets the username for HTTP basic authentication
*
diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache
index b076fa5d3ea..474cf84f356 100644
--- a/modules/swagger-codegen/src/main/resources/python/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/python/api.mustache
@@ -47,7 +47,7 @@ class {{classname}}(object):
self.api_client = config.api_client
{{#operation}}
- def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs):
+ def {{nickname}}(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs):
"""
{{{summary}}}
{{{notes}}}
@@ -58,7 +58,12 @@ class {{classname}}(object):
>>> def callback_function(response):
>>> pprint(response)
>>>
+{{#sortParamsByRequiredFlag}}
>>> thread = api.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}callback=callback_function)
+{{/sortParamsByRequiredFlag}}
+{{^sortParamsByRequiredFlag}}
+ >>> thread = api.{{nickname}}({{#allParams}}{{#required}}{{paramName}}={{paramName}}_value, {{/required}}{{/allParams}}callback=callback_function)
+{{/sortParamsByRequiredFlag}}
:param callback function: The callback function
for asynchronous request. (optional)
@@ -69,13 +74,6 @@ class {{classname}}(object):
If the method is called asynchronously,
returns the request thread.
"""
-{{#allParams}}
-{{#required}}
- # verify the required parameter '{{paramName}}' is set
- if {{paramName}} is None:
- raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{nickname}}`")
-{{/required}}
-{{/allParams}}
all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}]
all_params.append('callback')
@@ -90,6 +88,14 @@ class {{classname}}(object):
params[key] = val
del params['kwargs']
+{{#allParams}}
+{{#required}}
+ # verify the required parameter '{{paramName}}' is set
+ if ('{{paramName}}' not in params) or (params['{{paramName}}'] is None):
+ raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{nickname}}`")
+{{/required}}
+{{/allParams}}
+
resource_path = '{{path}}'.replace('{format}', 'json')
method = '{{httpMethod}}'
diff --git a/modules/swagger-codegen/src/main/resources/python/configuration.mustache b/modules/swagger-codegen/src/main/resources/python/configuration.mustache
index 78fa8fb6d3c..bab1d09d761 100644
--- a/modules/swagger-codegen/src/main/resources/python/configuration.mustache
+++ b/modules/swagger-codegen/src/main/resources/python/configuration.mustache
@@ -71,6 +71,10 @@ class Configuration(object):
self.username = ""
# Password for HTTP basic authentication
self.password = ""
+{{#authMethods}}{{#isOAuth}}
+ # access token for OAuth
+ self.access_token = ""
+{{/isOAuth}}{{/authMethods}}
# Logging Settings
self.logger = {}
@@ -231,8 +235,15 @@ class Configuration(object):
'key': 'Authorization',
'value': self.get_basic_auth_token()
},
-{{/isBasic}}
-{{/authMethods}}
+{{/isBasic}}{{#isOauth}}
+ '{{name}}':
+ {
+ 'type': 'oauth2',
+ 'in': 'header',
+ 'key': 'Authorization',
+ 'value': 'Bearer ' + self.access_token
+ },
+{{/isOauth}}{{/authMethods}}
}
def to_debug_report(self):
diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache
index 7f4d748c2dc..7bd9b3f46cc 100644
--- a/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache
+++ b/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache
@@ -25,6 +25,14 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
qint64 *val = static_cast(value);
*val = obj.toVariant().toLongLong();
}
+ else if(QStringLiteral("float").compare(type) == 0) {
+ float *val = static_cast(value);
+ *val = obj.toDouble();
+ }
+ else if(QStringLiteral("double").compare(type) == 0) {
+ double *val = static_cast(value);
+ *val = obj.toDouble();
+ }
else if (QStringLiteral("QString").compare(type) == 0) {
QString **val = static_cast(value);
@@ -86,6 +94,16 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
setValue(&val, jval, QStringLiteral("bool"), QStringLiteral(""));
output->append((void*)&val);
}
+ else if(QStringLiteral("float").compare(complexType) == 0) {
+ float val;
+ setValue(&val, jval, QStringLiteral("float"), QStringLiteral(""));
+ output->append((void*)&val);
+ }
+ else if(QStringLiteral("double").compare(complexType) == 0) {
+ double val;
+ setValue(&val, jval, QStringLiteral("double"), QStringLiteral(""));
+ output->append((void*)&val);
+ }
}
}
QList **val = static_cast**>(value);
@@ -131,6 +149,14 @@ toJsonValue(QString name, void* value, QJsonObject* output, QString type) {
bool* str = static_cast(value);
output->insert(name, QJsonValue(*str));
}
+ else if(QStringLiteral("float").compare(type) == 0) {
+ float* str = static_cast(value);
+ output->insert(name, QJsonValue((double)*str));
+ }
+ else if(QStringLiteral("double").compare(type) == 0) {
+ double* str = static_cast(value);
+ output->insert(name, QJsonValue(*str));
+ }
}
void
diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache
index ad885dac94e..a43260c0607 100644
--- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache
@@ -36,8 +36,8 @@ module {{moduleName}}
# query parameters
query_params = {}{{#queryParams}}{{#required}}
- query_params[:'{{{baseName}}}'] = {{{paramName}}}{{/required}}{{/queryParams}}{{#queryParams}}{{^required}}
- query_params[:'{{{baseName}}}'] = opts[:'{{{paramName}}}'] if opts[:'{{{paramName}}}']{{/required}}{{/queryParams}}
+ query_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}}{{/required}}{{/queryParams}}{{#queryParams}}{{^required}}
+ query_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param(opts[:'{{{paramName}}}'], :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}opts[:'{{{paramName}}}']{{/collectionFormat}} if opts[:'{{{paramName}}}']{{/required}}{{/queryParams}}
# header parameters
header_params = {}
@@ -49,13 +49,13 @@ module {{moduleName}}
# HTTP header 'Content-Type'
_header_content_type = [{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]
header_params['Content-Type'] = @api_client.select_header_content_type(_header_content_type){{#headerParams}}{{#required}}
- header_params[:'{{{baseName}}}'] = {{{paramName}}}{{/required}}{{/headerParams}}{{#headerParams}}{{^required}}
- header_params[:'{{{baseName}}}'] = opts[:'{{{paramName}}}'] if opts[:'{{{paramName}}}']{{/required}}{{/headerParams}}
+ header_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}}{{/required}}{{/headerParams}}{{#headerParams}}{{^required}}
+ header_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param(opts[:'{{{paramName}}}'], :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}opts[:'{{{paramName}}}']{{/collectionFormat}} if opts[:'{{{paramName}}}']{{/required}}{{/headerParams}}
# form parameters
form_params = {}{{#formParams}}{{#required}}
- form_params["{{baseName}}"] = {{paramName}}{{/required}}{{/formParams}}{{#formParams}}{{^required}}
- form_params["{{baseName}}"] = opts[:'{{paramName}}'] if opts[:'{{paramName}}']{{/required}}{{/formParams}}
+ form_params["{{baseName}}"] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}}{{/required}}{{/formParams}}{{#formParams}}{{^required}}
+ form_params["{{baseName}}"] = {{#collectionFormat}}@api_client.build_collection_param(opts[:'{{{paramName}}}'], :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}opts[:'{{{paramName}}}']{{/collectionFormat}} if opts[:'{{paramName}}']{{/required}}{{/formParams}}
# http body (model)
{{^bodyParam}}post_body = nil
diff --git a/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache
index 2bdcf6dc7be..4ef665bddf2 100644
--- a/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache
+++ b/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache
@@ -189,9 +189,15 @@ module {{moduleName}}
# http form
if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
header_params['Content-Type'] == 'multipart/form-data'
- data = form_params.dup
- data.each do |key, value|
- data[key] = value.to_s if value && !value.is_a?(File)
+ data = {}
+ form_params.each do |key, value|
+ case value
+ when File, Array, nil
+ # let typhoeus handle File, Array and nil parameters
+ data[key] = value
+ else
+ data[key] = value.to_s
+ end
end
elsif body
data = body.is_a?(String) ? body : body.to_json
@@ -269,5 +275,25 @@ module {{moduleName}}
obj
end
end
+
+ # Build parameter value according to the given collection format.
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
+ def build_collection_param(param, collection_format)
+ case collection_format
+ when :csv
+ param.join(',')
+ when :ssv
+ param.join(' ')
+ when :tsv
+ param.join("\t")
+ when :pipes
+ param.join('|')
+ when :multi
+ # return the array directly as typhoeus will handle it as expected
+ param
+ else
+ fail "unknown collection format: #{collection_format.inspect}"
+ end
+ end
end
end
diff --git a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache
index ccf6db4a4fd..ddb68998e9e 100644
--- a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache
+++ b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache
@@ -42,6 +42,17 @@ module {{moduleName}}
else
false
end
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
else # model
_model = {{moduleName}}.const_get(type).new
_model.build_from_hash(value)
@@ -63,11 +74,7 @@ module {{moduleName}}
self.class.attribute_map.each_pair do |attr, param|
value = self.send(attr)
next if value.nil?
- if value.is_a?(Array)
- hash[param] = value.compact.map{ |v| _to_hash(v) }
- else
- hash[param] = _to_hash(value)
- end
+ hash[param] = _to_hash(value)
end
hash
end
@@ -75,7 +82,13 @@ module {{moduleName}}
# Method to output non-array value in the form of hash
# For object, use to_hash. Otherwise, just return the value
def _to_hash(value)
- if value.respond_to? :to_hash
+ if value.is_a?(Array)
+ value.compact.map{ |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
value.to_hash
else
value
diff --git a/modules/swagger-codegen/src/main/resources/ruby/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/configuration.mustache
index 0385aaffd83..89bf133b22c 100644
--- a/modules/swagger-codegen/src/main/resources/ruby/configuration.mustache
+++ b/modules/swagger-codegen/src/main/resources/ruby/configuration.mustache
@@ -44,6 +44,9 @@ module {{moduleName}}
# @return [String]
attr_accessor :password
+ # Defines the access token (Bearer) used with OAuth2.
+ attr_accessor :access_token
+
# Set this to enable/disable debugging. When enabled (set to true), HTTP request/response
# details will be logged with `logger.debug` (see the `logger` attribute).
# Default to false.
@@ -179,6 +182,15 @@ module {{moduleName}}
value: basic_auth_token
},
{{/isBasic}}
+{{#isOAuth}}
+ '{{name}}' =>
+ {
+ type: 'oauth2',
+ in: 'header',
+ key: 'Authorization',
+ value: "Bearer #{access_token}"
+ },
+{{/isOAuth}}
{{/authMethods}}
}
end
diff --git a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache
index 495752f624d..5a9f1f7a278 100644
--- a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache
+++ b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache
@@ -7,8 +7,9 @@
import Foundation
public class {{projectName}}API {
- static let basePath = "{{basePath}}"
- static var credential: NSURLCredential?
+ public static var basePath = "{{basePath}}"
+ public static var credential: NSURLCredential?
+ public static var customHeaders: [String:String] = [:]
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
}
@@ -41,9 +42,17 @@ public class RequestBuilder {
self.URLString = URLString
self.parameters = parameters
self.isBody = isBody
+
+ addHeaders({{projectName}}API.customHeaders)
}
- public func execute(completion: (response: Response?, erorr: ErrorType?) -> Void) { }
+ public func addHeaders(aHeaders:[String:String]) {
+ for (header, value) in aHeaders {
+ headers[header] = value
+ }
+ }
+
+ public func execute(completion: (response: Response?, error: ErrorType?) -> Void) { }
public func addHeader(name name: String, value: String) -> Self {
if !value.isEmpty {
diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache
index dbc25584886..6b4d36f9410 100644
--- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache
+++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache
@@ -20,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder {
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody)
}
- override func execute(completion: (response: Response?, erorr: ErrorType?) -> Void) {
+ override func execute(completion: (response: Response?, error: ErrorType?) -> Void) {
let managerId = NSUUID().UUIDString
// Create a new manager for each request to customize its request header
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
@@ -60,7 +60,7 @@ class AlamofireRequestBuilder: RequestBuilder {
case .Success(let upload, _, _):
self.processRequest(upload, managerId, completion)
case .Failure(let encodingError):
- completion(response: nil, erorr: encodingError)
+ completion(response: nil, error: encodingError)
}
}
)
@@ -70,7 +70,7 @@ class AlamofireRequestBuilder: RequestBuilder {
}
- private func processRequest(request: Request, _ managerId: String, _ completion: (response: Response?, erorr: ErrorType?) -> Void) {
+ private func processRequest(request: Request, _ managerId: String, _ completion: (response: Response