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
```
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)
@ -116,7 +116,7 @@ To build from source, you need the following installed and available in your $PA
#### OS X Users
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
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
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
```
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
@ -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
```
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:
@ -541,7 +541,7 @@ Your config file for Java can look like
For all the unspecified options default values will be used.
Another way to override default options is to extend 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
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)
- [High Technologies Center](http://htc-cs.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)
- [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications)
- [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-wrap-calls.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
- sudo update-java-alternatives -s java-1.7.0-openjdk-amd64
- java -version
- cp pom.xml.circleci.java7 pom.xml # use jdk7 pom
- mvn clean install
- mvn -q verify -Psamples
# skip the rest if previous mvn task fails

View File

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

View File

@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-project</artifactId>
<version>2.3.1</version>
<version>2.4.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<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_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
*/
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 type;
public Boolean hasMore, isBasic, isOAuth, isApiKey;
public Map<String, Object> vendorExtensions;
// ApiKey specific
public String keyParamName;
public Boolean isKeyInQuery, isKeyInHeader;
@ -39,6 +40,8 @@ public class CodegenSecurity {
return false;
if (isApiKey != null ? !isApiKey.equals(that.isApiKey) : that.isApiKey != null)
return false;
if (vendorExtensions != null ? !vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions != null)
return false;
if (keyParamName != null ? !keyParamName.equals(that.keyParamName) : that.keyParamName != null)
return false;
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 + (isOAuth != null ? isOAuth.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 + (isKeyInQuery != null ? isKeyInQuery.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)) {
this.setSortParamsByRequiredFlag(Boolean.valueOf(additionalProperties
this.setRemoveOperationIdPrefix(Boolean.valueOf(additionalProperties
.get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX).toString()));
}
}
@ -2756,6 +2756,7 @@ public class DefaultCodegen {
sec.name = entry.getKey();
sec.type = schemeDefinition.getType();
sec.isCode = sec.isPassword = sec.isApplication = sec.isImplicit = false;
sec.vendorExtensions = schemeDefinition.getVendorExtensions();
if (schemeDefinition instanceof ApiKeyAuthDefinition) {
final ApiKeyAuthDefinition apiKeyDefinition = (ApiKeyAuthDefinition) schemeDefinition;

View File

@ -152,11 +152,15 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
public String toModelName(String name) {
// camelize the model name
// phone_number => PhoneNumber
return camelize(toModelFilename(name));
return camelize(toModel(name));
}
@Override
public String toModelFilename(String name) {
return toModel("model_" + name);
}
public String toModel(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
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'.
// 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 invokerPackage = "io.swagger.client";
protected String sourceFolder = "src/main/scala";
protected boolean stripPackageName = true;
public AbstractScalaCodegen() {
super();
@ -102,6 +103,13 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
if (additionalProperties.containsKey(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) {
@ -265,10 +273,16 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
}
protected String stripPackageName(String input) {
if (StringUtils.isEmpty(input) || input.lastIndexOf(".") < 0)
if (!stripPackageName || StringUtils.isEmpty(input) || input.lastIndexOf(".") < 0)
return input;
int lastIndexOfDot = input.lastIndexOf(".");
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("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.go"));
supportingFiles.add(new SupportingFile("api_client.mustache", "", "api_client.go"));
supportingFiles.add(new SupportingFile("api_response.mustache", "", "api_response.go"));
supportingFiles.add(new SupportingFile("client.mustache", "", "client.go"));
supportingFiles.add(new SupportingFile("response.mustache", "", "response.go"));
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.regex.Pattern;
import java.io.File;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.codegen.CliOption;
@ -28,7 +29,7 @@ import java.util.regex.Matcher;
public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenConfig {
// source folder where to write the files
protected String sourceFolder = "src";
protected String sourceFolder = "lib";
protected String artifactId = "swagger-haskell-http-client";
protected String artifactVersion = "1.0.0";
@ -36,11 +37,13 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
protected String defaultDateFormat = "%Y-%m-%d";
protected Boolean useMonadLogger = false;
protected Boolean allowNonUniqueOperationIds = false;
protected Boolean genEnums = true;
// CLI PROPS
public static final String PROP_ALLOW_FROMJSON_NULLS = "allowFromJsonNulls";
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_DATE_FORMAT = "dateFormat";
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_ENUM_VALUES = "x-enumValues";
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_OPERATION_TYPE = "x-operationType";
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_UNKNOWN_MIME_TYPES = "x-unknownMimeTypes";
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_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, String> knownMimeDataTypes = new HashMap<>();
protected Set<String> typeNames = new HashSet<String>();
protected Set<String> modelTypeNames = new HashSet<String>();
public CodegenType getTag() {
return CodegenType.CLIENT;
@ -128,8 +134,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
outputFolder = "generated-code/haskell-http-client";
embeddedTemplateDir = templateDir = "haskell-http-client";
apiPackage = "API";
modelPackage = "Model";
//apiPackage = "API";
//modelPackage = "Model";
// Haskell keywords and reserved function names, taken mostly from https://wiki.haskell.org/Keywords
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_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_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()));
@ -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) {
additionalProperties.put(PROP_ALLOW_FROMJSON_NULLS, value);
}
@ -317,6 +328,12 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
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)) {
setGenerateModelConstructors(convertPropertyToBoolean(PROP_GENERATE_MODEL_CONSTRUCTORS));
} else {
@ -408,7 +425,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
for (String word : words) {
wordsCaps.add(firstLetterToUpper(word));
}
String apiName = StringUtils.join(wordsCaps, "");
apiPackage = StringUtils.join(wordsCaps, "");
// 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"));
// lib
supportingFiles.add(new SupportingFile("TopLevel.mustache", "lib/", apiName + ".hs"));
supportingFiles.add(new SupportingFile("Client.mustache", "lib/" + apiName, "Client.hs"));
supportingFiles.add(new SupportingFile("TopLevel.mustache", sourceFolder + File.separator, apiPackage + ".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"));
supportingFiles.add(new SupportingFile("Model.mustache", "lib/" + apiName, "Model.hs"));
supportingFiles.add(new SupportingFile("MimeTypes.mustache", "lib/" + apiName, "MimeTypes.hs"));
if(!allowNonUniqueOperationIds) {
supportingFiles.add(new SupportingFile("APIS.mustache", sourceFolder + File.separator + apiPackage, "API.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
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("Model.mustache", ".hs");
apiTemplateFiles.put("API.mustache", ".hs");
// modelTemplateFiles.put("Model.mustache", ".hs");
// lens
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("titleLower", firstLetterToLower(apiName));
additionalProperties.put("title", apiPackage);
additionalProperties.put("titleLower", firstLetterToLower(apiPackage));
additionalProperties.put("package", cabalName);
additionalProperties.put("pathsName", pathsName);
additionalProperties.put("requestType", apiName + "Request");
additionalProperties.put("configType", apiName + "Config");
additionalProperties.put("requestType", apiPackage + "Request");
additionalProperties.put("configType", apiPackage + "Config");
additionalProperties.put("swaggerVersion", swagger.getSwagger());
super.preprocessSwagger(swagger);
@ -508,9 +528,41 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
return null;
}
}
@Override
public CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
CodegenOperation op = super.fromOperation(resourcePath, httpMethod, operation, definitions, swagger);
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation op, Map<String, List<CodegenOperation>> operations) {
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
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 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);
HashMap<String, Object> props = new HashMap<>();
@ -554,7 +606,6 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
processReturnType(op);
return op;
}
@Override
@ -647,6 +698,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
model.classname = generateNextName(model.classname);
}
typeNames.add(model.classname);
modelTypeNames.add(model.classname);
// From the model name, compute the prefix for the fields.
String prefix = StringUtils.uncapitalize(model.classname);
@ -721,7 +773,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
}
if (op.hasProduces) {
for (Map<String, String> m : op.produces) {
processMediaType(op,m);
processMediaType(op, m);
processInlineProducesContentType(op, m);
}
}
@ -753,7 +805,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
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
&& uniqueParamNameTypes.containsKey(paramNameType)
&& !isDuplicate(paramNameType, dataType)) {
@ -768,6 +820,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
}
typeNames.add(paramNameType);
modelTypeNames.add(paramNameType);
return paramNameType;
}
@ -842,7 +895,9 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (isJsonMimeType(mediaType)) {
m.put(X_MEDIA_IS_JSON, "true");
}
if (isWildcardMimeType(mediaType)) {
m.put(X_MEDIA_IS_WILDCARD, "true");
}
if (!knownMimeDataTypes.containsValue(mimeType) && !unknownMimeTypesContainsType(mimeType)) {
unknownMimeTypes.add(m);
}
@ -968,6 +1023,20 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
public String toModelFilename(String 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) {
name = escapeIdentifier(prefix, camelize(sanitizeName(name)));
return name;
@ -978,17 +1047,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
throw new RuntimeException("Empty method/operation name (operationId) not allowed");
}
operationId = escapeIdentifier("op",camelize(sanitizeName(operationId), true));
String uniqueName = 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;
return operationId;
}
public String escapeIdentifier(String prefix, String 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();
}
static boolean isWildcardMimeType(String mime) {
return mime != null && mime.equals("*/*");
}
@Override
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
@ -1100,7 +1163,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (duplicateEnum.getLeft()) {
paramNameType = duplicateEnum.getRight();
} else {
paramNameType = toDedupedName(paramNameType, enumValues, false);
paramNameType = toDedupedModelName(paramNameType, enumValues, false);
var.datatypeWithEnum = paramNameType;
updateCodegenPropertyEnum(var);
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) {
//App/Controllers
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

View File

@ -169,6 +169,20 @@ public class Qt5CPPGenerator extends AbstractCppCodegen implements CodegenConfig
}
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
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
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

View File

@ -440,6 +440,14 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
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
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger 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 != null && !consumes.isEmpty()) {
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>();
String mimeType = processMimeType(key);
if (mimeType.startsWith("Application/Xml")) {
if (isMimetypeXml(mimeType)) {
additionalProperties.put("usesXml", true);
consumesXml = true;
} else if (mimeType.startsWith("Text/Plain")) {
} else if (isMimetypePlainText(mimeType)) {
consumesPlainText = true;
}
@ -562,14 +569,13 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
boolean producesPlainText = false;
if (produces != null && !produces.isEmpty()) {
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>();
String mimeType = processMimeType(key);
if (mimeType.startsWith("Application/Xml")) {
if (isMimetypeXml(mimeType)) {
additionalProperties.put("usesXml", true);
producesXml = true;
} else if (mimeType.startsWith("Text/Plain")) {
} else if (isMimetypePlainText(mimeType)) {
producesPlainText = true;
}
@ -1023,57 +1029,4 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
}
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("authPreemptive", authPreemptive);
additionalProperties.put("clientName", clientName);
additionalProperties.put(CodegenConstants.STRIP_PACKAGE_NAME, stripPackageName);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
@ -230,10 +231,4 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC
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;
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
objs = super.postProcessModelsEnum(objs);

View File

@ -16,7 +16,7 @@ import java.util.Map;
public class ScalatraServerCodegen extends AbstractScalaCodegen implements CodegenConfig {
protected String groupId = "io.swagger";
protected String artifactId = "swagger-client";
protected String artifactId = "swagger-server";
protected String artifactVersion = "1.0.0";
public ScalatraServerCodegen() {
@ -25,8 +25,8 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
embeddedTemplateDir = templateDir = "scalatra";
apiPackage = "com.wordnik.client.api";
modelPackage = "com.wordnik.client.model";
apiPackage = "io.swagger.server.api";
modelPackage = "io.swagger.server.model";
setReservedWordsLowerCase(
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("build.sbt", "", "build.sbt"));
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("Bootstrap.mustache", sourceFolder, "ScalatraBootstrap.scala"));
supportingFiles.add(new SupportingFile("ServletApp.mustache", sourceFolder, "ServletApp.scala"));
@ -151,11 +153,4 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
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);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
private class EnumEntryLambda extends CustomLambda {
@Override
public String formatFragment(String fragment) {

View File

@ -139,19 +139,52 @@ public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
// name used by swift client
"ErrorResponse", "Response",
// swift keywords
"Int", "Int32", "Int64", "Int64", "Float", "Double", "Bool", "Void", "String",
"Character", "AnyObject", "Any", "Error", "URL", "class", "Class", "break",
"as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum",
"continue", "false", "dynamic", "extension", "default", "is", "didSet",
"func", "do", "nil", "final", "import", "else", "self", "get", "init",
"fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let",
"if", "true", "lazy", "operator", "in", "COLUMN", "left", "private", "return",
"FILE", "mutating", "protocol", "switch", "FUNCTION", "none", "public",
"where", "LINE", "nonmutating", "static", "while", "optional", "struct",
"override", "subscript", "postfix", "typealias", "precedence", "var",
"prefix", "Protocol", "required", "right", "set", "throw", "Type", "unowned", "weak",
"Data", "Codable", "Encodable", "Decodable")
// Added for Objective-C compatibility
"id", "description", "NSArray", "NSURL", "CGFloat", "NSSet", "NSString", "NSInteger", "NSUInteger",
"NSError", "NSDictionary",
//
// Swift keywords. This list is taken from here:
// https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-ID410
//
// Keywords used in declarations
"associatedtype", "class", "deinit", "enum", "extension", "fileprivate", "func", "import", "init",
"inout", "internal", "let", "open", "operator", "private", "protocol", "public", "static", "struct",
"subscript", "typealias", "var",
// 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<>();

View File

@ -93,6 +93,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
supportingFiles.add(new SupportingFile("encoder.mustache", getIndexDirectory(), "encoder.ts"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
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)) {
addNpmPackageGeneration();
@ -143,7 +144,6 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
}
//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("typings.mustache", getIndexDirectory(), "typings.json"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json"));

View File

@ -1,24 +1,41 @@
# {{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
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
To install the API client library to your local Maven repository, simply execute:
```shell
mvn install
mvn clean install
```
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
```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
@ -45,12 +62,14 @@ compile "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}"
At first generate the JAR by executing:
mvn package
```shell
mvn clean package
```
Then manually install the following JARs:
* target/{{{artifactId}}}-{{{artifactVersion}}}.jar
* target/lib/*.jar
* `target/{{{artifactId}}}-{{{artifactVersion}}}.jar`
* `target/lib/*.jar`
## Getting Started

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
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!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

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

View File

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

View File

@ -106,8 +106,9 @@ if(hasProperty('target') && target == 'android') {
ext {
swagger_annotations_version = "1.5.8"
jackson_version = "2.7.5"
jackson_version = "2.6.4"
jersey_version = "2.22.2"
resteasy_version = "3.1.3.Final"
{{^java8}}
jodatime_version = "2.9.4"
{{/java8}}
@ -120,12 +121,16 @@ ext {
dependencies {
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.media:jersey-media-multipart:$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-annotations:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
compile "com.github.joschi.jackson:jackson-datatype-threetenbp:$jackson_version"
{{#java8}}
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
{{/java8}}

View File

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

View File

@ -104,6 +104,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<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}}
{{/allParams}}
* @return Call&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object{{/returnType}}&gt;
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
{{#formParams}}
{{#-first}}
{{#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"
{{/useRxJava2}}
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"
{{#joda}}
compile "joda-time:joda-time:$jodatime_version"

View File

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

View File

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

View File

@ -67,6 +67,13 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
{{/isContainer}}
{{/vars}}
{{#gson}}
{{#discriminator}}
public {{classname}}() {
this.{{discriminator}} = this.getClass().getSimpleName();
}
{{/discriminator}}
{{/gson}}
{{#vars}}
{{^isReadOnly}}
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
@ -140,7 +147,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
return false;
}{{#hasVars}}
{{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}} &&
super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}}
@ -148,7 +155,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
@Override
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}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
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!
}}{{^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}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
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!
}}{{^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}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
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!
}}{{^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>
<maven.compiler.source>${java.version}</maven.compiler.source>
<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>
<junit-version>4.12</junit-version>
<logback-version>1.1.7</logback-version>
@ -189,8 +189,8 @@
{{#useBeanValidation}}
<beanvalidation-version>1.1.0.Final</beanvalidation-version>
{{/useBeanValidation}}
<cxf-version>3.1.11</cxf-version>
<jackson-jaxrs-version>2.8.9</jackson-jaxrs-version>
<cxf-version>3.2.1</cxf-version>
<jackson-jaxrs-version>2.9.1</jackson-jaxrs-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

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

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
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!
}}{{^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}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
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!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
# ~~~~
{{#useSwaggerUI}}
GET /api controllers.ApiDocController.api
GET /api {{apiPackage}}.ApiDocController.api
{{/useSwaggerUI}}
{{#apiInfo}}
@ -12,7 +12,7 @@ GET /api controllers.ApiDocController.api
#Functions for {{{baseName}}} API
{{#operations}}
{{#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}}
{{/operations}}
{{/apis}}

View File

@ -15,6 +15,6 @@ check for integer or long / all others=decimal type with @Decimal*
isInteger set
}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{!
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!
}}{{^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}}
vertx.eventBus().<JsonObject> consumer({{#vendorExtensions}}{{x-serviceid-varname}}{{/vendorExtensions}}).handler(message -> {
try {
// Workaround for #allParams section clearing the vendorExtensions map
String serviceId = "{{#vendorExtensions}}{{x-serviceid}}{{/vendorExtensions}}";
{{#hasParams}}
{{#allParams}}
{{#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));
{{/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}}
{{#isPrimitiveType}}
{{#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}}
{{{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}}
{{/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}}
{{/isListContainer}}
{{/allParams}}

View File

@ -44,7 +44,7 @@
describe('{{classname}}', function() {
it('should create an instance of {{classname}}', function() {
// 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}});
});
@ -53,7 +53,7 @@
{{#vars}}
it('should have the property {{name}} (base name: "{{baseName}}")', function() {
// 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();
});

View File

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

View File

@ -1,42 +1,40 @@
# NAME
# {{artifactId}}
{{appName}}
- API version: {{appVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
{{#appDescription}}{{{appDescription}}}{{/appDescription}}
# VERSION
Automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project:
- API version: {{appVersion}}
- Package version: {{moduleVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
- Build package: {{generatorClass}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
For more information, please visit [{{{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
To install the API client library to your local Maven repository, simply execute:
```shell
mvn install
mvn clean install
```
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
```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
@ -65,13 +63,15 @@ compile "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}"
libraryDependencies += "{{{groupId}}}" % "{{{artifactId}}}" % "{{{artifactVersion}}}"
```
## Getting Started
## Documentation for API Endpoints
All URIs are relative to *{{basePath}}*
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}}
## Documentation for Models
@ -101,28 +101,6 @@ Class | Method | HTTP request | Description
{{/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
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}

View File

@ -1,8 +1,4 @@
/**
* 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
*/
{{>licenseInfo}}
package {{package}}
{{#imports}}

View File

@ -1,9 +1,4 @@
/**
* 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
*/
{{>licenseInfo}}
package {{invokerPackage}}
import java.io.File

View File

@ -1,8 +1,4 @@
/**
* 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
*/
{{>licenseInfo}}
package {{invokerPackage}}
sealed trait ResponseState

View File

@ -1,8 +1,4 @@
/**
* 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
*/
{{>licenseInfo}}
package {{invokerPackage}}
import java.util.concurrent.TimeUnit

View File

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

View File

@ -1,8 +1,4 @@
/**
* 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
*/
{{>licenseInfo}}
package {{apiPackage}}
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 @@
/**
* 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
*/
{{>licenseInfo}}
package {{package}}
import {{invokerPackage}}.ApiModel

View File

@ -13,90 +13,86 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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>
<scala-test-version>3.0.4</scala-test-version>
<java.version>1.8</java.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>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala-version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>${swagger-core-version}</version>
<version>${scala.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time-version}</version>
</dependency>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-convert</artifactId>
<version>${joda-convert-version}</version>
<version>${joda.time.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.2.1</version>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>${akka-version}</version>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>io.spray</groupId>
<artifactId>spray-client</artifactId>
<version>${spray-version}</version>
<version>${spray.version}</version>
</dependency>
<dependency>
<groupId>org.json4s</groupId>
<artifactId>json4s-jackson_2.11</artifactId>
<version>${json4s-jackson-version}</version>
<version>${json4s.jackson.version}</version>
</dependency>
<!--test dependencies-->
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.11</artifactId>
<version>${scala-test-version}</version>
<version>${scala.test.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</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>
<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>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
@ -207,14 +203,14 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin-version}</version>
<version>${scala.maven.plugin.version}</version>
<executions>
<execution>
<id>scala-compile-first</id>
@ -244,15 +240,4 @@
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<configuration>
<scalaVersion>${scala-version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -1,8 +1,4 @@
/**
* 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
*/
{{>licenseInfo}}
package {{invokerPackage}}
import java.io.File

View File

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

View File

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

View File

@ -5,22 +5,23 @@ import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"errors"
"fmt"
"io"
"mime/multipart"
"golang.org/x/oauth2"
"golang.org/x/net/context"
"net/http"
"net/url"
"time"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
"unicode/utf8"
"strconv"
"strings"
"time"
"unicode/utf8"
"golang.org/x/net/context"
"golang.org/x/oauth2"
)
var (
@ -38,6 +39,7 @@ type APIClient struct {
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{classname}} *{{classname}}Service
{{/operations}}
{{/apis}}
@ -75,7 +77,6 @@ func atoi(in string) (int, error) {
return strconv.Atoi(in)
}
// selectHeaderContentType select a content type from the available list.
func selectHeaderContentType(contentTypes []string) string {
if len(contentTypes) == 0 {
@ -152,12 +153,12 @@ func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
}
// Change base path to allow switching to mocks
func (c *APIClient) ChangeBasePath (path string) {
func (c *APIClient) ChangeBasePath(path string) {
c.cfg.BasePath = path
}
// prepareRequest build the request
func (c *APIClient) prepareRequest (
func (c *APIClient) prepareRequest(
ctx context.Context,
path string, method string,
postBody interface{},
@ -267,7 +268,6 @@ func (c *APIClient) prepareRequest (
// Add the user agent to the request.
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
if ctx != nil {
// add context to the request
localVarRequest = localVarRequest.WithContext(ctx)
@ -292,7 +292,7 @@ func (c *APIClient) prepareRequest (
// AccessToken Authentication
if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
localVarRequest.Header.Add("Authorization", "Bearer " + auth)
localVarRequest.Header.Add("Authorization", "Bearer "+auth)
}
}
@ -303,7 +303,6 @@ func (c *APIClient) prepareRequest (
return localVarRequest, nil
}
// Add a file to the multipart request
func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path)
@ -322,7 +321,7 @@ func addFile(w *multipart.Writer, fieldName, path string) error {
}
// Prevent trying to import "fmt"
func reportError(format string, a ...interface{}) (error) {
func reportError(format string, a ...interface{}) error {
return fmt.Errorf(format, a...)
}
@ -376,7 +375,6 @@ func detectContentType(body interface{}) string {
return contentType
}
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
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.
func CacheExpires(r *http.Response) (time.Time) {
func CacheExpires(r *http.Response) time.Time {
// Figure out when the cache expires.
var expires time.Time
now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
@ -426,7 +424,6 @@ func CacheExpires(r *http.Response) (time.Time) {
return expires
}
func strlen(s string) (int) {
func strlen(s string) int {
return utf8.RuneCountInString(s)
}

View File

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

View File

@ -1,22 +1,16 @@
{{>partial_header}}
{-|
Module : {{title}}.API
Module : {{title}}.API.{{classname}}
-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# 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}}.MimeTypes
@ -24,8 +18,6 @@ import {{title}}.Model as M
import qualified Data.Aeson as A
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.Data as P (Typeable, TypeRep, typeOf, typeRep)
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.Encoding as TL
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.Media as ME
import qualified Network.HTTP.Types as NH
import qualified Web.FormUrlEncoded as WH
import qualified Web.HttpApiData as WH
import Data.Monoid ((<>))
import Data.Function ((&))
import Data.Text (Text)
import GHC.Base ((<|>))
@ -56,7 +44,7 @@ import Prelude ((==),(/=),($), (.),(<$>),(<*>),(>>=),Maybe(..),Bool(..),Char,Dou
import qualified Prelude as P
-- * Operations
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#vendorExtensions.x-hasNewTag}}
{{#operations}}{{#operation}}{{#vendorExtensions.x-hasNewTag}}
-- ** {{baseName}}{{/vendorExtensions.x-hasNewTag}}
@ -100,75 +88,11 @@ instance HasOptionalParam {{{vendorExtensions.x-operationType}}} {{{vendorExtens
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}}
{{#consumes}}-- | @{{{mediaType}}}@
instance Consumes {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}}
{{#consumes}}-- | @{{{mediaType}}}@{{^x-mediaIsWildcard}}
instance Consumes {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}}{{/x-mediaIsWildcard}}{{#x-mediaIsWildcard}}
instance MimeType mtype => Consumes {{{vendorExtensions.x-operationType}}} mtype{{/x-mediaIsWildcard}}
{{/consumes}}{{/hasConsumes}}{{#hasProduces}}
{{#produces}}-- | @{{{mediaType}}}@
instance Produces {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}}
{{/produces}}{{/hasProduces}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
-- * 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}}
{{#produces}}-- | @{{{mediaType}}}@{{^x-mediaIsWildcard}}
instance Produces {{{vendorExtensions.x-operationType}}} {{{x-mediaDataType}}}{{/x-mediaIsWildcard}}{{#x-mediaIsWildcard}}
instance MimeType mtype => Produces {{{vendorExtensions.x-operationType}}} mtype{{/x-mediaIsWildcard}}
{{/produces}}{{/hasProduces}}{{/operation}}{{/operations}}

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@
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 Data.Aeson as A
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.Data as P (Data, Typeable)
import qualified Data.Data as P (Typeable, TypeRep, typeOf, typeRep)
import qualified Data.Foldable as P
import qualified Data.HashMap.Lazy as HM
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.Encoding as T
import qualified Data.Time as TI
import qualified Lens.Micro as L
import qualified Web.FormUrlEncoded as WH
import qualified Web.HttpApiData as WH
import Control.Applicative ((<|>))
import Control.Applicative (Alternative)
import Data.Function ((&))
import Data.Monoid ((<>))
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
@ -51,6 +56,12 @@ import qualified Prelude as P
{{#imports}}import {{import}}
{{/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}}
@ -140,3 +151,47 @@ to{{{x-paramNameType}}} = \case{{#allowableValues}}{{#enumVars}}
{{{value}}} -> P.Right {{{name}}}{{/enumVars}}{{/allowableValues}}
s -> P.Left $ "to{{{x-paramNameType}}}: enum parse failure: " P.++ P.show s
{{/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 |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
| 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}}} |
| 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}}} |

View File

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

View File

@ -36,34 +36,35 @@ library
lib
ghc-options: -Wall -funbox-strict-fields
build-depends:
base >=4.7 && <5.0
, transformers >=0.4.0.0
, mtl >=2.2.1
, unordered-containers
, aeson >=1.0 && <2.0
, bytestring >=0.10.0 && <0.11
aeson >=1.0 && <2.0
, base >=4.7 && <5.0
, base64-bytestring >1.0 && <2.0
, bytestring >=0.10.0 && <0.11
, case-insensitive
, 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-tls
, http-api-data >= 0.3.4 && <0.4
, http-media >= 0.4 && < 0.8
, text >=0.11 && <1.3
, time >=1.5 && <1.9
, http-types >=0.8 && <0.12
, 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
, 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
, case-insensitive
, microlens >= 0.4.3 && <0.5
, deepseq >= 1.4 && <1.6
, text >=0.11 && <1.3
, time >=1.5 && <1.9
, 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:
{{title}}
{{title}}.API
{{title}}{{^x-allowNonUniqueOperationIds}}
{{title}}.API{{/x-allowNonUniqueOperationIds}}{{#apiInfo}}{{#apis}}
{{title}}.API.{{classname}}{{/apis}}{{/apiInfo}}
{{title}}.Client
{{title}}.Core
{{title}}.Logging
@ -81,21 +82,21 @@ test-suite tests
tests
ghc-options: -Wall -fno-warn-orphans
build-depends:
base >=4.7 && <5.0
, transformers >=0.4.0.0
, mtl >=2.2.1
, unordered-containers
, {{package}}
{{package}}
, QuickCheck
, aeson
, base >=4.7 && <5.0
, bytestring >=0.10.0 && <0.11
, containers
, hspec >=1.8
, iso8601-time
, mtl >=2.2.1
, semigroups
, text
, time
, iso8601-time
, aeson
, transformers >=0.4.0.0
, unordered-containers
, vector
, semigroups
, QuickCheck
other-modules:
ApproxEq
Instances

View File

@ -17,7 +17,7 @@ import {{title}}.MimeTypes
main :: IO ()
main =
hspec $ modifyMaxSize (const 10) $ do
hspec $ modifyMaxSize (const 5) $ do
describe "JSON instances" $ do
pure ()
{{#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}}
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 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 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 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}}"{{baseName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}"){{/isContainer}}{{^isContainer}}{{paramName}}{{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}}
val localVariableConfig = RequestConfig(
RequestMethod.{{httpMethod}},
"{{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
*
* @category Class */
// * @description {{#description}}{{description}}{{/description}}{{^description}}{{classname}}{{/description}}
/**
* @category Class
* @description {{#description}}{{description}}{{/description}}{{^description}}{{classname}}{{/description}}
* @package {{invokerPackage}}
* @author Swagger Codegen team
* @link https://github.com/swagger-api/swagger-codegen

View File

@ -1,5 +1,5 @@
{{>licenseInfo}}
#include "SWGHttpRequest.h"
#include "{{prefix}}HttpRequest.h"
#include <QDateTime>
#include <QUrl>
#include <QFileInfo>
@ -11,28 +11,28 @@
namespace {{this}} {
{{/cppNamespaceDeclarations}}
HttpRequestInput::HttpRequestInput() {
{{prefix}}HttpRequestInput::{{prefix}}HttpRequestInput() {
initialize();
}
HttpRequestInput::HttpRequestInput(QString v_url_str, QString v_http_method) {
{{prefix}}HttpRequestInput::{{prefix}}HttpRequestInput(QString v_url_str, QString v_http_method) {
initialize();
url_str = v_url_str;
http_method = v_http_method;
}
void HttpRequestInput::initialize() {
void {{prefix}}HttpRequestInput::initialize() {
var_layout = NOT_SET;
url_str = "";
http_method = "GET";
}
void HttpRequestInput::add_var(QString key, QString value) {
void {{prefix}}HttpRequestInput::add_var(QString key, QString value) {
vars[key] = value;
}
void HttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) {
SWGHttpRequestInputFileElement file;
void {{prefix}}HttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) {
{{prefix}}HttpRequestInputFileElement file;
file.variable_name = variable_name;
file.local_filename = local_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)
{
qsrand(QDateTime::currentDateTime().toTime_t());
@ -50,10 +50,10 @@ HttpRequestWorker::HttpRequestWorker(QObject *parent)
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
bool need_utf_encoding = false;
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);
}
void HttpRequestWorker::execute(HttpRequestInput *input) {
void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) {
// reset variables
@ -181,7 +181,7 @@ void HttpRequestWorker::execute(HttpRequestInput *input) {
}
// 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);
// ensure necessary variables are available
@ -253,8 +253,8 @@ void HttpRequestWorker::execute(HttpRequestInput *input) {
// prepare connection
QNetworkRequest request = QNetworkRequest(QUrl(input->url_str));
if (HttpRequestWorker::sslDefaultConfiguration != nullptr) {
request.setSslConfiguration(*HttpRequestWorker::sslDefaultConfiguration);
if ({{prefix}}HttpRequestWorker::sslDefaultConfiguration != nullptr) {
request.setSslConfiguration(*{{prefix}}HttpRequestWorker::sslDefaultConfiguration);
}
request.setRawHeader("User-Agent", "Swagger-Client");
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();
response = reply->readAll();
error_str = reply->errorString();
@ -310,7 +310,7 @@ void HttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
emit on_execution_finished(this);
}
QSslConfiguration* HttpRequestWorker::sslDefaultConfiguration;
QSslConfiguration* {{prefix}}HttpRequestWorker::sslDefaultConfiguration;
{{#cppNamespaceDeclarations}}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,19 @@
{{>licenseInfo}}
#ifndef SWGHELPERS_H
#define SWGHELPERS_H
#ifndef {{prefix}}_HELPERS_H
#define {{prefix}}_HELPERS_H
#include <QJsonValue>
#include <QList>
#include <QMap>
{{#cppNamespaceDeclarations}}
namespace {{this}} {
{{/cppNamespaceDeclarations}}
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 toJsonMap(QMap<QString, void*>* value, QJsonObject* output, QString innerName, QString innerType);
bool isCompatibleJsonValue(QString type);
QString stringValue(QString* value);
QString stringValue(qint32 value);
@ -21,4 +24,4 @@ namespace {{this}} {
}
{{/cppNamespaceDeclarations}}
#endif // SWGHELPERS_H
#endif // {{prefix}}_HELPERS_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.license = "{{{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"
{{/gemLicense}}
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
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} /// Create Mime objects for the response content types for {{operationId}}
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}}
}
@ -15,7 +15,7 @@ pub mod requests {
use hyper::mime::*;
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{operationId}}
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}}
}

View File

@ -1,12 +1,15 @@
{{>partial_header}}
use std::rc::Rc;
use std::borrow::Borrow;
use std::borrow::Cow;
use hyper;
use serde_json;
use futures;
use futures::{Future, Stream};
use hyper::header::UserAgent;
use super::{Error, configuration};
pub struct {{{classname}}}Client<C: hyper::client::Connect> {
@ -24,7 +27,7 @@ impl<C: hyper::client::Connect> {{{classname}}}Client<C> {
pub trait {{classname}} {
{{#operations}}
{{#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}}
{{/operations}}
}
@ -33,7 +36,7 @@ pub trait {{classname}} {
impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
{{#operations}}
{{#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 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());
if let Some(ref user_agent) = configuration.user_agent {
req.headers_mut().set(UserAgent::new(Cow::Owned(user_agent.clone())));
}
{{#hasHeaderParams}}
{
let mut headers = req.headers_mut();
@ -77,8 +84,21 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.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}}
.and_then(|_| futures::future::ok(()))
{{/returnType}}
@ -86,7 +106,7 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
.and_then(|body| {
let parsed: Result<{{{returnType}}}, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
{{/returnType}}
)
}

View File

@ -1,19 +1,48 @@
use hyper;
use serde;
use serde_json;
#[derive(Debug)]
pub enum Error {
pub enum Error<T> {
Hyper(hyper::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 {
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 {
return Error::Serde(e)
}

View File

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

View File

@ -2,6 +2,7 @@
extern crate serde_derive;
extern crate hyper;
extern crate serde;
extern crate serde_json;
extern crate futures;
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