Merge pull request #7426 from swagger-api/2.4.0

Merge 2.4.0 into master
This commit is contained in:
William Cheng 2018-01-21 23:01:21 +08:00 committed by GitHub
commit 174b14ba1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1137 changed files with 20766 additions and 11405 deletions

View File

@ -107,7 +107,7 @@ On a mac, it's even easier with `brew`:
brew install swagger-codegen brew install swagger-codegen
``` ```
To build from source, you need the following installed and available in your $PATH: To build from source, you need the following installed and available in your `$PATH:`
* [Java 7 or 8](http://java.oracle.com) * [Java 7 or 8](http://java.oracle.com)
@ -116,7 +116,7 @@ To build from source, you need the following installed and available in your $PA
#### OS X Users #### OS X Users
Don't forget to install Java 7 or 8. You probably have 1.6. Don't forget to install Java 7 or 8. You probably have 1.6.
Export JAVA_HOME in order to use the supported Java version: Export `JAVA_HOME` in order to use the supported Java version:
```sh ```sh
export JAVA_HOME=`/usr/libexec/java_home -v 1.8` export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
export PATH=${JAVA_HOME}/bin:$PATH export PATH=${JAVA_HOME}/bin:$PATH
@ -264,7 +264,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-o samples/client/petstore/java -o samples/client/petstore/java
``` ```
with a number of options. You can get the options with the `help generate` command (below only shows partal results): with a number of options. You can get the options with the `help generate` command (below only shows partial results):
``` ```
NAME NAME
@ -340,7 +340,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar meta \
-o output/myLibrary -n myClientCodegen -p com.my.company.codegen -o output/myLibrary -n myClientCodegen -p com.my.company.codegen
``` ```
This will write, in the folder `output/myLibrary`, all the files you need to get started, including a README.md. Once modified and compiled, you can load your library with the codegen and generate clients with your own, custom-rolled logic. This will write, in the folder `output/myLibrary`, all the files you need to get started, including a `README.md. Once modified and compiled, you can load your library with the codegen and generate clients with your own, custom-rolled logic.
You would then compile your library in the `output/myLibrary` folder with `mvn package` and execute the codegen like such: You would then compile your library in the `output/myLibrary` folder with `mvn package` and execute the codegen like such:
@ -541,7 +541,7 @@ Your config file for Java can look like
For all the unspecified options default values will be used. For all the unspecified options default values will be used.
Another way to override default options is to extend the config class for the 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: To change, for example, the prefix for the Objective-C generated files, simply subclass the `ObjcClientCodegen.java`:
```java ```java
package com.mycompany.swagger.codegen; package com.mycompany.swagger.codegen;
@ -790,7 +790,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [Hewlett Packard Enterprise](https://hpe.com) - [Hewlett Packard Enterprise](https://hpe.com)
- [High Technologies Center](http://htc-cs.com) - [High Technologies Center](http://htc-cs.com)
- [Hootsuite](https://hootsuite.com/) - [Hootsuite](https://hootsuite.com/)
- [Huawei Cloud](https://www.huaweicloud.com) - [Cloud Stream Service](http://www.huaweicloud.com/en-us/product/cs.html) - [Huawei Cloud](http://www.huaweicloud.com/en-us/product/cs.html)
- [IBM](https://www.ibm.com) - [IBM](https://www.ibm.com)
- [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications) - [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications)
- [Individual Standard IVS](http://www.individual-standard.com) - [Individual Standard IVS](http://www.individual-standard.com)

View File

@ -8,3 +8,4 @@
./bin/java-play-framework-petstore-server-no-swagger-ui.sh ./bin/java-play-framework-petstore-server-no-swagger-ui.sh
./bin/java-play-framework-petstore-server-no-wrap-calls.sh ./bin/java-play-framework-petstore-server-no-wrap-calls.sh
./bin/java-play-framework-petstore-server-fake-endpoints.sh ./bin/java-play-framework-petstore-server-fake-endpoints.sh
./bin/java-play-framework-petstore-server-api-package-override.sh

View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaPlayFramework -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l java-play-framework -o samples/server/petstore/java-play-framework-api-package-override -DhideGenerationTimestamp=true,apiPackage=com.puppies.store.apis"
java $JAVA_OPTS -jar $executable $ags

31
bin/scala-gatling-petstore.sh Executable file
View File

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

View File

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

View File

@ -41,6 +41,7 @@ test:
## test with jdk7 ## test with jdk7
- sudo update-java-alternatives -s java-1.7.0-openjdk-amd64 - sudo update-java-alternatives -s java-1.7.0-openjdk-amd64
- java -version - java -version
- cp pom.xml.circleci.java7 pom.xml # use jdk7 pom
- mvn clean install - mvn clean install
- mvn -q verify -Psamples - mvn -q verify -Psamples
# skip the rest if previous mvn task fails # skip the rest if previous mvn task fails

View File

@ -3,7 +3,7 @@
<parent> <parent>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-codegen-project</artifactId> <artifactId>swagger-codegen-project</artifactId>
<version>2.3.1</version> <version>2.4.0-SNAPSHOT</version>
<relativePath>../..</relativePath> <relativePath>../..</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,12 +1,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <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"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-codegen-project</artifactId> <artifactId>swagger-codegen-project</artifactId>
<version>2.3.1</version> <version>2.4.0-SNAPSHOT</version>
<relativePath>../..</relativePath> <relativePath>../..</relativePath>
</parent> </parent>
<artifactId>swagger-codegen-maven-plugin</artifactId> <artifactId>swagger-codegen-maven-plugin</artifactId>

View File

@ -3,7 +3,7 @@
<parent> <parent>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-codegen-project</artifactId> <artifactId>swagger-codegen-project</artifactId>
<version>2.3.1</version> <version>2.4.0-SNAPSHOT</version>
<relativePath>../..</relativePath> <relativePath>../..</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -222,4 +222,7 @@ public class CodegenConstants {
public static final String REMOVE_OPERATION_ID_PREFIX = "removeOperationIdPrefix"; public static final String REMOVE_OPERATION_ID_PREFIX = "removeOperationIdPrefix";
public static final String REMOVE_OPERATION_ID_PREFIX_DESC = "Remove prefix of operationId, e.g. config_getId => getId"; public static final String REMOVE_OPERATION_ID_PREFIX_DESC = "Remove prefix of operationId, e.g. config_getId => getId";
public static final String STRIP_PACKAGE_NAME = "stripPackageName";
public static final String STRIP_PACKAGE_NAME_DESC = "Whether to strip leading dot-separated packages from generated model classes";
} }

View File

@ -111,7 +111,7 @@ public class CodegenOperation {
* @return true if act as Restful index method, false otherwise * @return true if act as Restful index method, false otherwise
*/ */
public boolean isRestfulIndex() { public boolean isRestfulIndex() {
return "GET".equals(httpMethod) && "".equals(pathWithoutBaseName()); return "GET".equalsIgnoreCase(httpMethod) && "".equals(pathWithoutBaseName());
} }
/** /**

View File

@ -7,6 +7,7 @@ public class CodegenSecurity {
public String name; public String name;
public String type; public String type;
public Boolean hasMore, isBasic, isOAuth, isApiKey; public Boolean hasMore, isBasic, isOAuth, isApiKey;
public Map<String, Object> vendorExtensions;
// ApiKey specific // ApiKey specific
public String keyParamName; public String keyParamName;
public Boolean isKeyInQuery, isKeyInHeader; public Boolean isKeyInQuery, isKeyInHeader;
@ -39,6 +40,8 @@ public class CodegenSecurity {
return false; return false;
if (isApiKey != null ? !isApiKey.equals(that.isApiKey) : that.isApiKey != null) if (isApiKey != null ? !isApiKey.equals(that.isApiKey) : that.isApiKey != null)
return false; return false;
if (vendorExtensions != null ? !vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions != null)
return false;
if (keyParamName != null ? !keyParamName.equals(that.keyParamName) : that.keyParamName != null) if (keyParamName != null ? !keyParamName.equals(that.keyParamName) : that.keyParamName != null)
return false; return false;
if (isKeyInQuery != null ? !isKeyInQuery.equals(that.isKeyInQuery) : that.isKeyInQuery != null) if (isKeyInQuery != null ? !isKeyInQuery.equals(that.isKeyInQuery) : that.isKeyInQuery != null)
@ -71,6 +74,7 @@ public class CodegenSecurity {
result = 31 * result + (isBasic != null ? isBasic.hashCode() : 0); result = 31 * result + (isBasic != null ? isBasic.hashCode() : 0);
result = 31 * result + (isOAuth != null ? isOAuth.hashCode() : 0); result = 31 * result + (isOAuth != null ? isOAuth.hashCode() : 0);
result = 31 * result + (isApiKey != null ? isApiKey.hashCode() : 0); result = 31 * result + (isApiKey != null ? isApiKey.hashCode() : 0);
result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0);
result = 31 * result + (keyParamName != null ? keyParamName.hashCode() : 0); result = 31 * result + (keyParamName != null ? keyParamName.hashCode() : 0);
result = 31 * result + (isKeyInQuery != null ? isKeyInQuery.hashCode() : 0); result = 31 * result + (isKeyInQuery != null ? isKeyInQuery.hashCode() : 0);
result = 31 * result + (isKeyInHeader != null ? isKeyInHeader.hashCode() : 0); result = 31 * result + (isKeyInHeader != null ? isKeyInHeader.hashCode() : 0);

View File

@ -152,7 +152,7 @@ public class DefaultCodegen {
} }
if (additionalProperties.containsKey(CodegenConstants.REMOVE_OPERATION_ID_PREFIX)) { if (additionalProperties.containsKey(CodegenConstants.REMOVE_OPERATION_ID_PREFIX)) {
this.setSortParamsByRequiredFlag(Boolean.valueOf(additionalProperties this.setRemoveOperationIdPrefix(Boolean.valueOf(additionalProperties
.get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX).toString())); .get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX).toString()));
} }
} }
@ -2756,6 +2756,7 @@ public class DefaultCodegen {
sec.name = entry.getKey(); sec.name = entry.getKey();
sec.type = schemeDefinition.getType(); sec.type = schemeDefinition.getType();
sec.isCode = sec.isPassword = sec.isApplication = sec.isImplicit = false; sec.isCode = sec.isPassword = sec.isApplication = sec.isImplicit = false;
sec.vendorExtensions = schemeDefinition.getVendorExtensions();
if (schemeDefinition instanceof ApiKeyAuthDefinition) { if (schemeDefinition instanceof ApiKeyAuthDefinition) {
final ApiKeyAuthDefinition apiKeyDefinition = (ApiKeyAuthDefinition) schemeDefinition; final ApiKeyAuthDefinition apiKeyDefinition = (ApiKeyAuthDefinition) schemeDefinition;

View File

@ -152,11 +152,15 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
public String toModelName(String name) { public String toModelName(String name) {
// camelize the model name // camelize the model name
// phone_number => PhoneNumber // phone_number => PhoneNumber
return camelize(toModelFilename(name)); return camelize(toModel(name));
} }
@Override @Override
public String toModelFilename(String name) { public String toModelFilename(String name) {
return toModel("model_" + name);
}
public String toModel(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) { if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name; name = modelNamePrefix + "_" + name;
} }
@ -188,7 +192,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// e.g. PetApi.go => pet_api.go // e.g. PetApi.go => pet_api.go
return underscore(name) + "_api"; return "api_" + underscore(name);
} }
/** /**

View File

@ -29,6 +29,7 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
protected String modelPropertyNaming = "camelCase"; protected String modelPropertyNaming = "camelCase";
protected String invokerPackage = "io.swagger.client"; protected String invokerPackage = "io.swagger.client";
protected String sourceFolder = "src/main/scala"; protected String sourceFolder = "src/main/scala";
protected boolean stripPackageName = true;
public AbstractScalaCodegen() { public AbstractScalaCodegen() {
super(); super();
@ -102,6 +103,13 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) { if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER)); this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
} }
if (additionalProperties.containsKey(CodegenConstants.STRIP_PACKAGE_NAME) &&
"false".equalsIgnoreCase(additionalProperties.get(CodegenConstants.STRIP_PACKAGE_NAME).toString())) {
this.stripPackageName = false;
additionalProperties.put(CodegenConstants.STRIP_PACKAGE_NAME, false);
LOGGER.warn("stripPackageName=false. Compilation errors may occur if API type names clash with types " +
"in the default imports");
}
} }
public void setSourceFolder(String sourceFolder) { public void setSourceFolder(String sourceFolder) {
@ -265,10 +273,16 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
} }
protected String stripPackageName(String input) { protected String stripPackageName(String input) {
if (StringUtils.isEmpty(input) || input.lastIndexOf(".") < 0) if (!stripPackageName || StringUtils.isEmpty(input) || input.lastIndexOf(".") < 0)
return input; return input;
int lastIndexOfDot = input.lastIndexOf("."); int lastIndexOfDot = input.lastIndexOf(".");
return input.substring(lastIndexOfDot + 1); return input.substring(lastIndexOfDot + 1);
} }
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
} }

View File

@ -92,8 +92,8 @@ public class GoClientCodegen extends AbstractGoCodegen {
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore")); supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.go")); supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.go"));
supportingFiles.add(new SupportingFile("api_client.mustache", "", "api_client.go")); supportingFiles.add(new SupportingFile("client.mustache", "", "client.go"));
supportingFiles.add(new SupportingFile("api_response.mustache", "", "api_response.go")); supportingFiles.add(new SupportingFile("response.mustache", "", "response.go"));
supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml")); supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml"));
} }

View File

@ -8,6 +8,7 @@ import io.swagger.models.properties.*;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.io.File;
import io.swagger.models.auth.SecuritySchemeDefinition; import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.codegen.CliOption; import io.swagger.codegen.CliOption;
@ -28,7 +29,7 @@ import java.util.regex.Matcher;
public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenConfig { public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenConfig {
// source folder where to write the files // source folder where to write the files
protected String sourceFolder = "src"; protected String sourceFolder = "lib";
protected String artifactId = "swagger-haskell-http-client"; protected String artifactId = "swagger-haskell-http-client";
protected String artifactVersion = "1.0.0"; protected String artifactVersion = "1.0.0";
@ -36,11 +37,13 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
protected String defaultDateFormat = "%Y-%m-%d"; protected String defaultDateFormat = "%Y-%m-%d";
protected Boolean useMonadLogger = false; protected Boolean useMonadLogger = false;
protected Boolean allowNonUniqueOperationIds = false;
protected Boolean genEnums = true; protected Boolean genEnums = true;
// CLI PROPS // CLI PROPS
public static final String PROP_ALLOW_FROMJSON_NULLS = "allowFromJsonNulls"; public static final String PROP_ALLOW_FROMJSON_NULLS = "allowFromJsonNulls";
public static final String PROP_ALLOW_TOJSON_NULLS = "allowToJsonNulls"; public static final String PROP_ALLOW_TOJSON_NULLS = "allowToJsonNulls";
public static final String PROP_ALLOW_NONUNIQUE_OPERATION_IDS = "allowNonUniqueOperationIds";
public static final String PROP_DATETIME_FORMAT = "dateTimeFormat"; public static final String PROP_DATETIME_FORMAT = "dateTimeFormat";
public static final String PROP_DATE_FORMAT = "dateFormat"; public static final String PROP_DATE_FORMAT = "dateFormat";
public static final String PROP_GENERATE_ENUMS = "generateEnums"; public static final String PROP_GENERATE_ENUMS = "generateEnums";
@ -79,6 +82,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
static final String X_DATA_TYPE = "x-dataType"; static final String X_DATA_TYPE = "x-dataType";
static final String X_ENUM_VALUES = "x-enumValues"; static final String X_ENUM_VALUES = "x-enumValues";
static final String X_MEDIA_IS_JSON = "x-mediaIsJson"; static final String X_MEDIA_IS_JSON = "x-mediaIsJson";
static final String X_MEDIA_IS_WILDCARD = "x-mediaIsWildcard";
static final String X_MIME_TYPES = "x-mimeTypes"; static final String X_MIME_TYPES = "x-mimeTypes";
static final String X_OPERATION_TYPE = "x-operationType"; static final String X_OPERATION_TYPE = "x-operationType";
static final String X_PARAM_NAME_TYPE = "x-paramNameType"; static final String X_PARAM_NAME_TYPE = "x-paramNameType";
@ -87,6 +91,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
static final String X_STRICT_FIELDS = "x-strictFields"; static final String X_STRICT_FIELDS = "x-strictFields";
static final String X_UNKNOWN_MIME_TYPES = "x-unknownMimeTypes"; static final String X_UNKNOWN_MIME_TYPES = "x-unknownMimeTypes";
static final String X_USE_MONAD_LOGGER = "x-useMonadLogger"; static final String X_USE_MONAD_LOGGER = "x-useMonadLogger";
static final String X_ALLOW_NONUNIQUE_OPERATION_IDS = "x-allowNonUniqueOperationIds";
static final String X_NEWTYPE = "x-newtype"; static final String X_NEWTYPE = "x-newtype";
static final String X_ENUM = "x-enum"; static final String X_ENUM = "x-enum";
@ -96,6 +101,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
protected Map<String, Set<String>> modelMimeTypes = new HashMap<>(); protected Map<String, Set<String>> modelMimeTypes = new HashMap<>();
protected Map<String, String> knownMimeDataTypes = new HashMap<>(); protected Map<String, String> knownMimeDataTypes = new HashMap<>();
protected Set<String> typeNames = new HashSet<String>(); protected Set<String> typeNames = new HashSet<String>();
protected Set<String> modelTypeNames = new HashSet<String>();
public CodegenType getTag() { public CodegenType getTag() {
return CodegenType.CLIENT; return CodegenType.CLIENT;
@ -128,8 +134,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
outputFolder = "generated-code/haskell-http-client"; outputFolder = "generated-code/haskell-http-client";
embeddedTemplateDir = templateDir = "haskell-http-client"; embeddedTemplateDir = templateDir = "haskell-http-client";
apiPackage = "API"; //apiPackage = "API";
modelPackage = "Model"; //modelPackage = "Model";
// Haskell keywords and reserved function names, taken mostly from https://wiki.haskell.org/Keywords // Haskell keywords and reserved function names, taken mostly from https://wiki.haskell.org/Keywords
setReservedWordsLowerCase( setReservedWordsLowerCase(
@ -217,6 +223,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
cliOptions.add(CliOption.newBoolean(PROP_ALLOW_FROMJSON_NULLS, "allow JSON Null during model decoding from JSON").defaultValue(Boolean.TRUE.toString())); cliOptions.add(CliOption.newBoolean(PROP_ALLOW_FROMJSON_NULLS, "allow JSON Null during model decoding from JSON").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_ALLOW_TOJSON_NULLS, "allow emitting JSON Null during model encoding to JSON").defaultValue(Boolean.FALSE.toString())); cliOptions.add(CliOption.newBoolean(PROP_ALLOW_TOJSON_NULLS, "allow emitting JSON Null during model encoding to JSON").defaultValue(Boolean.FALSE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_ALLOW_NONUNIQUE_OPERATION_IDS, "allow different API modules to contain the same operationId. Each API must be imported qualified").defaultValue(Boolean.FALSE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_LENSES, "Generate Lens optics for Models").defaultValue(Boolean.TRUE.toString())); cliOptions.add(CliOption.newBoolean(PROP_GENERATE_LENSES, "Generate Lens optics for Models").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_MODEL_CONSTRUCTORS, "Generate smart constructors (only supply required fields) for models").defaultValue(Boolean.TRUE.toString())); cliOptions.add(CliOption.newBoolean(PROP_GENERATE_MODEL_CONSTRUCTORS, "Generate smart constructors (only supply required fields) for models").defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(PROP_GENERATE_ENUMS, "Generate specific datatypes for swagger enums").defaultValue(Boolean.TRUE.toString())); cliOptions.add(CliOption.newBoolean(PROP_GENERATE_ENUMS, "Generate specific datatypes for swagger enums").defaultValue(Boolean.TRUE.toString()));
@ -235,6 +242,10 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
} }
public void setAllowNonUniqueOperationIds(Boolean value) {
additionalProperties.put(X_ALLOW_NONUNIQUE_OPERATION_IDS, value);
this.allowNonUniqueOperationIds = value;
}
public void setAllowFromJsonNulls(Boolean value) { public void setAllowFromJsonNulls(Boolean value) {
additionalProperties.put(PROP_ALLOW_FROMJSON_NULLS, value); additionalProperties.put(PROP_ALLOW_FROMJSON_NULLS, value);
} }
@ -317,6 +328,12 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
setAllowToJsonNulls(false); setAllowToJsonNulls(false);
} }
if (additionalProperties.containsKey(PROP_ALLOW_NONUNIQUE_OPERATION_IDS)) {
setAllowNonUniqueOperationIds(convertPropertyToBoolean(PROP_ALLOW_NONUNIQUE_OPERATION_IDS));
} else {
setAllowNonUniqueOperationIds(false);
}
if (additionalProperties.containsKey(PROP_GENERATE_MODEL_CONSTRUCTORS)) { if (additionalProperties.containsKey(PROP_GENERATE_MODEL_CONSTRUCTORS)) {
setGenerateModelConstructors(convertPropertyToBoolean(PROP_GENERATE_MODEL_CONSTRUCTORS)); setGenerateModelConstructors(convertPropertyToBoolean(PROP_GENERATE_MODEL_CONSTRUCTORS));
} else { } else {
@ -408,7 +425,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
for (String word : words) { for (String word : words) {
wordsCaps.add(firstLetterToUpper(word)); wordsCaps.add(firstLetterToUpper(word));
} }
String apiName = StringUtils.join(wordsCaps, ""); apiPackage = StringUtils.join(wordsCaps, "");
// Set the filenames to write for the API // Set the filenames to write for the API
@ -417,31 +434,34 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
supportingFiles.add(new SupportingFile("swagger.mustache", "", "swagger.yaml")); supportingFiles.add(new SupportingFile("swagger.mustache", "", "swagger.yaml"));
// lib // lib
supportingFiles.add(new SupportingFile("TopLevel.mustache", "lib/", apiName + ".hs")); supportingFiles.add(new SupportingFile("TopLevel.mustache", sourceFolder + File.separator, apiPackage + ".hs"));
supportingFiles.add(new SupportingFile("Client.mustache", "lib/" + apiName, "Client.hs")); supportingFiles.add(new SupportingFile("Client.mustache", sourceFolder + File.separator + apiPackage, "Client.hs"));
supportingFiles.add(new SupportingFile("API.mustache", "lib/" + apiName, "API.hs"));
supportingFiles.add(new SupportingFile("Core.mustache", "lib/" + apiName, "Core.hs")); if(!allowNonUniqueOperationIds) {
supportingFiles.add(new SupportingFile("Model.mustache", "lib/" + apiName, "Model.hs")); supportingFiles.add(new SupportingFile("APIS.mustache", sourceFolder + File.separator + apiPackage, "API.hs"));
supportingFiles.add(new SupportingFile("MimeTypes.mustache", "lib/" + apiName, "MimeTypes.hs")); }
supportingFiles.add(new SupportingFile("Core.mustache", sourceFolder + File.separator + apiPackage, "Core.hs"));
supportingFiles.add(new SupportingFile("Model.mustache", sourceFolder + File.separator + apiPackage, "Model.hs"));
supportingFiles.add(new SupportingFile("MimeTypes.mustache", sourceFolder + File.separator + apiPackage, "MimeTypes.hs"));
// logger // logger
supportingFiles.add(new SupportingFile(useMonadLogger ? "LoggingMonadLogger.mustache" : "LoggingKatip.mustache", "lib/" + apiName, "Logging.hs")); supportingFiles.add(new SupportingFile(useMonadLogger ? "LoggingMonadLogger.mustache" : "LoggingKatip.mustache", sourceFolder + File.separator + apiPackage, "Logging.hs"));
// modelTemplateFiles.put("API.mustache", ".hs"); apiTemplateFiles.put("API.mustache", ".hs");
// apiTemplateFiles.put("Model.mustache", ".hs"); // modelTemplateFiles.put("Model.mustache", ".hs");
// lens // lens
if ((boolean)additionalProperties.get(PROP_GENERATE_LENSES)) { if ((boolean)additionalProperties.get(PROP_GENERATE_LENSES)) {
supportingFiles.add(new SupportingFile("ModelLens.mustache", "lib/" + apiName, "ModelLens.hs")); supportingFiles.add(new SupportingFile("ModelLens.mustache", sourceFolder + File.separator + apiPackage, "ModelLens.hs"));
} }
additionalProperties.put("title", apiName); additionalProperties.put("title", apiPackage);
additionalProperties.put("titleLower", firstLetterToLower(apiName)); additionalProperties.put("titleLower", firstLetterToLower(apiPackage));
additionalProperties.put("package", cabalName); additionalProperties.put("package", cabalName);
additionalProperties.put("pathsName", pathsName); additionalProperties.put("pathsName", pathsName);
additionalProperties.put("requestType", apiName + "Request"); additionalProperties.put("requestType", apiPackage + "Request");
additionalProperties.put("configType", apiName + "Config"); additionalProperties.put("configType", apiPackage + "Config");
additionalProperties.put("swaggerVersion", swagger.getSwagger()); additionalProperties.put("swaggerVersion", swagger.getSwagger());
super.preprocessSwagger(swagger); super.preprocessSwagger(swagger);
@ -508,9 +528,41 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
return null; return null;
} }
} }
@Override @Override
public CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) { public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation op, Map<String, List<CodegenOperation>> operations) {
CodegenOperation op = super.fromOperation(resourcePath, httpMethod, operation, definitions, swagger);
List<CodegenOperation> opList = operations.get(tag);
if (opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(tag, opList);
}
// check for operationId uniqueness
String uniqueName = op.operationId;
String uniqueNameType = toTypeName("Op", uniqueName);
int counter = 0;
HashSet<String> opIds = new HashSet<>();
for (CodegenOperation o : opList) {
opIds.add(o.operationId);
}
while (opIds.contains(uniqueName) ||
(allowNonUniqueOperationIds
? modelTypeNames.contains(uniqueNameType) // only check for model conflicts
: typeNames.contains(uniqueNameType))) { // check globally across all types
uniqueName = op.operationId + counter;
uniqueNameType = toTypeName("Op", uniqueName);
counter++;
}
if (!op.operationId.equals(uniqueName)) {
LOGGER.warn("generated unique operationId `" + uniqueName + "`");
}
op.operationId = uniqueName;
op.operationIdLowerCase = uniqueName.toLowerCase();
op.operationIdCamelCase = DefaultCodegen.camelize(uniqueName);
op.operationIdSnakeCase = DefaultCodegen.underscore(uniqueName);
opList.add(op);
op.baseName = tag;
// prevent aliasing/sharing of operation.vendorExtensions reference // prevent aliasing/sharing of operation.vendorExtensions reference
op.vendorExtensions = new LinkedHashMap(); op.vendorExtensions = new LinkedHashMap();
@ -539,7 +591,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
String dataType = genEnums && param.isEnum ? param.datatypeWithEnum : param.dataType; String dataType = genEnums && param.isEnum ? param.datatypeWithEnum : param.dataType;
String paramNameType = toDedupedName(toTypeName("Param", param.paramName), dataType, !param.isEnum); String paramNameType = toDedupedModelName(toTypeName("Param", param.paramName), dataType, !param.isEnum);
param.vendorExtensions.put(X_PARAM_NAME_TYPE, paramNameType); param.vendorExtensions.put(X_PARAM_NAME_TYPE, paramNameType);
HashMap<String, Object> props = new HashMap<>(); HashMap<String, Object> props = new HashMap<>();
@ -554,7 +606,6 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
processReturnType(op); processReturnType(op);
return op;
} }
@Override @Override
@ -647,6 +698,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
model.classname = generateNextName(model.classname); model.classname = generateNextName(model.classname);
} }
typeNames.add(model.classname); typeNames.add(model.classname);
modelTypeNames.add(model.classname);
// From the model name, compute the prefix for the fields. // From the model name, compute the prefix for the fields.
String prefix = StringUtils.uncapitalize(model.classname); String prefix = StringUtils.uncapitalize(model.classname);
@ -753,7 +805,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
op.vendorExtensions.put(inlineExtentionName, m); op.vendorExtensions.put(inlineExtentionName, m);
} }
private String toDedupedName(String paramNameType, String dataType, Boolean appendDataType) { private String toDedupedModelName(String paramNameType, String dataType, Boolean appendDataType) {
if (appendDataType if (appendDataType
&& uniqueParamNameTypes.containsKey(paramNameType) && uniqueParamNameTypes.containsKey(paramNameType)
&& !isDuplicate(paramNameType, dataType)) { && !isDuplicate(paramNameType, dataType)) {
@ -768,6 +820,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
} }
typeNames.add(paramNameType); typeNames.add(paramNameType);
modelTypeNames.add(paramNameType);
return paramNameType; return paramNameType;
} }
@ -842,7 +895,9 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (isJsonMimeType(mediaType)) { if (isJsonMimeType(mediaType)) {
m.put(X_MEDIA_IS_JSON, "true"); m.put(X_MEDIA_IS_JSON, "true");
} }
if (isWildcardMimeType(mediaType)) {
m.put(X_MEDIA_IS_WILDCARD, "true");
}
if (!knownMimeDataTypes.containsValue(mimeType) && !unknownMimeTypesContainsType(mimeType)) { if (!knownMimeDataTypes.containsValue(mimeType) && !unknownMimeTypesContainsType(mimeType)) {
unknownMimeTypes.add(m); unknownMimeTypes.add(m);
} }
@ -968,6 +1023,20 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
public String toModelFilename(String name) { public String toModelFilename(String name) {
return toTypeName("Model", name); return toTypeName("Model", name);
} }
public String toApiName(String name) {
if (name.length() == 0) {
return "Default";
}
return toTypeName("Api", name);
}
@Override
public String toApiFilename(String name) {
return toTypeName("Api", name);
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar) + File.separator + "API";
}
public String toTypeName(String prefix, String name) { public String toTypeName(String prefix, String name) {
name = escapeIdentifier(prefix, camelize(sanitizeName(name))); name = escapeIdentifier(prefix, camelize(sanitizeName(name)));
return name; return name;
@ -978,17 +1047,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
throw new RuntimeException("Empty method/operation name (operationId) not allowed"); throw new RuntimeException("Empty method/operation name (operationId) not allowed");
} }
operationId = escapeIdentifier("op",camelize(sanitizeName(operationId), true)); operationId = escapeIdentifier("op",camelize(sanitizeName(operationId), true));
String uniqueName = operationId; return operationId;
String uniqueNameType = toTypeName("Op", operationId);
while (typeNames.contains(uniqueNameType)) {
uniqueName = generateNextName(uniqueName);
uniqueNameType = toTypeName("Op", uniqueName);
}
typeNames.add(uniqueNameType);
if(!operationId.equals(uniqueName)) {
LOGGER.warn("generated unique operationId `" + uniqueName + "`");
}
return uniqueName;
} }
public String escapeIdentifier(String prefix, String name) { public String escapeIdentifier(String prefix, String name) {
if(StringUtils.isBlank(prefix)) return name; if(StringUtils.isBlank(prefix)) return name;
@ -1011,6 +1070,10 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
return mime != null && JSON_MIME_PATTERN.matcher(mime).matches(); return mime != null && JSON_MIME_PATTERN.matcher(mime).matches();
} }
static boolean isWildcardMimeType(String mime) {
return mime != null && mime.equals("*/*");
}
@Override @Override
public String toDefaultValue(Property p) { public String toDefaultValue(Property p) {
if (p instanceof StringProperty) { if (p instanceof StringProperty) {
@ -1100,7 +1163,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (duplicateEnum.getLeft()) { if (duplicateEnum.getLeft()) {
paramNameType = duplicateEnum.getRight(); paramNameType = duplicateEnum.getRight();
} else { } else {
paramNameType = toDedupedName(paramNameType, enumValues, false); paramNameType = toDedupedModelName(paramNameType, enumValues, false);
var.datatypeWithEnum = paramNameType; var.datatypeWithEnum = paramNameType;
updateCodegenPropertyEnum(var); updateCodegenPropertyEnum(var);
addEnumToUniques(paramNameType, var.datatype, enumValues, var.allowableValues, var.description); addEnumToUniques(paramNameType, var.datatype, enumValues, var.allowableValues, var.description);

View File

@ -168,7 +168,7 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
if(this.useSwaggerUI) { if(this.useSwaggerUI) {
//App/Controllers //App/Controllers
supportingFiles.add(new SupportingFile("swagger.mustache", "public", "swagger.json")); supportingFiles.add(new SupportingFile("swagger.mustache", "public", "swagger.json"));
supportingFiles.add(new SupportingFile("apiDocController.mustache", "app/controllers", "ApiDocController.java")); supportingFiles.add(new SupportingFile("apiDocController.mustache", String.format("app/%s", apiPackage.replace(".", File.separator)), "ApiDocController.java"));
} }
//We remove the default api.mustache that is used //We remove the default api.mustache that is used

View File

@ -169,6 +169,20 @@ public class Qt5CPPGenerator extends AbstractCppCodegen implements CodegenConfig
} }
additionalProperties.put("cppNamespaceDeclarations", cppNamespace.split("\\::")); additionalProperties.put("cppNamespaceDeclarations", cppNamespace.split("\\::"));
if(additionalProperties.containsKey("modelNamePrefix")){
supportingFiles.clear();
supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder, modelNamePrefix + "Helpers.h"));
supportingFiles.add(new SupportingFile("helpers-body.mustache", sourceFolder, modelNamePrefix + "Helpers.cpp"));
supportingFiles.add(new SupportingFile("HttpRequest.h.mustache", sourceFolder, modelNamePrefix + "HttpRequest.h"));
supportingFiles.add(new SupportingFile("HttpRequest.cpp.mustache", sourceFolder, modelNamePrefix + "HttpRequest.cpp"));
supportingFiles.add(new SupportingFile("modelFactory.mustache", sourceFolder, modelNamePrefix + "ModelFactory.h"));
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder, modelNamePrefix + "Object.h"));
typeMapping.put("object", modelNamePrefix + "Object");
typeMapping.put("file", modelNamePrefix + "HttpRequestInputFileElement");
importMapping.put("SWGHttpRequestInputFileElement", "#include \"" + modelNamePrefix + "HttpRequest.h\"");
additionalProperties().put("prefix", modelNamePrefix);
}
} }
/** /**
@ -258,7 +272,7 @@ public class Qt5CPPGenerator extends AbstractCppCodegen implements CodegenConfig
@Override @Override
public String toApiFilename(String name) { public String toApiFilename(String name) {
return PREFIX + initialCaps(name) + "Api"; return modelNamePrefix + initialCaps(name) + "Api";
} }
/** /**
@ -398,7 +412,7 @@ public class Qt5CPPGenerator extends AbstractCppCodegen implements CodegenConfig
@Override @Override
public String toApiName(String type) { public String toApiName(String type) {
return PREFIX + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api"; return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
} }
@Override @Override

View File

@ -440,6 +440,14 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
return input.replace("*/", "*_/").replace("/*", "/_*"); return input.replace("*/", "*_/").replace("/*", "/_*");
} }
boolean isMimetypeXml(String mimetype) {
return mimetype.toLowerCase().startsWith("application/xml");
}
boolean isMimetypePlainText(String mimetype) {
return mimetype.toLowerCase().startsWith("text/plain");
}
@Override @Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) { public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger); CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger);
@ -528,14 +536,13 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
// if "consumes" is defined (per operation or using global definition) // if "consumes" is defined (per operation or using global definition)
if (consumes != null && !consumes.isEmpty()) { if (consumes != null && !consumes.isEmpty()) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>(); List<Map<String, String>> c = new ArrayList<Map<String, String>>();
for (String key : consumes) { for (String mimeType : consumes) {
Map<String, String> mediaType = new HashMap<String, String>(); Map<String, String> mediaType = new HashMap<String, String>();
String mimeType = processMimeType(key);
if (mimeType.startsWith("Application/Xml")) { if (isMimetypeXml(mimeType)) {
additionalProperties.put("usesXml", true); additionalProperties.put("usesXml", true);
consumesXml = true; consumesXml = true;
} else if (mimeType.startsWith("Text/Plain")) { } else if (isMimetypePlainText(mimeType)) {
consumesPlainText = true; consumesPlainText = true;
} }
@ -562,14 +569,13 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
boolean producesPlainText = false; boolean producesPlainText = false;
if (produces != null && !produces.isEmpty()) { if (produces != null && !produces.isEmpty()) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>(); List<Map<String, String>> c = new ArrayList<Map<String, String>>();
for (String key : produces) { for (String mimeType : produces) {
Map<String, String> mediaType = new HashMap<String, String>(); Map<String, String> mediaType = new HashMap<String, String>();
String mimeType = processMimeType(key);
if (mimeType.startsWith("Application/Xml")) { if (isMimetypeXml(mimeType)) {
additionalProperties.put("usesXml", true); additionalProperties.put("usesXml", true);
producesXml = true; producesXml = true;
} else if (mimeType.startsWith("Text/Plain")) { } else if (isMimetypePlainText(mimeType)) {
producesPlainText = true; producesPlainText = true;
} }
@ -1023,57 +1029,4 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
} }
return false; return false;
} }
private String processMimeType(String mimeType){
// Transform mime type into a form that the hyper mime! macro can handle.
String result = "";
String[] split_attributes = mimeType.split(";");
String media = split_attributes[0];
String[] mediaTypes = media.split("/");
if (mediaTypes.length == 2) {
if (mediaTypes[0].equals("*")){
result += "Star";
} else {
result += escapeText(escapeQuotationMark(initialCaps(mediaTypes[0])));
}
result += "/";
if (mediaTypes[1].equals("*")) {
result += "Star";
} else {
result += escapeText(escapeQuotationMark(initialCaps(mediaTypes[1])));
}
} else {
LOGGER.error("Failed to parse media type: "
+ mimeType
+ ", media types should have exactly one /");
}
if (split_attributes.length == 2) {
String attributes = "";
String[] attrs = split_attributes[1].split(",");
for (String attr : attrs) {
String[] keyValuePair =attr.split("=");
if (keyValuePair.length == 2) {
attributes += "(\""
+ escapeText(escapeQuotationMark(keyValuePair[0].trim()))
+ "\")=(\""
+ escapeText(escapeQuotationMark(keyValuePair[1].trim()))
+ "\")";
} else {
LOGGER.error("Failed to parse parameter attributes: "
+ split_attributes[1]
+ ", attributes must be a comma separated list of 'key=value' pairs");
}
}
result += "; " + attributes;
}
return result;
}
} }

View File

@ -49,6 +49,7 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC
additionalProperties.put("authScheme", authScheme); additionalProperties.put("authScheme", authScheme);
additionalProperties.put("authPreemptive", authPreemptive); additionalProperties.put("authPreemptive", authPreemptive);
additionalProperties.put("clientName", clientName); additionalProperties.put("clientName", clientName);
additionalProperties.put(CodegenConstants.STRIP_PACKAGE_NAME, stripPackageName);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("apiInvoker.mustache", supportingFiles.add(new SupportingFile("apiInvoker.mustache",
@ -230,10 +231,4 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC
return formatIdentifier(stripPackageName(property.baseName), true); return formatIdentifier(stripPackageName(property.baseName), true);
} }
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
} }

View File

@ -0,0 +1,345 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.*;
import io.swagger.models.parameters.*;
import io.swagger.models.properties.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.*;
import java.io.File;
public class ScalaGatlingCodegen extends AbstractScalaCodegen implements CodegenConfig {
// source folder where to write the files
protected String sourceFolder = "src" + File.separator + "gatling" + File.separator + "scala";
protected String resourceFolder = "src" + File.separator + "gatling" + File.separator + "resources";
protected String confFolder = resourceFolder + File.separator + "conf";
protected String dataFolder = resourceFolder + File.separator + "data";
protected String apiVersion = "1.0.0";
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.swagger.codegen.CodegenType
*/
public CodegenType getTag() {
return CodegenType.CLIENT;
}
/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -l flag.
*
* @return the friendly name for the generator
*/
public String getName() {
return "scala-gatling";
}
/**
* 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 gatling simulation library (beta).";
}
public ScalaGatlingCodegen() {
super();
// set the output folder here
outputFolder = "generated-code/gatling";
/**
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
* as with models, add multiple entries with different extensions for multiple files per
* class
*/
apiTemplateFiles.put(
"api.mustache", // the template to use
"Simulation.scala"); // the extension for each file to write
modelTemplateFiles.put("model.mustache", ".scala");
/**
* 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 = "scala-gatling";
/**
* Api Package. Optional, if needed, this can be used in templates
*/
apiPackage = "io.swagger.client.api";
/**
* Model Package. Optional, if needed, this can be used in templates
*/
modelPackage = "io.swagger.client.model";
/**
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
additionalProperties.put("apiVersion", apiVersion);
/**
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
* it will be processed by the template engine. Otherwise, it will be copied
*/
supportingFiles.add(new SupportingFile("build.gradle",
"",
"build.gradle"));
supportingFiles.add(new SupportingFile("logback.xml",
confFolder,
"logback.xml"));
supportingFiles.add(new SupportingFile("default.conf.mustache",
confFolder,
"default.conf"));
supportingFiles.add(new SupportingFile("default.conf.mustache",
confFolder,
"CI.conf"));
supportingFiles.add(new SupportingFile("default.conf.mustache",
confFolder,
"CD.conf"));
supportingFiles.add(new SupportingFile("default.conf.mustache",
confFolder,
"stress.conf"));
supportingFiles.add(new SupportingFile("default.conf.mustache",
confFolder,
"baseline.conf"));
supportingFiles.add(new SupportingFile("default.conf.mustache",
confFolder,
"longevity.conf"));
importMapping.remove("List");
importMapping.remove("Set");
importMapping.remove("Map");
importMapping.put("Date", "java.util.Date");
importMapping.put("ListBuffer", "scala.collection.mutable.ListBuffer");
typeMapping = new HashMap<String, String>();
typeMapping.put("enum", "NSString");
typeMapping.put("array", "List");
typeMapping.put("set", "Set");
typeMapping.put("boolean", "Boolean");
typeMapping.put("string", "String");
typeMapping.put("int", "Int");
typeMapping.put("long", "Long");
typeMapping.put("float", "Float");
typeMapping.put("byte", "Byte");
typeMapping.put("short", "Short");
typeMapping.put("char", "Char");
typeMapping.put("double", "Double");
typeMapping.put("object", "Any");
typeMapping.put("file", "File");
typeMapping.put("binary", "String");
typeMapping.put("ByteArray", "String");
typeMapping.put("date-time", "Date");
typeMapping.put("DateTime", "Date");
instantiationTypes.put("array", "ListBuffer");
instantiationTypes.put("map", "HashMap");
setReservedWordsLowerCase(
Arrays.asList(
// local variable names used in API methods (endpoints)
"path", "contentTypes", "contentType", "queryParams", "headerParams",
"formParams", "postBody", "mp", "basePath", "apiInvoker",
// scala reserved words
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
"false", "final", "finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
);
}
/**
* Gatling does not need the models to have escaped words as it builds models dynamically instead of through
* an instance of the object.
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return name;
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
*/
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated
*/
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
/**
* Modifies the swagger doc to make mustache easier to use
*
* @param swagger
*/
@Override
public void preprocessSwagger(Swagger swagger) {
for (String pathname : swagger.getPaths().keySet()) {
Path path = swagger.getPath(pathname);
if (path.getOperations() == null) {
continue;
}
for (Operation operation : path.getOperations()) {
if (!operation.getVendorExtensions().keySet().contains("x-gatling-path")) {
if (pathname.contains("{")) {
String gatlingPath = pathname.replaceAll("\\{", "\\$\\{");
operation.setVendorExtension("x-gatling-path", gatlingPath);
} else {
operation.setVendorExtension("x-gatling-path", pathname);
}
}
Set<Parameter> headerParameters = new HashSet<>();
Set<Parameter> formParameters = new HashSet<>();
Set<Parameter> queryParameters = new HashSet<>();
Set<Parameter> pathParameters = new HashSet<>();
for (Parameter parameter : operation.getParameters()) {
if (parameter.getIn().equalsIgnoreCase("header")) {
headerParameters.add(parameter);
}
if (parameter.getIn().equalsIgnoreCase("formData")) {
formParameters.add(parameter);
}
if (parameter.getIn().equalsIgnoreCase("query")) {
queryParameters.add(parameter);
}
if (parameter.getIn().equalsIgnoreCase("path")) {
pathParameters.add(parameter);
}
if (parameter.getIn().equalsIgnoreCase("body")) {
BodyParameter bodyParameter = (BodyParameter) parameter;
Model model = bodyParameter.getSchema();
if (model instanceof RefModel) {
String[] refArray = model.getReference().split("\\/");
operation.setVendorExtension("x-gatling-body-object", refArray[refArray.length - 1] + ".toStringBody");
Set<String> bodyFeederParams = new HashSet<>();
Set<String> sessionBodyVars = new HashSet<>();
for (Map.Entry<String, Model> modelEntry : swagger.getDefinitions().entrySet()) {
if (refArray[refArray.length - 1].equalsIgnoreCase(modelEntry.getKey())) {
for (Map.Entry<String, Property> propertyEntry : modelEntry.getValue().getProperties().entrySet()) {
bodyFeederParams.add(propertyEntry.getKey());
sessionBodyVars.add("\"${" + propertyEntry.getKey() + "}\"");
}
}
}
operation.setVendorExtension("x-gatling-body-feeder", operation.getOperationId() + "BodyFeeder");
operation.setVendorExtension("x-gatling-body-feeder-params", StringUtils.join(sessionBodyVars, ","));
try {
FileUtils.writeStringToFile(new File(outputFolder + File.separator + dataFolder + File.separator + operation.getOperationId() + "-" + "BodyParams.csv"), StringUtils.join(bodyFeederParams, ","));
} catch (IOException ioe) {
LOGGER.error("Could not create feeder file for operationId" + operation.getOperationId(), ioe);
}
} else if (model instanceof ArrayModel) {
operation.setVendorExtension("x-gatling-body-object", "StringBody(\"[]\")");
} else {
operation.setVendorExtension("x-gatling-body-object", "StringBody(\"{}\")");
}
}
}
prepareGatlingData(operation, headerParameters, "header");
prepareGatlingData(operation, formParameters, "form");
prepareGatlingData(operation, queryParameters, "query");
prepareGatlingData(operation, pathParameters, "path");
}
}
}
/**
* Creates all the necessary swagger vendor extensions and feeder files for gatling
*
* @param operation Swagger Operation
* @param parameters Swagger Parameters
* @param parameterType Swagger Parameter Type
*/
private void prepareGatlingData(Operation operation, Set<Parameter> parameters, String parameterType) {
if (parameters.size() > 0) {
List<String> parameterNames = new ArrayList<>();
List<Object> vendorList = new ArrayList<>();
for (Parameter parameter : parameters) {
Map<String, Object> extensionMap = new HashMap<>();
extensionMap.put("gatlingParamName", parameter.getName());
extensionMap.put("gatlingParamValue", "${" + parameter.getName() + "}");
vendorList.add(extensionMap);
parameterNames.add(parameter.getName());
}
operation.setVendorExtension("x-gatling-" + parameterType.toLowerCase() + "-params", vendorList);
operation.setVendorExtension("x-gatling-" + parameterType.toLowerCase() + "-feeder", operation.getOperationId() + parameterType.toUpperCase() + "Feeder");
try {
FileUtils.writeStringToFile(new File(outputFolder + File.separator + dataFolder + File.separator + operation.getOperationId() + "-" + parameterType.toLowerCase() + "Params.csv"), StringUtils.join(parameterNames, ","));
} catch (IOException ioe) {
LOGGER.error("Could not create feeder file for operationId" + operation.getOperationId(), ioe);
}
}
}
/**
* Optional - type declaration. This is a String which is used by the templates to instantiate your
* types. There is typically special handling for different property types
*
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
*/
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
/**
* Optional - swagger type conversion. This is used to map swagger types in a `Property` into
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
*
* @return a string value of the type or complex model for this property
* @see io.swagger.models.properties.Property
*/
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return toModelName(type);
} else
type = swaggerType;
return toModelName(type);
}
}

View File

@ -218,12 +218,6 @@ public class ScalaLagomServerCodegen extends AbstractScalaCodegen implements Cod
return camelizedName; return camelizedName;
} }
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override @Override
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) { public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
objs = super.postProcessModelsEnum(objs); objs = super.postProcessModelsEnum(objs);

View File

@ -16,7 +16,7 @@ import java.util.Map;
public class ScalatraServerCodegen extends AbstractScalaCodegen implements CodegenConfig { public class ScalatraServerCodegen extends AbstractScalaCodegen implements CodegenConfig {
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";
protected String artifactId = "swagger-client"; protected String artifactId = "swagger-server";
protected String artifactVersion = "1.0.0"; protected String artifactVersion = "1.0.0";
public ScalatraServerCodegen() { public ScalatraServerCodegen() {
@ -25,8 +25,8 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
modelTemplateFiles.put("model.mustache", ".scala"); modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala"); apiTemplateFiles.put("api.mustache", ".scala");
embeddedTemplateDir = templateDir = "scalatra"; embeddedTemplateDir = templateDir = "scalatra";
apiPackage = "com.wordnik.client.api"; apiPackage = "io.swagger.server.api";
modelPackage = "com.wordnik.client.model"; modelPackage = "io.swagger.server.model";
setReservedWordsLowerCase( setReservedWordsLowerCase(
Arrays.asList( Arrays.asList(
@ -79,6 +79,8 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.sbt", "", "build.sbt")); supportingFiles.add(new SupportingFile("build.sbt", "", "build.sbt"));
supportingFiles.add(new SupportingFile("web.xml", "/src/main/webapp/WEB-INF", "web.xml")); supportingFiles.add(new SupportingFile("web.xml", "/src/main/webapp/WEB-INF", "web.xml"));
supportingFiles.add(new SupportingFile("logback.xml", "/src/main/resources", "logback.xml"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("JettyMain.mustache", sourceFolder, "JettyMain.scala")); supportingFiles.add(new SupportingFile("JettyMain.mustache", sourceFolder, "JettyMain.scala"));
supportingFiles.add(new SupportingFile("Bootstrap.mustache", sourceFolder, "ScalatraBootstrap.scala")); supportingFiles.add(new SupportingFile("Bootstrap.mustache", sourceFolder, "ScalatraBootstrap.scala"));
supportingFiles.add(new SupportingFile("ServletApp.mustache", sourceFolder, "ServletApp.scala")); supportingFiles.add(new SupportingFile("ServletApp.mustache", sourceFolder, "ServletApp.scala"));
@ -151,11 +153,4 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
return objs; return objs;
} }
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
} }

View File

@ -235,12 +235,6 @@ public class ScalazClientCodegen extends AbstractScalaCodegen implements Codegen
public abstract String formatFragment(String fragment); public abstract String formatFragment(String fragment);
} }
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
private class EnumEntryLambda extends CustomLambda { private class EnumEntryLambda extends CustomLambda {
@Override @Override
public String formatFragment(String fragment) { public String formatFragment(String fragment) {

View File

@ -139,19 +139,52 @@ public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
// name used by swift client // name used by swift client
"ErrorResponse", "Response", "ErrorResponse", "Response",
// swift keywords // Added for Objective-C compatibility
"Int", "Int32", "Int64", "Int64", "Float", "Double", "Bool", "Void", "String", "id", "description", "NSArray", "NSURL", "CGFloat", "NSSet", "NSString", "NSInteger", "NSUInteger",
"Character", "AnyObject", "Any", "Error", "URL", "class", "Class", "break", "NSError", "NSDictionary",
"as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum",
"continue", "false", "dynamic", "extension", "default", "is", "didSet", //
"func", "do", "nil", "final", "import", "else", "self", "get", "init", // Swift keywords. This list is taken from here:
"fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", // https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-ID410
"if", "true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", //
"FILE", "mutating", "protocol", "switch", "FUNCTION", "none", "public", // Keywords used in declarations
"where", "LINE", "nonmutating", "static", "while", "optional", "struct", "associatedtype", "class", "deinit", "enum", "extension", "fileprivate", "func", "import", "init",
"override", "subscript", "postfix", "typealias", "precedence", "var", "inout", "internal", "let", "open", "operator", "private", "protocol", "public", "static", "struct",
"prefix", "Protocol", "required", "right", "set", "throw", "Type", "unowned", "weak", "subscript", "typealias", "var",
"Data", "Codable", "Encodable", "Decodable") // Keywords uses in statements
"break", "case", "continue", "default", "defer", "do", "else", "fallthrough", "for", "guard", "if",
"in", "repeat", "return", "switch", "where", "while",
// Keywords used in expressions and types
"as", "Any", "catch", "false", "is", "nil", "rethrows", "super", "self", "Self", "throw", "throws", "true", "try",
// Keywords used in patterns
"_",
// Keywords that begin with a number sign
"#available", "#colorLiteral", "#column", "#else", "#elseif", "#endif", "#file", "#fileLiteral", "#function", "#if",
"#imageLiteral", "#line", "#selector", "#sourceLocation",
// Keywords reserved in particular contexts
"associativity", "convenience", "dynamic", "didSet", "final", "get", "infix", "indirect", "lazy", "left",
"mutating", "none", "nonmutating", "optional", "override", "postfix", "precedence", "prefix", "Protocol",
"required", "right", "set", "Type", "unowned", "weak", "willSet",
//
// Swift Standard Library types
// https://developer.apple.com/documentation/swift
//
// Numbers and Basic Values
"Bool", "Int", "Double", "Float", "Range", "ClosedRange", "Error", "Optional",
// Special-Use Numeric Types
"UInt", "UInt8", "UInt16", "UInt32", "UInt64", "Int8", "Int16", "Int32", "Int64", "Float80", "Float32", "Float64",
// Strings and Text
"String", "Character", "Unicode", "StaticString",
// Collections
"Array", "Dictionary", "Set", "OptionSet", "CountableRange", "CountableClosedRange",
// The following are commonly-used Foundation types
"URL", "Data", "Codable", "Encodable", "Decodable",
// The following are other words we want to reserve
"Void", "AnyObject", "Class", "dynamicType", "COLUMN", "FILE", "FUNCTION", "LINE"
)
); );
typeMapping = new HashMap<>(); typeMapping = new HashMap<>();

View File

@ -93,6 +93,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
supportingFiles.add(new SupportingFile("encoder.mustache", getIndexDirectory(), "encoder.ts")); supportingFiles.add(new SupportingFile("encoder.mustache", getIndexDirectory(), "encoder.ts"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("README.mustache", getIndexDirectory(), "README.md"));
if (additionalProperties.containsKey(NPM_NAME)) { if (additionalProperties.containsKey(NPM_NAME)) {
addNpmPackageGeneration(); addNpmPackageGeneration();
@ -143,7 +144,6 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
} }
//Files for building our lib //Files for building our lib
supportingFiles.add(new SupportingFile("README.mustache", getIndexDirectory(), "README.md"));
supportingFiles.add(new SupportingFile("package.mustache", getIndexDirectory(), "package.json")); supportingFiles.add(new SupportingFile("package.mustache", getIndexDirectory(), "package.json"));
supportingFiles.add(new SupportingFile("typings.mustache", getIndexDirectory(), "typings.json")); supportingFiles.add(new SupportingFile("typings.mustache", getIndexDirectory(), "typings.json"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json")); supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json"));

View File

@ -1,24 +1,41 @@
# {{artifactId}} # {{artifactId}}
{{appName}}
- API version: {{appVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
{{#appDescription}}{{{appDescription}}}{{/appDescription}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}
*Automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen)*
## Requirements ## Requirements
Building the API client library requires [Maven](https://maven.apache.org/) to be installed. Building the API client library requires:
1. Java 1.7+
2. Maven/Gradle
## Installation ## Installation
To install the API client library to your local Maven repository, simply execute: To install the API client library to your local Maven repository, simply execute:
```shell ```shell
mvn install mvn clean install
``` ```
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
```shell ```shell
mvn deploy mvn clean deploy
``` ```
Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
### Maven users ### Maven users
@ -45,12 +62,14 @@ compile "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}"
At first generate the JAR by executing: At first generate the JAR by executing:
mvn package ```shell
mvn clean package
```
Then manually install the following JARs: Then manually install the following JARs:
* target/{{{artifactId}}}-{{{artifactVersion}}}.jar * `target/{{{artifactId}}}-{{{artifactVersion}}}.jar`
* target/lib/*.jar * `target/lib/*.jar`
## Getting Started ## Getting Started

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}} @Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -104,6 +104,7 @@
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId> <artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions> <executions>
<execution> <execution>
<id>add_sources</id> <id>add_sources</id>

View File

@ -104,6 +104,7 @@
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId> <artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions> <executions>
<execution> <execution>
<id>add_sources</id> <id>add_sources</id>

View File

@ -106,8 +106,9 @@ if(hasProperty('target') && target == 'android') {
ext { ext {
swagger_annotations_version = "1.5.8" swagger_annotations_version = "1.5.8"
jackson_version = "2.7.5" jackson_version = "2.6.4"
jersey_version = "2.22.2" jersey_version = "2.22.2"
resteasy_version = "3.1.3.Final"
{{^java8}} {{^java8}}
jodatime_version = "2.9.4" jodatime_version = "2.9.4"
{{/java8}} {{/java8}}
@ -120,12 +121,16 @@ ext {
dependencies { dependencies {
compile "io.swagger:swagger-annotations:$swagger_annotations_version" compile "io.swagger:swagger-annotations:$swagger_annotations_version"
compile "org.jboss.resteasy:resteasy-client:$resteasy_version"
compile "org.jboss.resteasy:resteasy-multipart-provider:$resteasy_version"
compile "org.jboss.resteasy:resteasy-jackson2-provider:$resteasy_version"
compile "org.glassfish.jersey.core:jersey-client:$jersey_version" compile "org.glassfish.jersey.core:jersey-client:$jersey_version"
compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version"
compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version"
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_version"
{{#java8}} {{#java8}}
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
{{/java8}} {{/java8}}

View File

@ -85,6 +85,7 @@
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId> <artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions> <executions>
<execution> <execution>
<id>add_sources</id> <id>add_sources</id>

View File

@ -104,6 +104,7 @@
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId> <artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions> <executions>
<execution> <execution>
<id>add_sources</id> <id>add_sources</id>

View File

@ -36,11 +36,17 @@ public interface {{classname}} {
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}} {{/allParams}}
* @return Call&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object{{/returnType}}&gt; * @return Call&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object{{/returnType}}&gt;
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}} {{#externalDocs}}
* {{description}} * {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a> * @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}} {{/externalDocs}}
*/ */
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
{{#formParams}} {{#formParams}}
{{#-first}} {{#-first}}
{{#isMultipart}}@retrofit2.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit2.http.FormUrlEncoded{{/isMultipart}} {{#isMultipart}}@retrofit2.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit2.http.FormUrlEncoded{{/isMultipart}}

View File

@ -142,7 +142,9 @@ dependencies {
compile "io.reactivex.rxjava2:rxjava:$rx_java_version" compile "io.reactivex.rxjava2:rxjava:$rx_java_version"
{{/useRxJava2}} {{/useRxJava2}}
compile "io.swagger:swagger-annotations:$swagger_annotations_version" compile "io.swagger:swagger-annotations:$swagger_annotations_version"
compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" compile ("org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"){
exclude group:'org.apache.oltu.oauth2' , module: 'org.apache.oltu.oauth2.common'
}
compile "io.gsonfire:gson-fire:$json_fire_version" compile "io.gsonfire:gson-fire:$json_fire_version"
{{#joda}} {{#joda}}
compile "joda-time:joda-time:$jodatime_version" compile "joda-time:joda-time:$jodatime_version"

View File

@ -212,6 +212,12 @@
<groupId>org.apache.oltu.oauth2</groupId> <groupId>org.apache.oltu.oauth2</groupId>
<artifactId>org.apache.oltu.oauth2.client</artifactId> <artifactId>org.apache.oltu.oauth2.client</artifactId>
<version>${oltu-version}</version> <version>${oltu-version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.oltu.oauth2</groupId>
<artifactId>common</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.gsonfire</groupId> <groupId>io.gsonfire</groupId>

View File

@ -4,6 +4,7 @@ package {{package}};
{{^supportJava6}} {{^supportJava6}}
import java.util.Objects; import java.util.Objects;
import java.util.Arrays;
{{/supportJava6}} {{/supportJava6}}
{{#supportJava6}} {{#supportJava6}}
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;

View File

@ -67,6 +67,13 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
{{/isContainer}} {{/isContainer}}
{{/vars}} {{/vars}}
{{#gson}}
{{#discriminator}}
public {{classname}}() {
this.{{discriminator}} = this.getClass().getSimpleName();
}
{{/discriminator}}
{{/gson}}
{{#vars}} {{#vars}}
{{^isReadOnly}} {{^isReadOnly}}
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
@ -140,7 +147,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
return false; return false;
}{{#hasVars}} }{{#hasVars}}
{{classname}} {{classVarName}} = ({{classname}}) o; {{classname}} {{classVarName}} = ({{classname}}) o;
return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} && return {{#vars}}{{#isByteArray}}Arrays{{/isByteArray}}{{#isBinary}}Arrays{{/isBinary}}{{^isByteArray}}{{^isBinary}}Objects{{/isBinary}}{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
{{/hasMore}}{{/vars}}{{#parent}} && {{/hasMore}}{{/vars}}{{#parent}} &&
super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}} return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}}
@ -148,7 +155,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}); return Objects.hash({{#vars}}{{^isByteArray}}{{^isBinary}}{{name}}{{/isBinary}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{#isBinary}}Arrays.hashCode({{name}}){{/isBinary}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
} }
{{/supportJava6}} {{/supportJava6}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}} @Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}} @Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}} @Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -181,7 +181,7 @@
<java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version> <java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.target>${java.version}</maven.compiler.target>
<swagger-core-version>1.5.15</swagger-core-version> <swagger-core-version>1.5.17</swagger-core-version>
<jetty-version>9.2.9.v20150224</jetty-version> <jetty-version>9.2.9.v20150224</jetty-version>
<junit-version>4.12</junit-version> <junit-version>4.12</junit-version>
<logback-version>1.1.7</logback-version> <logback-version>1.1.7</logback-version>
@ -189,8 +189,8 @@
{{#useBeanValidation}} {{#useBeanValidation}}
<beanvalidation-version>1.1.0.Final</beanvalidation-version> <beanvalidation-version>1.1.0.Final</beanvalidation-version>
{{/useBeanValidation}} {{/useBeanValidation}}
<cxf-version>3.1.11</cxf-version> <cxf-version>3.2.1</cxf-version>
<jackson-jaxrs-version>2.8.9</jackson-jaxrs-version> <jackson-jaxrs-version>2.9.1</jackson-jaxrs-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
</project> </project>

View File

@ -215,7 +215,7 @@
<dependency> <dependency>
<groupId>org.webjars</groupId> <groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId> <artifactId>swagger-ui</artifactId>
<version>3.0.17</version> <version>3.6.1</version>
</dependency> </dependency>
{{/useSwaggerUI}} {{/useSwaggerUI}}
</dependencies> </dependencies>
@ -232,7 +232,7 @@
<java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version> <java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.target>${java.version}</maven.compiler.target>
<swagger-core-version>1.5.15</swagger-core-version> <swagger-core-version>1.5.17</swagger-core-version>
<jetty-version>9.2.9.v20150224</jetty-version> <jetty-version>9.2.9.v20150224</jetty-version>
<junit-version>4.12</junit-version> <junit-version>4.12</junit-version>
<logback-version>1.1.7</logback-version> <logback-version>1.1.7</logback-version>
@ -241,13 +241,13 @@
<beanvalidation-version>1.1.0.Final</beanvalidation-version> <beanvalidation-version>1.1.0.Final</beanvalidation-version>
{{/useBeanValidation}} {{/useBeanValidation}}
{{#generateSpringApplication}} {{#generateSpringApplication}}
<spring-version>4.3.9.RELEASE</spring-version> <spring-version>4.3.13.RELEASE</spring-version>
{{/generateSpringApplication}} {{/generateSpringApplication}}
{{#generateSpringBootApplication}} {{#generateSpringBootApplication}}
<spring.boot-version>1.5.4.RELEASE</spring.boot-version> <spring.boot-version>1.5.9.RELEASE</spring.boot-version>
{{/generateSpringBootApplication}} {{/generateSpringBootApplication}}
<cxf-version>3.1.11</cxf-version> <cxf-version>3.2.1</cxf-version>
<jackson-jaxrs-version>2.8.9</jackson-jaxrs-version> <jackson-jaxrs-version>2.9.1</jackson-jaxrs-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
</project> </project>

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}} @Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}} @Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -16,10 +16,12 @@ public enum {{datatypeWithEnum}} {
} }
@Override @Override
@JsonValue
public String toString() { public String toString() {
return String.valueOf(value); return String.valueOf(value);
} }
@JsonCreator
public static {{datatypeWithEnum}} fromValue(String v) { public static {{datatypeWithEnum}} fromValue(String v) {
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(v)) { if (String.valueOf(b.value).equals(v)) {

View File

@ -1,4 +1,4 @@
package controllers; package {{apiPackage}};
import javax.inject.*; import javax.inject.*;
import play.mvc.*; import play.mvc.*;

View File

@ -1,6 +1,6 @@
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import controllers.*; import {{apiPackage}}.*;
public class Module extends AbstractModule { public class Module extends AbstractModule {

View File

@ -3,7 +3,7 @@
# ~~~~ # ~~~~
{{#useSwaggerUI}} {{#useSwaggerUI}}
GET /api controllers.ApiDocController.api GET /api {{apiPackage}}.ApiDocController.api
{{/useSwaggerUI}} {{/useSwaggerUI}}
{{#apiInfo}} {{#apiInfo}}
@ -12,7 +12,7 @@ GET /api controllers.ApiDocController.api
#Functions for {{{baseName}}} API #Functions for {{{baseName}}} API
{{#operations}} {{#operations}}
{{#operation}} {{#operation}}
{{httpMethod}} {{{contextPath}}}{{{path}}} controllers.{{classname}}Controller.{{operationId}}({{#pathParams}}{{paramName}}: {{#isUuid}}java.util.UUID{{/isUuid}}{{^isUuid}}{{{dataType}}}{{/isUuid}}{{#hasMore}}, {{/hasMore}}{{/pathParams}}) {{httpMethod}} {{{contextPath}}}{{{path}}} {{apiPackage}}.{{classname}}Controller.{{operationId}}({{#pathParams}}{{paramName}}: {{#isUuid}}java.util.UUID{{/isUuid}}{{^isUuid}}{{{dataType}}}{{/isUuid}}{{#hasMore}}, {{/hasMore}}{{/pathParams}})
{{/operation}} {{/operation}}
{{/operations}} {{/operations}}
{{/apis}} {{/apis}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}}@Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L) {{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}") {{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}") {{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -37,23 +37,61 @@ public class {{classname}}Verticle extends AbstractVerticle {
//Consumer for {{#vendorExtensions}}{{x-serviceid}}{{/vendorExtensions}} //Consumer for {{#vendorExtensions}}{{x-serviceid}}{{/vendorExtensions}}
vertx.eventBus().<JsonObject> consumer({{#vendorExtensions}}{{x-serviceid-varname}}{{/vendorExtensions}}).handler(message -> { vertx.eventBus().<JsonObject> consumer({{#vendorExtensions}}{{x-serviceid-varname}}{{/vendorExtensions}}).handler(message -> {
try { try {
// Workaround for #allParams section clearing the vendorExtensions map
String serviceId = "{{#vendorExtensions}}{{x-serviceid}}{{/vendorExtensions}}";
{{#hasParams}} {{#hasParams}}
{{#allParams}} {{#allParams}}
{{#isListContainer}} {{#isListContainer}}
{{{dataType}}} {{paramName}} = Json.mapper.readValue(message.body().getJsonArray("{{baseName}}").encode(), JsonArray {{paramName}}Param = message.body().getJsonArray("{{baseName}}");
{{#required}}
if({{paramName}}Param == null) {
manageError(message, new MainApiException(400, "{{baseName}} is required"), serviceId);
return;
}
{{{dataType}}} {{paramName}} = Json.mapper.readValue({{paramName}}Param.encode(),
Json.mapper.getTypeFactory().constructCollectionType(List.class, {{{baseType}}}.class)); Json.mapper.getTypeFactory().constructCollectionType(List.class, {{{baseType}}}.class));
{{/required}}
{{^required}}
{{{dataType}}} {{paramName}} = ({{paramName}}Param == null) ? {{#defaultValue}}{{defaultValue}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}} : Json.mapper.readValue({{paramName}}Param.encode(),
Json.mapper.getTypeFactory().constructCollectionType(List.class, {{{baseType}}}.class));
{{/required}}
{{/isListContainer}} {{/isListContainer}}
{{^isListContainer}} {{^isListContainer}}
{{#isPrimitiveType}} {{#isPrimitiveType}}
{{#isString}} {{#isString}}
{{{dataType}}} {{paramName}} = message.body().getString("{{baseName}}"); String {{paramName}}Param = message.body().getString("{{baseName}}");
{{#required}}
if({{paramName}}Param == null) {
manageError(message, new MainApiException(400, "{{baseName}} is required"), serviceId);
return;
}
{{{dataType}}} {{paramName}} = {{paramName}}Param;
{{/required}}
{{^required}}
{{{dataType}}} {{paramName}} = ({{paramName}}Param == null) ? {{#defaultValue}}{{defaultValue}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}} : {{paramName}}Param;
{{/required}}
{{/isString}} {{/isString}}
{{^isString}} {{^isString}}
{{{dataType}}} {{paramName}} = Json.mapper.readValue(message.body().getString("{{baseName}}"), {{{dataType}}}.class); String {{paramName}}Param = message.body().getString("{{baseName}}");
{{#required}}
if({{paramName}}Param == null) {
manageError(message, new MainApiException(400, "{{baseName}} is required"), serviceId);
return;
}
{{{dataType}}} {{paramName}} = Json.mapper.readValue({{paramName}}Param, {{{dataType}}}.class);
{{/required}}
{{^required}}
{{{dataType}}} {{paramName}} = ({{paramName}}Param == null) ? {{#defaultValue}}{{defaultValue}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}} : Json.mapper.readValue({{paramName}}Param, {{{dataType}}}.class);
{{/required}}
{{/isString}} {{/isString}}
{{/isPrimitiveType}} {{/isPrimitiveType}}
{{^isPrimitiveType}} {{^isPrimitiveType}}
{{{dataType}}} {{paramName}} = Json.mapper.readValue(message.body().getJsonObject("{{baseName}}").encode(), {{{dataType}}}.class); JsonObject {{paramName}}Param = message.body().getJsonObject("{{baseName}}");
if ({{paramName}}Param == null) {
manageError(message, new MainApiException(400, "{{baseName}} is required"), serviceId);
return;
}
{{{dataType}}} {{paramName}} = Json.mapper.readValue({{paramName}}Param.encode(), {{{dataType}}}.class);
{{/isPrimitiveType}} {{/isPrimitiveType}}
{{/isListContainer}} {{/isListContainer}}
{{/allParams}} {{/allParams}}

View File

@ -44,7 +44,7 @@
describe('{{classname}}', function() { describe('{{classname}}', function() {
it('should create an instance of {{classname}}', function() { it('should create an instance of {{classname}}', function() {
// uncomment below and update the code to test {{classname}} // uncomment below and update the code to test {{classname}}
//var instane = new {{moduleName}}.{{classname}}(); //var instance = new {{moduleName}}.{{classname}}();
//expect(instance).to.be.a({{moduleName}}.{{classname}}); //expect(instance).to.be.a({{moduleName}}.{{classname}});
}); });
@ -53,7 +53,7 @@
{{#vars}} {{#vars}}
it('should have the property {{name}} (base name: "{{baseName}}")', function() { it('should have the property {{name}} (base name: "{{baseName}}")', function() {
// uncomment below and update the code to test the property {{name}} // uncomment below and update the code to test the property {{name}}
//var instane = new {{moduleName}}.{{classname}}(); //var instance = new {{moduleName}}.{{classname}}();
//expect(instance).to.be(); //expect(instance).to.be();
}); });

View File

@ -61,6 +61,7 @@ io.swagger.codegen.languages.RubyClientCodegen
io.swagger.codegen.languages.RustClientCodegen io.swagger.codegen.languages.RustClientCodegen
io.swagger.codegen.languages.RustServerCodegen io.swagger.codegen.languages.RustServerCodegen
io.swagger.codegen.languages.ScalaClientCodegen io.swagger.codegen.languages.ScalaClientCodegen
io.swagger.codegen.languages.ScalaGatlingCodegen
io.swagger.codegen.languages.ScalaLagomServerCodegen io.swagger.codegen.languages.ScalaLagomServerCodegen
io.swagger.codegen.languages.ScalatraServerCodegen io.swagger.codegen.languages.ScalatraServerCodegen
io.swagger.codegen.languages.ScalazClientCodegen io.swagger.codegen.languages.ScalazClientCodegen

View File

@ -1,42 +1,40 @@
# NAME # {{artifactId}}
{{appName}} {{appName}}
{{#appDescription}}{{{appDescription}}}{{/appDescription}}
# VERSION
Automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project:
- API version: {{appVersion}} - API version: {{appVersion}}
- Package version: {{moduleVersion}}
{{^hideGenerationTimestamp}} {{^hideGenerationTimestamp}}
- Build date: {{generatedDate}} - Build date: {{generatedDate}}
{{/hideGenerationTimestamp}} {{/hideGenerationTimestamp}}
- Build package: {{generatorClass}}
{{#appDescription}}{{{appDescription}}}{{/appDescription}}
{{#infoUrl}} {{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}} {{/infoUrl}}
# Requirements *Automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen)*
Building the API client library requires [Maven](https://maven.apache.org/) to be installed. ## Requirements
Building the API client library requires:
1. Java 1.7+
2. Maven/Gradle/SBT
## Installation ## Installation
To install the API client library to your local Maven repository, simply execute: To install the API client library to your local Maven repository, simply execute:
```shell ```shell
mvn install mvn clean install
``` ```
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
```shell ```shell
mvn deploy mvn clean deploy
``` ```
Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
### Maven users ### Maven users
@ -65,13 +63,15 @@ compile "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}"
libraryDependencies += "{{{groupId}}}" % "{{{artifactId}}}" % "{{{artifactVersion}}}" libraryDependencies += "{{{groupId}}}" % "{{{artifactId}}}" % "{{{artifactVersion}}}"
``` ```
## Getting Started
## Documentation for API Endpoints ## Documentation for API Endpoints
All URIs are relative to *{{basePath}}* All URIs are relative to *{{basePath}}*
Class | Method | HTTP request | Description Class | Method | HTTP request | Description
------------ | ------------- | ------------- | ------------- ------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | **{{operationId}}** | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
## Documentation for Models ## Documentation for Models
@ -101,28 +101,6 @@ Class | Method | HTTP request | Description
{{/authMethods}} {{/authMethods}}
# BUILDING YOUR LIBRARY
See the homepage `https://github.com/swagger-api/swagger-codegen` for full details.
But briefly, clone the git repository, build the codegen codebase, set up your build
config file, then run the API build script. You will need git, Java 7 or 8 and Apache
maven 3.0.3 or better already installed.
Your library files will be built under `WWW::MyProjectName`.
$ git clone https://github.com/swagger-api/swagger-codegen.git
$ cd swagger-codegen
$ mvn package
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-i [URL or file path to JSON swagger API spec] \
-l akka-scala \
-c /path/to/config/file.json \
-o /path/to/output/folder
Bang, all done. Run the `autodoc` script in the `bin` directory to see the API
you just built.
## Author ## Author
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} {{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}

View File

@ -1,8 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{package}} package {{package}}
{{#imports}} {{#imports}}

View File

@ -1,9 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{invokerPackage}} package {{invokerPackage}}
import java.io.File import java.io.File

View File

@ -1,8 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{invokerPackage}} package {{invokerPackage}}
sealed trait ResponseState sealed trait ResponseState

View File

@ -1,8 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{invokerPackage}} package {{invokerPackage}}
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit

View File

@ -4,13 +4,12 @@ organization := "{{groupId}}"
scalaVersion := "2.11.12" scalaVersion := "2.11.12"
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"io.swagger" % "swagger-core" % "1.5.15",
"com.typesafe" % "config" % "1.3.2", "com.typesafe" % "config" % "1.3.2",
"com.typesafe.akka" %% "akka-actor" % "2.5.8", "com.typesafe.akka" %% "akka-actor" % "2.5.8",
"io.spray" % "spray-client" % "1.3.1", "io.spray" % "spray-client" % "1.3.1",
"joda-time" % "joda-time" % "2.9.9", "joda-time" % "joda-time" % "2.9.9",
"org.joda" % "joda-convert" % "1.9.2",
"org.json4s" %% "json4s-jackson" % "3.5.3", "org.json4s" %% "json4s-jackson" % "3.5.3",
// test dependencies
"org.scalatest" %% "scalatest" % "3.0.4" % "test", "org.scalatest" %% "scalatest" % "3.0.4" % "test",
"junit" % "junit" % "4.12" % "test" "junit" % "junit" % "4.12" % "test"
) )

View File

@ -1,8 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{apiPackage}} package {{apiPackage}}
import {{modelPackage}}._ import {{modelPackage}}._

View File

@ -0,0 +1,11 @@
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/

View File

@ -1,9 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{package}} package {{package}}
import {{invokerPackage}}.ApiModel import {{invokerPackage}}.ApiModel

View File

@ -13,90 +13,86 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jdk.version>1.8</jdk.version>
<scala-version>2.11.12</scala-version>
<json4s-jackson-version>3.5.3</json4s-jackson-version>
<json4s-ext-version>3.2.11</json4s-ext-version>
<spray-version>1.3.1</spray-version>
<akka-version>2.5.8</akka-version>
<joda-convert-version>1.9.2</joda-convert-version>
<joda-time-version>2.9.9</joda-time-version>
<swagger-core-version>1.5.15</swagger-core-version>
<maven-plugin.version>1.0.0</maven-plugin.version>
<junit-version>4.12</junit-version> <java.version>1.8</java.version>
<scala-test-version>3.0.4</scala-test-version> <scala.version>2.11.12</scala.version>
<json4s.jackson.version>3.5.3</json4s.jackson.version>
<json4s.ext.version>3.2.11</json4s.ext.version>
<spray.version>1.3.1</spray.version>
<akka.version>2.5.8</akka.version>
<joda.time.version>2.9.9</joda.time.version>
<scala-maven-plugin-version>3.3.1</scala-maven-plugin-version> <junit.version>4.12</junit.version>
<scala.test.version>3.0.4</scala.test.version>
<scala.maven.plugin.version>3.3.1</scala.maven.plugin.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.scala-lang</groupId> <groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId> <artifactId>scala-library</artifactId>
<version>${scala-version}</version> <version>${scala.version}</version>
</dependency> <scope>provided</scope>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>${swagger-core-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
<version>${joda-time-version}</version> <version>${joda.time.version}</version>
</dependency>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-convert</artifactId>
<version>${joda-convert-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.typesafe</groupId> <groupId>com.typesafe</groupId>
<artifactId>config</artifactId> <artifactId>config</artifactId>
<version>1.2.1</version> <version>1.3.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.typesafe.akka</groupId> <groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId> <artifactId>akka-actor_2.11</artifactId>
<version>${akka-version}</version> <version>${akka.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.spray</groupId> <groupId>io.spray</groupId>
<artifactId>spray-client</artifactId> <artifactId>spray-client</artifactId>
<version>${spray-version}</version> <version>${spray.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.json4s</groupId> <groupId>org.json4s</groupId>
<artifactId>json4s-jackson_2.11</artifactId> <artifactId>json4s-jackson_2.11</artifactId>
<version>${json4s-jackson-version}</version> <version>${json4s.jackson.version}</version>
</dependency> </dependency>
<!--test dependencies--> <!--test dependencies-->
<dependency> <dependency>
<groupId>org.scalatest</groupId> <groupId>org.scalatest</groupId>
<artifactId>scalatest_2.11</artifactId> <artifactId>scalatest_2.11</artifactId>
<version>${scala-test-version}</version> <version>${scala.test.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>${junit-version}</version> <version>${junit.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<pluginRepositories>
<pluginRepository>
<id>maven-mongodb-plugin-repo</id>
<name>maven mongodb plugin repository</name>
<url>http://maven-mongodb-plugin.googlecode.com/svn/maven/repo</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId> <artifactId>maven-enforcer-plugin</artifactId>
@ -207,14 +203,14 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version> <version>3.7.0</version>
<configuration> <configuration>
<source>${jdk.version}</source> <source>${java.version}</source>
<target>${jdk.version}</target> <target>${java.version}</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>net.alchim31.maven</groupId> <groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId> <artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin-version}</version> <version>${scala.maven.plugin.version}</version>
<executions> <executions>
<execution> <execution>
<id>scala-compile-first</id> <id>scala-compile-first</id>
@ -244,15 +240,4 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<configuration>
<scalaVersion>${scala-version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</reporting>
</project> </project>

View File

@ -1,8 +1,4 @@
/** {{>licenseInfo}}
* NOTE: This class is auto generated by the akka-scala (beta) swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* For any issue or feedback, please open a ticket via https://github.com/swagger-api/swagger-codegen/issues/new
*/
package {{invokerPackage}} package {{invokerPackage}}
import java.io.File import java.io.File

View File

@ -19,8 +19,8 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
## Installation ## Installation
Put the package under your project folder and add the following in import: Put the package under your project folder and add the following in import:
``` ```golang
"./{{packageName}}" import "./{{packageName}}"
``` ```
## Documentation for API Endpoints ## Documentation for API Endpoints
@ -45,7 +45,7 @@ Class | Method | HTTP request | Description
{{#isApiKey}}- **Type**: API key {{#isApiKey}}- **Type**: API key
Example Example
``` ```golang
auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{ auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{
Key: "APIKEY", Key: "APIKEY",
Prefix: "Bearer", // Omit if not necessary. Prefix: "Bearer", // Omit if not necessary.
@ -56,7 +56,7 @@ Example
{{#isBasic}}- **Type**: HTTP basic authentication {{#isBasic}}- **Type**: HTTP basic authentication
Example Example
``` ```golang
auth := context.WithValue(context.Background(), sw.ContextBasicAuth, sw.BasicAuth{ auth := context.WithValue(context.Background(), sw.ContextBasicAuth, sw.BasicAuth{
UserName: "username", UserName: "username",
Password: "password", Password: "password",
@ -72,16 +72,16 @@ Example
{{/scopes}} {{/scopes}}
Example Example
``` ```golang
auth := context.WithValue(context.Background(), sw.ContextAccessToken, "ACCESSTOKENSTRING") auth := context.WithValue(context.Background(), sw.ContextAccessToken, "ACCESSTOKENSTRING")
r, err := client.Service.Operation(auth, args) r, err := client.Service.Operation(auth, args)
``` ```
Or via OAuth2 module to automatically refresh tokens and perform user authentication. Or via OAuth2 module to automatically refresh tokens and perform user authentication.
``` ```golang
import "golang.org/x/oauth2" import "golang.org/x/oauth2"
/ .. Perform OAuth2 round trip request and obtain a token .. // /* Perform OAuth2 round trip request and obtain a token */
tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token) tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token)
auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource) auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource)

View File

@ -4,8 +4,8 @@ package {{packageName}}
{{#operations}} {{#operations}}
import ( import (
"io/ioutil" "io/ioutil"
"net/url"
"net/http" "net/http"
"net/url"
"strings" "strings"
"golang.org/x/net/context" "golang.org/x/net/context"
{{#imports}} "{{import}}" {{#imports}} "{{import}}"
@ -18,15 +18,14 @@ var (
) )
type {{classname}}Service service type {{classname}}Service service
{{#operation}} {{#operation}}
/* {{{classname}}}Service {{summary}}{{#notes}} /* {{{classname}}}Service{{#summary}} {{.}}{{/summary}}{{#notes}}
{{notes}}{{/notes}} {{notes}}{{/notes}}
* @param ctx context.Context for authentication, logging, tracing, etc. * @param ctx context.Context for authentication, logging, tracing, etc.
{{#allParams}}{{#required}} @param {{paramName}} {{description}} {{#allParams}}{{#required}}@param {{paramName}}{{#description}} {{.}}{{/description}}
{{/required}}{{/allParams}}{{#hasOptionalParams}}@param optional (nil or map[string]interface{}) with one or more of: {{/required}}{{/allParams}}{{#hasOptionalParams}}@param optional (nil or map[string]interface{}) with one or more of:
{{#allParams}}{{^required}} @param "{{paramName}}" ({{dataType}}) {{description}} {{#allParams}}{{^required}} @param "{{paramName}}" ({{dataType}}){{#description}} {{.}}{{/description}}
{{/required}}{{/allParams}}{{/hasOptionalParams}}@return {{#returnType}}{{{returnType}}}{{/returnType}}*/ {{/required}}{{/allParams}}{{/hasOptionalParams}}@return {{#returnType}}{{{returnType}}}{{/returnType}}*/
func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}}, {{/hasParams}}{{#allParams}}{{#required}}{{paramName}} {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}}{{#hasOptionalParams}}localVarOptionals map[string]interface{}{{/hasOptionalParams}}) ({{#returnType}}{{{returnType}}}, {{/returnType}}*http.Response, error) { func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}}, {{/hasParams}}{{#allParams}}{{#required}}{{paramName}} {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}}{{#hasOptionalParams}}localVarOptionals map[string]interface{}{{/hasOptionalParams}}) ({{#returnType}}{{{returnType}}}, {{/returnType}}*http.Response, error) {
var ( var (
@ -46,7 +45,6 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}
localVarHeaderParams := make(map[string]string) localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{} localVarQueryParams := url.Values{}
localVarFormParams := url.Values{} localVarFormParams := url.Values{}
{{#allParams}} {{#allParams}}
{{^required}} {{^required}}
{{#isPrimitiveType}} {{#isPrimitiveType}}
@ -114,7 +112,9 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}
{{/queryParams}} {{/queryParams}}
{{/hasQueryParams}} {{/hasQueryParams}}
// to determine the Content-Type header // to determine the Content-Type header
localVarHttpContentTypes := []string{ {{#consumes}}"{{{mediaType}}}", {{/consumes}} } {{=<% %>=}}
localVarHttpContentTypes := []string{<%#consumes%>"<%&mediaType%>"<%^-last%>, <%/-last%><%/consumes%>}
<%={{ }}=%>
// set Content-Type header // set Content-Type header
localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
@ -123,11 +123,9 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}
} }
// to determine the Accept header // to determine the Accept header
localVarHttpHeaderAccepts := []string{ {{=<% %>=}}
{{#produces}} localVarHttpHeaderAccepts := []string{<%#produces%>"<%&mediaType%>"<%^-last%>, <%/-last%><%/produces%>}
"{{{mediaType}}}", <%={{ }}=%>
{{/produces}}
}
// set Accept header // set Accept header
localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
@ -223,7 +221,6 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}
} }
{{/returnType}} {{/returnType}}
return {{#returnType}}successPayload, {{/returnType}}localVarHttpResponse, err return {{#returnType}}successPayload, {{/returnType}}localVarHttpResponse, err
} }
{{/operation}}{{/operations}} {{/operation}}{{/operations}}

View File

@ -5,22 +5,23 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"encoding/xml" "encoding/xml"
"fmt"
"errors" "errors"
"fmt"
"io" "io"
"mime/multipart" "mime/multipart"
"golang.org/x/oauth2"
"golang.org/x/net/context"
"net/http" "net/http"
"net/url" "net/url"
"time"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"strings"
"unicode/utf8"
"strconv" "strconv"
"strings"
"time"
"unicode/utf8"
"golang.org/x/net/context"
"golang.org/x/oauth2"
) )
var ( var (
@ -38,6 +39,7 @@ type APIClient struct {
{{#apiInfo}} {{#apiInfo}}
{{#apis}} {{#apis}}
{{#operations}} {{#operations}}
{{classname}} *{{classname}}Service {{classname}} *{{classname}}Service
{{/operations}} {{/operations}}
{{/apis}} {{/apis}}
@ -75,7 +77,6 @@ func atoi(in string) (int, error) {
return strconv.Atoi(in) return strconv.Atoi(in)
} }
// selectHeaderContentType select a content type from the available list. // selectHeaderContentType select a content type from the available list.
func selectHeaderContentType(contentTypes []string) string { func selectHeaderContentType(contentTypes []string) string {
if len(contentTypes) == 0 { if len(contentTypes) == 0 {
@ -267,7 +268,6 @@ func (c *APIClient) prepareRequest (
// Add the user agent to the request. // Add the user agent to the request.
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
if ctx != nil { if ctx != nil {
// add context to the request // add context to the request
localVarRequest = localVarRequest.WithContext(ctx) localVarRequest = localVarRequest.WithContext(ctx)
@ -303,7 +303,6 @@ func (c *APIClient) prepareRequest (
return localVarRequest, nil return localVarRequest, nil
} }
// Add a file to the multipart request // Add a file to the multipart request
func addFile(w *multipart.Writer, fieldName, path string) error { func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path) file, err := os.Open(path)
@ -322,7 +321,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
} }
// Prevent trying to import "fmt" // Prevent trying to import "fmt"
func reportError(format string, a ...interface{}) (error) { func reportError(format string, a ...interface{}) error {
return fmt.Errorf(format, a...) return fmt.Errorf(format, a...)
} }
@ -376,7 +375,6 @@ func detectContentType(body interface{}) string {
return contentType return contentType
} }
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go // Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
type cacheControl map[string]string type cacheControl map[string]string
@ -399,7 +397,7 @@ func parseCacheControl(headers http.Header) cacheControl {
} }
// CacheExpires helper function to determine remaining time before repeating a request. // CacheExpires helper function to determine remaining time before repeating a request.
func CacheExpires(r *http.Response) (time.Time) { func CacheExpires(r *http.Response) time.Time {
// Figure out when the cache expires. // Figure out when the cache expires.
var expires time.Time var expires time.Time
now, err := time.Parse(time.RFC1123, r.Header.Get("date")) now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
@ -426,7 +424,6 @@ func CacheExpires(r *http.Response) (time.Time) {
return expires return expires
} }
func strlen(s string) (int) { func strlen(s string) int {
return utf8.RuneCountInString(s) return utf8.RuneCountInString(s)
} }

View File

@ -11,14 +11,22 @@ type {{{name}}} {{^format}}{{dataType}}{{/format}}{{#format}}{{{format}}}{{/form
const ( const (
{{#allowableValues}} {{#allowableValues}}
{{#enumVars}} {{#enumVars}}
{{^-first}}
{{/-first}}
{{name}} {{{classname}}} = "{{{value}}}" {{name}} {{{classname}}} = "{{{value}}}"
{{/enumVars}} {{/enumVars}}
{{/allowableValues}} {{/allowableValues}}
){{/isEnum}}{{^isEnum}}{{#description}} ){{/isEnum}}{{^isEnum}}{{#description}}
// {{{description}}}{{/description}} // {{{description}}}{{/description}}
type {{classname}} struct { type {{classname}} struct {
{{#vars}}{{#description}} {{#vars}}
// {{{description}}}{{/description}} {{^-first}}
{{/-first}}
{{#description}}
// {{{description}}}
{{/description}}
{{name}} {{^isEnum}}{{^isPrimitiveType}}{{^isContainer}}{{^isDateTime}}*{{/isDateTime}}{{/isContainer}}{{/isPrimitiveType}}{{/isEnum}}{{{datatype}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"` {{name}} {{^isEnum}}{{^isPrimitiveType}}{{^isContainer}}{{^isDateTime}}*{{/isDateTime}}{{/isContainer}}{{/isPrimitiveType}}{{/isEnum}}{{{datatype}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"`
{{/vars}} {{/vars}}
}{{/isEnum}}{{/model}}{{/models}} }{{/isEnum}}{{/model}}{{/models}}

View File

@ -1,22 +1,16 @@
{{>partial_header}} {{>partial_header}}
{-| {-|
Module : {{title}}.API Module : {{title}}.API.{{classname}}
-} -}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-binds -fno-warn-unused-imports #-} {-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-binds -fno-warn-unused-imports #-}
module {{title}}.API where module {{title}}.API.{{classname}} where
import {{title}}.Core import {{title}}.Core
import {{title}}.MimeTypes import {{title}}.MimeTypes
@ -24,8 +18,6 @@ import {{title}}.Model as M
import qualified Data.Aeson as A import qualified Data.Aeson as A
import qualified Data.ByteString as B import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy as BL
import qualified Data.Data as P (Typeable, TypeRep, typeOf, typeRep) import qualified Data.Data as P (Typeable, TypeRep, typeOf, typeRep)
import qualified Data.Foldable as P import qualified Data.Foldable as P
@ -39,16 +31,12 @@ import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL import qualified Data.Text.Lazy.Encoding as TL
import qualified Data.Time as TI import qualified Data.Time as TI
import qualified GHC.Base as P (Alternative)
import qualified Lens.Micro as L
import qualified Network.HTTP.Client.MultipartFormData as NH import qualified Network.HTTP.Client.MultipartFormData as NH
import qualified Network.HTTP.Media as ME import qualified Network.HTTP.Media as ME
import qualified Network.HTTP.Types as NH import qualified Network.HTTP.Types as NH
import qualified Web.FormUrlEncoded as WH import qualified Web.FormUrlEncoded as WH
import qualified Web.HttpApiData as WH import qualified Web.HttpApiData as WH
import Data.Monoid ((<>))
import Data.Function ((&))
import Data.Text (Text) import Data.Text (Text)
import GHC.Base ((<|>)) import GHC.Base ((<|>))
@ -56,7 +44,7 @@ import Prelude ((==),(/=),($), (.),(<$>),(<*>),(>>=),Maybe(..),Bool(..),Char,Dou
import qualified Prelude as P import qualified Prelude as P
-- * Operations -- * Operations
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#vendorExtensions.x-hasNewTag}} {{#operations}}{{#operation}}{{#vendorExtensions.x-hasNewTag}}
-- ** {{baseName}}{{/vendorExtensions.x-hasNewTag}} -- ** {{baseName}}{{/vendorExtensions.x-hasNewTag}}
@ -100,75 +88,11 @@ instance HasOptionalParam {{{vendorExtensions.x-operationType}}} {{{vendorExtens
applyOptionalParam req ({{{vendorExtensions.x-paramNameType}}} xs) = applyOptionalParam req ({{{vendorExtensions.x-paramNameType}}} xs) =
{{#isHeaderParam}}req `setHeader` {{>_headerColl}} ("{{{baseName}}}", xs){{/isHeaderParam}}{{#isQueryParam}}req `setQuery` {{>_queryColl}} ("{{{baseName}}}", Just xs){{/isQueryParam}}{{#isFormParam}}{{#isFile}}req `_addMultiFormPart` NH.partFileSource "{{{baseName}}}" xs{{/isFile}}{{^isFile}}{{#isMultipart}}req `_addMultiFormPart` NH.partLBS "{{{baseName}}}" (mimeRender' MimeMultipartFormData xs){{/isMultipart}}{{^isMultipart}}req `addForm` {{>_formColl}} ("{{{baseName}}}", xs){{/isMultipart}}{{/isFile}}{{/isFormParam}}{{/required}}{{/isBodyParam}}{{/allParams}}{{/vendorExtensions.x-hasOptionalParams}}{{#hasConsumes}} {{#isHeaderParam}}req `setHeader` {{>_headerColl}} ("{{{baseName}}}", xs){{/isHeaderParam}}{{#isQueryParam}}req `setQuery` {{>_queryColl}} ("{{{baseName}}}", Just xs){{/isQueryParam}}{{#isFormParam}}{{#isFile}}req `_addMultiFormPart` NH.partFileSource "{{{baseName}}}" xs{{/isFile}}{{^isFile}}{{#isMultipart}}req `_addMultiFormPart` NH.partLBS "{{{baseName}}}" (mimeRender' MimeMultipartFormData xs){{/isMultipart}}{{^isMultipart}}req `addForm` {{>_formColl}} ("{{{baseName}}}", xs){{/isMultipart}}{{/isFile}}{{/isFormParam}}{{/required}}{{/isBodyParam}}{{/allParams}}{{/vendorExtensions.x-hasOptionalParams}}{{#hasConsumes}}
{{#consumes}}-- | @{{{mediaType}}}@ {{#consumes}}-- | @{{{mediaType}}}@{{^x-mediaIsWildcard}}
instance Consumes {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}} instance Consumes {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}}{{/x-mediaIsWildcard}}{{#x-mediaIsWildcard}}
instance MimeType mtype => Consumes {{{vendorExtensions.x-operationType}}} mtype{{/x-mediaIsWildcard}}
{{/consumes}}{{/hasConsumes}}{{#hasProduces}} {{/consumes}}{{/hasConsumes}}{{#hasProduces}}
{{#produces}}-- | @{{{mediaType}}}@ {{#produces}}-- | @{{{mediaType}}}@{{^x-mediaIsWildcard}}
instance Produces {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}} instance Produces {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}}{{/x-mediaIsWildcard}}{{#x-mediaIsWildcard}}
{{/produces}}{{/hasProduces}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} instance MimeType mtype => Produces {{{vendorExtensions.x-operationType}}} mtype{{/x-mediaIsWildcard}}
{{/produces}}{{/hasProduces}}{{/operation}}{{/operations}}
-- * Parameter newtypes
{{#x-allUniqueParams}}{{#x-newtype}}
newtype {{{x-paramNameType}}} = {{{x-paramNameType}}} { un{{{x-paramNameType}}} :: {{{x-dataType}}} } deriving (P.Eq, P.Show{{#x-isBodyParam}}, A.ToJSON{{/x-isBodyParam}}){{/x-newtype}}{{/x-allUniqueParams}}
{{#authMethods}}{{#-first}}-- * Auth Methods
{{/-first}}{{#isBasic}}-- ** {{name}}
data {{name}} =
{{name}} B.ByteString B.ByteString -- ^ username password
deriving (P.Eq, P.Show, P.Typeable)
instance AuthMethod {{name}} where
applyAuthMethod _ a@({{name}} user pw) req =
P.pure $
if (P.typeOf a `P.elem` rAuthTypes req)
then req `setHeader` toHeader ("Authorization", T.decodeUtf8 cred)
& L.over rAuthTypesL (P.filter (/= P.typeOf a))
else req
where cred = BC.append "Basic " (B64.encode $ BC.concat [ user, ":", pw ])
{{/isBasic}}{{#isApiKey}}-- ** {{name}}
data {{name}} =
{{name}} Text -- ^ secret
deriving (P.Eq, P.Show, P.Typeable)
instance AuthMethod {{name}} where
applyAuthMethod _ a@({{name}} secret) req =
P.pure $
if (P.typeOf a `P.elem` rAuthTypes req)
then req {{#isKeyInHeader}}`setHeader` toHeader ("{{keyParamName}}", secret){{/isKeyInHeader}}{{^isKeyInHeader}}`setQuery` toQuery ("{{keyParamName}}", Just secret){{/isKeyInHeader}}
& L.over rAuthTypesL (P.filter (/= P.typeOf a))
else req
{{/isApiKey}}{{#isOAuth}}-- ** {{name}}
data {{name}} =
{{name}} Text -- ^ secret
deriving (P.Eq, P.Show, P.Typeable)
instance AuthMethod {{name}} where
applyAuthMethod _ a@({{name}} secret) req =
P.pure $
if (P.typeOf a `P.elem` rAuthTypes req)
then req `setHeader` toHeader ("Authorization", "Bearer " <> secret)
& L.over rAuthTypesL (P.filter (/= P.typeOf a))
else req
{{/isOAuth}}{{/authMethods}}
{{#x-hasUnknownMimeTypes}}
-- * Custom Mime Types
{{#x-unknownMimeTypes}}-- ** {{{x-mediaDataType}}}
data {{{x-mediaDataType}}} = {{{x-mediaDataType}}} deriving (P.Typeable)
-- | @{{{mediaType}}}@
instance MimeType {{{x-mediaDataType}}} where
mimeType _ = Just $ P.fromString "{{{mediaType}}}"{{#x-mediaIsJson}}
instance A.ToJSON a => MimeRender {{{x-mediaDataType}}} a where mimeRender _ = A.encode
instance A.FromJSON a => MimeUnrender {{{x-mediaDataType}}} a where mimeUnrender _ = A.eitherDecode{{/x-mediaIsJson}}
-- instance MimeRender {{{x-mediaDataType}}} T.Text where mimeRender _ = undefined
-- instance MimeUnrender {{{x-mediaDataType}}} T.Text where mimeUnrender _ = undefined
{{/x-unknownMimeTypes}}{{/x-hasUnknownMimeTypes}}

View File

@ -0,0 +1,10 @@
{{>partial_header}}
{-|
Module : {{title}}.API
-}
module {{title}}.API
( {{#apiInfo}}{{#apis}}module {{title}}.API.{{classname}}
{{#hasMore}}, {{/hasMore}}{{/apis}}{{/apiInfo}}) where
{{#apiInfo}}{{#apis}}
import {{title}}.API.{{classname}}{{/apis}}{{/apiInfo}}

View File

@ -190,3 +190,21 @@ instance MimeUnrender MimeOctetStream String where mimeUnrender _ = P.Right . BC
-- | @P.Right . P.const NoContent@ -- | @P.Right . P.const NoContent@
instance MimeUnrender MimeNoContent NoContent where mimeUnrender _ = P.Right . P.const NoContent instance MimeUnrender MimeNoContent NoContent where mimeUnrender _ = P.Right . P.const NoContent
{{#x-hasUnknownMimeTypes}}
-- * Custom Mime Types
{{#x-unknownMimeTypes}}-- ** {{{x-mediaDataType}}}
data {{{x-mediaDataType}}} = {{{x-mediaDataType}}} deriving (P.Typeable)
-- | @{{{mediaType}}}@
instance MimeType {{{x-mediaDataType}}} where
mimeType _ = Just $ P.fromString "{{{mediaType}}}"{{#x-mediaIsJson}}
instance A.ToJSON a => MimeRender {{{x-mediaDataType}}} a where mimeRender _ = A.encode
instance A.FromJSON a => MimeUnrender {{{x-mediaDataType}}} a where mimeUnrender _ = A.eitherDecode{{/x-mediaIsJson}}
-- instance MimeRender {{{x-mediaDataType}}} T.Text where mimeRender _ = undefined
-- instance MimeUnrender {{{x-mediaDataType}}} T.Text where mimeUnrender _ = undefined
{{/x-unknownMimeTypes}}{{/x-hasUnknownMimeTypes}}

View File

@ -27,8 +27,10 @@ import Data.Aeson ((.:),(.:!),(.:?),(.=))
import qualified Control.Arrow as P (left) import qualified Control.Arrow as P (left)
import qualified Data.Aeson as A import qualified Data.Aeson as A
import qualified Data.ByteString as B import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy as BL
import qualified Data.Data as P (Data, Typeable) import qualified Data.Data as P (Typeable, TypeRep, typeOf, typeRep)
import qualified Data.Foldable as P import qualified Data.Foldable as P
import qualified Data.HashMap.Lazy as HM import qualified Data.HashMap.Lazy as HM
import qualified Data.Map as Map import qualified Data.Map as Map
@ -37,13 +39,16 @@ import qualified Data.Set as Set
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
import qualified Data.Time as TI import qualified Data.Time as TI
import qualified Lens.Micro as L
import qualified Web.FormUrlEncoded as WH import qualified Web.FormUrlEncoded as WH
import qualified Web.HttpApiData as WH import qualified Web.HttpApiData as WH
import Control.Applicative ((<|>)) import Control.Applicative ((<|>))
import Control.Applicative (Alternative) import Control.Applicative (Alternative)
import Data.Function ((&))
import Data.Monoid ((<>))
import Data.Text (Text) import Data.Text (Text)
import Prelude (($), (.),(<$>),(<*>),(>>=),(=<<),Maybe(..),Bool(..),Char,Double,FilePath,Float,Int,Integer,String,fmap,undefined,mempty,maybe,pure,Monad,Applicative,Functor) import Prelude (($),(/=),(.),(<$>),(<*>),(>>=),(=<<),Maybe(..),Bool(..),Char,Double,FilePath,Float,Int,Integer,String,fmap,undefined,mempty,maybe,pure,Monad,Applicative,Functor)
import qualified Prelude as P import qualified Prelude as P
@ -51,6 +56,12 @@ import qualified Prelude as P
{{#imports}}import {{import}} {{#imports}}import {{import}}
{{/imports}} {{/imports}}
-- * Parameter newtypes
{{#x-allUniqueParams}}{{#x-newtype}}
-- ** {{{x-paramNameType}}}
newtype {{{x-paramNameType}}} = {{{x-paramNameType}}} { un{{{x-paramNameType}}} :: {{{x-dataType}}} } deriving (P.Eq, P.Show{{#x-isBodyParam}}, A.ToJSON{{/x-isBodyParam}}){{/x-newtype}}{{/x-allUniqueParams}}
-- * Models -- * Models
{{#models}} {{#models}}
@ -140,3 +151,47 @@ to{{{x-paramNameType}}} = \case{{#allowableValues}}{{#enumVars}}
{{{value}}} -> P.Right {{{name}}}{{/enumVars}}{{/allowableValues}} {{{value}}} -> P.Right {{{name}}}{{/enumVars}}{{/allowableValues}}
s -> P.Left $ "to{{{x-paramNameType}}}: enum parse failure: " P.++ P.show s s -> P.Left $ "to{{{x-paramNameType}}}: enum parse failure: " P.++ P.show s
{{/x-enum}}{{/x-allUniqueParams}}{{/x-hasEnumSection}} {{/x-enum}}{{/x-allUniqueParams}}{{/x-hasEnumSection}}
{{#authMethods}}{{#-first}}-- * Auth Methods
{{/-first}}{{#isBasic}}-- ** {{name}}
data {{name}} =
{{name}} B.ByteString B.ByteString -- ^ username password
deriving (P.Eq, P.Show, P.Typeable)
instance AuthMethod {{name}} where
applyAuthMethod _ a@({{name}} user pw) req =
P.pure $
if (P.typeOf a `P.elem` rAuthTypes req)
then req `setHeader` toHeader ("Authorization", T.decodeUtf8 cred)
& L.over rAuthTypesL (P.filter (/= P.typeOf a))
else req
where cred = BC.append "Basic " (B64.encode $ BC.concat [ user, ":", pw ])
{{/isBasic}}{{#isApiKey}}-- ** {{name}}
data {{name}} =
{{name}} Text -- ^ secret
deriving (P.Eq, P.Show, P.Typeable)
instance AuthMethod {{name}} where
applyAuthMethod _ a@({{name}} secret) req =
P.pure $
if (P.typeOf a `P.elem` rAuthTypes req)
then req {{#isKeyInHeader}}`setHeader` toHeader ("{{keyParamName}}", secret){{/isKeyInHeader}}{{^isKeyInHeader}}`setQuery` toQuery ("{{keyParamName}}", Just secret){{/isKeyInHeader}}
& L.over rAuthTypesL (P.filter (/= P.typeOf a))
else req
{{/isApiKey}}{{#isOAuth}}-- ** {{name}}
data {{name}} =
{{name}} Text -- ^ secret
deriving (P.Eq, P.Show, P.Typeable)
instance AuthMethod {{name}} where
applyAuthMethod _ a@({{name}} secret) req =
P.pure $
if (P.typeOf a `P.elem` rAuthTypes req)
then req `setHeader` toHeader ("Authorization", "Bearer " <> secret)
& L.over rAuthTypesL (P.filter (/= P.typeOf a))
else req
{{/isOAuth}}{{/authMethods}}

View File

@ -58,6 +58,7 @@ These options allow some customization of the code generation process.
| OPTION | DESCRIPTION | DEFAULT | ACTUAL | | OPTION | DESCRIPTION | DEFAULT | ACTUAL |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- | | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
| allowNonUniqueOperationIds | allow *different* API modules to contain the same operationId. Each API must be imported qualified | false | {{{x-allowNonUniqueOperationIds}}} |
| allowFromJsonNulls | allow JSON Null during model decoding from JSON | true | {{{allowFromJsonNulls}}} | | allowFromJsonNulls | allow JSON Null during model decoding from JSON | true | {{{allowFromJsonNulls}}} |
| allowToJsonNulls | allow emitting JSON Null during model encoding to JSON | false | {{{allowToJsonNulls}}} | | allowToJsonNulls | allow emitting JSON Null during model encoding to JSON | false | {{{allowToJsonNulls}}} |
| dateFormat | format string used to parse/render a date | %Y-%m-%d | {{{dateFormat}}} | | dateFormat | format string used to parse/render a date | %Y-%m-%d | {{{dateFormat}}} |

View File

@ -4,8 +4,8 @@ Module : {{title}}
-} -}
module {{title}} module {{title}}
( module {{title}}.API ( {{^x-allowNonUniqueOperationIds}} module {{title}}.API
, module {{title}}.Client ,{{/x-allowNonUniqueOperationIds}} module {{title}}.Client
, module {{title}}.Core , module {{title}}.Core
, module {{title}}.Logging , module {{title}}.Logging
, module {{title}}.MimeTypes , module {{title}}.MimeTypes
@ -13,7 +13,7 @@ module {{title}}
, module {{title}}.ModelLens , module {{title}}.ModelLens
) where ) where
import {{title}}.API {{^x-allowNonUniqueOperationIds}}import {{title}}.API{{/x-allowNonUniqueOperationIds}}
import {{title}}.Client import {{title}}.Client
import {{title}}.Core import {{title}}.Core
import {{title}}.Logging import {{title}}.Logging

View File

@ -36,34 +36,35 @@ library
lib lib
ghc-options: -Wall -funbox-strict-fields ghc-options: -Wall -funbox-strict-fields
build-depends: build-depends:
base >=4.7 && <5.0 aeson >=1.0 && <2.0
, transformers >=0.4.0.0 , base >=4.7 && <5.0
, mtl >=2.2.1
, unordered-containers
, aeson >=1.0 && <2.0
, bytestring >=0.10.0 && <0.11
, base64-bytestring >1.0 && <2.0 , base64-bytestring >1.0 && <2.0
, bytestring >=0.10.0 && <0.11
, case-insensitive
, containers >=0.5.0.0 && <0.6 , containers >=0.5.0.0 && <0.6
, http-types >=0.8 && <0.11 , deepseq >= 1.4 && <1.6
, exceptions >= 0.4
, http-api-data >= 0.3.4 && <0.4
, http-client >=0.5 && <0.6 , http-client >=0.5 && <0.6
, http-client-tls , http-client-tls
, http-api-data >= 0.3.4 && <0.4
, http-media >= 0.4 && < 0.8 , http-media >= 0.4 && < 0.8
, text >=0.11 && <1.3 , http-types >=0.8 && <0.12
, time >=1.5 && <1.9
, iso8601-time >=0.1.3 && <0.2.0 , iso8601-time >=0.1.3 && <0.2.0
, vector >=0.10.9 && <0.13 , microlens >= 0.4.3 && <0.5
, mtl >=2.2.1
, network >=2.6.2 && <2.7 , network >=2.6.2 && <2.7
, random >=1.1 , random >=1.1
, exceptions >= 0.4
, {{^x-useMonadLogger}}katip >=0.4 && < 0.6{{/x-useMonadLogger}}{{#x-useMonadLogger}}monad-logger >=0.3 && <0.4{{/x-useMonadLogger}}
, safe-exceptions <0.2 , safe-exceptions <0.2
, case-insensitive , text >=0.11 && <1.3
, microlens >= 0.4.3 && <0.5 , time >=1.5 && <1.9
, deepseq >= 1.4 && <1.6 , transformers >=0.4.0.0
, unordered-containers
, vector >=0.10.9 && <0.13
, {{^x-useMonadLogger}}katip >=0.4 && < 0.6{{/x-useMonadLogger}}{{#x-useMonadLogger}}monad-logger >=0.3 && <0.4{{/x-useMonadLogger}}
exposed-modules: exposed-modules:
{{title}} {{title}}{{^x-allowNonUniqueOperationIds}}
{{title}}.API {{title}}.API{{/x-allowNonUniqueOperationIds}}{{#apiInfo}}{{#apis}}
{{title}}.API.{{classname}}{{/apis}}{{/apiInfo}}
{{title}}.Client {{title}}.Client
{{title}}.Core {{title}}.Core
{{title}}.Logging {{title}}.Logging
@ -81,21 +82,21 @@ test-suite tests
tests tests
ghc-options: -Wall -fno-warn-orphans ghc-options: -Wall -fno-warn-orphans
build-depends: build-depends:
base >=4.7 && <5.0 {{package}}
, transformers >=0.4.0.0 , QuickCheck
, mtl >=2.2.1 , aeson
, unordered-containers , base >=4.7 && <5.0
, {{package}}
, bytestring >=0.10.0 && <0.11 , bytestring >=0.10.0 && <0.11
, containers , containers
, hspec >=1.8 , hspec >=1.8
, iso8601-time
, mtl >=2.2.1
, semigroups
, text , text
, time , time
, iso8601-time , transformers >=0.4.0.0
, aeson , unordered-containers
, vector , vector
, semigroups
, QuickCheck
other-modules: other-modules:
ApproxEq ApproxEq
Instances Instances

View File

@ -17,7 +17,7 @@ import {{title}}.MimeTypes
main :: IO () main :: IO ()
main = main =
hspec $ modifyMaxSize (const 10) $ do hspec $ modifyMaxSize (const 5) $ do
describe "JSON instances" $ do describe "JSON instances" $ do
pure () pure ()
{{#models}}{{#model}}propMimeEq MimeJSON (Proxy :: Proxy {{classname}}) {{#models}}{{#model}}propMimeEq MimeJSON (Proxy :: Proxy {{classname}})

View File

@ -19,8 +19,8 @@ class {{classname}}(basePath: kotlin.String = "{{{basePath}}}") : ApiClient(base
@Suppress("UNCHECKED_CAST"){{/returnType}} @Suppress("UNCHECKED_CAST"){{/returnType}}
fun {{operationId}}({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}} { fun {{operationId}}({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}} {
val localVariableBody: kotlin.Any? = {{#hasBodyParam}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}mapOf({{#formParams}}"{{{baseName}}}" to "${{paramName}}"{{#hasMore}}, {{/hasMore}}{{/formParams}}){{/hasFormParams}}{{/hasBodyParam}} val localVariableBody: kotlin.Any? = {{#hasBodyParam}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}mapOf({{#formParams}}"{{{baseName}}}" to "${{paramName}}"{{#hasMore}}, {{/hasMore}}{{/formParams}}){{/hasFormParams}}{{/hasBodyParam}}
val localVariableQuery: MultiValueMap = {{^hasQueryParams}}mapOf(){{/hasQueryParams}}{{#hasQueryParams}}mapOf({{#queryParams}}"{{paramName}}" to {{#isContainer}}toMultiValue({{paramName}}.toList(), "{{collectionFormat}}"){{/isContainer}}{{^isContainer}}listOf("${{paramName}}"){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/queryParams}}){{/hasQueryParams}} val localVariableQuery: MultiValueMap = {{^hasQueryParams}}mapOf(){{/hasQueryParams}}{{#hasQueryParams}}mapOf({{#queryParams}}"{{baseName}}" to {{#isContainer}}toMultiValue({{paramName}}.toList(), "{{collectionFormat}}"){{/isContainer}}{{^isContainer}}listOf("${{paramName}}"){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/queryParams}}){{/hasQueryParams}}
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf({{#hasFormParams}}"Content-Type" to "multipart/form-data"{{/hasFormParams}}{{^hasHeaderParams}}){{/hasHeaderParams}}{{#hasHeaderParams}}{{#hasFormParams}}, {{/hasFormParams}}{{#headerParams}}"{{paramName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}"){{/isContainer}}{{^isContainer}}{{paramName}}{{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}} val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf({{#hasFormParams}}"Content-Type" to "multipart/form-data"{{/hasFormParams}}{{^hasHeaderParams}}){{/hasHeaderParams}}{{#hasHeaderParams}}{{#hasFormParams}}, {{/hasFormParams}}{{#headerParams}}"{{baseName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}"){{/isContainer}}{{^isContainer}}{{paramName}}{{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}}
val localVariableConfig = RequestConfig( val localVariableConfig = RequestConfig(
RequestMethod.{{httpMethod}}, RequestMethod.{{httpMethod}},
"{{path}}"{{#pathParams}}.replace("{"+"{{baseName}}"+"}", "${{paramName}}"){{/pathParams}}, "{{path}}"{{#pathParams}}.replace("{"+"{{baseName}}"+"}", "${{paramName}}"){{/pathParams}},

View File

@ -1,361 +0,0 @@
<?php
/**
* ApiClient
*
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author Swagger Codegen team
* @link https://github.com/swagger-api/swagger-codegen
*/
{{>partial_header}}
/**
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{invokerPackage}};
/**
* ApiClient Class Doc Comment
*
* @category Class
* @package {{invokerPackage}}
* @author Swagger Codegen team
* @link https://github.com/swagger-api/swagger-codegen
*/
class ApiClient
{
public static $PATCH = "PATCH";
public static $POST = "POST";
public static $GET = "GET";
public static $HEAD = "HEAD";
public static $OPTIONS = "OPTIONS";
public static $PUT = "PUT";
public static $DELETE = "DELETE";
/**
* Configuration
*
* @var Configuration
*/
protected $config;
/**
* Object Serializer
*
* @var ObjectSerializer
*/
protected $serializer;
/**
* Constructor of the class
*
* @param Configuration $config config for this ApiClient
*/
public function __construct(\{{invokerPackage}}\Configuration $config = null)
{
if ($config === null) {
$config = Configuration::getDefaultConfiguration();
}
$this->config = $config;
$this->serializer = new ObjectSerializer();
}
/**
* Get the config
*
* @return Configuration
*/
public function getConfig()
{
return $this->config;
}
/**
* Get the serializer
*
* @return ObjectSerializer
*/
public function getSerializer()
{
return $this->serializer;
}
/**
* Get API key (with prefix if set)
*
* @param string $apiKeyIdentifier name of apikey
*
* @return string API key with the prefix
*/
public function getApiKeyWithPrefix($apiKeyIdentifier)
{
$prefix = $this->config->getApiKeyPrefix($apiKeyIdentifier);
$apiKey = $this->config->getApiKey($apiKeyIdentifier);
if (!isset($apiKey)) {
return null;
}
if (isset($prefix)) {
$keyWithPrefix = $prefix." ".$apiKey;
} else {
$keyWithPrefix = $apiKey;
}
return $keyWithPrefix;
}
/**
* Make the HTTP call (Sync)
*
* @param string $resourcePath path to method endpoint
* @param string $method method to call
* @param array $queryParams parameters to be place in query URL
* @param array $postData parameters to be placed in POST body
* @param array $headerParams parameters to be place in request header
* @param string $responseType expected response type of the endpoint
* @param string $endpointPath path to method endpoint before expanding parameters
*
* @throws \{{invokerPackage}}\ApiException on a non 2xx response
* @return mixed
*/
public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams, $responseType = null, $endpointPath = null)
{
$headers = [];
// construct the http header
$headerParams = array_merge(
(array)$this->config->getDefaultHeaders(),
(array)$headerParams
);
foreach ($headerParams as $key => $val) {
$headers[] = "$key: $val";
}
// form data
if ($postData and in_array('Content-Type: application/x-www-form-urlencoded', $headers, true)) {
$postData = http_build_query($postData);
} elseif ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers, true)) { // json model
$postData = json_encode(\{{invokerPackage}}\ObjectSerializer::sanitizeForSerialization($postData));
}
$url = $this->config->getHost() . $resourcePath;
$curl = curl_init();
// set timeout, if needed
if ($this->config->getCurlTimeout() !== 0) {
curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout());
}
// set connect timeout, if needed
if ($this->config->getCurlConnectTimeout() != 0) {
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $this->config->getCurlConnectTimeout());
}
// return the result on success, rather than just true
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// disable SSL verification, if needed
if ($this->config->getSSLVerification() === false) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
}
if ($this->config->getCurlProxyHost()) {
curl_setopt($curl, CURLOPT_PROXY, $this->config->getCurlProxyHost());
}
if ($this->config->getCurlProxyPort()) {
curl_setopt($curl, CURLOPT_PROXYPORT, $this->config->getCurlProxyPort());
}
if ($this->config->getCurlProxyType()) {
curl_setopt($curl, CURLOPT_PROXYTYPE, $this->config->getCurlProxyType());
}
if ($this->config->getCurlProxyUser()) {
curl_setopt($curl, CURLOPT_PROXYUSERPWD, $this->config->getCurlProxyUser() . ':' .$this->config->getCurlProxyPassword());
}
if (!empty($queryParams)) {
$url = ($url . '?' . http_build_query($queryParams));
}
if ($this->config->getAllowEncoding()) {
curl_setopt($curl, CURLOPT_ENCODING, '');
}
if ($method === self::$POST) {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} elseif ($method === self::$HEAD) {
curl_setopt($curl, CURLOPT_NOBODY, true);
} elseif ($method === self::$OPTIONS) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "OPTIONS");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} elseif ($method === self::$PATCH) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} elseif ($method === self::$PUT) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} elseif ($method === self::$DELETE) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} elseif ($method !== self::$GET) {
throw new ApiException('Method ' . $method . ' is not recognized.');
}
curl_setopt($curl, CURLOPT_URL, $url);
// Set user agent
curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent());
// debugging for curl
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Request body ~BEGIN~".PHP_EOL.print_r($postData, true).PHP_EOL."~END~".PHP_EOL, 3, $this->config->getDebugFile());
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a'));
} else {
curl_setopt($curl, CURLOPT_VERBOSE, 0);
}
// obtain the HTTP response headers
curl_setopt($curl, CURLOPT_HEADER, 1);
// Make the request
$response = curl_exec($curl);
$http_header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$http_header = $this->httpParseHeaders(substr($response, 0, $http_header_size));
$http_body = substr($response, $http_header_size);
$response_info = curl_getinfo($curl);
// debug HTTP response body
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Response body ~BEGIN~".PHP_EOL.print_r($http_body, true).PHP_EOL."~END~".PHP_EOL, 3, $this->config->getDebugFile());
}
// Handle the response
if ($response_info['http_code'] === 0) {
$curl_error_message = curl_error($curl);
// curl_exec can sometimes fail but still return a blank message from curl_error().
if (!empty($curl_error_message)) {
$error_message = "API call to $url failed: $curl_error_message";
} else {
$error_message = "API call to $url failed, but for an unknown reason. " .
"This could happen if you are disconnected from the network.";
}
$exception = new ApiException($error_message, 0, null, null);
$exception->setResponseObject($response_info);
throw $exception;
} elseif ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299) {
// return raw body if response is a file
if ($responseType === '\SplFileObject' || $responseType === 'string') {
return [$http_body, $response_info['http_code'], $http_header];
}
$data = json_decode($http_body);
if (json_last_error() > 0) { // if response is a string
$data = $http_body;
}
} else {
$data = json_decode($http_body);
if (json_last_error() > 0) { // if response is a string
$data = $http_body;
}
throw new ApiException(
"[".$response_info['http_code']."] Error connecting to the API ($url)",
$response_info['http_code'],
$http_header,
$data
);
}
return [$data, $response_info['http_code'], $http_header];
}
/**
* Return the header 'Accept' based on an array of Accept provided
*
* @param string[] $accept Array of header
*
* @return string Accept (e.g. application/json)
*/
public function selectHeaderAccept($accept)
{
if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) {
return null;
} elseif (preg_grep("/application\/json/i", $accept)) {
return 'application/json';
} else {
return implode(',', $accept);
}
}
/**
* Return the content type based on an array of content-type provided
*
* @param string[] $content_type Array fo content-type
*
* @return string Content-Type (e.g. application/json)
*/
public function selectHeaderContentType($content_type)
{
if (count($content_type) === 0 or (count($content_type) === 1 and $content_type[0] === '')) {
return 'application/json';
} elseif (preg_grep("/application\/json/i", $content_type)) {
return 'application/json';
} else {
return implode(',', $content_type);
}
}
/**
* Return an array of HTTP response headers
*
* @param string $raw_headers A string of raw HTTP response headers
*
* @return string[] Array of HTTP response heaers
*/
protected function httpParseHeaders($raw_headers)
{
// ref/credit: http://php.net/manual/en/function.http-parse-headers.php#112986
$headers = [];
$key = '';
foreach (explode("\n", $raw_headers) as $h) {
$h = explode(':', $h, 2);
if (isset($h[1])) {
if (!isset($headers[$h[0]])) {
$headers[$h[0]] = trim($h[1]);
} elseif (is_array($headers[$h[0]])) {
$headers[$h[0]] = array_merge($headers[$h[0]], [trim($h[1])]);
} else {
$headers[$h[0]] = array_merge([$headers[$h[0]]], [trim($h[1])]);
}
$key = $h[0];
} else {
if (substr($h[0], 0, 1) === "\t") {
$headers[$key] .= "\r\n\t".trim($h[0]);
} elseif (!$key) {
$headers[0] = trim($h[0]);
}
trim($h[0]);
}
}
return $headers;
}
}

View File

@ -24,9 +24,8 @@ namespace {{invokerPackage}};
/** /**
* {{classname}}Test Class Doc Comment * {{classname}}Test Class Doc Comment
* *
* @category Class */ * @category Class
// * @description {{#description}}{{description}}{{/description}}{{^description}}{{classname}}{{/description}} * @description {{#description}}{{description}}{{/description}}{{^description}}{{classname}}{{/description}}
/**
* @package {{invokerPackage}} * @package {{invokerPackage}}
* @author Swagger Codegen team * @author Swagger Codegen team
* @link https://github.com/swagger-api/swagger-codegen * @link https://github.com/swagger-api/swagger-codegen

View File

@ -1,5 +1,5 @@
{{>licenseInfo}} {{>licenseInfo}}
#include "SWGHttpRequest.h" #include "{{prefix}}HttpRequest.h"
#include <QDateTime> #include <QDateTime>
#include <QUrl> #include <QUrl>
#include <QFileInfo> #include <QFileInfo>
@ -11,28 +11,28 @@
namespace {{this}} { namespace {{this}} {
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}
HttpRequestInput::HttpRequestInput() { {{prefix}}HttpRequestInput::{{prefix}}HttpRequestInput() {
initialize(); initialize();
} }
HttpRequestInput::HttpRequestInput(QString v_url_str, QString v_http_method) { {{prefix}}HttpRequestInput::{{prefix}}HttpRequestInput(QString v_url_str, QString v_http_method) {
initialize(); initialize();
url_str = v_url_str; url_str = v_url_str;
http_method = v_http_method; http_method = v_http_method;
} }
void HttpRequestInput::initialize() { void {{prefix}}HttpRequestInput::initialize() {
var_layout = NOT_SET; var_layout = NOT_SET;
url_str = ""; url_str = "";
http_method = "GET"; http_method = "GET";
} }
void HttpRequestInput::add_var(QString key, QString value) { void {{prefix}}HttpRequestInput::add_var(QString key, QString value) {
vars[key] = value; vars[key] = value;
} }
void HttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) { void {{prefix}}HttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) {
SWGHttpRequestInputFileElement file; {{prefix}}HttpRequestInputFileElement file;
file.variable_name = variable_name; file.variable_name = variable_name;
file.local_filename = local_filename; file.local_filename = local_filename;
file.request_filename = request_filename; file.request_filename = request_filename;
@ -41,7 +41,7 @@ void HttpRequestInput::add_file(QString variable_name, QString local_filename, Q
} }
HttpRequestWorker::HttpRequestWorker(QObject *parent) {{prefix}}HttpRequestWorker::{{prefix}}HttpRequestWorker(QObject *parent)
: QObject(parent), manager(nullptr) : QObject(parent), manager(nullptr)
{ {
qsrand(QDateTime::currentDateTime().toTime_t()); qsrand(QDateTime::currentDateTime().toTime_t());
@ -50,10 +50,10 @@ HttpRequestWorker::HttpRequestWorker(QObject *parent)
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_manager_finished(QNetworkReply*))); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_manager_finished(QNetworkReply*)));
} }
HttpRequestWorker::~HttpRequestWorker() { {{prefix}}HttpRequestWorker::~{{prefix}}HttpRequestWorker() {
} }
QString HttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) { QString {{prefix}}HttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) {
// result structure follows RFC 5987 // result structure follows RFC 5987
bool need_utf_encoding = false; bool need_utf_encoding = false;
QString result = ""; QString result = "";
@ -101,7 +101,7 @@ QString HttpRequestWorker::http_attribute_encode(QString attribute_name, QString
return QString("%1=\"%2\"; %1*=utf-8''%3").arg(attribute_name, result, result_utf8); return QString("%1=\"%2\"; %1*=utf-8''%3").arg(attribute_name, result, result_utf8);
} }
void HttpRequestWorker::execute(HttpRequestInput *input) { void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) {
// reset variables // reset variables
@ -181,7 +181,7 @@ void HttpRequestWorker::execute(HttpRequestInput *input) {
} }
// add files // add files
for (QList<SWGHttpRequestInputFileElement>::iterator file_info = input->files.begin(); file_info != input->files.end(); file_info++) { for (QList<{{prefix}}HttpRequestInputFileElement>::iterator file_info = input->files.begin(); file_info != input->files.end(); file_info++) {
QFileInfo fi(file_info->local_filename); QFileInfo fi(file_info->local_filename);
// ensure necessary variables are available // ensure necessary variables are available
@ -253,8 +253,8 @@ void HttpRequestWorker::execute(HttpRequestInput *input) {
// prepare connection // prepare connection
QNetworkRequest request = QNetworkRequest(QUrl(input->url_str)); QNetworkRequest request = QNetworkRequest(QUrl(input->url_str));
if (HttpRequestWorker::sslDefaultConfiguration != nullptr) { if ({{prefix}}HttpRequestWorker::sslDefaultConfiguration != nullptr) {
request.setSslConfiguration(*HttpRequestWorker::sslDefaultConfiguration); request.setSslConfiguration(*{{prefix}}HttpRequestWorker::sslDefaultConfiguration);
} }
request.setRawHeader("User-Agent", "Swagger-Client"); request.setRawHeader("User-Agent", "Swagger-Client");
foreach(QString key, input->headers.keys()) { foreach(QString key, input->headers.keys()) {
@ -301,7 +301,7 @@ void HttpRequestWorker::execute(HttpRequestInput *input) {
} }
void HttpRequestWorker::on_manager_finished(QNetworkReply *reply) { void {{prefix}}HttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
error_type = reply->error(); error_type = reply->error();
response = reply->readAll(); response = reply->readAll();
error_str = reply->errorString(); error_str = reply->errorString();
@ -310,7 +310,7 @@ void HttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
emit on_execution_finished(this); emit on_execution_finished(this);
} }
QSslConfiguration* HttpRequestWorker::sslDefaultConfiguration; QSslConfiguration* {{prefix}}HttpRequestWorker::sslDefaultConfiguration;
{{#cppNamespaceDeclarations}} {{#cppNamespaceDeclarations}}

View File

@ -5,8 +5,8 @@
* *
**/ **/
#ifndef HTTPREQUESTWORKER_H #ifndef {{prefix}}_HTTPREQUESTWORKER_H
#define HTTPREQUESTWORKER_H #define {{prefix}}_HTTPREQUESTWORKER_H
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@ -14,13 +14,15 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
enum HttpRequestVarLayout {NOT_SET, ADDRESS, URL_ENCODED, MULTIPART};
{{#cppNamespaceDeclarations}} {{#cppNamespaceDeclarations}}
namespace {{this}} { namespace {{this}} {
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}
class SWGHttpRequestInputFileElement { enum {{prefix}}HttpRequestVarLayout {NOT_SET, ADDRESS, URL_ENCODED, MULTIPART};
class {{prefix}}HttpRequestInputFileElement {
public: public:
QString variable_name; QString variable_name;
@ -31,19 +33,19 @@ public:
}; };
class HttpRequestInput { class {{prefix}}HttpRequestInput {
public: public:
QString url_str; QString url_str;
QString http_method; QString http_method;
HttpRequestVarLayout var_layout; {{prefix}}HttpRequestVarLayout var_layout;
QMap<QString, QString> vars; QMap<QString, QString> vars;
QMap<QString, QString> headers; QMap<QString, QString> headers;
QList<SWGHttpRequestInputFileElement> files; QList<{{prefix}}HttpRequestInputFileElement> files;
QByteArray request_body; QByteArray request_body;
HttpRequestInput(); {{prefix}}HttpRequestInput();
HttpRequestInput(QString v_url_str, QString v_http_method); {{prefix}}HttpRequestInput(QString v_url_str, QString v_http_method);
void initialize(); void initialize();
void add_var(QString key, QString value); void add_var(QString key, QString value);
void add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type); void add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type);
@ -51,7 +53,7 @@ public:
}; };
class HttpRequestWorker : public QObject { class {{prefix}}HttpRequestWorker : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -59,15 +61,15 @@ public:
QNetworkReply::NetworkError error_type; QNetworkReply::NetworkError error_type;
QString error_str; QString error_str;
explicit HttpRequestWorker(QObject *parent = 0); explicit {{prefix}}HttpRequestWorker(QObject *parent = 0);
virtual ~HttpRequestWorker(); virtual ~{{prefix}}HttpRequestWorker();
QString http_attribute_encode(QString attribute_name, QString input); QString http_attribute_encode(QString attribute_name, QString input);
void execute(HttpRequestInput *input); void execute({{prefix}}HttpRequestInput *input);
static QSslConfiguration* sslDefaultConfiguration; static QSslConfiguration* sslDefaultConfiguration;
signals: signals:
void on_execution_finished(HttpRequestWorker *worker); void on_execution_finished({{prefix}}HttpRequestWorker *worker);
private: private:
QNetworkAccessManager *manager; QNetworkAccessManager *manager;
@ -81,4 +83,4 @@ private slots:
} }
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}
#endif // HTTPREQUESTWORKER_H #endif // {{prefix}}_HTTPREQUESTWORKER_H

View File

@ -22,7 +22,7 @@ namespace {{this}} {
{{#operations}} {{#operations}}
{{#operation}} {{#operation}}
void void
{{classname}}::{{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{classname}}::{{nickname}}({{#allParams}}{{{dataType}}}{{#isBodyParam}}&{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
QString fullPath; QString fullPath;
fullPath.append(this->host).append(this->basePath).append("{{{path}}}"); fullPath.append(this->host).append(this->basePath).append("{{{path}}}");
@ -87,8 +87,8 @@ void
{{/collectionFormat}} {{/collectionFormat}}
{{/queryParams}} {{/queryParams}}
HttpRequestWorker *worker = new HttpRequestWorker(); {{prefix}}HttpRequestWorker *worker = new {{prefix}}HttpRequestWorker();
HttpRequestInput input(fullPath, "{{httpMethod}}"); {{prefix}}HttpRequestInput input(fullPath, "{{httpMethod}}");
{{#formParams}} {{#formParams}}
if ({{paramName}} != nullptr) { if ({{paramName}} != nullptr) {
@ -98,16 +98,17 @@ void
{{#bodyParams}} {{#bodyParams}}
{{#isContainer}} {{#isContainer}}
QJsonArray* {{paramName}}Array = new QJsonArray(); auto {{paramName}}_jobj = new QJsonObject();
toJsonArray((QList<void*>*){{paramName}}, {{paramName}}Array, QString("body"), QString("SWGUser*")); toJsonArray((QList<void*>*){{paramName}}, {{paramName}}_jobj, QString("body"), QString("{{prefix}}User*"));
QJsonDocument doc(*{{paramName}}Array); QJsonDocument doc(*{{paramName}}_jobj);
QByteArray bytes = doc.toJson(); QByteArray bytes = doc.toJson();
input.request_body.append(bytes); input.request_body.append(bytes);
{{/isContainer}} {{/isContainer}}
{{^isContainer}} {{^isContainer}}{{#isString}}
QString output = {{paramName}}.asJson(); QString output(*{{paramName}});{{/isString}}{{#isByteArray}}QString output(*{{paramName}});{{/isByteArray}}{{^isString}}{{^isByteArray}}
QString output = {{paramName}}.asJson();{{/isByteArray}}{{/isString}}
input.request_body.append(output); input.request_body.append(output);
{{/isContainer}}{{/bodyParams}} {{/isContainer}}{{/bodyParams}}
@ -122,7 +123,7 @@ void
} }
connect(worker, connect(worker,
&HttpRequestWorker::on_execution_finished, &{{prefix}}HttpRequestWorker::on_execution_finished,
this, this,
&{{classname}}::{{nickname}}Callback); &{{classname}}::{{nickname}}Callback);
@ -130,7 +131,7 @@ void
} }
void void
{{classname}}::{{nickname}}Callback(HttpRequestWorker * worker) { {{classname}}::{{nickname}}Callback({{prefix}}HttpRequestWorker * worker) {
QString msg; QString msg;
QString error_str = worker->error_str; QString error_str = worker->error_str;
QNetworkReply::NetworkError error_type = worker->error_type; QNetworkReply::NetworkError error_type = worker->error_type;
@ -159,10 +160,10 @@ void
} }
{{/isListContainer}} {{/isListContainer}}
{{^isListContainer}} {{^isListContainer}}{{^isMapContainer}}
{{#returnTypeIsPrimitive}} {{#returnTypeIsPrimitive}}
{{{returnType}}} output; // TODO add primitive output support {{{returnType}}} output; // TODO add primitive output support
{{/returnTypeIsPrimitive}} {{/returnTypeIsPrimitive}}{{/isMapContainer}}
{{#isMapContainer}} {{#isMapContainer}}
{{{returnType}}} output = {{{defaultResponse}}}; {{{returnType}}} output = {{{defaultResponse}}};
QString json(worker->response); QString json(worker->response);

View File

@ -1,6 +1,6 @@
{{>licenseInfo}} {{>licenseInfo}}
#ifndef _SWG_{{classname}}_H_ #ifndef _{{prefix}}_{{classname}}_H_
#define _SWG_{{classname}}_H_ #define _{{prefix}}_{{classname}}_H_
#include "{{prefix}}HttpRequest.h" #include "{{prefix}}HttpRequest.h"
@ -25,17 +25,17 @@ public:
QString basePath; QString basePath;
QMap<QString, QString> defaultHeaders; QMap<QString, QString> defaultHeaders;
{{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{{dataType}}}{{#isBodyParam}}&{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}{{/operations}} {{/operation}}{{/operations}}
private: private:
{{#operations}}{{#operation}}void {{nickname}}Callback (HttpRequestWorker * worker); {{#operations}}{{#operation}}void {{nickname}}Callback ({{prefix}}HttpRequestWorker * worker);
{{/operation}}{{/operations}} {{/operation}}{{/operations}}
signals: signals:
{{#operations}}{{#operation}}void {{nickname}}Signal({{#returnType}}{{{returnType}}} summary{{/returnType}}); {{#operations}}{{#operation}}void {{nickname}}Signal({{#returnType}}{{{returnType}}} summary{{/returnType}});
{{/operation}}{{/operations}} {{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{nickname}}SignalE({{#returnType}}{{{returnType}}} summary, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str); {{#operations}}{{#operation}}void {{nickname}}SignalE({{#returnType}}{{{returnType}}} summary, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str);
{{/operation}}{{/operations}} {{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{nickname}}SignalEFull(HttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); {{#operations}}{{#operation}}void {{nickname}}SignalEFull({{prefix}}HttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str);
{{/operation}}{{/operations}} {{/operation}}{{/operations}}
}; };

View File

@ -1,7 +1,7 @@
{{>licenseInfo}} {{>licenseInfo}}
#include "SWGHelpers.h" #include "{{prefix}}Helpers.h"
#include "SWGModelFactory.h" #include "{{prefix}}ModelFactory.h"
#include "SWGObject.h" #include "{{prefix}}Object.h"
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonValue> #include <QJsonValue>
@ -40,17 +40,16 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
} }
else if (QStringLiteral("QString").compare(type) == 0) { else if (QStringLiteral("QString").compare(type) == 0) {
QString **val = static_cast<QString**>(value); QString **val = static_cast<QString**>(value);
if(val != nullptr) { if(val != nullptr) {
if(!obj.isNull()) { if(!obj.isNull()) {
// create a new value and return // create a new value and return
delete *val; if(*val != nullptr) delete *val;
*val = new QString(obj.toString()); *val = new QString(obj.toString());
return; return;
} }
else { else {
// set target to nullptr // set target to nullptr
delete *val; if(*val != nullptr) delete *val;
*val = nullptr; *val = nullptr;
} }
} }
@ -64,13 +63,13 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
if(val != nullptr) { if(val != nullptr) {
if(!obj.isNull()) { if(!obj.isNull()) {
// create a new value and return // create a new value and return
delete *val; if(*val != nullptr) delete *val;
*val = new QDateTime(QDateTime::fromString(obj.toString(), Qt::ISODate)); *val = new QDateTime(QDateTime::fromString(obj.toString(), Qt::ISODate));
return; return;
} }
else { else {
// set target to nullptr // set target to nullptr
delete *val; if(*val != nullptr) delete *val;
*val = nullptr; *val = nullptr;
} }
} }
@ -84,13 +83,13 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
if(val != nullptr) { if(val != nullptr) {
if(!obj.isNull()) { if(!obj.isNull()) {
// create a new value and return // create a new value and return
delete *val; if(*val != nullptr) delete *val;
*val = new QDate(QDate::fromString(obj.toString(), Qt::ISODate)); *val = new QDate(QDate::fromString(obj.toString(), Qt::ISODate));
return; return;
} }
else { else {
// set target to nullptr // set target to nullptr
delete *val; if(*val != nullptr) delete *val;
*val = nullptr; *val = nullptr;
} }
} }
@ -104,14 +103,14 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
if(val != nullptr) { if(val != nullptr) {
if(!obj.isNull()) { if(!obj.isNull()) {
// create a new value and return // create a new value and return
delete *val; if(*val != nullptr) delete *val;
*val = new QByteArray(QByteArray::fromBase64(QByteArray::fromStdString(obj.toString().toStdString()))); *val = new QByteArray(QByteArray::fromBase64(QByteArray::fromStdString(obj.toString().toStdString())));
return; return;
} }
else { else {
// set target to nullptr // set target to nullptr
delete *val; if(*val != nullptr) delete *val;
*val = nullptr; *val = nullptr;
} }
} }
@ -119,127 +118,256 @@ setValue(void* value, QJsonValue obj, QString type, QString complexType) {
qDebug() << "Can't set value because the target pointer is nullptr"; qDebug() << "Can't set value because the target pointer is nullptr";
} }
} }
else if(type.startsWith("SWG") && obj.isObject()) { else if(type.startsWith("{{prefix}}") && obj.isObject()) {
// complex type // complex type
QJsonObject jsonObj = obj.toObject(); QJsonObject jsonObj = obj.toObject();
SWGObject * so = (SWGObject*)::{{cppNamespace}}::create(type); {{prefix}}Object * so = ({{prefix}}Object*)::{{cppNamespace}}::create(complexType);
if(so != nullptr) { if(so != nullptr) {
so->fromJsonObject(jsonObj); so->fromJsonObject(jsonObj);
SWGObject **val = static_cast<SWGObject**>(value); {{prefix}}Object **val = static_cast<{{prefix}}Object**>(value);
delete *val; if(*val != nullptr) delete *val;
*val = so; *val = so;
} }
} }
else if(type.startsWith("QList") && QString("").compare(complexType) != 0 && obj.isArray()) { else if(type.startsWith("QList") && QString("").compare(complexType) != 0 && obj.isArray()) {
// list of values // list of values
if(complexType.startsWith("SWG")) { if(complexType.startsWith("{{prefix}}")) {
QList<SWGObject*>* output = new QList<SWGObject*>(); auto output = reinterpret_cast<QList<{{prefix}}Object *> **> (value);
for (auto item : **output) {
if(item != nullptr) delete item;
}
(*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr) { for (const QJsonValue & jval : arr) {
// it's an object // it's an object
SWGObject * val = (SWGObject*)create(complexType); {{prefix}}Object * val = ({{prefix}}Object*)::{{cppNamespace}}::create(complexType);
QJsonObject t = jval.toObject(); QJsonObject t = jval.toObject();
val->fromJsonObject(t); val->fromJsonObject(t);
output->append(val); (*output)->append(val);
} }
QList<SWGObject*> **val = static_cast<QList<SWGObject*>**>(value);
for (auto item : **val) {
delete item;
}
delete *val;
*val = output;
} }
else if(QStringLiteral("qint32").compare(complexType) == 0) { else if(QStringLiteral("qint32").compare(complexType) == 0) {
QList<qint32> **output = reinterpret_cast<QList<qint32> **> (value); auto output = reinterpret_cast<QList<qint32> **> (value);
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
qint32 val; qint32 val;
setValue(&val, jval, QStringLiteral("qint32"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("qint32"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("qint64").compare(complexType) == 0) { else if(QStringLiteral("qint64").compare(complexType) == 0) {
QList<qint64> **output = reinterpret_cast<QList<qint64> **> (value); auto output = reinterpret_cast<QList<qint64> **> (value);
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
qint64 val; qint64 val;
setValue(&val, jval, QStringLiteral("qint64"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("qint64"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("bool").compare(complexType) == 0) { else if(QStringLiteral("bool").compare(complexType) == 0) {
QList<bool> **output = reinterpret_cast<QList<bool> **> (value); auto output = reinterpret_cast<QList<bool> **> (value);
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
bool val; bool val;
setValue(&val, jval, QStringLiteral("bool"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("bool"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("float").compare(complexType) == 0) { else if(QStringLiteral("float").compare(complexType) == 0) {
QList<float> **output = reinterpret_cast<QList<float> **> (value); auto output = reinterpret_cast<QList<float> **> (value);
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
float val; float val;
setValue(&val, jval, QStringLiteral("float"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("float"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("double").compare(complexType) == 0) { else if(QStringLiteral("double").compare(complexType) == 0) {
QList<double> **output = reinterpret_cast<QList<double> **> (value); auto output = reinterpret_cast<QList<double> **> (value);
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
double val; double val;
setValue(&val, jval, QStringLiteral("double"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("double"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("QString").compare(complexType) == 0) { else if(QStringLiteral("QString").compare(complexType) == 0) {
QList<QString*> **output = reinterpret_cast<QList<QString*> **> (value); auto output = reinterpret_cast<QList<QString*> **> (value);
for (auto item : **output) { for (auto item : **output) {
delete item; if(item != nullptr) delete item;
} }
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
QString * val = new QString(); QString * val = new QString();
setValue(&val, jval, QStringLiteral("QString"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("QString"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("QDate").compare(complexType) == 0) { else if(QStringLiteral("QDate").compare(complexType) == 0) {
QList<QDate*> **output = reinterpret_cast<QList<QDate*> **> (value); auto output = reinterpret_cast<QList<QDate*> **> (value);
for (auto item : **output) { for (auto item : **output) {
delete item; if(item != nullptr) delete item;
} }
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
QDate * val = new QDate(); QDate * val = new QDate();
setValue(&val, jval, QStringLiteral("QDate"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("QDate"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
else if(QStringLiteral("QDateTime").compare(complexType) == 0) { else if(QStringLiteral("QDateTime").compare(complexType) == 0) {
QList<QDateTime*> **output = reinterpret_cast<QList<QDateTime*> **> (value); auto output = reinterpret_cast<QList<QDateTime*> **> (value);
for (auto item : **output) { for (auto item : **output) {
delete item; if(item != nullptr) delete item;
} }
(*output)->clear(); (*output)->clear();
QJsonArray arr = obj.toArray(); QJsonArray arr = obj.toArray();
for (const QJsonValue & jval : arr){ for (const QJsonValue & jval : arr){
QDateTime * val = new QDateTime(); QDateTime * val = new QDateTime();
setValue(&val, jval, QStringLiteral("QDateTime"), QStringLiteral("")); ::{{cppNamespace}}::setValue(&val, jval, QStringLiteral("QDateTime"), QStringLiteral(""));
(*output)->push_back(val); (*output)->push_back(val);
} }
} }
} }
else if(type.startsWith("QMap") && QString("").compare(complexType) != 0 && obj.isObject()) {
// list of values
if(complexType.startsWith("{{prefix}}")) {
auto output = reinterpret_cast<QMap<QString, {{prefix}}Object*> **> (value);
for (auto item : **output) {
if(item != nullptr) delete item;
}
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
auto val = ({{prefix}}Object*)::{{cppNamespace}}::create(complexType);
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, complexType, complexType);
(*output)->insert(itemkey, val);
}
}
}
else if(QStringLiteral("qint32").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, qint32> **> (value);
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
qint32 val;
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("qint32"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("qint64").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, qint64> **> (value);
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
qint64 val;
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("qint64"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("bool").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, bool> **> (value);
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
bool val;
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("bool"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("float").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, float> **> (value);
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
float val;
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("float"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("double").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, double> **> (value);
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
double val;
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("double"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("QString").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, QString*> **> (value);
for (auto item : **output) {
if(item != nullptr) delete item;
}
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
QString * val = new QString();
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("QString"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("QDate").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, QDate*> **> (value);
for (auto item : **output) {
if(item != nullptr) delete item;
}
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
QDate * val = new QDate();
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("QDate"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
else if(QStringLiteral("QDateTime").compare(complexType) == 0) {
auto output = reinterpret_cast<QMap<QString, QDateTime*> **> (value);
for (auto item : **output) {
if(item != nullptr) delete item;
}
(*output)->clear();
auto varmap = obj.toObject().toVariantMap();
if(varmap.count() > 0){
for(auto itemkey : varmap.keys() ){
QDateTime * val = new QDateTime();
auto jsonval = QJsonValue::fromVariant(varmap.value(itemkey));
::{{cppNamespace}}::setValue(&val, jsonval, QStringLiteral("QDateTime"), QStringLiteral(""));
(*output)->insert( itemkey, val);
}
}
}
}
} }
void void
@ -247,13 +375,13 @@ toJsonValue(QString name, void* value, QJsonObject* output, QString type) {
if(value == nullptr) { if(value == nullptr) {
return; return;
} }
if(type.startsWith("SWG")) { if(type.startsWith("{{prefix}}")) {
SWGObject *swgObject = reinterpret_cast<SWGObject *>(value); {{prefix}}Object *{{prefix}}object = reinterpret_cast<{{prefix}}Object *>(value);
if(swgObject != nullptr) { if({{prefix}}object != nullptr) {
QJsonObject* o = (*swgObject).asJsonObject(); QJsonObject* o = (*{{prefix}}object).asJsonObject();
if(name != nullptr) { if(name != nullptr) {
output->insert(name, *o); output->insert(name, *o);
delete o; if(o != nullptr) delete o;
} }
else { else {
output->empty(); output->empty();
@ -302,54 +430,133 @@ toJsonValue(QString name, void* value, QJsonObject* output, QString type) {
} }
void void
toJsonArray(QList<void*>* value, QJsonArray* output, QString innerName, QString innerType) { toJsonArray(QList<void*>* value, QJsonObject* output, QString innerName, QString innerType) {
if(innerType.startsWith("SWG")){ if((value == nullptr) || (output == nullptr)) {
return;
}
QJsonArray outputarray;
if(innerType.startsWith("{{prefix}}")){
for(void* obj : *value) { for(void* obj : *value) {
SWGObject *swgObject = reinterpret_cast<SWGObject *>(obj); {{prefix}}Object *{{prefix}}object = reinterpret_cast<{{prefix}}Object *>(obj);
if(swgObject != nullptr) { if({{prefix}}object != nullptr) {
output->append(*(swgObject->asJsonObject())); outputarray.append(*({{prefix}}object->asJsonObject()));
} }
} }
} }
else if(QStringLiteral("QString").compare(innerType) == 0) { else if(QStringLiteral("QString").compare(innerType) == 0) {
for(QString* obj : *(reinterpret_cast<QList<QString*>*>(value))){ for(QString* obj : *(reinterpret_cast<QList<QString*>*>(value))){
output->append(QJsonValue(*obj)); outputarray.append(QJsonValue(*obj));
} }
} }
else if(QStringLiteral("QDate").compare(innerType) == 0) { else if(QStringLiteral("QDate").compare(innerType) == 0) {
for(QDate* obj : *(reinterpret_cast<QList<QDate*>*>(value))){ for(QDate* obj : *(reinterpret_cast<QList<QDate*>*>(value))){
output->append(QJsonValue(obj->toString(Qt::ISODate))); outputarray.append(QJsonValue(obj->toString(Qt::ISODate)));
} }
} }
else if(QStringLiteral("QDateTime").compare(innerType) == 0) { else if(QStringLiteral("QDateTime").compare(innerType) == 0) {
for(QDateTime* obj : *(reinterpret_cast<QList<QDateTime*>*>(value))){ for(QDateTime* obj : *(reinterpret_cast<QList<QDateTime*>*>(value))){
output->append(QJsonValue(obj->toString(Qt::ISODate))); } outputarray.append(QJsonValue(obj->toString(Qt::ISODate))); }
} }
else if(QStringLiteral("QByteArray").compare(innerType) == 0) { else if(QStringLiteral("QByteArray").compare(innerType) == 0) {
for(QByteArray* obj : *(reinterpret_cast<QList<QByteArray*>*>(value))){ for(QByteArray* obj : *(reinterpret_cast<QList<QByteArray*>*>(value))){
output->append(QJsonValue(QString(obj->toBase64()))); outputarray.append(QJsonValue(QString(obj->toBase64())));
} }
} }
else if(QStringLiteral("qint32").compare(innerType) == 0) { else if(QStringLiteral("qint32").compare(innerType) == 0) {
for(qint32 obj : *(reinterpret_cast<QList<qint32>*>(value))) for(qint32 obj : *(reinterpret_cast<QList<qint32>*>(value)))
output->append(QJsonValue(obj)); outputarray.append(QJsonValue(obj));
} }
else if(QStringLiteral("qint64").compare(innerType) == 0) { else if(QStringLiteral("qint64").compare(innerType) == 0) {
for(qint64 obj : *(reinterpret_cast<QList<qint64>*>(value))) for(qint64 obj : *(reinterpret_cast<QList<qint64>*>(value)))
output->append(QJsonValue(obj)); outputarray.append(QJsonValue(obj));
} }
else if(QStringLiteral("bool").compare(innerType) == 0) { else if(QStringLiteral("bool").compare(innerType) == 0) {
for(bool obj : *(reinterpret_cast<QList<bool>*>(value))) for(bool obj : *(reinterpret_cast<QList<bool>*>(value)))
output->append(QJsonValue(obj)); outputarray.append(QJsonValue(obj));
} }
else if(QStringLiteral("float").compare(innerType) == 0) { else if(QStringLiteral("float").compare(innerType) == 0) {
for(float obj : *(reinterpret_cast<QList<float>*>(value))) for(float obj : *(reinterpret_cast<QList<float>*>(value)))
output->append(QJsonValue(obj)); outputarray.append(QJsonValue(obj));
} }
else if(QStringLiteral("double").compare(innerType) == 0) { else if(QStringLiteral("double").compare(innerType) == 0) {
for(double obj : *(reinterpret_cast<QList<double>*>(value))) for(double obj : *(reinterpret_cast<QList<double>*>(value)))
output->append(QJsonValue(obj)); outputarray.append(QJsonValue(obj));
} }
output->insert(innerName, outputarray);
}
void
toJsonMap(QMap<QString, void*>* value, QJsonObject* output, QString innerName, QString innerType) {
if((value == nullptr) || (output == nullptr)) {
return;
}
QJsonObject mapobj;
if(innerType.startsWith("{{prefix}}")){
auto items = reinterpret_cast< QMap<QString, {{prefix}}Object*> *>(value);
for(auto itemkey: items->keys()) {
::{{cppNamespace}}::toJsonValue(itemkey, items->value(itemkey), &mapobj, innerType);
}
}
else if(QStringLiteral("QString").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, QString*> *>(value);
for(auto itemkey: items->keys()) {
::{{cppNamespace}}::toJsonValue(itemkey, items->value(itemkey), &mapobj, innerType);
}
}
else if(QStringLiteral("QDate").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, QDate*> *>(value);
for(auto itemkey: items->keys()) {
::{{cppNamespace}}::toJsonValue(itemkey, items->value(itemkey), &mapobj, innerType);
}
}
else if(QStringLiteral("QDateTime").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, QDateTime*> *>(value);
for(auto itemkey: items->keys()) {
::{{cppNamespace}}::toJsonValue(itemkey, items->value(itemkey), &mapobj, innerType);
}
}
else if(QStringLiteral("QByteArray").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, QByteArray*> *>(value);
for(auto itemkey: items->keys()) {
::{{cppNamespace}}::toJsonValue(itemkey, items->value(itemkey), &mapobj, innerType);
}
}
else if(QStringLiteral("qint32").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, qint32> *>(value);
for(auto itemkey: items->keys()) {
auto val = items->value(itemkey);
::{{cppNamespace}}::toJsonValue(itemkey, &val, &mapobj, innerType);
}
}
else if(QStringLiteral("qint64").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, qint64> *>(value);
for(auto itemkey: items->keys()) {
auto val = items->value(itemkey);
::{{cppNamespace}}::toJsonValue(itemkey, &val, &mapobj, innerType);
}
}
else if(QStringLiteral("bool").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, bool> *>(value);
for(auto itemkey: items->keys()) {
auto val = items->value(itemkey);
::{{cppNamespace}}::toJsonValue(itemkey, &val, &mapobj, innerType);
}
}
else if(QStringLiteral("float").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, float> *>(value);
for(auto itemkey: items->keys()) {
auto val = items->value(itemkey);
::{{cppNamespace}}::toJsonValue(itemkey, &val, &mapobj, innerType);
}
}
else if(QStringLiteral("double").compare(innerType) == 0) {
auto items = reinterpret_cast< QMap<QString, double> *>(value);
for(auto itemkey: items->keys() ) {
auto val = items->value(itemkey);
::{{cppNamespace}}::toJsonValue(itemkey, &val, &mapobj, innerType);
}
}
output->insert(innerName, mapobj);
} }
QString QString

View File

@ -1,16 +1,19 @@
{{>licenseInfo}} {{>licenseInfo}}
#ifndef SWGHELPERS_H #ifndef {{prefix}}_HELPERS_H
#define SWGHELPERS_H #define {{prefix}}_HELPERS_H
#include <QJsonValue> #include <QJsonValue>
#include <QList>
#include <QMap>
{{#cppNamespaceDeclarations}} {{#cppNamespaceDeclarations}}
namespace {{this}} { namespace {{this}} {
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}
void setValue(void* value, QJsonValue obj, QString type, QString complexType); void setValue(void* value, QJsonValue obj, QString type, QString complexType);
void toJsonArray(QList<void*>* value, QJsonArray* output, QString innerName, QString innerType); void toJsonArray(QList<void*>* value, QJsonObject* output, QString innerName, QString innerType);
void toJsonValue(QString name, void* value, QJsonObject* output, QString type); void toJsonValue(QString name, void* value, QJsonObject* output, QString type);
void toJsonMap(QMap<QString, void*>* value, QJsonObject* output, QString innerName, QString innerType);
bool isCompatibleJsonValue(QString type); bool isCompatibleJsonValue(QString type);
QString stringValue(QString* value); QString stringValue(QString* value);
QString stringValue(qint32 value); QString stringValue(qint32 value);
@ -21,4 +24,4 @@ namespace {{this}} {
} }
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}
#endif // SWGHELPERS_H #endif // {{prefix}}_HELPERS_H

View File

@ -2,7 +2,7 @@
{{#models}}{{#model}} {{#models}}{{#model}}
#include "{{classname}}.h" #include "{{classname}}.h"
#include "SWGHelpers.h" #include "{{prefix}}Helpers.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonArray> #include <QJsonArray>
@ -30,6 +30,7 @@ void
{{classname}}::init() { {{classname}}::init() {
{{#vars}} {{#vars}}
{{name}} = {{{defaultValue}}}; {{name}} = {{{defaultValue}}};
m_{{name}}_isSet = false;
{{/vars}} {{/vars}}
} }
@ -37,12 +38,15 @@ void
{{classname}}::cleanup() { {{classname}}::cleanup() {
{{#vars}} {{#vars}}
{{#complexType}} {{#complexType}}
if({{name}} != nullptr) { if({{name}} != nullptr) { {{#isContainer}}
{{#isContainer}}{{#isListContainer}}QList<{{complexType}}*>* arr = {{name}};{{/isListContainer}}{{#isMapContainer}}QMap<QString, {{complexType}}*>* arr = {{name}};{{/isMapContainer}} auto arr = {{name}};
foreach({{complexType}}* o, *arr) { for(auto o: *arr) { {{#items.isContainer}}
for(auto o1: *o) {
delete o1;
}{{/items.isContainer}}
delete o; delete o;
} }{{/isContainer}}
{{/isContainer}}delete {{name}}; delete {{name}};
}{{/complexType}} }{{/complexType}}
{{/vars}} {{/vars}}
} }
@ -59,33 +63,30 @@ void
void void
{{classname}}::fromJsonObject(QJsonObject &pJson) { {{classname}}::fromJsonObject(QJsonObject &pJson) {
{{#vars}} {{#vars}}
{{^isContainer}} {{^isContainer}}::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{complexType}}");{{/isContainer}}
::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{complexType}}"); {{#isContainer}}{{^items.isContainer}}::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{items.baseType}}");{{/items.isContainer}}{{#items.isContainer}}{{#isListContainer}}
{{/isContainer}} if(pJson["{{baseName}}"].isArray()){
{{#isListContainer}} auto arr = pJson["{{baseName}}"].toArray();
{{#complexType}} for (const QJsonValue & jval : arr) {
::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{complexType}}"); {{#items.isListContainer}}auto {{name}}_item = new QList<{{items.items.baseType}}{{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isListContainer}}
{{/complexType}} {{#items.isMapContainer}}auto {{name}}_item = new QMap<QString, {{items.items.baseType}} {{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isMapContainer}}
{{^complexType}} auto jsonval = jval.toObject();
::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{items.baseType}}"); ::{{cppNamespace}}::setValue({{name}}_item, jsonval, "{{items.baseType}}", "{{items.items.baseType}}");
{{/complexType}} {{name}}->push_back({{name}}_item);
{{/isListContainer}} }
{{#isMapContainer}} }{{/isListContainer}}{{#isMapContainer}}
if(pJson["{{baseName}}"].isObject()){ if(pJson["{{baseName}}"].isObject()){
auto varmap = pJson["{{baseName}}"].toObject().toVariantMap(); auto varmap = pJson["{{baseName}}"].toObject().toVariantMap();
if(varmap.count() > 0){ if(varmap.count() > 0){
for(auto val : varmap.keys()){ for(auto val : varmap.keys()){
{ {{#items.isListContainer}}auto {{name}}_item = new QList<{{items.items.baseType}}{{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isListContainer}}
{{items.baseType}} *{{name}}_item = new {{items.baseType}}(); {{#items.isMapContainer}}auto {{name}}_item = new QMap<QString, {{items.items.baseType}}{{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isMapContainer}}
auto jsonval = QJsonValue::fromVariant(varmap[val]); auto jsonval = QJsonValue::fromVariant(varmap.value(val));
::{{cppNamespace}}::setValue(&{{name}}_item, jsonval, "{{items.baseType}}", "{{items.baseType}}"); ::{{cppNamespace}}::setValue((QMap<QString, void *>*)&{{name}}_item, jsonval, "{{items.baseType}}", "{{items.items.baseType}}");
{{name}}->insert({{name}}->end(), val, {{name}}_item); {{name}}->insert({{name}}->end(), val, {{name}}_item);
} }
} }
} }{{/isMapContainer}}{{/items.isContainer}}{{/isContainer}}
}
{{/isMapContainer}}
{{/vars}} {{/vars}}
} }
@ -103,51 +104,47 @@ QJsonObject*
{{classname}}::asJsonObject() { {{classname}}::asJsonObject() {
QJsonObject* obj = new QJsonObject(); QJsonObject* obj = new QJsonObject();
{{#vars}} {{#vars}}
{{#complexType}} {{^isContainer}}{{#complexType}}{{^isString}}{{^isDate}}{{^isDateTime}}{{^isByteArray}}
{{^isContainer}} if(({{name}} != nullptr) && ({{name}}->isSet())){
{{#complexType}}
toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}")); toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
{{/complexType}} }{{/isByteArray}}{{/isDateTime}}{{/isDate}}{{/isString}}{{#isString}}
{{^complexType}} if({{name}} != nullptr && *{{name}} != QString("")){
if({{name}} != nullptr && *{{name}} != nullptr) { toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
obj->insert("{{name}}", QJsonValue(*{{name}})); }{{/isString}}{{/complexType}}{{#isPrimitiveType}}{{^isDateTime}}{{^isDate}}{{^isByteArray}}
} if(m_{{name}}_isSet){
{{/complexType}}
{{/isContainer}}
{{#isListContainer}}
QJsonArray {{name}}JsonArray;
toJsonArray((QList<void*>*){{name}}, &{{name}}JsonArray, "{{name}}", "{{complexType}}");
obj->insert("{{baseName}}", {{name}}JsonArray);
{{/isListContainer}}
{{#isMapContainer}}
QJsonArray {{name}}JsonArray;
for(auto keyval : {{name}}->keys()){
QJsonObject {{name}}_jobj;
toJsonValue(keyval, ((*{{name}})[keyval]), &{{name}}_jobj, "{{complexType}}");
{{name}}JsonArray.append({{name}}_jobj);
}
obj->insert("{{baseName}}", {{name}}JsonArray);
{{/isMapContainer}}
{{/complexType}}
{{^complexType}}
{{^isContainer}}
obj->insert("{{baseName}}", QJsonValue({{name}})); obj->insert("{{baseName}}", QJsonValue({{name}}));
{{/isContainer}} }{{/isByteArray}}{{/isDate}}{{/isDateTime}}{{/isPrimitiveType}}{{#isDate}}
{{#isListContainer}} if({{name}} != nullptr) {
QJsonArray {{name}}JsonArray; toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
toJsonArray((QList<void*>*){{name}}, &{{name}}JsonArray, "{{name}}", "{{items.baseType}}"); }{{/isDate}}{{#isByteArray}}
obj->insert("{{baseName}}", {{name}}JsonArray); if({{name}} != nullptr) {
{{/isListContainer}} obj->insert("{{name}}", QJsonValue(*{{name}}));
{{#isMapContainer}} }{{/isByteArray}}{{#isDateTime}}
QJsonArray {{name}}JsonArray; if({{name}} != nullptr) {
for(auto keyval : {{name}}->keys()){ toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
QJsonObject {{name}}_jobj; }{{/isDateTime}}{{/isContainer}}{{#isContainer}}{{#isListContainer}}
toJsonValue(keyval, ((*{{name}})[keyval]), &{{name}}_jobj, "{{items.baseType}}"); if({{name}}->size() > 0){
{{name}}JsonArray.append(portsobj); {{^items.isContainer}}toJsonArray((QList<void*>*){{name}}, obj, "{{baseName}}", "{{complexType}}");{{/items.isContainer}}{{#items.isContainer}}
QJsonArray jarray;
for(auto items : *{{name}}){
QJsonObject jobj;
{{#items.isListContainer}}toJsonArray((QList<void*>*)items, &jobj, "{{baseName}}", "{{items.items.baseType}}");{{/items.isListContainer}}
{{#items.isMapContainer}}toJsonMap((QMap<QString, void*>*)items, &jobj, "{{baseName}}", "{{items.items.baseType}}");{{/items.isMapContainer}}
jarray.append(jobj.value("{{baseName}}"));
} }
obj->insert("{{baseName}}", {{name}}JsonArray); obj->insert("{{baseName}}", jarray);{{/items.isContainer}}
{{/isMapContainer}} }{{/isListContainer}}{{#isMapContainer}}
{{/complexType}} if({{name}}->size() > 0){
{{^items.isContainer}}toJsonMap((QMap<QString, void*>*) {{name}}, obj, "{{baseName}}", "{{complexType}}");{{/items.isContainer}}{{#items.isContainer}}
QJsonObject mapobj;
for(auto itemkey : {{name}}->keys()){
QJsonObject jobj;
{{#items.isListContainer}}toJsonArray((QList<void*>*){{name}}->value(itemkey), &jobj, itemkey, "{{items.items.baseType}}");{{/items.isListContainer}}
{{#items.isMapContainer}}toJsonMap((QMap<QString, void*>*){{name}}->value(itemkey), &jobj, itemkey, "{{items.items.baseType}}");{{/items.isMapContainer}}
mapobj.insert(itemkey, jobj);
}
obj->insert("{{baseName}}", mapobj);{{/items.isContainer}}
}{{/isMapContainer}}{{/isContainer}}
{{/vars}} {{/vars}}
return obj; return obj;
@ -161,10 +158,21 @@ QJsonObject*
void void
{{classname}}::{{setter}}({{{datatype}}} {{name}}) { {{classname}}::{{setter}}({{{datatype}}} {{name}}) {
this->{{name}} = {{name}}; this->{{name}} = {{name}};
this->m_{{name}}_isSet = true;
} }
{{/vars}} {{/vars}}
bool
{{classname}}::isSet(){
bool isObjectUpdated = false;
do{
{{#vars}}
{{#isPrimitiveType}}if(m_{{name}}_isSet){ isObjectUpdated = true; break;}{{/isPrimitiveType}}{{#isContainer}}if({{name}}->size() > 0){ isObjectUpdated = true; break;}{{/isContainer}}{{^isContainer}}{{#complexType}}{{^isString}}{{^isDateTime}}if({{name}} != nullptr && {{name}}->isSet()){ isObjectUpdated = true; break;}{{/isDateTime}}{{/isString}}{{#isString}}if({{name}} != nullptr && *{{name}} != QString("")){ isObjectUpdated = true; break;}{{/isString}}{{/complexType}}{{/isContainer}}
{{/vars}}
}while(false);
return isObjectUpdated;
}
{{#cppNamespaceDeclarations}} {{#cppNamespaceDeclarations}}
} }
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}

View File

@ -14,7 +14,7 @@
{{#imports}}{{{import}}} {{#imports}}{{{import}}}
{{/imports}} {{/imports}}
#include "SWGObject.h" #include "{{prefix}}Object.h"
{{#models}} {{#models}}
{{#model}} {{#model}}
@ -22,7 +22,7 @@
namespace {{this}} { namespace {{this}} {
{{/cppNamespaceDeclarations}} {{/cppNamespaceDeclarations}}
class {{classname}}: public SWGObject { class {{classname}}: public {{prefix}}Object {
public: public:
{{classname}}(); {{classname}}();
{{classname}}(QString* json); {{classname}}(QString* json);
@ -41,9 +41,13 @@ public:
{{/vars}} {{/vars}}
virtual bool isSet() override;
private: private:
{{#vars}} {{#vars}}
{{{datatype}}} {{name}}; {{{datatype}}} {{name}};
bool m_{{name}}_isSet;
{{/vars}} {{/vars}}
}; };

View File

@ -20,7 +20,7 @@ namespace {{this}} {
inline void* create(QString json, QString type) { inline void* create(QString json, QString type) {
void* val = create(type); void* val = create(type);
if(val != nullptr) { if(val != nullptr) {
SWGObject* obj = static_cast<SWGObject*>(val); {{prefix}}Object* obj = static_cast<{{prefix}}Object*>(val);
return obj->fromJson(json); return obj->fromJson(json);
} }
if(type.startsWith("QString")) { if(type.startsWith("QString")) {

View File

@ -11,12 +11,12 @@ namespace {{this}} {
class {{prefix}}Object { class {{prefix}}Object {
public: public:
virtual QJsonObject* asJsonObject() { virtual QJsonObject* asJsonObject() {
return nullptr; return new QJsonObject();
} }
virtual ~SWGObject() {} virtual ~{{prefix}}Object() {}
virtual SWGObject* fromJson(QString &jsonString) { virtual {{prefix}}Object* fromJson(QString &jsonString) {
Q_UNUSED(jsonString); Q_UNUSED(jsonString);
return nullptr; return new {{prefix}}Object();
} }
virtual void fromJsonObject(QJsonObject &json) { virtual void fromJsonObject(QJsonObject &json) {
Q_UNUSED(json); Q_UNUSED(json);
@ -24,6 +24,9 @@ class {{prefix}}Object {
virtual QString asJson() { virtual QString asJson() {
return QString(""); return QString("");
} }
virtual bool isSet() {
return false;
}
}; };
{{#cppNamespaceDeclarations}} {{#cppNamespaceDeclarations}}

View File

@ -127,7 +127,7 @@
self$`{{baseName}}` <- lapply({{classname}}Object$`{{baseName}}`, function(x) {{datatype}}$new()$fromJSON(jsonlite::toJSON(x, auto_unbox = TRUE))) self$`{{baseName}}` <- lapply({{classname}}Object$`{{baseName}}`, function(x) {{datatype}}$new()$fromJSON(jsonlite::toJSON(x, auto_unbox = TRUE)))
{{/isListContainer}} {{/isListContainer}}
{{^isListContainer}} {{^isListContainer}}
{{datatype}}Object -> {{datatype}}$new() {{datatype}}Object <- {{datatype}}$new()
self$`{{baseName}}` <- {{datatype}}Object$fromJSON(jsonlite::toJSON({{classname}}Object${{baseName}}, auto_unbox = TRUE)) self$`{{baseName}}` <- {{datatype}}Object$fromJSON(jsonlite::toJSON({{classname}}Object${{baseName}}, auto_unbox = TRUE))
{{/isListContainer}} {{/isListContainer}}
{{/isPrimitiveType}} {{/isPrimitiveType}}

View File

@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.license = "{{{gemLicense}}}" s.license = "{{{gemLicense}}}"
{{/gemLicense}} {{/gemLicense}}
{{^gemLicense}} {{^gemLicense}}
# TODO uncommnet and update below with a proper license # TODO uncomment and update below with a proper license
#s.license = "Apache 2.0" #s.license = "Apache 2.0"
{{/gemLicense}} {{/gemLicense}}
s.required_ruby_version = "{{{gemRequiredRubyVersion}}}{{^gemRequiredRubyVersion}}>= 1.9{{/gemRequiredRubyVersion}}" s.required_ruby_version = "{{{gemRequiredRubyVersion}}}{{^gemRequiredRubyVersion}}>= 1.9{{/gemRequiredRubyVersion}}"

View File

@ -6,7 +6,7 @@ pub mod responses {
// The macro is called per-operation to beat the recursion limit // The macro is called per-operation to beat the recursion limit
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} /// Create Mime objects for the response content types for {{operationId}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} /// Create Mime objects for the response content types for {{operationId}}
lazy_static! { lazy_static! {
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}: Mime = mime!({{{mediaType}}}); pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}: Mime = "{{{mediaType}}}".parse().unwrap();
} }
{{/dataType}}{{/-first}}{{/produces}}{{/responses}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/dataType}}{{/-first}}{{/produces}}{{/responses}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
} }
@ -15,7 +15,7 @@ pub mod requests {
use hyper::mime::*; use hyper::mime::*;
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{operationId}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{operationId}}
lazy_static! { lazy_static! {
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = mime!({{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}Application/Json{{/consumes}}); pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}Application/Json{{/consumes}}".parse().unwrap();
} }
{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
} }

View File

@ -1,12 +1,15 @@
{{>partial_header}} {{>partial_header}}
use std::rc::Rc; use std::rc::Rc;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::borrow::Cow;
use hyper; use hyper;
use serde_json; use serde_json;
use futures; use futures;
use futures::{Future, Stream}; use futures::{Future, Stream};
use hyper::header::UserAgent;
use super::{Error, configuration}; use super::{Error, configuration};
pub struct {{{classname}}}Client<C: hyper::client::Connect> { pub struct {{{classname}}}Client<C: hyper::client::Connect> {
@ -24,7 +27,7 @@ impl<C: hyper::client::Connect> {{{classname}}}Client<C> {
pub trait {{classname}} { pub trait {{classname}} {
{{#operations}} {{#operations}}
{{#operation}} {{#operation}}
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error = Error>>; fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error = Error<serde_json::Value>>>;
{{/operation}} {{/operation}}
{{/operations}} {{/operations}}
} }
@ -33,7 +36,7 @@ pub trait {{classname}} {
impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> { impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
{{#operations}} {{#operations}}
{{#operation}} {{#operation}}
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{.}}}{{/returnType}}, Error = Error>> { fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{.}}}{{/returnType}}, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow(); let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::{{httpMethod}}; let method = hyper::Method::{{httpMethod}};
@ -57,6 +60,10 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
// } // }
let mut req = hyper::Request::new(method, uri.unwrap()); let mut req = hyper::Request::new(method, uri.unwrap());
if let Some(ref user_agent) = configuration.user_agent {
req.headers_mut().set(UserAgent::new(Cow::Owned(user_agent.clone())));
}
{{#hasHeaderParams}} {{#hasHeaderParams}}
{ {
let mut headers = req.headers_mut(); let mut headers = req.headers_mut();
@ -77,8 +84,21 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
// send request // send request
Box::new( Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() }) configuration.client.request(req)
.map_err(|e| Error::from(e)) .map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
{{^returnType}} {{^returnType}}
.and_then(|_| futures::future::ok(())) .and_then(|_| futures::future::ok(()))
{{/returnType}} {{/returnType}}
@ -86,7 +106,7 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
.and_then(|body| { .and_then(|body| {
let parsed: Result<{{{returnType}}}, _> = serde_json::from_slice(&body); let parsed: Result<{{{returnType}}}, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e)) parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e)) })
{{/returnType}} {{/returnType}}
) )
} }

View File

@ -1,19 +1,48 @@
use hyper; use hyper;
use serde;
use serde_json; use serde_json;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error<T> {
Hyper(hyper::Error), Hyper(hyper::Error),
Serde(serde_json::Error), Serde(serde_json::Error),
ApiError(ApiError<T>),
} }
impl From<hyper::Error> for Error { #[derive(Debug)]
pub struct ApiError<T> {
pub code: hyper::StatusCode,
pub content: Option<T>,
}
impl<'de, T> From<(hyper::StatusCode, &'de [u8])> for Error<T>
where T: serde::Deserialize<'de> {
fn from(e: (hyper::StatusCode, &'de [u8])) -> Self {
if e.1.len() == 0 {
return Error::ApiError(ApiError{
code: e.0,
content: None,
});
}
match serde_json::from_slice::<T>(e.1) {
Ok(t) => Error::ApiError(ApiError{
code: e.0,
content: Some(t),
}),
Err(e) => {
Error::from(e)
}
}
}
}
impl<T> From<hyper::Error> for Error<T> {
fn from(e: hyper::Error) -> Self { fn from(e: hyper::Error) -> Self {
return Error::Hyper(e) return Error::Hyper(e)
} }
} }
impl From<serde_json::Error> for Error { impl<T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self { fn from(e: serde_json::Error) -> Self {
return Error::Serde(e) return Error::Serde(e)
} }

View File

@ -3,6 +3,7 @@ use hyper;
pub struct Configuration<C: hyper::client::Connect> { pub struct Configuration<C: hyper::client::Connect> {
pub base_path: String, pub base_path: String,
pub user_agent: Option<String>,
pub client: hyper::client::Client<C>, pub client: hyper::client::Client<C>,
} }
@ -10,6 +11,7 @@ impl<C: hyper::client::Connect> Configuration<C> {
pub fn new(client: hyper::client::Client<C>) -> Configuration<C> { pub fn new(client: hyper::client::Client<C>) -> Configuration<C> {
Configuration { Configuration {
base_path: "{{{basePath}}}".to_owned(), base_path: "{{{basePath}}}".to_owned(),
user_agent: {{#httpUserAgent}}Some("{{{.}}}".to_owned()){{/httpUserAgent}}{{^httpUserAgent}}Some("Swagger-Codegen/{{version}}/rust".to_owned()){{/httpUserAgent}},
client: client, client: client,
} }
} }

View File

@ -2,6 +2,7 @@
extern crate serde_derive; extern crate serde_derive;
extern crate hyper; extern crate hyper;
extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate futures; extern crate futures;
extern crate url; extern crate url;

View File

@ -0,0 +1,147 @@
package {{package}}
import {{modelPackage}}._
import com.typesafe.config.ConfigFactory
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.structure.PopulationBuilder
import java.io.File
import scala.collection.mutable
class {{classname}}Simulation extends Simulation {
def getCurrentDirectory = new File("").getAbsolutePath
def userDataDirectory = getCurrentDirectory + "/src/gatling/resources/data"
// basic test setup
val configName = System.getProperty("testConfig", "baseline")
val config = ConfigFactory.load(configName).withFallback(ConfigFactory.load("default"))
val durationSeconds = config.getInt("performance.durationSeconds")
val rampUpSeconds = config.getInt("performance.rampUpSeconds")
val rampDownSeconds = config.getInt("performance.rampDownSeconds")
val authentication = config.getString("performance.authorizationHeader")
val acceptHeader = config.getString("performance.acceptType")
val contentTypeHeader = config.getString("performance.contentType")
val rateMultiplier = config.getDouble("performance.rateMultiplier")
val instanceMultiplier = config.getDouble("performance.instanceMultiplier")
// global assertion data
val globalResponseTimeMinLTE = config.getInt("performance.global.assertions.responseTime.min.lte")
val globalResponseTimeMinGTE = config.getInt("performance.global.assertions.responseTime.min.gte")
val globalResponseTimeMaxLTE = config.getInt("performance.global.assertions.responseTime.max.lte")
val globalResponseTimeMaxGTE = config.getInt("performance.global.assertions.responseTime.max.gte")
val globalResponseTimeMeanLTE = config.getInt("performance.global.assertions.responseTime.mean.lte")
val globalResponseTimeMeanGTE = config.getInt("performance.global.assertions.responseTime.mean.gte")
val globalResponseTimeFailedRequestsPercentLTE = config.getDouble("performance.global.assertions.failedRequests.percent.lte")
val globalResponseTimeFailedRequestsPercentGTE = config.getDouble("performance.global.assertions.failedRequests.percent.gte")
val globalResponseTimeSuccessfulRequestsPercentLTE = config.getDouble("performance.global.assertions.successfulRequests.percent.lte")
val globalResponseTimeSuccessfulRequestsPercentGTE = config.getDouble("performance.global.assertions.successfulRequests.percent.gte")
// Setup http protocol configuration
val httpConf = http
.baseURL("{{basePath}}")
.doNotTrackHeader("1")
.acceptLanguageHeader("en-US,en;q=0.5")
.acceptEncodingHeader("gzip, deflate")
.userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
.acceptHeader(acceptHeader)
.contentTypeHeader(contentTypeHeader)
// set authorization header if it has been modified from config
if(!authentication.equals("~MANUAL_ENTRY")){
httpConf.authorizationHeader(authentication)
}
// Setup all the operations per second for the test to ultimately be generated from configs
{{#operations}}
{{#operation}}
val {{operationId}}PerSecond = config.getDouble("performance.operationsPerSecond.{{operationId}}") * rateMultiplier * instanceMultiplier
{{/operation}}
{{/operations}}
val scenarioBuilders: mutable.MutableList[PopulationBuilder] = new mutable.MutableList[PopulationBuilder]()
// Set up CSV feeders
{{#operations}}
{{#operation}}
{{#vendorExtensions.x-gatling-query-feeder}}
val {{vendorExtensions.x-gatling-query-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-queryParams.csv").random
{{/vendorExtensions.x-gatling-query-feeder}}
{{#vendorExtensions.x-gatling-header-feeder}}
val {{vendorExtensions.x-gatling-header-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-headerParams.csv").random
{{/vendorExtensions.x-gatling-header-feeder}}
{{#vendorExtensions.x-gatling-form-feeder}}
val {{vendorExtensions.x-gatling-form-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-formParams.csv").random
{{/vendorExtensions.x-gatling-form-feeder}}
{{#vendorExtensions.x-gatling-path-feeder}}
val {{vendorExtensions.x-gatling-path-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-pathParams.csv").random
{{/vendorExtensions.x-gatling-path-feeder}}
{{#vendorExtensions.x-gatling-body-feeder}}
val {{vendorExtensions.x-gatling-body-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-bodyParams.csv", escapeChar = '\\').random
{{/vendorExtensions.x-gatling-body-feeder}}
{{/operation}}
{{/operations}}
// Setup all scenarios
{{#operations}}
{{#operation}}
{{#description}}/* {{{description}}} */{{/description}}
val scn{{operationId}} = scenario("{{operationId}}Simulation")
{{#vendorExtensions.x-gatling-query-feeder}}
.feed({{vendorExtensions.x-gatling-query-feeder}})
{{/vendorExtensions.x-gatling-query-feeder}}
{{#vendorExtensions.x-gatling-header-feeder}}
.feed({{vendorExtensions.x-gatling-header-feeder}})
{{/vendorExtensions.x-gatling-header-feeder}}
{{#vendorExtensions.x-gatling-form-feeder}}
.feed({{vendorExtensions.x-gatling-form-feeder}})
{{/vendorExtensions.x-gatling-form-feeder}}
{{#vendorExtensions.x-gatling-body-feeder}}
.feed({{vendorExtensions.x-gatling-body-feeder}})
{{/vendorExtensions.x-gatling-body-feeder}}
{{#vendorExtensions.x-gatling-path-feeder}}
.feed({{vendorExtensions.x-gatling-path-feeder}})
{{/vendorExtensions.x-gatling-path-feeder}}
.exec(http("{{operationId}}")
.httpRequest("{{httpMethod}}","{{{vendorExtensions.x-gatling-path}}}")
{{#vendorExtensions.x-gatling-query-params}}
.queryParam("{{gatlingParamName}}","{{gatlingParamValue}}")
{{/vendorExtensions.x-gatling-query-params}}
{{#vendorExtensions.x-gatling-header-params}}
.header("{{gatlingParamName}}","{{gatlingParamValue}}")
{{/vendorExtensions.x-gatling-header-params}}
{{#vendorExtensions.x-gatling-form-params}}
.formParam("{{gatlingParamName}}","{{gatlingParamValue}}")
{{/vendorExtensions.x-gatling-form-params}}
{{#vendorExtensions.x-gatling-body-object}}
.body(StringBody({{{vendorExtensions.x-gatling-body-object}}}{{#vendorExtensions.x-gatling-body-feeder-params}}({{{vendorExtensions.x-gatling-body-feeder-params}}}){{/vendorExtensions.x-gatling-body-feeder-params}}))
{{/vendorExtensions.x-gatling-body-object}})
// Run scn{{operationId}} with warm up and reach a constant rate for entire duration
scenarioBuilders += scn{{operationId}}.inject(
rampUsersPerSec(1) to({{operationId}}PerSecond) during(rampUpSeconds),
constantUsersPerSec({{operationId}}PerSecond) during(durationSeconds),
rampUsersPerSec({{operationId}}PerSecond) to(1) during(rampDownSeconds)
)
{{/operation}}
{{/operations}}
setUp(
scenarioBuilders.toList
).protocols(httpConf).assertions(
global.responseTime.min.lte(globalResponseTimeMinLTE),
global.responseTime.min.gte(globalResponseTimeMinGTE),
global.responseTime.max.lte(globalResponseTimeMaxLTE),
global.responseTime.max.gte(globalResponseTimeMaxGTE),
global.responseTime.mean.lte(globalResponseTimeMeanLTE),
global.responseTime.mean.gte(globalResponseTimeMeanGTE),
global.failedRequests.percent.lte(globalResponseTimeFailedRequestsPercentLTE),
global.failedRequests.percent.gte(globalResponseTimeFailedRequestsPercentGTE),
global.successfulRequests.percent.lte(globalResponseTimeSuccessfulRequestsPercentLTE),
global.successfulRequests.percent.gte(globalResponseTimeSuccessfulRequestsPercentGTE)
)
}

View File

@ -0,0 +1,29 @@
plugins {
id 'com.github.lkishalmi.gatling' version '0.4.1'
}
repositories {
mavenCentral()
}
dependencies {
}
apply plugin: "com.github.lkishalmi.gatling"
gatling {
toolVersion = '2.3.0'
jvmArgs = ['-server', '-XX:+UseThreadPriorities',
'-XX:ThreadPriorityPolicy=42',
'-Xms2048M', '-Xmx2048M', '-Xmn500M',
'-XX:+HeapDumpOnOutOfMemoryError',
'-XX:+AggressiveOpts',
'-XX:+OptimizeStringConcat',
'-XX:+UseFastAccessorMethods',
'-XX:+UseParNewGC',
'-XX:+UseConcMarkSweepGC',
'-XX:+CMSParallelRemarkEnabled',
'-Djava.net.preferIPv4Stack=true',
'-Djava.net.preferIPv6Addresses=false']
}

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