mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-07 02:55:19 +00:00
Merge branch 'masterswaggerio' into params_support_2.0_spec
Conflicts: .gitignore
This commit is contained in:
commit
2c52cc1d86
7
.gitignore
vendored
7
.gitignore
vendored
@ -55,4 +55,9 @@ samples/client/petstore/python/.projectile
|
||||
samples/client/petstore/python/.venv/
|
||||
|
||||
*/.settings
|
||||
modules/*/.settings/
|
||||
|
||||
*.mustache~
|
||||
*.java~
|
||||
*.pm~
|
||||
*.xml~
|
||||
*.t~
|
141
README.md
141
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
|
||||
-------
|
||||
|
||||
|
@ -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
|
||||
|
31
bin/clojure-petstore.sh
Executable file
31
bin/clojure-petstore.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l clojure -o samples/client/petstore/clojure"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
31
bin/flaskConnexion.sh
Executable file
31
bin/flaskConnexion.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l flaskConnexion -o samples/server/petstore/flaskConnexion "
|
||||
|
||||
java $JAVA_OPTS -Dservice -jar $executable $ags
|
4
bin/java-petstore-retrofit2.json
Normal file
4
bin/java-petstore-retrofit2.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"library": "retrofit2",
|
||||
"artifactId": "swagger-petstore-retrofit2"
|
||||
}
|
31
bin/java-petstore-retrofit2.sh
Executable file
31
bin/java-petstore-retrofit2.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l java -c bin/java-petstore-retrofit2.json -o samples/client/petstore/java/retrofit2"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,18 @@
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<String, String> 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<String, String>();
|
||||
}
|
||||
if (!enumValues.containsKey(value)) {
|
||||
enumValues.put(value, description);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, String> getEnum() {
|
||||
return enumValues;
|
||||
}
|
||||
|
||||
public void setEnum(Map<String, String> 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<String, String> entry : enumValues.entrySet()) {
|
||||
sb.append("\n ").append(entry.getKey()).append(" - ").append(entry.getValue());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ public interface CodegenConfig {
|
||||
|
||||
String templateDir();
|
||||
|
||||
String embeddedTemplateDir();
|
||||
|
||||
String modelFileFolder();
|
||||
|
||||
String modelPackage();
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -10,9 +10,10 @@ import java.util.Set;
|
||||
|
||||
public class CodegenOperation {
|
||||
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
|
||||
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<Map<String, String>> consumes, produces;
|
||||
|
@ -78,6 +78,7 @@ public class DefaultCodegen {
|
||||
protected Map<String, String> apiTemplateFiles = new HashMap<String, String>();
|
||||
protected Map<String, String> modelTemplateFiles = new HashMap<String, String>();
|
||||
protected String templateDir;
|
||||
protected String embeddedTemplateDir;
|
||||
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
|
||||
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
|
||||
@ -86,6 +87,7 @@ public class DefaultCodegen {
|
||||
protected Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
|
||||
protected String library = null;
|
||||
protected Boolean sortParamsByRequiredFlag = true;
|
||||
protected Boolean ensureUniqueParams = true;
|
||||
|
||||
public List<CliOption> 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<String, String> 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<String, Object> 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<CodegenParameter>() {
|
||||
@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("\\[\\]", "");
|
||||
|
@ -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("")
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<String>(Arrays.asList("abstract",
|
||||
"continue", "for", "new", "switch", "assert", "default", "if",
|
||||
"package", "synchronized", "do", "goto", "private",
|
||||
"this", "break", "double", "implements", "protected", "throw",
|
||||
"byte", "else", "import", "public", "throws", "case", "enum",
|
||||
"instanceof", "return", "transient", "catch", "extends", "int",
|
||||
"short", "try", "char", "final", "interface", "static", "void",
|
||||
"class", "finally", "const", "super", "while"));
|
||||
reservedWords = new HashSet<String>(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<String>(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);
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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"));
|
||||
|
@ -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() {
|
||||
|
@ -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<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
// check to see if model name is same as the property name
|
||||
// which will result in compilation error
|
||||
// if found, prepend with _ to workaround the limitation
|
||||
if (var.name.equals(cm.name)) {
|
||||
var.name = "_" + var.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
}
|
||||
|
@ -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<String, Object> postProcessOperations(Map<String, Object> operations) {
|
||||
Map<String, Object> objs = (Map<String, Object>) operations.get("operations");
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) 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("[_ ]", "-");
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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<String>(
|
||||
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<String>(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
|
||||
|
@ -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<String>(
|
||||
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<Map<String, String>> tags = new ArrayList<Map<String, String>>();
|
||||
for(String tag : operation.getTags()) {
|
||||
Map<String, String> value = new HashMap<String, String>();
|
||||
value.put("tag", tag);
|
||||
value.put("hasMore", "true");
|
||||
tags.add(value);
|
||||
}
|
||||
if(tags.size() > 0) {
|
||||
tags.get(tags.size() - 1).remove("hasMore");
|
||||
}
|
||||
if(operation.getTags().size() > 0) {
|
||||
String tag = operation.getTags().get(0);
|
||||
operation.setTags(Arrays.asList(tag));
|
||||
}
|
||||
operation.setVendorExtension("x-tags", tags);
|
||||
}
|
||||
else {
|
||||
String tag = "default_controller";
|
||||
operation.setTags(Arrays.asList(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Map<String, Object>> getOperations(Map<String, Object> objs) {
|
||||
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
|
||||
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
|
||||
List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
|
||||
for (Map<String, Object> api : apis) {
|
||||
result.add((Map<String, Object>) api.get("operations"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> sortOperationsByPath(List<CodegenOperation> ops) {
|
||||
Multimap<String, CodegenOperation> opsByPath = ArrayListMultimap.create();
|
||||
|
||||
for (CodegenOperation op : ops) {
|
||||
opsByPath.put(op.path, op);
|
||||
}
|
||||
|
||||
List<Map<String, Object>> opsByPathList = new ArrayList<Map<String, Object>>();
|
||||
for (Map.Entry<String, Collection<CodegenOperation>> entry : opsByPath.asMap().entrySet()) {
|
||||
Map<String, Object> opsByPathEntry = new HashMap<String, Object>();
|
||||
opsByPathList.add(opsByPathEntry);
|
||||
opsByPathEntry.put("path", entry.getKey());
|
||||
opsByPathEntry.put("operation", entry.getValue());
|
||||
List<CodegenOperation> 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<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||
Swagger swagger = (Swagger)objs.get("swagger");
|
||||
if(swagger != null) {
|
||||
try {
|
||||
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (Map<String, Object> operations : getOperations(objs)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
|
||||
List<Map<String, Object>> opsByPathList = sortOperationsByPath(ops);
|
||||
operations.put("operationsByPath", opsByPathList);
|
||||
}
|
||||
return super.postProcessSupportingFileData(objs);
|
||||
}
|
||||
}
|
@ -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 = "<default>";
|
||||
|
||||
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("<default>", "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<String, %s>()";
|
||||
}
|
||||
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<String, String> 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<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
if("retrofit".equals(getLibrary())) {
|
||||
if("retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary())) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
if (operations != null) {
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
// 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<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
if (operations != null) {
|
||||
|
@ -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<Map<String, String>> tags = new ArrayList<Map<String, String>>();
|
||||
for(String tag : operation.getTags()) {
|
||||
Map<String, String> value = new HashMap<String, String>();
|
||||
value.put("tag", tag);
|
||||
value.put("hasMore", "true");
|
||||
tags.add(value);
|
||||
}
|
||||
if(tags.size() > 0) {
|
||||
tags.get(tags.size() - 1).remove("hasMore");
|
||||
}
|
||||
if(operation.getTags().size() > 0) {
|
||||
String tag = operation.getTags().get(0);
|
||||
operation.setTags(Arrays.asList(tag));
|
||||
}
|
||||
operation.setVendorExtension("x-tags", tags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
// 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<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
Map<String, Object> operations = (Map<String, Object>) 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) {
|
||||
|
@ -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<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||
Swagger swagger = (Swagger)objs.get("swagger");
|
||||
if(swagger != null) {
|
||||
try {
|
||||
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (Map<String, Object> operations : getOperations(objs)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
|
@ -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<String> foundationClasses = new HashSet<String>();
|
||||
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;
|
||||
|
||||
|
@ -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<String>(
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<CliOption> itr = cliOptions.iterator();
|
||||
while (itr.hasNext()) {
|
||||
CliOption opt = itr.next();
|
||||
if (CodegenConstants.MODEL_PACKAGE.equals(opt.getOpt()) ||
|
||||
CodegenConstants.API_PACKAGE.equals(opt.getOpt())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
cliOptions.add(new CliOption(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)
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -35,7 +35,7 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
modelTemplateFiles.clear();
|
||||
apiTemplateFiles.clear();
|
||||
|
||||
templateDir = "silex";
|
||||
embeddedTemplateDir = templateDir = "silex";
|
||||
|
||||
reservedWords = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
|
@ -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();
|
||||
|
@ -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<String>(
|
||||
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<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -28,7 +28,7 @@ public class StaticHtmlGenerator extends DefaultCodegen implements CodegenConfig
|
||||
public StaticHtmlGenerator() {
|
||||
super();
|
||||
outputFolder = "docs";
|
||||
templateDir = "htmlDocs";
|
||||
embeddedTemplateDir = templateDir = "htmlDocs";
|
||||
|
||||
defaultIncludes = new HashSet<String>();
|
||||
|
||||
|
@ -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"));
|
||||
|
@ -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"));
|
||||
|
@ -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<String, String>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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<String>(
|
||||
|
@ -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"));
|
||||
|
@ -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"));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
<dependency>
|
||||
<groupId>{{groupId}}</groupId>
|
||||
<artifactId>{{artifactId}}</artifactId>
|
||||
<version>{{artifactVersion}}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
```
|
||||
|
||||
## 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}}
|
||||
|
@ -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)
|
||||
|
@ -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<Pair> queryParams, Map<String, String> headerParams) {
|
||||
// TODO: support oauth
|
||||
if (accessToken != null) {
|
||||
headerParams.put("Authorization", "Bearer " + accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -45,6 +45,7 @@ import {{invokerPackage}}.auth.OAuth;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class ApiClient {
|
||||
private Client client;
|
||||
private Map<String, Client> hostMap = new HashMap<String, Client>();
|
||||
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
|
||||
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<String, Authentication>();{{#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> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, 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<String, List<String>> buildResponseHeaders(Response response) {
|
||||
Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
|
||||
for (Entry<String, List<Object>> entry: response.getHeaders().entrySet()) {
|
||||
|
@ -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 {
|
||||
|
@ -162,7 +162,7 @@
|
||||
</dependencies>
|
||||
<properties>
|
||||
<swagger-annotations-version>1.5.0</swagger-annotations-version>
|
||||
<jersey-version>2.6</jersey-version>
|
||||
<jersey-version>2.12</jersey-version>
|
||||
<jackson-version>2.4.2</jackson-version>
|
||||
<jodatime-version>2.3</jodatime-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
|
@ -75,13 +75,11 @@ public class ApiClient {
|
||||
private int statusCode;
|
||||
private Map<String, List<String>> 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 <code>parseDatetime</code>.
|
||||
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 <code>datetimeFormat</code> supports these ISO 8601 datetime formats:
|
||||
* Parse the given datetime string into Date object.
|
||||
* When <code>lenientDatetimeFormat</code> 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).
|
||||
*/
|
||||
|
@ -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 {
|
||||
|
@ -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<String, Interceptor> getApiAuthorizations() {
|
||||
return apiAuthorizations;
|
||||
}
|
||||
|
@ -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<String, String> 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<String, String> 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() {
|
||||
|
@ -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 {
|
||||
|
@ -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<String, Interceptor> apiAuthorizations;
|
||||
private OkHttpClient okClient;
|
||||
private Retrofit.Builder adapterBuilder;
|
||||
|
||||
public ApiClient() {
|
||||
apiAuthorizations = new LinkedHashMap<String, Interceptor>();
|
||||
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> S createService(Class<S> 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<String, Interceptor> getApiAuthorizations() {
|
||||
return apiAuthorizations;
|
||||
}
|
||||
|
||||
public void setApiAuthorizations(Map<String, Interceptor> 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<T> implements Converter<ResponseBody, T> {
|
||||
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<ResponseBody, ?> fromResponseBody(Type type, Annotation[] annotations) {
|
||||
if(type.equals(String.class))
|
||||
return new GsonResponseBodyConverterToString<Object>(gson, type);
|
||||
else
|
||||
return gsonConverterFactory.fromResponseBody(type, annotations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
|
||||
return gsonConverterFactory.toRequestBody(type, annotations);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,95 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class CollectionFormats {
|
||||
|
||||
public static class CSVParams {
|
||||
|
||||
protected List<String> params;
|
||||
|
||||
public CSVParams() {
|
||||
}
|
||||
|
||||
public CSVParams(List<String> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public CSVParams(String... params) {
|
||||
this.params = Arrays.asList(params);
|
||||
}
|
||||
|
||||
public List<String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(List<String> 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<String> 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<String> 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<String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
public PIPESParams(String... params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.join(params.toArray(new String[0]), "|");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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}}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
@ -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 extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
|
||||
String requestMethod, Class<T> responseClass)
|
||||
throws OAuthSystemException, OAuthProblemException {
|
||||
|
||||
MediaType mediaType = MediaType.parse("application/json");
|
||||
Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri());
|
||||
|
||||
if(headers != null) {
|
||||
for (Entry<String, String> 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
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
{{#isBodyParam}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}}
|
@ -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"
|
||||
}
|
@ -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}}
|
@ -0,0 +1 @@
|
||||
{{#isHeaderParam}}@Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}}
|
@ -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}}
|
@ -0,0 +1 @@
|
||||
{{#isPathParam}}@Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}
|
@ -0,0 +1,158 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>{{groupId}}</groupId>
|
||||
<artifactId>{{artifactId}}</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>{{artifactId}}</name>
|
||||
<version>{{artifactVersion}}</version>
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:swagger-api/swagger-mustache.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:swagger-api/swagger-codegen.git</developerConnection>
|
||||
<url>https://github.com/swagger-api/swagger-codegen</url>
|
||||
</scm>
|
||||
<prerequisites>
|
||||
<maven>2.2.0</maven>
|
||||
</prerequisites>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>loggerPath</name>
|
||||
<value>conf/log4j.properties</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<argLine>-Xms512m -Xmx1500m</argLine>
|
||||
<parallel>methods</parallel>
|
||||
<forkMode>pertest</forkMode>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/lib</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- attach test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add_sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/main/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add_test_sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/test/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>${swagger-annotations-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>${retrofit-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit</groupId>
|
||||
<artifactId>converter-gson</artifactId>
|
||||
<version>${retrofit-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.oltu.oauth2</groupId>
|
||||
<artifactId>org.apache.oltu.oauth2.client</artifactId>
|
||||
<version>${oltu-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<swagger-annotations-version>1.5.0</swagger-annotations-version>
|
||||
<retrofit-version>2.0.0-beta2</retrofit-version>
|
||||
<okhttp-version>2.5.0</okhttp-version>
|
||||
<gson-version>2.4</gson-version>
|
||||
<oltu-version>1.0.0</oltu-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
</properties>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
{{#isQueryParam}}@Query("{{baseName}}") {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}} {{paramName}}{{/isQueryParam}}
|
@ -0,0 +1,3 @@
|
||||
<manifest package="{{invokerPackage}}" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application />
|
||||
</manifest>
|
@ -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}} })
|
||||
|
@ -34,14 +34,14 @@
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>swagger.api.basepath</param-name>
|
||||
<param-value>http://localhost:8080</param-value>
|
||||
<param-value>{{basePath}}</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>2</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>jersey</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<url-pattern>{{contextPath}}/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<filter>
|
||||
<filter-name>ApiOriginFilter</filter-name>
|
||||
|
@ -1 +1 @@
|
||||
{{#isBodyParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}} {{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/isBodyParam}}
|
||||
{{#isBodyParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}} {{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @RequestBody {{{dataType}}} {{paramName}}{{/isBodyParam}}
|
@ -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
|
||||
|
@ -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<T1,T2>(objA: T1, objB: T2) {
|
||||
for(let key in objB){
|
||||
if(objB.hasOwnProperty(key)){
|
||||
objA[key] = objB[key];
|
||||
}
|
||||
}
|
||||
return <T1&T2>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);
|
||||
|
@ -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}}
|
||||
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
|
||||
}
|
||||
{{/isEnum}}
|
||||
@ -36,4 +36,4 @@ namespace {{package}} {
|
||||
{{/hasEnums}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,11 @@ class VoidAuth implements Authentication {
|
||||
*/
|
||||
{{/description}}
|
||||
export class {{classname}} {
|
||||
private basePath = '{{basePath}}';
|
||||
protected basePath = '{{basePath}}';
|
||||
protected defaultHeaders : any = {};
|
||||
|
||||
|
||||
|
||||
public authentications = {
|
||||
'default': <Authentication>new VoidAuth(),
|
||||
{{#authMethods}}
|
||||
@ -154,17 +158,25 @@ export class {{classname}} {
|
||||
{{#isOAuth}}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
private extendObj<T1,T2>(objA: T1, objB: T2) {
|
||||
for(let key in objB){
|
||||
if(objB.hasOwnProperty(key)){
|
||||
objA[key] = objB[key];
|
||||
}
|
||||
}
|
||||
return <T1&T2>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}}',
|
||||
|
@ -0,0 +1,19 @@
|
||||
{{=< >=}}(ns <package>.<classname>
|
||||
(:require [<projectName>.core :refer [call-api check-required-params]])
|
||||
(:import (java.io File)))
|
||||
<#operations><#operation>
|
||||
(defn <nickname>
|
||||
"<&summary><#notes>
|
||||
<¬es></notes>"<#hasOptionalParams>
|
||||
([<#allParams><#required><#isFile>^File </isFile><paramName> </required></allParams>] (<nickname><#allParams><#required> <paramName></required></allParams> nil))</hasOptionalParams>
|
||||
<#hasOptionalParams>(</hasOptionalParams>[<#allParams><#required><#isFile>^File </isFile><paramName> </required></allParams><#hasOptionalParams>{:keys [<#allParams><^required><#isFile>^File </isFile><paramName> </required></allParams>]}</hasOptionalParams>]<#hasRequiredParams>
|
||||
<#hasOptionalParams> </hasOptionalParams>(check-required-params<#allParams><#required> <paramName></required></allParams>)</hasRequiredParams>
|
||||
<#hasOptionalParams> </hasOptionalParams>(call-api "<path>" :<httpMethod>
|
||||
<#hasOptionalParams> </hasOptionalParams> {:path-params {<#pathParams>"<baseName>" <paramName> </pathParams>}
|
||||
<#hasOptionalParams> </hasOptionalParams> :header-params {<#headerParams>"<baseName>" <paramName> </headerParams>}
|
||||
<#hasOptionalParams> </hasOptionalParams> :query-params {<#queryParams>"<baseName>" <paramName> </queryParams>}
|
||||
<#hasOptionalParams> </hasOptionalParams> :form-params {<#formParams>"<baseName>" <paramName> </formParams>}<#bodyParam>
|
||||
<#hasOptionalParams> </hasOptionalParams> :body-param <paramName></bodyParam>
|
||||
<#hasOptionalParams> </hasOptionalParams> :content-types [<#consumes>"<mediaType>"<#hasMore> </hasMore></consumes>]
|
||||
<#hasOptionalParams> </hasOptionalParams> :accepts [<#produces>"<mediaType>"<#hasMore> </hasMore></produces>]}))<#hasOptionalParams>)</hasOptionalParams>
|
||||
</operation></operations>
|
178
modules/swagger-codegen/src/main/resources/clojure/core.mustache
Normal file
178
modules/swagger-codegen/src/main/resources/clojure/core.mustache
Normal file
@ -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)))
|
@ -0,0 +1,8 @@
|
||||
{{=< >=}}(defproject <&projectName> "<&projectVersion>"
|
||||
:description "<&projectDescription>"<#projectUrl>
|
||||
:url "<&projectUrl>"</projectUrl><#licenseName>
|
||||
:license {:name "<&licenseName>"<#licenseUrl>
|
||||
:url "<&licenseUrl>"</licenseUrl>}</licenseName>
|
||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
||||
[clj-http "2.0.0"]
|
||||
[cheshire "5.5.0"]])
|
@ -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
|
||||
/// <returns>Escaped string.</returns>
|
||||
public string EscapeString(string str)
|
||||
{
|
||||
return RestSharp.Extensions.StringExtensions.UrlEncode(str);
|
||||
return UrlEncode(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert stream to byte array
|
||||
/// Credit/Ref: http://stackoverflow.com/a/221941/677735
|
||||
/// </summary>
|
||||
/// <param name="input">Input stream to be converted</param>
|
||||
/// <returns>Byte array</returns>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL encode a string
|
||||
/// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50
|
||||
/// </summary>
|
||||
/// <param name="input">String to be URL encoded</param>
|
||||
/// <returns>Byte array</returns>
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,12 @@ namespace {{packageName}}.Client
|
||||
/// <value>The password.</value>
|
||||
public static String Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the access token for OAuth2 authentication.
|
||||
/// </summary>
|
||||
/// <value>The access token.</value>
|
||||
public static String AccessToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the API key based on the authentication name.
|
||||
/// </summary>
|
||||
|
@ -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<String, String>();
|
||||
var queryParams = new Dictionary<String, String>();
|
||||
@ -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<String, String>();
|
||||
var queryParams = new Dictionary<String, String>();
|
||||
@ -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);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -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()
|
@ -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}}
|
@ -0,0 +1 @@
|
||||
{{{swagger-yaml}}}
|
@ -94,17 +94,15 @@
|
||||
</div> <!-- field-items -->
|
||||
{{/hasFormParams}}
|
||||
|
||||
<!-- Remove Return type... unclear where this comes from;
|
||||
for our swagger.json files, it is always empty and there is no boolean guard or hasReturnType
|
||||
do we end up with a heading but not content
|
||||
|
||||
{{#returnType}}
|
||||
<h3 class="field-label">Return type</h3>
|
||||
<div class="return-type"><a href="#{{returnContainer}}">{{{returnType}}}</a></div>
|
||||
<div class="return-type">
|
||||
{{#hasReference}}{{^returnSimpleType}}{{returnContainer}}[{{/returnSimpleType}}<a href="#{{returnBaseType}}">{{returnBaseType}}</a>{{^returnSimpleType}}]{{/returnSimpleType}}{{/hasReference}}
|
||||
{{^hasReference}}{{returnType}}{{/hasReference}}
|
||||
</div>
|
||||
{{/returnType}}
|
||||
|
||||
Todo: process Response Object and its headers, schema, examples
|
||||
-->
|
||||
<!--Todo: process Response Object and its headers, schema, examples -->
|
||||
|
||||
{{#hasExamples}}
|
||||
{{#examples}}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user