Merge branch 'develop_2.0' into params-order

Conflicts:
	modules/swagger-codegen/src/main/resources/php/api.mustache
This commit is contained in:
xhh 2015-07-13 15:30:06 +08:00
commit fb0b7d622f
260 changed files with 21049 additions and 2560 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@ version.properties
lib/*
build/*
generated-files/*
generated-sources/*
generated-code/*
*.swp
*.swo

View File

@ -183,7 +183,7 @@ StaticDocCodegen.java
StaticHtmlGenerator.java
SwaggerGenerator.java
SwaggerYamlGenerator.java
SwiftGenerator.java
SwiftCodegen.java
TizenClientCodegen.java
```

View File

@ -41,3 +41,5 @@ cd $APP_DIR
./bin/spring-mvc-petstore-server.sh
./bin/swift-petstore.sh
./bin/tizen-petstore.sh
./bin/typescript-angular-petstore.sh
./bin/typescript-node-petstore.sh

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l csharp -o samples/client/petstore/csharp"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l csharp -o samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient"
java $JAVA_OPTS -jar $executable $ags

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/client/petstore/silex"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/server/petstore/silex"
java $JAVA_OPTS -jar $executable $ags

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

4
bin/swift-petstore.json Normal file
View File

@ -0,0 +1,4 @@
{
"projectName": "PetstoreClient",
"responseAs": "PromiseKit"
}

View File

@ -26,6 +26,6 @@ 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/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -c ./bin/swift-petstore.json -o samples/client/petstore/swift"
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags
java $JAVA_OPTS -jar $executable $ags

View File

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

31
bin/typescript-node-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 -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-node -o samples/client/petstore/typescript-node"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,41 @@
swagger-codegen-maven-plugin
============================
A Maven plugin to support the [swagger](http://swagger.io) code generation project
Usage
============================
Add to your `build->plugins` section (default phase is `generate-sources` phase)
```xml
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>src/main/resources/api.yaml</inputSpec>
<language>java</language>
</configuration>
</execution>
</executions>
</plugin>
```
Followed by:
```
mvn clean compile
```
### Configuration parameters
- `inputSpec` - swagger spec file path
- `language` - target generation language
- `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`)
- `templateDirectory` - directory with mustache templates
- `addCompileSourceRoot` - add the output directory to the project as a source root (`true` by default)

View File

@ -0,0 +1,87 @@
<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.1.3-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<name>swagger-codegen (maven-plugin)</name>
<packaging>maven-plugin</packaging>
<description>maven plugin to build modules from swagger codegen</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.4</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,16 @@
package io.swagger.codegen.plugin;
/**
* User: lanwen
* Date: 24.03.15
* Time: 14:47
*/
public final class AdditionalParams {
public static final String TEMPLATE_DIR_PARAM = "templateDir";
private AdditionalParams() {
}
}

View File

@ -0,0 +1,118 @@
package io.swagger.codegen.plugin;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import io.swagger.codegen.ClientOptInput;
import io.swagger.codegen.ClientOpts;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.DefaultGenerator;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import java.io.File;
import java.util.ServiceLoader;
import static io.swagger.codegen.plugin.AdditionalParams.TEMPLATE_DIR_PARAM;
/**
* Goal which generates client/server code from a swagger json/yaml definition.
*/
@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class CodeGenMojo extends AbstractMojo {
/**
* Location of the output directory.
*/
@Parameter(name = "output",
property = "swagger.codegen.maven.plugin.output",
defaultValue = "${project.build.directory}/generated-sources/swagger")
private File output;
/**
* Location of the swagger spec, as URL or file.
*/
@Parameter(name = "inputSpec", required = true)
private String inputSpec;
/**
* Folder containing the template files.
*/
@Parameter(name = "templateDirectory")
private File templateDirectory;
/**
* Client language to generate.
*/
@Parameter(name = "language", required = true)
private String language;
/**
* Add the output directory to the project as a source root, so that the
* generated java types are compiled and included in the project artifact.
*/
@Parameter(defaultValue = "true")
private boolean addCompileSourceRoot = true;
/**
* The project being built.
*/
@Parameter(readonly = true, required = true, defaultValue = "${project}")
private MavenProject project;
@Override
public void execute() throws MojoExecutionException {
Swagger swagger = new SwaggerParser().read(inputSpec);
CodegenConfig config = forName(language);
config.setOutputDir(output.getAbsolutePath());
if (null != templateDirectory) {
config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath());
}
ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger);
input.setConfig(config);
new DefaultGenerator().opts(input).generate();
if (addCompileSourceRoot) {
project.addCompileSourceRoot(output.toString());
}
}
private CodegenConfig forName(String name) {
ServiceLoader<CodegenConfig> loader = ServiceLoader.load(CodegenConfig.class);
for (CodegenConfig config : loader) {
if (config.getName().equals(name)) {
return config;
}
}
// else try to load directly
try {
return (CodegenConfig) Class.forName(name).newInstance();
} catch (Exception e) {
throw new RuntimeException("Can't load config class with name ".concat(name), e);
}
}
}

View File

@ -1,5 +1,7 @@
package io.swagger.codegen;
import java.util.Set;
public class CodegenSecurity {
public String name;
public String type;
@ -7,4 +9,7 @@ public class CodegenSecurity {
// ApiKey specific
public String keyParamName;
public Boolean isKeyInQuery, isKeyInHeader;
// Oauth specific
public String flow, authorizationUrl, tokenUrl;
public Set<String> scopes;
}

View File

@ -14,6 +14,7 @@ import io.swagger.models.Swagger;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.BasicAuthDefinition;
import io.swagger.models.auth.In;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.CookieParameter;
@ -1068,10 +1069,17 @@ public class DefaultCodegen {
sec.keyParamName = apiKeyDefinition.getName();
sec.isKeyInHeader = apiKeyDefinition.getIn() == In.HEADER;
sec.isKeyInQuery = !sec.isKeyInHeader;
} else if(schemeDefinition instanceof BasicAuthDefinition) {
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isOAuth = false;
sec.isBasic = true;
} else {
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = false;
sec.isBasic = schemeDefinition instanceof BasicAuthDefinition;
sec.isOAuth = !sec.isBasic;
final OAuth2Definition oauth2Definition = (OAuth2Definition) schemeDefinition;
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false;
sec.isOAuth = true;
sec.flow = oauth2Definition.getFlow();
sec.authorizationUrl = oauth2Definition.getAuthorizationUrl();
sec.tokenUrl = oauth2Definition.getTokenUrl();
sec.scopes = oauth2Definition.getScopes().keySet();
}
sec.hasMore = it.hasNext();

View File

@ -9,6 +9,7 @@ import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.util.Json;
import org.apache.commons.io.IOUtils;
@ -367,7 +368,22 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
String securityName = security.keySet().iterator().next();
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
if (securityDefinition != null) {
authMethods.put(securityName, securityDefinition);
if(securityDefinition instanceof OAuth2Definition) {
OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
OAuth2Definition oauth2Operation = new OAuth2Definition();
oauth2Operation.setType(oauth2Definition.getType());
oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
oauth2Operation.setFlow(oauth2Definition.getFlow());
oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
for (String scope : security.values().iterator().next()) {
if (oauth2Definition.getScopes().containsKey(scope)) {
oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
}
}
authMethods.put(securityName, oauth2Operation);
} else {
authMethods.put(securityName, securityDefinition);
}
}
}
if (!authMethods.isEmpty()) {

View File

@ -232,6 +232,8 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
supportingFiles.add(new SupportingFile("apiException.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
supportingFiles.add(new SupportingFile("Pair.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Pair.java"));
}
public Boolean getUseAndroidMavenGradlePlugin() {

View File

@ -7,6 +7,7 @@ import io.swagger.codegen.SupportingFile;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.codegen.CliOption;
import java.io.File;
import java.util.Arrays;
@ -14,15 +15,14 @@ import java.util.HashMap;
import java.util.HashSet;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "IO.Swagger.Client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-csharp-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/csharp";
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client";
protected String sourceFolder = "src" + File.separator + "main" + File.separator + "csharp";
public CSharpClientCodegen() {
super();
outputFolder = "generated-code/csharp";
outputFolder = "generated-code" + File.separator + "csharp";
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
templateDir = "csharp";
@ -34,17 +34,6 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while")
);
additionalProperties.put("invokerPackage", invokerPackage);
supportingFiles.add(new SupportingFile("Configuration.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.cs"));
supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll"));
supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll"));
supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
@ -85,6 +74,43 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger"));
cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packageVersion")) {
packageVersion = (String) additionalProperties.get("packageVersion");
} else {
additionalProperties.put("packageVersion", packageVersion);
}
if (additionalProperties.containsKey("packageName")) {
packageName = (String) additionalProperties.get("packageName");
apiPackage = packageName + ".Api";
modelPackage = packageName + ".Model";
clientPackage = packageName + ".Client";
} else {
additionalProperties.put("packageName", packageName);
}
additionalProperties.put("clientPackage", clientPackage);
supportingFiles.add(new SupportingFile("Configuration.mustache",
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiException.cs"));
supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll"));
supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll"));
supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat"));
}
public CodegenType getTag() {
@ -106,11 +132,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String apiFileFolder() {
return (outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/')).replace('.', File.separatorChar);
return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar);
}
public String modelFileFolder() {
return (outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/')).replace('.', File.separatorChar);
return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar);
}
@Override

View File

@ -116,6 +116,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
supportingFiles.add(new SupportingFile("JsonUtil.mustache", invokerFolder, "JsonUtil.java"));
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator);
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
@ -144,6 +145,10 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
if("_".equals(name)) {
name = "_u";
}
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;

View File

@ -166,6 +166,15 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
return objs;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
name = name.replaceAll("[^a-zA-Z0-9]+", "_");
return camelize(name) + "Api";
}
@Override
public String apiFilename(String templateName, String tag) {

View File

@ -1,5 +1,6 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
@ -18,12 +19,14 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "Swagger\\Client";
protected String groupId = "swagger";
protected String artifactId = "swagger-client";
protected String packagePath = "SwaggerClient-php";
protected String artifactVersion = null;
protected String srcBasePath = "lib";
public PhpClientCodegen() {
super();
outputFolder = "generated-code/php";
outputFolder = "generated-code" + File.separator + "php";
modelTemplateFiles.put("model.mustache", ".php");
apiTemplateFiles.put("api.mustache", ".php");
templateDir = "php";
@ -38,6 +41,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("modelPackage", modelPackage);
additionalProperties.put("apiPackage", apiPackage);
additionalProperties.put("srcBasePath", srcBasePath);
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
@ -81,16 +85,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("list", "array");
typeMapping.put("object", "object");
typeMapping.put("DateTime", "\\DateTime");
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, "lib"), "Configuration.php"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php"));
supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php"));
supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
cliOptions.add(new CliOption("packagePath", "main package name for classes"));
cliOptions.add(new CliOption("srcBasePath", "directory directory under packagePath to serve as source root"));
}
public String getPackagePath() {
return "SwaggerClient-php";
return packagePath;
}
public String toPackagePath(String packageName, String basePath) {
@ -99,13 +100,27 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar;
}
String regFirstPathSeparator;
if ("/".equals(File.separator)) { // for mac, linux
regFirstPathSeparator = "^/";
} else { // for windows
regFirstPathSeparator = "^\\\\";
}
String regLastPathSeparator;
if ("/".equals(File.separator)) { // for mac, linux
regLastPathSeparator = "/$";
} else { // for windows
regLastPathSeparator = "\\\\$";
}
return (getPackagePath() + File.separatorChar + basePath
// Replace period, backslash, forward slash with file separator in package name
+ packageName.replaceAll("[\\.\\\\/]", File.separator)
// Trim prefix file separators from package path
.replaceAll("^" + File.separator, ""))
// Trim trailing file separators from the overall path
.replaceAll(File.separator + "$", "");
.replaceAll(regFirstPathSeparator, ""))
// Trim trailing file separators from the overall path
.replaceAll(regLastPathSeparator+ "$", "");
}
public CodegenType getTag() {
@ -120,6 +135,39 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
return "Generates a PHP client library.";
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packagePath")) {
this.setPackagePath((String) additionalProperties.get("packagePath"));
}
if (additionalProperties.containsKey("srcBasePath")) {
this.setSrcBasePath((String) additionalProperties.get("srcBasePath"));
}
if (additionalProperties.containsKey("modelPackage")) {
this.setModelPackage((String) additionalProperties.get("modelPackage"));
}
if (additionalProperties.containsKey("apiPackage")) {
this.setApiPackage((String) additionalProperties.get("apiPackage"));
}
additionalProperties.put("srcBasePath", srcBasePath);
additionalProperties.put("modelPackage", modelPackage);
additionalProperties.put("apiPackage", apiPackage);
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, srcBasePath), "Configuration.php"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClient.php"));
supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiException.php"));
supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php"));
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
@ -127,11 +175,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return (outputFolder + "/" + toPackagePath(apiPackage(), "lib"));
return (outputFolder + "/" + toPackagePath(apiPackage(), srcBasePath));
}
public String modelFileFolder() {
return (outputFolder + "/" + toPackagePath(modelPackage(), "lib"));
return (outputFolder + "/" + toPackagePath(modelPackage(), srcBasePath));
}
@Override
@ -184,6 +232,17 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
return "null";
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setPackagePath(String packagePath) {
this.packagePath = packagePath;
}
public void setSrcBasePath(String srcBasePath) {
this.srcBasePath = srcBasePath;
}
@Override
public String toVarName(String name) {
@ -221,5 +280,4 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
// should be the same as the model name
return toModelName(name);
}
}

View File

@ -33,6 +33,7 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
languageSpecificPrimitives.add("date");
typeMapping.clear();
typeMapping.put("integer", "int");
@ -43,7 +44,8 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
typeMapping.put("map", "map");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "str");
typeMapping.put("date", "datetime");
typeMapping.put("date", "date");
typeMapping.put("DateTime", "datetime");
// from https://docs.python.org/release/2.5.4/ref/keywords.html
reservedWords = new HashSet<String>(

View File

@ -1,5 +1,6 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
@ -13,25 +14,19 @@ import java.util.Arrays;
import java.util.HashSet;
public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String module = "SwaggerPetstore";
protected String invokerPackage;
protected String eggPackage;
protected String packageName = null;
protected String packageVersion = null;
public PythonClientCodegen() {
super();
eggPackage = module + "-python";
invokerPackage = eggPackage + File.separatorChar + module;
modelPackage = "models";
apiPackage = "api";
outputFolder = "generated-code" + File.separatorChar + "python";
modelTemplateFiles.put("model.mustache", ".py");
apiTemplateFiles.put("api.mustache", ".py");
templateDir = "python";
apiPackage = invokerPackage + File.separatorChar + "apis";
modelPackage = invokerPackage + File.separatorChar + "models";
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("float");
@ -39,6 +34,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("str");
languageSpecificPrimitives.add("datetime");
languageSpecificPrimitives.add("date");
typeMapping.clear();
typeMapping.put("integer", "int");
@ -49,7 +45,8 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("map", "dict");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "str");
typeMapping.put("date", "datetime");
typeMapping.put("date", "date");
typeMapping.put("DateTime", "datetime");
typeMapping.put("object", "object");
// from https://docs.python.org/release/2.5.4/ref/keywords.html
@ -60,14 +57,43 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
"print", "class", "exec", "in", "raise", "continue", "finally", "is",
"return", "def", "for", "lambda", "try"));
additionalProperties.put("module", module);
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "python package name (convension: under_score), default: swagger_client"));
cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0"));
}
supportingFiles.add(new SupportingFile("README.mustache", eggPackage, "README.md"));
supportingFiles.add(new SupportingFile("setup.mustache", eggPackage, "setup.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", invokerPackage, "api_client.py"));
supportingFiles.add(new SupportingFile("rest.mustache", invokerPackage, "rest.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", invokerPackage, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", invokerPackage, "__init__.py"));
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packageName")) {
setPackageName((String) additionalProperties.get("packageName"));
}
else {
setPackageName("swagger_client");
}
if (additionalProperties.containsKey("packageVersion")) {
setPackageVersion((String) additionalProperties.get("packageVersion"));
}
else {
setPackageVersion("1.0.0");
}
additionalProperties.put("packageName", packageName);
additionalProperties.put("packageVersion", packageVersion);
String swaggerFolder = packageName;
modelPackage = swaggerFolder + File.separatorChar + "models";
apiPackage = swaggerFolder + File.separatorChar + "apis";
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFolder, "api_client.py"));
supportingFiles.add(new SupportingFile("rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFolder, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFolder, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py"));
}
@ -225,4 +251,23 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
return underscore(operationId);
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
/**
* Generate Python package name from String `packageName`
*
* (PEP 0008) Python packages should also have short, all-lowercase names,
* although the use of underscores is discouraged.
*/
public String generatePackageName(String packageName) {
return underscore(packageName.replaceAll("[^\\w]+", ""));
}
}

View File

@ -61,6 +61,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("List", "Array");
typeMapping.put("map", "Hash");
typeMapping.put("object", "Object");
typeMapping.put("file", "File");
// remove modelPackage and apiPackage added by default
cliOptions.clear();

View File

@ -20,6 +20,9 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
@ -214,4 +217,17 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
return camelize(operationId, true);
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// remove model imports to avoid warnings for importing class in the same package in Scala
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
final String prefix = modelPackage() + ".";
Iterator<Map<String, String>> iterator = imports.iterator();
while (iterator.hasNext()) {
String _import = iterator.next().get("import");
if (_import.startsWith(prefix)) iterator.remove();
}
return objs;
}
}

View File

@ -0,0 +1,215 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = null;
protected String moduleName = null;
protected String gemVersion = "1.0.0";
protected String libFolder = "lib";
public SinatraServerCodegen() {
super();
apiPackage = "lib";
outputFolder = "generated-code" + File.separator + "sinatra";
// no model
modelTemplateFiles.clear();
apiTemplateFiles.put("api.mustache", ".rb");
templateDir = "sinatra";
typeMapping.clear();
languageSpecificPrimitives.clear();
reservedWords = new HashSet<String>(
Arrays.asList(
"__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__",
"begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN",
"break", "do", "false", "next", "rescue", "then", "when", "END", "case",
"else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif",
"if", "not", "return", "undef", "yield")
);
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("array");
languageSpecificPrimitives.add("map");
languageSpecificPrimitives.add("string");
languageSpecificPrimitives.add("DateTime");
typeMapping.put("long", "int");
typeMapping.put("integer", "int");
typeMapping.put("Array", "array");
typeMapping.put("String", "string");
typeMapping.put("List", "array");
typeMapping.put("map", "map");
// remove modelPackage and apiPackage added by default
cliOptions.clear();
}
@Override
public void processOpts() {
super.processOpts();
// use constant model/api package (folder path)
//setModelPackage("models");
setApiPackage("api");
supportingFiles.add(new SupportingFile("my_app.mustache", "", "my_app.rb"));
supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "swaggering.rb"));
supportingFiles.add(new SupportingFile("config.ru", "", "config.ru"));
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "sinatra";
}
public String getHelp() {
return "Generates a Sinatra server library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + apiPackage.replace("/", File.separator);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = swaggerType;
}
if (type == null) {
return null;
}
return type;
}
public String toDefaultValue(Property p) {
return "null";
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, convert to lower case
if (name.matches("^[A-Z_]*$")) {
name = name.toLowerCase();
}
// camelize (lower first character) the variable name
// petId => pet_id
name = underscore(name);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// underscore the model file name
// PhoneNumber.rb => phone_number.rb
return underscore(name);
}
@Override
public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// e.g. PhoneNumberApi.rb => phone_number_api.rb
return underscore(name) + "_api";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
// e.g. phone_number_api => PhoneNumberApi
return camelize(name) + "Api";
}
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return underscore(operationId);
}
}

View File

@ -2,6 +2,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenResponse;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Operation;
@ -146,6 +147,14 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
List<CodegenResponse> responses = operation.responses;
if (responses != null) {
for (CodegenResponse resp : responses) {
if ("0".equals(resp.code)) {
resp.code = "200";
}
}
}
if (operation.returnType == null) {
operation.returnType = "Void";
} else if (operation.returnType.startsWith("List")) {

View File

@ -0,0 +1,286 @@
package io.swagger.codegen.languages;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import io.swagger.codegen.*;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
import java.util.*;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
protected static final String LIBRARY_PROMISE_KIT = "PromiseKit";
protected static final String[] RESPONSE_LIBRARIES = { LIBRARY_PROMISE_KIT };
protected String projectName = "SwaggerClient";
protected boolean unwrapRequired = false;
protected String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "Swaggers";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "swift";
}
public String getHelp() {
return "Generates a swift client library.";
}
public SwiftCodegen() {
super();
outputFolder = "generated-code" + File.separator + "swift";
modelTemplateFiles.put("model.mustache", ".swift");
apiTemplateFiles.put("api.mustache", ".swift");
templateDir = "swift";
apiPackage = File.separator + "APIs";
modelPackage = File.separator + "Models";
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"Int",
"Float",
"Double",
"Bool",
"Void",
"String",
"Character")
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"NSDate",
"Array",
"Dictionary",
"Set",
"Any",
"Empty",
"AnyObject")
);
reservedWords = new HashSet<String>(
Arrays.asList(
"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", "Type", "unowned", "weak")
);
typeMapping = new HashMap<String, String>();
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("date", "NSDate");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "Bool");
typeMapping.put("string", "String");
typeMapping.put("char", "Character");
typeMapping.put("short", "Int");
typeMapping.put("int", "Int");
typeMapping.put("long", "Int");
typeMapping.put("integer", "Int");
typeMapping.put("Integer", "Int");
typeMapping.put("float", "Float");
typeMapping.put("number", "Double");
typeMapping.put("double", "Double");
typeMapping.put("object", "String");
typeMapping.put("file", "NSData");
importMapping = new HashMap<String, String>();
cliOptions.add(new CliOption("projectName", "Project name in Xcode"));
cliOptions.add(new CliOption("responseAs", "Optionally use libraries to manage response. Currently " +
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " +
"(which would crash the app if api returns null as opposed to required option specified in json schema"));
}
@Override
public void processOpts() {
super.processOpts();
// Setup project name
if (additionalProperties.containsKey("projectName")) {
projectName = (String) additionalProperties.get("projectName");
} else {
additionalProperties.put("projectName", projectName);
}
sourceFolder = projectName + File.separator + sourceFolder;
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
if (additionalProperties.containsKey("unwrapRequired")) {
unwrapRequired = Boolean.parseBoolean(String.valueOf(additionalProperties.get("unwrapRequired")));
}
additionalProperties.put("unwrapRequired", unwrapRequired);
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
if (additionalProperties.containsKey("responseAs")) {
Object responseAsObject = additionalProperties.get("responseAs");
if (responseAsObject instanceof String) {
responseAs = ((String)responseAsObject).split(",");
} else {
responseAs = (String[]) responseAsObject;
}
}
additionalProperties.put("responseAs", responseAs);
if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) {
additionalProperties.put("usePromiseKit", true);
}
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder,
"AlamofireImplementations.swift"));
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
}
@Override
public String escapeReservedWord(String name) {
return "Swagger" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar);
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + apiPackage().replace('.', File.separatorChar);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return "[String:" + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return toModelName(type);
} else
type = swaggerType;
return toModelName(type);
}
@Override
public String toDefaultValue(Property p) {
// nil
return null;
}
@Override
public String toInstantiationType(Property p) {
if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "[String:" + inner + "]";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "[" + inner + "]";
}
return null;
}
@Override
public CodegenProperty fromProperty(String name, Property p) {
CodegenProperty codegenProperty = super.fromProperty(name, p);
if (codegenProperty.isEnum) {
List<Map<String, String>> swiftEnums = new ArrayList<Map<String, String>>();
List<String> values = (List<String>) codegenProperty.allowableValues.get("values");
for (String value : values) {
Map<String, String> map = new HashMap<String, String>();
map.put("enum", StringUtils.capitalize(value));
map.put("raw", value);
swiftEnums.add(map);
}
codegenProperty.allowableValues.put("values", swiftEnums);
codegenProperty.datatypeWithEnum =
StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length());
if (reservedWords.contains(codegenProperty.datatypeWithEnum)) {
codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum);
}
}
return codegenProperty;
}
@Override
public String toApiName(String name) {
if(name.length() == 0)
return "DefaultAPI";
return initialCaps(name) + "API";
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
path = normalizePath(path);
List<Parameter> parameters = operation.getParameters();
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
return super.fromOperation(path, httpMethod, operation, definitions);
}
private static String normalizePath(String path) {
StringBuilder builder = new StringBuilder();
int cursor = 0;
Matcher matcher = PATH_PARAM_PATTERN.matcher(path);
boolean found = matcher.find();
while (found) {
String stringBeforeMatch = path.substring(cursor, matcher.start());
builder.append(stringBeforeMatch);
String group = matcher.group().substring(1, matcher.group().length() - 1);
group = camelize(group, true);
builder
.append("{")
.append(group)
.append("}");
cursor = matcher.end();
found = matcher.find();
}
String stringAfterMatch = path.substring(cursor);
builder.append(stringAfterMatch);
return builder.toString();
}
}

View File

@ -1,265 +0,0 @@
package io.swagger.codegen.languages;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SwiftGenerator extends DefaultCodegen implements CodegenConfig {
private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}");
protected String sourceFolder = "Classes/Swaggers";
public SwiftGenerator() {
super();
outputFolder = "generated-code/swift";
modelTemplateFiles.put("model.mustache", ".swift");
apiTemplateFiles.put("api.mustache", ".swift");
templateDir = "swift";
apiPackage = "/APIs";
modelPackage = "/Models";
// Inject application name
String appName = System.getProperty("appName");
if (appName == null) {
appName = "SwaggerClient";
}
additionalProperties.put("projectName", appName);
// Inject base url override
String basePathOverride = System.getProperty("basePathOverride");
if (basePathOverride != null) {
additionalProperties.put("basePathOverride", basePathOverride);
}
sourceFolder = appName + "/" + sourceFolder;
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift"));
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"Int",
"Float",
"Double",
"Bool",
"Void",
"String",
"Character")
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"NSDate",
"Array",
"Dictionary",
"Set",
"Any",
"Empty",
"AnyObject")
);
reservedWords = new HashSet<String>(
Arrays.asList(
"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", "Type", "unowned", "weak")
);
typeMapping = new HashMap<String, String>();
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("date", "NSDate");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "Bool");
typeMapping.put("string", "String");
typeMapping.put("char", "Character");
typeMapping.put("short", "Int");
typeMapping.put("int", "Int");
typeMapping.put("long", "Int");
typeMapping.put("integer", "Int");
typeMapping.put("Integer", "Int");
typeMapping.put("float", "Float");
typeMapping.put("number", "Double");
typeMapping.put("double", "Double");
typeMapping.put("object", "AnyObject");
typeMapping.put("file", "NSData");
importMapping = new HashMap<String, String>();
}
private static String normalizePath(String path) {
StringBuilder builder = new StringBuilder();
int cursor = 0;
Matcher matcher = PATH_PARAM_PATTERN.matcher(path);
boolean found = matcher.find();
while (found) {
String stringBeforeMatch = path.substring(cursor, matcher.start());
builder.append(stringBeforeMatch);
String group = matcher.group().substring(1, matcher.group().length() - 1);
group = camelize(group, true);
builder
.append("{")
.append(group)
.append("}");
cursor = matcher.end();
found = matcher.find();
}
String stringAfterMatch = path.substring(cursor);
builder.append(stringAfterMatch);
return builder.toString();
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "swift";
}
public String getHelp() {
return "Generates a swift client library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar);
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return "[String:" + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type)) {
return toModelName(type);
}
} else {
type = swaggerType;
}
return toModelName(type);
}
@Override
public String toDefaultValue(Property p) {
// nil
return null;
}
@Override
public String toInstantiationType(Property p) {
if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "[String:" + inner + "]";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "[" + inner + "]";
}
return null;
}
@Override
public CodegenProperty fromProperty(String name, Property p) {
CodegenProperty codegenProperty = super.fromProperty(name, p);
if (codegenProperty.isEnum) {
List<Map<String, String>> swiftEnums = new ArrayList<Map<String, String>>();
List<String> values = (List<String>) codegenProperty.allowableValues.get("values");
for (String value : values) {
Map<String, String> map = new HashMap<String, String>();
map.put("enum", StringUtils.capitalize(value));
map.put("raw", value);
swiftEnums.add(map);
}
codegenProperty.allowableValues.put("values", swiftEnums);
codegenProperty.datatypeWithEnum =
StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length());
}
return codegenProperty;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultAPI";
}
return initialCaps(name) + "API";
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
path = normalizePath(path);
List<Parameter> parameters = operation.getParameters();
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
return super.fromOperation(path, httpMethod, operation, definitions);
}
}

View File

@ -0,0 +1,25 @@
package io.swagger.codegen.languages;
import java.io.File;
import io.swagger.codegen.SupportingFile;
public class TypeScriptAngularClientCodegen extends TypeScriptNodeClientCodegen {
@Override
public String getName() {
return "typescript-angular";
}
public TypeScriptAngularClientCodegen() {
super();
outputFolder = "generated-code/typescript-angular";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-Angular";
apiPackage = "api";
modelPackage = "model";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage + File.separator, "api.d.ts"));
}
}

View File

@ -0,0 +1,171 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import java.util.*;
import java.io.File;
public class TypeScriptNodeClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-typescript-node-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/typescript";
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "typescript-node";
}
@Override
public String getHelp() {
return "Generates a TypeScript nodejs client library.";
}
public TypeScriptNodeClientCodegen() {
super();
outputFolder = "generated-code/typescript-node";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-node";
apiPackage = "api";
modelPackage = "model";
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws", "case", "enum",
"instanceof", "return", "transient", "catch", "extends", "int",
"short", "try", "char", "final", "interface", "static", "void",
"class", "finally", "const", "super", "while"));
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
additionalProperties.put("artifactVersion", artifactVersion);
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object"));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("DateTime", "Date");
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
public String modelFileFolder() {
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$"))
return name;
// camelize the variable name
// pet_id => PetId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*"))
name = escapeReservedWord(name);
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name))
throw new RuntimeException(name
+ " (reserved word) cannot be used as a model name");
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner)
+ ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
type = swaggerType;
return type;
}
}

View File

@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;
@ -238,6 +239,62 @@ public class ApiClient {
}
}
/*
Format to {@code Pair} objects.
*/
public List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
List<Pair> params = new ArrayList<Pair>();
// preconditions
if (name == null || name.isEmpty() || value == null) return params;
Collection valueCollection = null;
if (value instanceof Collection) {
valueCollection = (Collection) value;
} else {
params.add(new Pair(name, parameterToString(value)));
return params;
}
if (valueCollection.isEmpty()){
return params;
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
return params;
}
String delimiter = ",";
if (collectionFormat.equals("csv")) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
delimiter = "|";
}
StringBuilder sb = new StringBuilder() ;
for (Object item : valueCollection) {
sb.append(delimiter);
sb.append(parameterToString(item));
}
params.add(new Pair(name, sb.substring(1)));
return params;
}
/**
* Select the Accept header's value from the given accepts array:
* if JSON exists in the given array, use it;
@ -341,23 +398,25 @@ public class ApiClient {
* @param authNames The authentications to apply
* @return The response body in type of string
*/
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
public String invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);
Client client = getClient();
StringBuilder b = new StringBuilder();
for(String key : queryParams.keySet()) {
String value = queryParams.get(key);
if (value != null){
if(b.toString().length() == 0)
b.append("?");
else
b.append("?");
if (queryParams != null){
for (Pair queryParam : queryParams){
if (!queryParam.getName().isEmpty()) {
b.append(escapeString(queryParam.getName()));
b.append("=");
b.append(escapeString(queryParam.getValue()));
b.append("&");
b.append(escapeString(key)).append("=").append(escapeString(value));
}
}
}
String querystring = b.toString();
String querystring = b.substring(0, b.length() - 1);
Builder builder;
if (accept == null)
@ -421,10 +480,10 @@ public class ApiClient {
throw new ApiException(500, "unknown method type " + method);
}
if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) {
if(response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) {
return null;
}
else if(response.getClientResponseStatus().getFamily() == Family.SUCCESSFUL) {
else if(response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
if(response.hasEntity()) {
return (String) response.getEntity(String.class);
}
@ -445,7 +504,7 @@ public class ApiClient {
}
}
throw new ApiException(
response.getClientResponseStatus().getStatusCode(),
response.getStatusInfo().getStatusCode(),
message,
response.getHeaders(),
respBody);
@ -457,7 +516,7 @@ public class ApiClient {
*
* @param authNames The authentications to apply
*/
private void updateParamsForAuth(String[] authNames, Map<String, String> queryParams, Map<String, String> headerParams) {
private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);

View File

@ -0,0 +1,38 @@
package {{invokerPackage}};
public class Pair {
private String name = "";
private String value = "";
public Pair (String name, String value) {
setName(name);
setValue(value);
}
private void setName(String name) {
if (!isValidString(name)) return;
this.name = name;
}
private void setValue(String value) {
if (!isValidString(value)) return;
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
private boolean isValidString(String arg) {
if (arg == null) return false;
if (arg.trim().isEmpty()) return false;
return true;
}
}

View File

@ -3,6 +3,7 @@ package {{package}};
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;
import {{modelPackage}}.*;
@ -58,19 +59,19 @@ public class {{classname}} {
// create path and map variables
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
.replaceAll("\\{" + "{{baseName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
Map<String, String> headerParams = new HashMap<String, String>();
Map<String, String> formParams = new HashMap<String, String>();
{{#queryParams}}if ({{paramName}} != null)
queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
{{#queryParams}}
queryParams.addAll(apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
{{/queryParams}}
{{#headerParams}}if ({{paramName}} != null)
headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
{{/headerParams}}
final String[] accepts = {

View File

@ -1,6 +1,9 @@
package {{invokerPackage}}.auth;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
public class ApiKeyAuth implements Authentication {
private final String location;
@ -39,7 +42,7 @@ public class ApiKeyAuth implements Authentication {
}
@Override
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
String value;
if (apiKeyPrefix != null) {
value = apiKeyPrefix + " " + apiKey;
@ -47,7 +50,7 @@ public class ApiKeyAuth implements Authentication {
value = apiKey;
}
if (location == "query") {
queryParams.put(paramName, value);
queryParams.add(new Pair(paramName, value));
} else if (location == "header") {
headerParams.put(paramName, value);
}

View File

@ -1,8 +1,11 @@
package {{invokerPackage}}.auth;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
public interface Authentication {
/** Apply authentication settings to header and query params. */
void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams);
void applyToParams(List<Pair> queryParams, Map<String, String> headerParams);
}

View File

@ -1,6 +1,9 @@
package {{invokerPackage}}.auth;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
import java.io.UnsupportedEncodingException;
import javax.xml.bind.DatatypeConverter;
@ -26,7 +29,7 @@ public class HttpBasicAuth implements Authentication {
}
@Override
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
try {
headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8")));

View File

@ -1,10 +1,13 @@
package {{invokerPackage}}.auth;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
public class OAuth implements Authentication {
@Override
public void applyToParams(Map<String, String> queryParams, Map<String, String> headerParams) {
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
// TODO: support oauth
}
}

View File

@ -8,4 +8,5 @@ This server was generated by the [swagger-codegen](https://github.com/swagger-ap
The underlying library integrating swagger to Spring-MVC is [springfox](https://github.com/springfox/springfox)
You can view the server in swagger-ui by pointing to http://localhost:8002{{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}/sdoc.jsp
You can view the server in swagger-ui by pointing to
http://localhost:8002{{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}/swagger-ui.html

View File

@ -33,8 +33,7 @@
<webAppConfig>
<contextPath>{{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}</contextPath>
</webAppConfig>
<webAppSourceDirectory>target/${project.artifactId}-${project-version}</webAppSourceDirectory>
<webDefaultXml>${project.basedir}/conf/jetty/webdefault.xml</webDefaultXml>
<webAppSourceDirectory>target/${project.artifactId}-${project.version}</webAppSourceDirectory>
<stopPort>8079</stopPort>
<stopKey>stopit</stopKey>
<httpConnector>
@ -63,49 +62,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>swagger-ui</id>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://github.com/swagger-api/swagger-ui/archive/v${swagger-ui-version}.tar.gz</url>
<unpack>true</unpack>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/${project.artifactId}-${project.version}</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/swagger-ui-${swagger-ui-version}/dist</directory>
<filtering>true</filtering>
<excludes>
<exclude>index.html</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
@ -163,21 +119,6 @@
</dependency>
<!--SpringFox dependencies-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-core</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spi</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
@ -189,12 +130,6 @@
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.9.1</artifactId>
<version>${scala-test-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@ -217,13 +152,12 @@
<properties>
<swagger-core-version>1.5.0</swagger-core-version>
<jetty-version>9.2.9.v20150224</jetty-version>
<swagger-ui-version>2.1.0-M2</swagger-ui-version>
<jersey-version>1.13</jersey-version>
<slf4j-version>1.6.3</slf4j-version>
<scala-test-version>1.6.1</scala-test-version>
<junit-version>4.8.1</junit-version>
<servlet-api-version>2.5</servlet-api-version>
<springfox-version>2.0.0-SNAPSHOT</springfox-version>
<springfox-version>2.0.4-SNAPSHOT</springfox-version>
<spring-version>4.0.9.RELEASE</spring-version>
</properties>
</project>

View File

@ -15,11 +15,14 @@ io.swagger.codegen.languages.RubyClientCodegen
io.swagger.codegen.languages.ScalaClientCodegen
io.swagger.codegen.languages.ScalatraServerCodegen
io.swagger.codegen.languages.SilexServerCodegen
io.swagger.codegen.languages.SinatraServerCodegen
io.swagger.codegen.languages.SpringMVCServerCodegen
io.swagger.codegen.languages.StaticDocCodegen
io.swagger.codegen.languages.StaticHtmlGenerator
io.swagger.codegen.languages.SwaggerGenerator
io.swagger.codegen.languages.SwaggerYamlGenerator
io.swagger.codegen.languages.SwiftGenerator
io.swagger.codegen.languages.SwiftCodegen
io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen
io.swagger.codegen.languages.AkkaScalaClientCodegen

View File

@ -0,0 +1,13 @@
{{#models}}
{{#model}}
/// <reference path="{{{classname}}}.ts" />
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
/// <reference path="{{classname}}.ts" />
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@ -0,0 +1,65 @@
/// <reference path="api.d.ts" />
/* tslint:disable:no-unused-variable member-ordering */
{{#operations}}
module {{package}} {
'use strict';
{{#description}}
/**
* {{&description}}
*/
{{/description}}
export class {{classname}} {
private basePath = '{{contextPath}}';
static $inject: string[] = ['$http'];
constructor(private $http: ng.IHttpService, basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
var path = this.basePath + '{{path}}';
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
var queryParameters: any = {};
var headerParams: any = {};
{{#allParams}}{{#required}}
// verify required parameter '{{paramName}}' is set
if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
}
{{/required}}{{/allParams}}
{{#queryParams}}if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}};
}{{/queryParams}}
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};{{/headerParams}}
var httpRequestParams: any = {
method: '{{httpMethod}}',
url: path,
json: true,
{{#bodyParam}}data: {{paramName}},
{{/bodyParam}}
params: queryParameters,
headers: headerParams
};
if (extraHttpRequestParams) {
for (var k in extraHttpRequestParams) {
if (extraHttpRequestParams.hasOwnProperty(k)) {
httpRequestParams[k] = extraHttpRequestParams[k];
}
}
}
return this.$http(httpRequestParams);
}
{{/operation}}
}
}
{{/operations}}

View File

@ -0,0 +1,39 @@
/// <reference path="api.d.ts" />
module {{package}} {
'use strict';
{{#models}}
{{#model}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
{{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export module {{classname}} {
{{#vars}}
{{#isEnum}}
export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}
}

View File

@ -0,0 +1,73 @@
/* tslint:disable:no-unused-variable */
{{#operations}}
{{#description}}
/**
* {{&description}}
*/
{{/description}}
export class {{classname}} {
private basePath = '{{contextPath}}';
constructor(private url: string, private username: string, private password: string, basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> {
var path = this.url + this.basePath + '{{path}}';
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
var queryParameters: any = {};
var headerParams: any = {};
{{#allParams}}{{#required}}
// verify required parameter '{{paramName}}' is set
if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
}
{{/required}}{{/allParams}}
{{#queryParams}}if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}};
}
{{/queryParams}}
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};
{{/headerParams}}
var deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>();
request({
method: '{{httpMethod}}',
qs: queryParameters,
uri: path,
json: true,
{{#bodyParam}}body: {{paramName}},
{{/bodyParam}}
auth: {
username: this.username, password: this.password
}
}, (error, response, body) => {
if (error) {
deferred.reject(error);
} else {
if (response.statusCode >= 200 && response.statusCode <= 299) {
deferred.resolve({ response: response, body: body });
} else {
deferred.reject({ response: response, body: body });
}
}
});
return deferred.promise;
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,33 @@
{{#models}}
{{#model}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
{{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export module {{classname}} {
{{#vars}}
{{#isEnum}}
export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}

View File

@ -0,0 +1,38 @@
package {{invokerPackage}};
public class Pair {
private String name = "";
private String value = "";
public Pair(String name, String value) {
setName(name);
setValue(value);
}
private void setName(String name) {
if (!isValidString(name)) return;
this.name = name;
}
private void setValue(String value) {
if (!isValidString(value)) return;
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
private boolean isValidString(String arg) {
if (arg == null) return false;
if (arg.trim().isEmpty()) return false;
return true;
}
}

View File

@ -2,6 +2,7 @@ package {{package}};
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.ApiInvoker;
import {{invokerPackage}}.Pair;
import {{modelPackage}}.*;
@ -55,20 +56,21 @@ public class {{classname}} {
{{/required}}{{/allParams}}
// create path and map variables
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}};
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{baseName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
Map<String, String> formParams = new HashMap<String, String>();
{{#queryParams}}if ({{paramName}} != null)
queryParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
{{#queryParams}}
queryParams.addAll(ApiInvoker.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
{{/queryParams}}
{{#headerParams}}headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
{{#headerParams}}
headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
{{/headerParams}}
String[] contentTypes = {

View File

@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@ -132,6 +133,62 @@ public class ApiInvoker {
}
}
/*
Format to {@code Pair} objects.
*/
public static List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
List<Pair> params = new ArrayList<Pair>();
// preconditions
if (name == null || name.isEmpty() || value == null) return params;
Collection valueCollection = null;
if (value instanceof Collection) {
valueCollection = (Collection) value;
} else {
params.add(new Pair(name, parameterToString(value)));
return params;
}
if (valueCollection.isEmpty()){
return params;
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
return params;
}
String delimiter = ",";
if (collectionFormat.equals("csv")) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
delimiter = "|";
}
StringBuilder sb = new StringBuilder() ;
for (Object item : valueCollection) {
sb.append(delimiter);
sb.append(parameterToString(item));
}
params.add(new Pair(name, sb.substring(1)));
return params;
}
public ApiInvoker() {
initConnectionManager();
}
@ -184,21 +241,24 @@ public class ApiInvoker {
}
}
public String invokeAPI(String host, String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
public String invokeAPI(String host, String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
HttpClient client = getClient(host);
StringBuilder b = new StringBuilder();
for(String key : queryParams.keySet()) {
String value = queryParams.get(key);
if (value != null){
if(b.toString().length() == 0)
b.append("?");
else
b.append("?");
if (queryParams != null){
for (Pair queryParam : queryParams){
if (!queryParam.getName().isEmpty()) {
b.append(escapeString(queryParam.getName()));
b.append("=");
b.append(escapeString(queryParam.getValue()));
b.append("&");
b.append(escapeString(key)).append("=").append(escapeString(value));
}
}
}
String url = host + path + b.toString();
String querystring = b.substring(0, b.length() - 1);
String url = host + path + querystring;
HashMap<String, String> headers = new HashMap<String, String>();

View File

@ -11,10 +11,9 @@ import collection.mutable
class {{classname}}(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {
{{#operation}}
def {{nickname}}({{#allParams}}{{#optional}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}},
{{/hasMore}}
{{/optional}}{{^optional}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}},
{{/hasMore}}{{/optional}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = {
def {{nickname}}({{#allParams}}{{^required}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}},{{/hasMore}}
{{/required}}{{#required}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}},
{{/hasMore}}{{/required}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = {
// create path and map variables
val path = (addFmt("{{path}}"){{#pathParams}}
replaceAll ("\\{" + "{{baseName}}" + "\\}",{{paramName}}.toString){{/pathParams}})
@ -27,8 +26,8 @@ class {{classname}}(client: TransportClient, config: SwaggerConfig) extends ApiC
val paramCount = (Set[Any]({{/requiredParamCount}}{{#requiredParams}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) - null).size
if (paramCount != {{requiredParamCount}}) sys.error("missing required params"){{/requiredParamCount}}
{{#queryParams}}{{#optional}}if({{paramName}} != null) {{paramName}}.foreach { v => queryParams += "{{baseName}}" -> v.toString }{{/optional}}{{^optional}}
if({{paramName}} != null) queryParams += "{{baseName}}" -> {{paramName}}.toString{{/optional}}{{/queryParams}}
{{#queryParams}}{{^required}}if({{paramName}} != null) {{paramName}}.foreach { v => queryParams += "{{baseName}}" -> v.toString }{{/required}}{{#required}}
if({{paramName}} != null) queryParams += "{{baseName}}" -> {{paramName}}.toString{{/required}}{{/queryParams}}
{{#headerParams}}headerParams += "{{baseName}}" -> {{paramName}}.toString{{/headerParams}}

View File

@ -8,7 +8,7 @@ using System.Threading.Tasks;
using Newtonsoft.Json;
using RestSharp;
namespace {{invokerPackage}} {
namespace {{packageName}}.Client {
/// <summary>
/// API client is mainly responible for making the HTTP call to the API backend
/// </summary>

View File

@ -1,6 +1,6 @@
using System;
namespace {{invokerPackage}} {
namespace {{packageName}}.Client {
/// <summary>
/// API Exception
/// </summary>

View File

@ -4,14 +4,18 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using {{invokerPackage}};
namespace {{invokerPackage}} {
namespace {{packageName}}.Client {
/// <summary>
/// Represents a set of configuration settings
/// </summary>
public class Configuration{
/// <summary>
/// Version of the package
/// </summary>
public const string Version = "{{packageVersion}}";
/// <summary>
/// Gets or sets the API client. This is the default API client for making HTTP calls.
/// </summary>

View File

@ -2,12 +2,12 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using RestSharp;
using {{invokerPackage}};
using {{modelPackage}};
using {{packageName}}.Client;
using {{packageName}}.Model;
{{#imports}}
{{/imports}}
namespace {{package}} {
namespace {{packageName}}.Api {
{{#operations}}
public interface I{{classname}} {

View File

@ -7,13 +7,13 @@ using Newtonsoft.Json;
{{#models}}
{{#model}}
namespace {{package}} {
namespace {{packageName}}.Model {
/// <summary>
/// {{description}}
/// </summary>
[DataContract]
public class {{classname}} {
public class {{classname}}{{#parent}} : {{{parent}}}{{/parent}} {
{{#vars}}
{{#description}}/* {{{description}}} */{{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue=false)]
@ -39,11 +39,11 @@ namespace {{package}} {
/// Get the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public string ToJson() {
public {{#parent}} new {{/parent}}string ToJson() {
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
{{/model}}
{{/models}}
{{/model}}
{{/models}}
}

View File

@ -54,7 +54,7 @@ sub new {
#
# {{{summary}}}
#
{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}}
{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
{{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
#
sub {{nickname}} {

View File

@ -25,141 +25,60 @@ class ApiClient {
public static $PUT = "PUT";
public static $DELETE = "DELETE";
/** @var string[] Array of default headers where the key is the header name and the value is the header value */
private $default_header = array();
/** @var Configuration */
protected $config;
/** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */
protected $curl_timeout = 0;
/** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */
protected $user_agent = "PHP-Swagger";
/** @var ObjectSerializer */
protected $serializer;
/**
* @param string $host Base url of the API server (optional)
* @param Configuration $config config for this ApiClient
*/
function __construct($host = null) {
if ($host === null) {
$this->host = '{{basePath}}';
} else {
$this->host = $host;
function __construct(Configuration $config = null) {
if ($config == null) {
$config = Configuration::getDefaultConfiguration();
}
$this->config = $config;
$this->serializer = new ObjectSerializer();
}
/**
* add default header
*
* @param string $header_name header name (e.g. Token)
* @param string $header_value header value (e.g. 1z8wp3)
* get the config
* @return Configuration
*/
public function addDefaultHeader($header_name, $header_value) {
if (!is_string($header_name))
throw new \InvalidArgumentException('Header name must be a string.');
$this->default_header[$header_name] = $header_value;
public function getConfig() {
return $this->config;
}
/**
* get the default header
*
* @return array default header
* get the serializer
* @return ObjectSerializer
*/
public function getDefaultHeader() {
return $this->default_header;
public function getSerializer() {
return $this->serializer;
}
/**
* delete the default header based on header name
*
* @param string $header_name header name (e.g. Token)
*/
public function deleteDefaultHeader($header_name) {
unset($this->default_header[$header_name]);
}
/**
* set the user agent of the api client
*
* @param string $user_agent the user agent of the api client
*/
public function setUserAgent($user_agent) {
if (!is_string($user_agent))
throw new \InvalidArgumentException('User-agent must be a string.');
$this->user_agent= $user_agent;
}
/**
* get the user agent of the api client
*
* @return string user agent
*/
public function getUserAgent($user_agent) {
return $this->user_agent;
}
/**
* set the HTTP timeout value
*
* @param integer $seconds Number of seconds before timing out [set to 0 for no timeout]
*/
public function setTimeout($seconds) {
if (!is_numeric($seconds) || $seconds < 0)
throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.');
$this->curl_timeout = $seconds;
}
/**
* get the HTTP timeout value
*
* @return string HTTP timeout value
*/
public function getTimeout() {
return $this->curl_timeout;
}
/**
* Get API key (with prefix if set)
* @param string key name
* @param string $apiKey name of apikey
* @return string API key with the prefix
*/
public function getApiKeyWithPrefix($apiKey) {
if (isset(Configuration::$apiKeyPrefix[$apiKey])) {
return Configuration::$apiKeyPrefix[$apiKey]." ".Configuration::$apiKey[$apiKey];
} else if (isset(Configuration::$apiKey[$apiKey])) {
return Configuration::$apiKey[$apiKey];
$prefix = $this->config->getApiKeyPrefix($apiKey);
$apiKey = $this->config->getApiKey($apiKey);
if (!isset($apiKey)) {
return null;
}
if (isset($prefix)) {
$keyWithPrefix = $prefix." ".$apiKey;
} else {
return;
$keyWithPrefix = $apiKey;
}
}
/**
* update hearder and query param based on authentication setting
*
* @param array $headerParams header parameters (by ref)
* @param array $queryParams query parameters (by ref)
* @param array $authSettings array of authentication scheme (e.g ['api_key'])
*/
public function updateParamsForAuth(&$headerParams, &$queryParams, $authSettings)
{
if (count($authSettings) == 0)
return;
// one endpoint can have more than 1 auth settings
foreach($authSettings as $auth) {
// determine which one to use
switch($auth) {
{{#authMethods}}
case '{{name}}':
{{#isApiKey}}{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode(Configuration::$username.":".Configuration::$password);{{/isBasic}}
{{#isOAuth}}//TODO support oauth{{/isOAuth}}
break;
{{/authMethods}}
default:
//TODO show warning about security definition not found
}
}
return $keyWithPrefix;
}
/**
@ -168,18 +87,15 @@ class ApiClient {
* @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
* @throws \{{invokerPackage}}\ApiException on a non 2xx response
* @return mixed
*/
public function callApi($resourcePath, $method, $queryParams, $postData,
$headerParams, $authSettings) {
public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) {
$headers = array();
# determine authentication setting
$this->updateParamsForAuth($headerParams, $queryParams, $authSettings);
# construct the http header
$headerParams = array_merge((array)$this->default_header, (array)$headerParams);
$headerParams = array_merge((array)$this->config->getDefaultHeaders(), (array)$headerParams);
foreach ($headerParams as $key => $val) {
$headers[] = "$key: $val";
@ -190,15 +106,15 @@ class ApiClient {
$postData = http_build_query($postData);
}
else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model
$postData = json_encode($this->sanitizeForSerialization($postData));
$postData = json_encode($this->serializer->sanitizeForSerialization($postData));
}
$url = $this->host . $resourcePath;
$url = $this->config->getHost() . $resourcePath;
$curl = curl_init();
// set timeout, if needed
if ($this->curl_timeout != 0) {
curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_timeout);
if ($this->config->getCurlTimeout() != 0) {
curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout());
}
// return the result on success, rather than just TRUE
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
@ -227,14 +143,14 @@ class ApiClient {
curl_setopt($curl, CURLOPT_URL, $url);
// Set user agent
curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent());
// debugging for curl
if (Configuration::$debug) {
error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file);
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile());
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a'));
curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a'));
} else {
curl_setopt($curl, CURLOPT_VERBOSE, 0);
}
@ -250,8 +166,8 @@ class ApiClient {
$response_info = curl_getinfo($curl);
// debug HTTP response body
if (Configuration::$debug) {
error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file);
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile());
}
// Handle the response
@ -269,153 +185,13 @@ class ApiClient {
return $data;
}
/**
* Build a JSON POST object
*/
protected function sanitizeForSerialization($data)
{
if (is_scalar($data) || null === $data) {
$sanitized = $data;
} else if ($data instanceof \DateTime) {
$sanitized = $data->format(\DateTime::ISO8601);
} else if (is_array($data)) {
foreach ($data as $property => $value) {
$data[$property] = $this->sanitizeForSerialization($value);
}
$sanitized = $data;
} else if (is_object($data)) {
$values = array();
foreach (array_keys($data::$swaggerTypes) as $property) {
if ($data->$property !== null) {
$values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property);
}
}
$sanitized = $values;
} else {
$sanitized = (string)$data;
}
return $sanitized;
}
/**
* Take value and turn it into a string suitable for inclusion in
* the path, by url-encoding.
* @param string $value a string which will be part of the path
* @return string the serialized object
*/
public function toPathValue($value) {
return rawurlencode($this->toString($value));
}
/**
* Take value and turn it into a string suitable for inclusion in
* the query, by imploding comma-separated if it's an object.
* If it's a string, pass through unchanged. It will be url-encoded
* later.
* @param object $object an object to be serialized to a string
* @return string the serialized object
*/
public function toQueryValue($object) {
if (is_array($object)) {
return implode(',', $object);
} else {
return $this->toString($object);
}
}
/**
* Take value and turn it into a string suitable for inclusion in
* the header. If it's a string, pass through unchanged
* If it's a datetime object, format it in ISO8601
* @param string $value a string which will be part of the header
* @return string the header string
*/
public function toHeaderValue($value) {
return $this->toString($value);
}
/**
* Take value and turn it into a string suitable for inclusion in
* the http body (form parameter). If it's a string, pass through unchanged
* If it's a datetime object, format it in ISO8601
* @param string $value the value of the form parameter
* @return string the form string
*/
public function toFormValue($value) {
return $this->toString($value);
}
/**
* Take value and turn it into a string suitable for inclusion in
* the parameter. If it's a string, pass through unchanged
* If it's a datetime object, format it in ISO8601
* @param string $value the value of the parameter
* @return string the header string
*/
public function toString($value) {
if ($value instanceof \DateTime) { // datetime in ISO8601 format
return $value->format(\DateTime::ISO8601);
}
else {
return $value;
}
}
/**
* Deserialize a JSON string into an object
*
* @param object $object object or primitive to be deserialized
* @param string $class class name is passed as a string
* @return object an instance of $class
*/
public function deserialize($data, $class)
{
if (null === $data) {
$deserialized = null;
} elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int]
$inner = substr($class, 4, -1);
$deserialized = array();
if(strrpos($inner, ",") !== false) {
$subClass_array = explode(',', $inner, 2);
$subClass = $subClass_array[1];
foreach ($data as $key => $value) {
$deserialized[$key] = $this->deserialize($value, $subClass);
}
}
} elseif (strcasecmp(substr($class, -2),'[]') == 0) {
$subClass = substr($class, 0, -2);
$values = array();
foreach ($data as $key => $value) {
$values[] = $this->deserialize($value, $subClass);
}
$deserialized = $values;
} elseif ($class == 'DateTime') {
$deserialized = new \DateTime($data);
} elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) {
settype($data, $class);
$deserialized = $data;
} else {
$instance = new $class();
foreach ($instance::$swaggerTypes as $property => $type) {
$original_property_name = $instance::$attributeMap[$property];
if (isset($original_property_name) && isset($data->$original_property_name)) {
$instance->$property = $this->deserialize($data->$original_property_name, $type);
}
}
$deserialized = $instance;
}
return $deserialized;
}
/*
* return the header 'Accept' based on an array of Accept provided
*
* @param array[string] $accept Array of header
* @param string[] $accept Array of header
* @return string Accept (e.g. application/json)
*/
public function selectHeaderAccept($accept) {
public static function selectHeaderAccept($accept) {
if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) {
return NULL;
} elseif (preg_grep("/application\/json/i", $accept)) {
@ -428,10 +204,10 @@ class ApiClient {
/*
* return the content type based on an array of content-type provided
*
* @param array[string] content_type_array Array fo content-type
* @param string[] content_type_array Array fo content-type
* @return string Content-Type (e.g. application/json)
*/
public function selectHeaderContentType($content_type) {
public static 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)) {
@ -440,6 +216,4 @@ class ApiClient {
return implode(',', $content_type);
}
}
}

View File

@ -22,15 +22,20 @@ use \Exception;
class ApiException extends Exception {
/** @var string The HTTP body of the server response. */
protected $response_body;
protected $responseBody;
/** @var string[] The HTTP header of the server response. */
protected $response_headers;
protected $responseHeaders;
/**
* The deserialized response object
*/
protected $responseObject;
public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) {
parent::__construct($message, $code);
$this->response_headers = $responseHeaders;
$this->response_body = $responseBody;
$this->responseHeaders = $responseHeaders;
$this->responseBody = $responseBody;
}
/**
@ -39,7 +44,7 @@ class ApiException extends Exception {
* @return string HTTP response header
*/
public function getResponseHeaders() {
return $this->response_headers;
return $this->responseHeaders;
}
/**
@ -48,7 +53,18 @@ class ApiException extends Exception {
* @return string HTTP response body
*/
public function getResponseBody() {
return $this->response_body;
return $this->responseBody;
}
/**
* sets the deseralized response object (during deserialization)
* @param mixed $obj
*/
public function setResponseObject($obj) {
$this->responseObject = $obj;
}
public function getResponseObject() {
return $this->responseObject;
}
}

View File

@ -0,0 +1,151 @@
<?php
namespace {{invokerPackage}};
class ObjectSerializer {
/**
* Build a JSON POST object
* @param mixed $data the data to serialize
* @return string serialized form of $data
*/
public function sanitizeForSerialization($data) {
if (is_scalar($data) || null === $data) {
$sanitized = $data;
} else if ($data instanceof \DateTime) {
$sanitized = $data->format(\DateTime::ISO8601);
} else if (is_array($data)) {
foreach ($data as $property => $value) {
$data[$property] = $this->sanitizeForSerialization($value);
}
$sanitized = $data;
} else if (is_object($data)) {
$values = array();
foreach (array_keys($data::$swaggerTypes) as $property) {
$getter = $data::$getters[$property];
if ($data->$getter() !== null) {
$values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$getter());
}
}
$sanitized = $values;
} else {
$sanitized = (string)$data;
}
return $sanitized;
}
/**
* Take value and turn it into a string suitable for inclusion in
* the path, by url-encoding.
* @param string $value a string which will be part of the path
* @return string the serialized object
*/
public function toPathValue($value) {
return rawurlencode($this->toString($value));
}
/**
* Take value and turn it into a string suitable for inclusion in
* the query, by imploding comma-separated if it's an object.
* If it's a string, pass through unchanged. It will be url-encoded
* later.
* @param object $object an object to be serialized to a string
* @return string the serialized object
*/
public function toQueryValue($object) {
if (is_array($object)) {
return implode(',', $object);
} else {
return $this->toString($object);
}
}
/**
* Take value and turn it into a string suitable for inclusion in
* the header. If it's a string, pass through unchanged
* If it's a datetime object, format it in ISO8601
* @param string $value a string which will be part of the header
* @return string the header string
*/
public function toHeaderValue($value) {
return $this->toString($value);
}
/**
* Take value and turn it into a string suitable for inclusion in
* the http body (form parameter). If it's a string, pass through unchanged
* If it's a datetime object, format it in ISO8601
* @param string $value the value of the form parameter
* @return string the form string
*/
public function toFormValue($value) {
return $this->toString($value);
}
/**
* Take value and turn it into a string suitable for inclusion in
* the parameter. If it's a string, pass through unchanged
* If it's a datetime object, format it in ISO8601
* @param string $value the value of the parameter
* @return string the header string
*/
public function toString($value) {
if ($value instanceof \DateTime) { // datetime in ISO8601 format
return $value->format(\DateTime::ISO8601);
} else {
return $value;
}
}
/**
* Deserialize a JSON string into an object
*
* @param mixed $data object or primitive to be deserialized
* @param string $class class name is passed as a string
* @return object an instance of $class
*/
public function deserialize($data, $class) {
if (null === $data) {
$deserialized = null;
} elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int]
$inner = substr($class, 4, -1);
$deserialized = array();
if(strrpos($inner, ",") !== false) {
$subClass_array = explode(',', $inner, 2);
$subClass = $subClass_array[1];
foreach ($data as $key => $value) {
$deserialized[$key] = $this->deserialize($value, $subClass);
}
}
} elseif (strcasecmp(substr($class, -2),'[]') == 0) {
$subClass = substr($class, 0, -2);
$values = array();
foreach ($data as $key => $value) {
$values[] = $this->deserialize($value, $subClass);
}
$deserialized = $values;
} elseif ($class == 'DateTime') {
$deserialized = new \DateTime($data);
} elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) {
settype($data, $class);
$deserialized = $data;
} else {
$instance = new $class();
foreach ($instance::$swaggerTypes as $property => $type) {
$propertySetter = $instance::$setters[$property];
if (!isset($propertySetter) || !isset($data->{$instance::$attributeMap[$property]})) {
continue;
}
$propertyValue = $data->{$instance::$attributeMap[$property]};
if (isset($propertyValue)) {
$instance->$propertySetter($this->deserialize($propertyValue, $type));
}
}
$deserialized = $instance;
}
return $deserialized;
}
}

View File

@ -22,31 +22,29 @@
namespace {{apiPackage}};
use \{{invokerPackage}}\ApiClient;
use \{{invokerPackage}}\Configuration;
use \{{invokerPackage}}\ApiClient;
use \{{invokerPackage}}\ApiException;
use \{{invokerPackage}}\ObjectSerializer;
{{#operations}}
class {{classname}} {
/**
* @param \{{invokerPackage}}\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration
*/
function __construct($apiClient = null) {
if (null === $apiClient) {
if (Configuration::$apiClient === null) {
Configuration::$apiClient = new ApiClient(); // create a new API client if not present
$this->apiClient = Configuration::$apiClient;
}
else
$this->apiClient = Configuration::$apiClient; // use the default one
} else {
$this->apiClient = $apiClient; // use the one provided by the user
}
}
/** @var \{{invokerPackage}}\ApiClient instance of the ApiClient */
private $apiClient;
/**
* @param \{{invokerPackage}}\ApiClient|null $apiClient The api client to use
*/
function __construct($apiClient = null) {
if ($apiClient == null) {
$apiClient = new ApiClient();
$apiClient->getConfig()->setHost('{{basePath}}');
}
$this->apiClient = $apiClient;
}
/**
* @return \{{invokerPackage}}\ApiClient get the API client
*/
@ -55,10 +53,12 @@ class {{classname}} {
}
/**
* @param \{{invokerPackage}} $apiClient set the API client
* @param \{{invokerPackage}}\ApiClient $apiClient set the API client
* @return {{classname}}
*/
public function setApiClient($apiClient) {
public function setApiClient(ApiClient $apiClient) {
$this->apiClient = $apiClient;
return $this;
}
{{#operation}}
@ -67,10 +67,11 @@ class {{classname}} {
*
* {{{summary}}}
*
{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}}{{#required}} (required){{/required}}
{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
* @throws \{{invokerPackage}}\ApiException on non-2xx response
*/
public function {{nickname}}({{#allParams}}${{paramName}}{{#optional}}=null{{/optional}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
public function {{nickname}}({{#allParams}}${{paramName}}{{^required}}=null{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if (${{paramName}} === null) {
@ -86,28 +87,29 @@ class {{classname}} {
$queryParams = array();
$headerParams = array();
$formParams = array();
$_header_accept = $this->apiClient->selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}));
$_header_accept = ApiClient::selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}));
if (!is_null($_header_accept)) {
$headerParams['Accept'] = $_header_accept;
}
$headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}}));
$headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}}));
{{#queryParams}}// query params
if(${{paramName}} !== null) {
$queryParams['{{baseName}}'] = $this->apiClient->toQueryValue(${{paramName}});
$queryParams['{{baseName}}'] = $this->apiClient->getSerializer()->toQueryValue(${{paramName}});
}{{/queryParams}}
{{#headerParams}}// header params
if(${{paramName}} !== null) {
$headerParams['{{baseName}}'] = $this->apiClient->toHeaderValue(${{paramName}});
$headerParams['{{baseName}}'] = $this->apiClient->getSerializer()->toHeaderValue(${{paramName}});
}{{/headerParams}}
{{#pathParams}}// path params
if(${{paramName}} !== null) {
$resourcePath = str_replace("{" . "{{baseName}}" . "}",
$this->apiClient->toPathValue(${{paramName}}), $resourcePath);
$this->apiClient->getSerializer()->toPathValue(${{paramName}}),
$resourcePath);
}{{/pathParams}}
{{#formParams}}// form params
if (${{paramName}} !== null) {
$formParams['{{baseName}}'] = {{#isFile}}'@'.{{/isFile}}$this->apiClient->toFormValue(${{paramName}});
$formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->getSerializer()->toFormValue(${{paramName}});
}{{/formParams}}
{{#bodyParams}}// body params
$_tempBody = null;
@ -122,22 +124,38 @@ class {{classname}} {
// for HTTP post (form)
$httpBody = $formParams;
}
// authentication setting, if any
$authSettings = array({{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}});
{{#authMethods}}{{#isApiKey}}
$apiKey = $this->apiClient->getApiKeyWithPrefix('{{keyParamName}}');
if (isset($apiKey)) {
{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $apiKey;{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $apiKey;{{/isKeyInQuery}}
}{{/isApiKey}}
{{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode($this->apiClient->getConfig()->getUsername().":".$this->apiClient->getConfig()->getPassword());{{/isBasic}}
{{#isOAuth}}//TODO support oauth{{/isOAuth}}
{{/authMethods}}
// make the API Call
$response = $this->apiClient->callAPI($resourcePath, $method,
$queryParams, $httpBody,
$headerParams, $authSettings);
{{#returnType}}if(! $response) {
try {
$response = $this->apiClient->callAPI($resourcePath, $method,
$queryParams, $httpBody,
$headerParams);
} catch (ApiException $e) {
switch ($e->getCode()) { {{#responses}}{{#dataType}}
case {{code}}:
$data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '{{dataType}}');
$e->setResponseObject($data);
break;{{/dataType}}{{/responses}}
}
throw $e;
}
{{#returnType}}
if (!$response) {
return null;
}
$responseObject = $this->apiClient->deserialize($response,'{{returnType}}');
return $responseObject;{{/returnType}}
$responseObject = $this->apiClient->getSerializer()->deserialize($response,'{{returnType}}');
return $responseObject;
{{/returnType}}
}
{{/operation}}
{{newline}}
{{/operations}}
}
{{/operations}}

View File

@ -4,7 +4,7 @@
*
* After registering this autoload function with SPL, the following line
* would cause the function to attempt to load the \{{invokerPackage}}\Baz\Qux class
* from /path/to/project/lib/Baz/Qux.php:
* from /path/to/project/{{srcBasePath}}/Baz/Qux.php:
*
* new \{{invokerPackage}}\Baz\Qux;
*
@ -17,7 +17,7 @@ spl_autoload_register(function ($class) {
$prefix = '{{escapedInvokerPackage}}\\';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/lib/';
$base_dir = __DIR__ . '/{{srcBasePath}}/';
// does the class use the namespace prefix?
$len = strlen($prefix);

View File

@ -28,6 +28,6 @@
"squizlabs/php_codesniffer": "~2.0"
},
"autoload": {
"psr-4": { "{{escapedInvokerPackage}}\\" : "lib/" }
"psr-4": { "{{escapedInvokerPackage}}\\" : "{{srcBasePath}}/" }
}
}

View File

@ -17,37 +17,250 @@
namespace {{invokerPackage}};
use \{{invokerPackage}}\ApiClient;
class Configuration {
private static $defaultConfiguration = null;
/** @var string[] Associate array to store API key(s) */
public static $apiKey = array();
protected $apiKeys = array();
/** string[] Associate array to store API prefix (e.g. Bearer) */
public static $apiKeyPrefix = array();
protected $apiKeyPrefixes = array();
/** @var string Username for HTTP basic authentication */
public static $username = '';
protected $username = '';
/** @var string Password for HTTP basic authentication */
public static $password = '';
protected $password = '';
/** @var \{{invokerPackage}}\ApiClient The default instance of ApiClient */
public static $apiClient;
protected $defaultHeaders = array();
/** @var string The host */
protected $host = 'http://localhost';
/** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */
protected $curlTimeout = 0;
/** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */
protected $userAgent = "PHP-Swagger";
/** @var bool Debug switch (default set to false) */
public static $debug = false;
protected $debug = false;
/** @var string Debug file location (log to STDOUT by default) */
public static $debug_file = 'php://output';
protected $debugFile = 'php://output';
/*
* manually initalize ApiClient
/**
* @param string $key
* @param string $value
* @return Configuration
*/
public static function init() {
if (self::$apiClient === null)
self::$apiClient = new ApiClient();
public function setApiKey($key, $value) {
$this->apiKeys[$key] = $value;
return $this;
}
/**
* @param $key
* @return string
*/
public function getApiKey($key) {
return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null;
}
/**
* @param string $key
* @param string $value
* @return Configuration
*/
public function setApiKeyPrefix($key, $value) {
$this->apiKeyPrefixes[$key] = $value;
return $this;
}
/**
* @param $key
* @return string
*/
public function getApiKeyPrefix($key) {
return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null;
}
/**
* @param string $username
* @return Configuration
*/
public function setUsername($username) {
$this->username = $username;
return $this;
}
/**
* @return string
*/
public function getUsername() {
return $this->username;
}
/**
* @param string $password
* @return Configuration
*/
public function setPassword($password) {
$this->password = $password;
return $this;
}
/**
* @return string
*/
public function getPassword() {
return $this->password;
}
/**
* add default header
*
* @param string $headerName header name (e.g. Token)
* @param string $headerValue header value (e.g. 1z8wp3)
* @return ApiClient
*/
public function addDefaultHeader($headerName, $headerValue) {
if (!is_string($headerName)) {
throw new \InvalidArgumentException('Header name must be a string.');
}
$this->defaultHeaders[$headerName] = $headerValue;
return $this;
}
/**
* get the default header
*
* @return array default header
*/
public function getDefaultHeaders() {
return $this->defaultHeaders;
}
/**
* delete a default header
* @param string $headerName the header to delete
* @return Configuration
*/
public function deleteDefaultHeader($headerName) {
unset($this->defaultHeaders[$headerName]);
}
/**
* @param string $host
* @return Configuration
*/
public function setHost($host) {
$this->host = $host;
return $this;
}
/**
* @return string
*/
public function getHost() {
return $this->host;
}
/**
* set the user agent of the api client
*
* @param string $userAgent the user agent of the api client
* @return ApiClient
*/
public function setUserAgent($userAgent) {
if (!is_string($userAgent)) {
throw new \InvalidArgumentException('User-agent must be a string.');
}
$this->userAgent = $userAgent;
return $this;
}
/**
* get the user agent of the api client
*
* @return string user agent
*/
public function getUserAgent() {
return $this->userAgent;
}
/**
* set the HTTP timeout value
*
* @param integer $seconds Number of seconds before timing out [set to 0 for no timeout]
* @return ApiClient
*/
public function setCurlTimeout($seconds) {
if (!is_numeric($seconds) || $seconds < 0) {
throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.');
}
$this->curlTimeout = $seconds;
return $this;
}
/**
* get the HTTP timeout value
*
* @return string HTTP timeout value
*/
public function getCurlTimeout() {
return $this->curlTimeout;
}
/**
* @param bool $debug
* @return Configuration
*/
public function setDebug($debug) {
$this->debug = $debug;
return $this;
}
/**
* @return bool
*/
public function getDebug() {
return $this->debug;
}
/**
* @param string $debugFile
* @return Configuration
*/
public function setDebugFile($debugFile) {
$this->debugFile = $debugFile;
return $this;
}
/**
* @return string
*/
public function getDebugFile() {
return $this->debugFile;
}
/**
* @return Configuration
*/
public static function getDefaultConfiguration() {
if (self::$defaultConfiguration == null) {
return new Configuration();
}
return self::$defaultConfiguration;
}
public static function setDefaultConfiguration(Configuration $config) {
self::$defaultConfiguration = $config;
}
}

View File

@ -40,18 +40,48 @@ class {{classname}} implements ArrayAccess {
{{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
/** @var string[] Array of attributes to setter functions (for deserialization of responses) */
static $setters = array(
{{#vars}}'{{name}}' => '{{setter}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
/** @var string[] Array of attributes to getter functions (for serialization of requests) */
static $getters = array(
{{#vars}}'{{name}}' => '{{getter}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
{{#vars}}
/** @var {{datatype}} ${{name}} {{#description}}{{{description}}} {{/description}}*/
public ${{name}};
protected ${{name}};
{{/vars}}
/**
* @param mixed[] Array of parameters to initialize the object with
*/
public function __construct(array $data = null) {
{{#vars}}$this->{{name}} = @$data["{{name}}"];{{#hasMore}}
{{/hasMore}}{{/vars}}
if ($data != null) {
{{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}}
{{/hasMore}}{{/vars}}
}
}
{{#vars}}
/**
* get {{name}}
* @return {{datatype}}
*/
public function {{getter}}() {
return $this->{{name}};
}
/**
* set {{name}}
* @param {{datatype}} ${{name}}
* @return $this
*/
public function {{setter}}(${{name}}) {
$this->{{name}} = ${{name}};
return $this;
}
{{/vars}}
public function offsetExists($offset) {
return isset($this->$offset);
}

View File

@ -47,7 +47,7 @@ class {{classname}}(object):
{{{summary}}}
{{{notes}}}
{{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}}
{{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
{{/allParams}}
:return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}
"""

View File

@ -1,6 +1,9 @@
import sys
from setuptools import setup, find_packages
NAME = "{{packageName}}"
VERSION = "{{packageVersion}}"
{{#apiInfo}}{{#apis}}{{^hasMore}}
# To install the library, open a Terminal shell, then run this
@ -15,8 +18,8 @@ from setuptools import setup, find_packages
REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"]
setup(
name="{{module}}",
version="{{version}}",
name=NAME,
version=VERSION,
description="{{appName}}",
author_email="{{infoEmail}}",
url="{{infoUrl}}",

View File

@ -36,7 +36,7 @@ class {{classname}}(object):
{{{notes}}}
Args:
{{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}}
{{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}}
{{/allParams}}
Returns: {{returnType}}

View File

@ -3,6 +3,18 @@ module {{moduleName}}
class Configuration
attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl
# Defines the temporary folder to store downloaded files
# (for API endpoints that have file response).
# Default to use `Tempfile`.
#
# @return [String]
attr_accessor :temp_folder_path
# Defines the headers to be used in HTTP requests of all API calls by default.
#
# @return [Hash]
attr_accessor :default_headers
# Defaults go in here..
def initialize
@format = 'json'
@ -14,6 +26,11 @@ module {{moduleName}}
@force_ending_format = false
@camelize_params = true
@default_headers = {
'Content-Type' => "application/#{@format.downcase}",
'User-Agent' => @user_agent
}
# keys for API key authentication (param-name => api-key)
@api_key = {}
# api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix)

View File

@ -10,27 +10,22 @@ module {{moduleName}}
# All requests must have an HTTP method and a path
# Optionals parameters are :params, :headers, :body, :format, :host
def initialize(http_method, path, attributes={})
attributes[:format] ||= Swagger.configuration.format
attributes[:params] ||= {}
@http_method = http_method.to_sym
@path = path
# Set default headers
default_headers = {
'Content-Type' => "application/#{attributes[:format].downcase}",
'User-Agent' => Swagger.configuration.user_agent
}
attributes.each do |name, value|
send("#{name.to_s.underscore.to_sym}=", value)
end
# Merge argument headers into defaults
attributes[:headers] = default_headers.merge(attributes[:headers] || {})
@format ||= Swagger.configuration.format
@params ||= {}
# Apply default headers
@headers = Swagger.configuration.default_headers.merge(@headers || {})
# Stick in the auth token if there is one
if Swagger.authenticated?
attributes[:headers].merge!({:auth_token => Swagger.configuration.auth_token})
end
self.http_method = http_method.to_sym
self.path = path
attributes.each do |name, value|
send("#{name.to_s.underscore.to_sym}=", value)
@headers.merge!({:auth_token => Swagger.configuration.auth_token})
end
update_params_for_auth!

View File

@ -3,6 +3,7 @@ module {{moduleName}}
class Response
require 'json'
require 'date'
require 'tempfile'
attr_accessor :raw
@ -31,8 +32,11 @@ module {{moduleName}}
def deserialize(return_type)
return nil if body.blank?
# handle file downloading - save response body into a tmp file and return the File instance
return download_file if return_type == 'File'
# ensuring a default content type
content_type = raw.headers_hash['Content-Type'] || 'application/json'
content_type = raw.headers['Content-Type'] || 'application/json'
unless content_type.start_with?('application/json')
fail "Content-Type is not supported: #{content_type}"
@ -82,6 +86,28 @@ module {{moduleName}}
end
end
# Save response body into a file in (the defined) temporary folder, using the filename
# from the "Content-Disposition" header if provided, otherwise a random filename.
#
# @see Configuration#temp_folder_path
# @return [File] the file downloaded
def download_file
tmp_file = Tempfile.new '', Swagger.configuration.temp_folder_path
content_disposition = raw.headers['Content-Disposition']
if content_disposition
filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
path = File.join File.dirname(tmp_file), filename
else
path = tmp_file.path
end
# close and delete temp file
tmp_file.close!
File.open(path, 'w') { |file| file.write(raw.body) }
Swagger.logger.info "File written to #{path}. Please move the file to a proper folder for further processing and delete the temp afterwards"
return File.new(path)
end
# `headers_hash` is a Typhoeus-specific extension of Hash,
# so simplify it back into a regular old Hash.
def headers

View File

@ -22,5 +22,6 @@ require '{{importPath}}'
module {{moduleName}}
# Initialize the default configuration
Swagger.configuration ||= Swagger::Configuration.new
Swagger.configuration = Swagger::Configuration.new
Swagger.configure { |config| }
end

View File

@ -141,7 +141,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
}
case _ => null
}
response.getClientResponseStatus().getStatusCode() match {
response.getStatusInfo().getStatusCode() match {
case 204 => ""
case code: Int if (Range(200, 299).contains(code)) => {
response.hasEntity() match {
@ -155,7 +155,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
case false => "no data"
}
throw new ApiException(
response.getClientResponseStatus().getStatusCode(),
response.getStatusInfo().getStatusCode(),
entity)
}
}
@ -172,7 +172,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
}
}
}
def newClient(host: String): Client = asyncHttpClient match {
case true => {
import org.sonatype.spice.jersey.client.ahc.config.DefaultAhcConfig
@ -200,4 +200,3 @@ object ApiInvoker extends ApiInvoker(mapper = ScalaJsonUtil.getJsonMapper,
authPreemptive = {{authPreemptive}})
class ApiException(val code: Int, msg: String) extends RuntimeException(msg)

View File

@ -72,6 +72,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add_sources</id>
@ -208,7 +209,7 @@
<scala-version>2.10.4</scala-version>
<joda-version>1.2</joda-version>
<joda-time-version>2.2</joda-time-version>
<jersey-version>1.7</jersey-version>
<jersey-version>1.19</jersey-version>
<swagger-core-version>1.5.0</swagger-core-version>
<jersey-async-version>1.0.5</jersey-async-version>
<maven-plugin.version>1.0.0</maven-plugin.version>
@ -216,6 +217,8 @@
<junit-version>4.8.1</junit-version>
<scala-maven-plugin-version>3.1.5</scala-maven-plugin-version>
<scala-test-version>2.1.3</scala-test-version>
<scala-test-version>2.2.4</scala-test-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem "sinatra"
gem "sinatra-cross_origin"

View File

@ -0,0 +1,29 @@
# Swagger for Sinatra
## Overview
This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find
out more about both the spec and the framework at http://swagger.io. For more information about
Wordnik's APIs, please visit http://developer.wordnik.com.
## Prerequisites
You need to install ruby 1.9.3 and the following gems:
```
sinatra
sinatra-cross_origin
```
## Getting started
This sample was generated with the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
```
rackup -p 4567 config.ru
```
In your [swagger ui](https://github.com/swagger-api/swagger-ui), put in the following URL:
```
http://localhost:4567/resources.json
```
Voila!

View File

@ -0,0 +1,154 @@
require 'json'
require 'sinatra/base'
require 'sinatra/cross_origin'
class Configuration
attr_accessor :base_path, :api_version, :swagger_version, :format_specifier
def initialize
@api_version = '1.0'
@base_path = 'http://localhost:4567'
@swagger_version = '1.1'
@format_specifier = ".json"
end
end
class Swaggering < Sinatra::Base
register Sinatra::CrossOrigin
@@routes = {}
@@configuration = Configuration.new
attr_accessor :configuration
def self.configure
get("/resources" + @@configuration.format_specifier) {
cross_origin
Swaggering.to_resource_listing
}
@@configuration ||= Configuration.new
yield(@@configuration) if block_given?
end
def self.add_route(method, path, swag={}, opts={}, &block)
fullPath = swag["resourcePath"].to_s + @@configuration.format_specifier + path
accepted = case method
when 'get'
get(fullPath, opts, &block)
true
when 'post'
post(fullPath, opts, &block)
true
when 'delete'
delete(fullPath, opts, &block)
true
when 'put'
put(fullPath, opts, &block)
true
else
false
end
if accepted then
resourcePath = swag["resourcePath"].to_s
ops = @@routes[resourcePath]
if ops.nil?
ops = Array.new
@@routes.merge!(resourcePath => ops)
get(resourcePath + @@configuration.format_specifier) do
cross_origin
Swaggering.to_api(resourcePath)
end
end
swag.merge!("httpMethod" => method.to_s.upcase)
ops.push(swag)
end
end
def self.to_resource_listing
apis = Array.new
(@@routes.keys).each do |key|
api = {
"path" => (key + ".{format}"),
"description" => "no description"
}
apis.push api
end
resource = {
"apiVersion" => @@configuration.api_version,
"swaggerVersion" => @@configuration.swagger_version,
"apis" => apis
}
resource.to_json
end
def self.to_api(resourcePath)
apis = {}
models = []
@@routes[resourcePath].each do |route|
endpoint = route["endpoint"].gsub(/:(\w+)(\/?)/,'{\1}\2')
path = (resourcePath + ".{format}" + endpoint)
api = apis[path]
if api.nil?
api = {"path" => path, "description" => "description", "operations" => []}
apis.merge!(path => api)
end
parameters = route["parameters"]
unless parameters.nil? then
parameters.each do |param|
av_string = param["allowableValues"]
unless av_string.nil?
if av_string.count('[') > 0
pattern = /^([A-Z]*)\[(.*)\]/
match = pattern.match av_string
case match.to_a[1]
when "LIST"
allowables = match.to_a[2].split(',')
param["allowableValues"] = {
"valueType" => "LIST",
"values" => allowables
}
when "RANGE"
allowables = match.to_a[2].split(',')
param["allowableValues"] = {
"valueType" => "RANGE",
"min" => allowables[0],
"max" => allowables[1]
}
end
end
end
end
end
op = {
"httpMethod" => route["httpMethod"],
"description" => route["summary"],
"responseClass" => route["responseClass"],
"notes" => route["notes"],
"nickname" => route["nickname"],
"summary" => route["summary"],
"parameters" => route["parameters"]
}
api["operations"].push(op)
end
api_listing = {
"apiVersion" => @@configuration.api_version,
"swaggerVersion" => @@configuration.swagger_version,
"basePath" => @@configuration.base_path,
"resourcePath" => resourcePath,
"apis" => apis.values,
"models" => models
}
api_listing.to_json
end
end

View File

@ -0,0 +1,57 @@
require 'json'
{{#operations}}
{{#operation}}
MyApp.add_route('{{httpMethod}}', '{{path}}', {
"resourcePath" => "/{{baseName}}",
"summary" => "{{{summary}}}",
"nickname" => "{{nickname}}",
"responseClass" => "{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}",
"endpoint" => "{{path}}",
"notes" => "{{{notes}}}",
"parameters" => [
{{#queryParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "query",
"allowMultiple" => {{allowMultiple}},
"allowableValues" => "{{allowableValues}}",
{{#defaultValue}}"defaultValue" => {{{defaultValue}}}{{/defaultValue}}
},
{{/queryParams}}
{{#pathParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "path",
},
{{/pathParams}}
{{#headerParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "header",
},
{{/headerParams}}
{{#bodyParams}}
{
"name" => "body",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "body",
}
{{/bodyParams}}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,2 @@
require './my_app'
run MyApp

View File

@ -0,0 +1,12 @@
require './lib/swaggering'
# only need to extend if you want special configuration!
class MyApp < Swaggering
self.configure do |config|
config.api_version = '0.2'
end
end
{{#apis}}
require './lib/{{className}}.rb'
{{/apis}}

View File

@ -5,17 +5,16 @@
//
import Foundation
import PromiseKit
class {{projectName}}API {
static let basePath = "{{^basePathOverride}}{{basePath}}{{/basePathOverride}}{{basePathOverride}}"
class OneteamAPI {
static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/"
static var credential: NSURLCredential?
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
}
class APIBase {
func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? {
let encoded: AnyObject? = encodable?.encode()
let encoded: AnyObject? = encodable?.encodeToJSON()
if encoded! is [AnyObject] {
var dictionary = [String:AnyObject]()
@ -44,7 +43,7 @@ class RequestBuilder<T> {
self.isBody = isBody
}
func execute() -> Promise<Response<T>> { fatalError("Not implemented") }
func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) { }
func addHeader(#name: String, value: String) -> Self {
if !value.isEmpty {
@ -54,7 +53,7 @@ class RequestBuilder<T> {
}
func addCredential() -> Self {
self.credential = {{projectName}}API.credential
self.credential = OneteamAPI.credential
return self
}
}
@ -63,4 +62,3 @@ protocol RequestBuilderFactory {
func getBuilder<T>() -> RequestBuilder<T>.Type
}

View File

@ -5,7 +5,6 @@
//
import Alamofire
import PromiseKit
class AlamofireRequestBuilderFactory: RequestBuilderFactory {
func getBuilder<T>() -> RequestBuilder<T>.Type {
@ -21,7 +20,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody)
}
override func execute() -> Promise<Response<T>> {
override func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) {
let managerId = NSUUID().UUIDString
// Create a new manager for each request to customize its request header
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
@ -35,36 +34,41 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
request.authenticate(usingCredential: credential)
}
let defer = Promise<Response<T>>.defer()
request.responseJSON(options: .AllowFragments) { (req, res, json, error) in
managerStore.removeValueForKey(managerId)
if let error = error {
defer.reject(error)
completion(response: nil, erorr: error)
return
}
if res!.statusCode >= 400 {
//TODO: Add error entity
let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: [:])
defer.reject(error)
let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:]
let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo)
completion(response: nil, erorr: error)
return
}
if () is T {
let response = Response(response: res!, body: () as! T)
defer.fulfill(response)
completion(response: response, erorr: nil)
return
}
if let json: AnyObject = json {
let body = Decoders.decode(clazz: T.self, source: json)
let response = Response(response: res!, body: body)
defer.fulfill(response)
completion(response: response, erorr: nil)
return
} else if "" is T {
// swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release
// https://github.com/swagger-api/swagger-parser/pull/34
let response = Response(response: res!, body: "" as! T)
completion(response: response, erorr: nil)
return
}
defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
}
return defer.promise
}
private func buildHeaders() -> [String: AnyObject] {
@ -76,4 +80,3 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
}
}

View File

@ -4,45 +4,45 @@
// https://github.com/swagger-api/swagger-codegen
//
import Alamofire
import PromiseKit
import Alamofire{{#usePromiseKit}}
import PromiseKit{{/usePromiseKit}}
extension Bool: JSONEncodable {
func encode() -> AnyObject { return self }
func encodeToJSON() -> AnyObject { return self }
}
extension Float: JSONEncodable {
func encode() -> AnyObject { return self }
func encodeToJSON() -> AnyObject { return self }
}
extension Int: JSONEncodable {
func encode() -> AnyObject { return self }
func encodeToJSON() -> AnyObject { return self }
}
extension Double: JSONEncodable {
func encode() -> AnyObject { return self }
func encodeToJSON() -> AnyObject { return self }
}
extension String: JSONEncodable {
func encode() -> AnyObject { return self }
func encodeToJSON() -> AnyObject { return self }
}
private func encodeIfPossible<T>(object: T) -> AnyObject {
if object is JSONEncodable {
return (object as! JSONEncodable).encode()
return (object as! JSONEncodable).encodeToJSON()
} else {
return object as! AnyObject
}
}
extension Array: JSONEncodable {
func encode() -> AnyObject {
func encodeToJSON() -> AnyObject {
return self.map(encodeIfPossible)
}
}
extension Dictionary: JSONEncodable {
func encode() -> AnyObject {
func encodeToJSON() -> AnyObject {
var dictionary = [NSObject:AnyObject]()
for (key, value) in self {
dictionary[key as! NSObject] = encodeIfPossible(value)
@ -50,3 +50,30 @@ extension Dictionary: JSONEncodable {
return dictionary
}
}
private let dateFormatter: NSDateFormatter = {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter
}()
extension NSDate: JSONEncodable {
func encodeToJSON() -> AnyObject {
return dateFormatter.stringFromDate(self)
}
}
{{#usePromiseKit}}extension RequestBuilder {
func execute() -> Promise<Response<T>> {
let deferred = Promise<Response<T>>.defer()
self.execute { (response: Response<T>?, error: NSError?) in
if let response = response {
deferred.fulfill(response)
} else {
deferred.reject(error!)
}
}
return deferred.promise
}
}{{/usePromiseKit}}

View File

@ -7,7 +7,7 @@
import Foundation
protocol JSONEncodable {
func encode() -> AnyObject
func encodeToJSON() -> AnyObject
}
class Response<T> {
@ -97,25 +97,32 @@ class Decoders {
static private func initialize() {
dispatch_once(&once) {
let dateTimeFormatter = NSDateFormatter()
dateTimeFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let formatters = [
"yyyy-MM-dd",
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
"yyyy-MM-dd'T'HH:mm:ss'Z'"
].map { (format: String) -> NSDateFormatter in
let formatter = NSDateFormatter()
formatter.dateFormat = format
return formatter
}
// Decoder for NSDate
Decoders.addDecoder(clazz: NSDate.self) { (source: AnyObject) -> NSDate in
let sourceString = source as! String
if count(sourceString) == 10 {
return dateFormatter.dateFromString(sourceString)!
for formatter in formatters {
if let date = formatter.dateFromString(sourceString) {
return date
}
}
return dateTimeFormatter.dateFromString(sourceString)!
fatalError("formatter failed to parse \(sourceString)")
} {{#models}}{{#model}}
// Decoder for {{{classname}}}
Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in
let sourceDictionary = source as! [NSObject:AnyObject]
var instance = {{classname}}(){{#vars}}{{#isEnum}}
instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#required}}!{{/required}} {{/isEnum}}{{^isEnum}}
instance.{{name}} = Decoders.decode{{^required}}Optional{{/required}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#required}}!{{/required}}){{/isEnum}}{{/vars}}
instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}} {{/isEnum}}{{^isEnum}}
instance.{{name}} = Decoders.decode{{^unwrapRequired}}Optional{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}Optional{{/required}}{{/unwrapRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}}){{/isEnum}}{{/vars}}
return instance
}{{/model}}
{{/models}}

View File

@ -21,7 +21,9 @@ extension {{projectName}}API {
- {{{notes}}}{{/notes}}{{#subresourceOperation}}
- subresourceOperation: {{subresourceOperation}}{{/subresourceOperation}}{{#defaultResponse}}
- defaultResponse: {{defaultResponse}}{{/defaultResponse}}{{#authMethods}}
- authMethods: {{authMethods}}{{/authMethods}}{{#responseHeaders}}
- {{#isBasic}}BASIC{{/isBasic}}{{#isOAuth}}OAuth{{/isOAuth}}{{#isApiKey}}API Key{{/isApiKey}}:
- type: {{type}}{{#keyParamName}} {{keyParamName}} {{#isKeyInQuery}}(QUERY){{/isKeyInQuery}}{{#isKeyInHeaer}}(HEADER){{/isKeyInHeaer}}{{/keyParamName}}
- name: {{name}}{{/authMethods}}{{#responseHeaders}}
- responseHeaders: {{responseHeaders}}{{/responseHeaders}}{{#examples}}
- examples: {{{examples}}}{{/examples}}{{#externalDocs}}
- externalDocs: {{externalDocs}}{{/externalDocs}}{{#hasParams}}
@ -35,7 +37,7 @@ extension {{projectName}}API {
path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}}
let url = {{projectName}}API.basePath + path
{{#bodyParam}}
let parameters = {{paramName}}{{^required}}?{{/required}}.encode() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}}
let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}}
let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}}
"{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}}
]{{/hasMore}}{{/queryParams}}

View File

@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable {
}
{{/isEnum}}{{/vars}}
{{#vars}}{{#isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatype}}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}
{{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}
{{/vars}}
// MARK: JSONEncodable
func encode() -> AnyObject {
func encodeToJSON() -> AnyObject {
var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}}
nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}}
nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.rawValue{{/isEnum}}{{^isPrimitiveType}}
nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encode(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}}
nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encode(){{/isContainer}}{{/vars}}
nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}}
nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}}
nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isContainer}}{{/vars}}
let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:]
return dictionary
}

View File

@ -3,6 +3,7 @@ package Java
import io.swagger.codegen.languages.JavaClientCodegen
import io.swagger.models._
import io.swagger.models.properties._
import io.swagger.util.Json
import org.junit.runner.RunWith
import org.scalatest.{FlatSpec, Matchers}
import org.scalatest.junit.JUnitRunner
@ -344,3 +345,32 @@ class JavaModelTest extends FlatSpec with Matchers {
cm.classname should be("WithDots")
}
}
@RunWith(classOf[JUnitRunner])
class JavaModelTest2 extends FlatSpec with Matchers {
it should "translate an invalid param name" in {
val model = new ModelImpl()
.description("a model with a 2nd char upper-case property names")
.property("_", new StringProperty())
val codegen = new JavaClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.vars.size should be(1)
val vars = cm.vars
Json.prettyPrint(vars.get(0))
vars.get(0).baseName should be("_")
vars.get(0).getter should be("getU")
vars.get(0).setter should be("setU")
vars.get(0).datatype should be("String")
vars.get(0).name should be("u")
vars.get(0).defaultValue should be("null")
vars.get(0).baseType should be("String")
vars.get(0).hasMore should equal(null)
vars.get(0).isNotContainer should equal(true)
}
}

View File

@ -0,0 +1,170 @@
package typescriptangular
import io.swagger.codegen.languages.TypeScriptAngularClientCodegen
import io.swagger.models._
import io.swagger.models.properties._
import org.junit.runner.RunWith
import org.scalatest.{FlatSpec, Matchers}
import org.scalatest.junit.JUnitRunner
import scala.collection.JavaConverters._
@RunWith(classOf[JUnitRunner])
class TypeScriptAngularModelTest extends FlatSpec with Matchers {
it should "convert a simple TypeScript Angular model" in {
val model = new ModelImpl()
.description("a sample model")
.property("id", new LongProperty())
.property("name", new StringProperty())
.property("createdAt", new DateTimeProperty())
.required("id")
.required("name")
val codegen = new TypeScriptAngularClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(3)
val vars = cm.vars
vars.get(0).baseName should be("id")
vars.get(0).datatype should be("number")
vars.get(0).name should be("id")
vars.get(0).defaultValue should be("null")
vars.get(0).baseType should be("number")
vars.get(0).hasMore should equal(true)
vars.get(0).required should equal(true)
vars.get(0).isNotContainer should equal(true)
vars.get(1).baseName should be("name")
vars.get(1).datatype should be("string")
vars.get(1).name should be("name")
vars.get(1).defaultValue should be("null")
vars.get(1).baseType should be("string")
vars.get(1).hasMore should equal(true)
vars.get(1).required should equal(true)
vars.get(1).isNotContainer should equal(true)
vars.get(2).baseName should be("createdAt")
vars.get(2).complexType should be("Date")
vars.get(2).datatype should be("Date")
vars.get(2).name should be("createdAt")
vars.get(2).defaultValue should be("null")
vars.get(2).hasMore should equal(null)
vars.get(2).required should equal(null)
vars.get(2).isNotContainer should equal(true)
}
it should "convert a model with list property" in {
val model = new ModelImpl()
.description("a sample model")
.property("id", new LongProperty())
.property("urls", new ArrayProperty()
.items(new StringProperty()))
.required("id")
val codegen = new TypeScriptAngularClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(2)
val vars = cm.vars
vars.get(0).baseName should be("id")
vars.get(0).datatype should be("number")
vars.get(0).name should be("id")
vars.get(0).defaultValue should be("null")
vars.get(0).baseType should be("number")
vars.get(0).hasMore should equal(true)
vars.get(0).required should equal(true)
vars.get(0).isNotContainer should equal(true)
vars.get(1).baseName should be("urls")
vars.get(1).datatype should be("Array<string>")
vars.get(1).name should be("urls")
vars.get(1).baseType should be("Array")
vars.get(1).hasMore should be(null)
vars.get(1).required should equal(null)
vars.get(1).isContainer should equal(true)
}
it should "convert a model with complex property" in {
val model = new ModelImpl()
.description("a sample model")
.property("children", new RefProperty("#/definitions/Children"))
val codegen = new TypeScriptAngularClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(1)
val vars = cm.vars
vars.get(0).baseName should be("children")
vars.get(0).datatype should be("Children")
vars.get(0).name should be("children")
vars.get(0).baseType should be("Children")
vars.get(0).required should equal(null)
vars.get(0).isNotContainer should equal(true)
}
it should "convert a model with complex list property" in {
val model = new ModelImpl()
.description("a sample model")
.property("children", new ArrayProperty()
.items(new RefProperty("#/definitions/Children")))
val codegen = new TypeScriptAngularClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(1)
val vars = cm.vars
vars.get(0).baseName should be("children")
vars.get(0).complexType should be("Children")
vars.get(0).datatype should be("Array<Children>")
vars.get(0).name should be("children")
vars.get(0).baseType should be("Array")
vars.get(0).required should equal(null)
vars.get(0).isContainer should equal(true)
}
it should "convert an array model" in {
val model = new ArrayModel()
.description("an array model")
.items(new RefProperty("#/definitions/Children"))
val codegen = new TypeScriptAngularClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("an array model")
cm.vars.size should be(0)
}
it should "convert an map model" in {
val model = new ModelImpl()
.description("an map model")
.additionalProperties(new RefProperty("#/definitions/Children"))
val codegen = new TypeScriptAngularClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("an map model")
cm.vars.size should be(0)
cm.imports.size should be(1)
(cm.imports.asScala.toSet & Set("Children")).size should be(1)
}
}

View File

@ -0,0 +1,170 @@
package typescriptnode
import io.swagger.codegen.languages.TypeScriptNodeClientCodegen
import io.swagger.models._
import io.swagger.models.properties._
import org.junit.runner.RunWith
import org.scalatest.{FlatSpec, Matchers}
import org.scalatest.junit.JUnitRunner
import scala.collection.JavaConverters._
@RunWith(classOf[JUnitRunner])
class TypeScriptNodeModelTest extends FlatSpec with Matchers {
it should "convert a simple TypeScript Node model" in {
val model = new ModelImpl()
.description("a sample model")
.property("id", new LongProperty())
.property("name", new StringProperty())
.property("createdAt", new DateTimeProperty())
.required("id")
.required("name")
val codegen = new TypeScriptNodeClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(3)
val vars = cm.vars
vars.get(0).baseName should be("id")
vars.get(0).datatype should be("number")
vars.get(0).name should be("id")
vars.get(0).defaultValue should be("null")
vars.get(0).baseType should be("number")
vars.get(0).hasMore should equal(true)
vars.get(0).required should equal(true)
vars.get(0).isNotContainer should equal(true)
vars.get(1).baseName should be("name")
vars.get(1).datatype should be("string")
vars.get(1).name should be("name")
vars.get(1).defaultValue should be("null")
vars.get(1).baseType should be("string")
vars.get(1).hasMore should equal(true)
vars.get(1).required should equal(true)
vars.get(1).isNotContainer should equal(true)
vars.get(2).baseName should be("createdAt")
vars.get(2).complexType should be("Date")
vars.get(2).datatype should be("Date")
vars.get(2).name should be("createdAt")
vars.get(2).defaultValue should be("null")
vars.get(2).hasMore should equal(null)
vars.get(2).required should equal(null)
vars.get(2).isNotContainer should equal(true)
}
it should "convert a model with list property" in {
val model = new ModelImpl()
.description("a sample model")
.property("id", new LongProperty())
.property("urls", new ArrayProperty()
.items(new StringProperty()))
.required("id")
val codegen = new TypeScriptNodeClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(2)
val vars = cm.vars
vars.get(0).baseName should be("id")
vars.get(0).datatype should be("number")
vars.get(0).name should be("id")
vars.get(0).defaultValue should be("null")
vars.get(0).baseType should be("number")
vars.get(0).hasMore should equal(true)
vars.get(0).required should equal(true)
vars.get(0).isNotContainer should equal(true)
vars.get(1).baseName should be("urls")
vars.get(1).datatype should be("Array<string>")
vars.get(1).name should be("urls")
vars.get(1).baseType should be("Array")
vars.get(1).hasMore should be(null)
vars.get(1).required should equal(null)
vars.get(1).isContainer should equal(true)
}
it should "convert a model with complex property" in {
val model = new ModelImpl()
.description("a sample model")
.property("children", new RefProperty("#/definitions/Children"))
val codegen = new TypeScriptNodeClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(1)
val vars = cm.vars
vars.get(0).baseName should be("children")
vars.get(0).datatype should be("Children")
vars.get(0).name should be("children")
vars.get(0).baseType should be("Children")
vars.get(0).required should equal(null)
vars.get(0).isNotContainer should equal(true)
}
it should "convert a model with complex list property" in {
val model = new ModelImpl()
.description("a sample model")
.property("children", new ArrayProperty()
.items(new RefProperty("#/definitions/Children")))
val codegen = new TypeScriptNodeClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("a sample model")
cm.vars.size should be(1)
val vars = cm.vars
vars.get(0).baseName should be("children")
vars.get(0).complexType should be("Children")
vars.get(0).datatype should be("Array<Children>")
vars.get(0).name should be("children")
vars.get(0).baseType should be("Array")
vars.get(0).required should equal(null)
vars.get(0).isContainer should equal(true)
}
it should "convert an array model" in {
val model = new ArrayModel()
.description("an array model")
.items(new RefProperty("#/definitions/Children"))
val codegen = new TypeScriptNodeClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("an array model")
cm.vars.size should be(0)
}
it should "convert an map model" in {
val model = new ModelImpl()
.description("an map model")
.additionalProperties(new RefProperty("#/definitions/Children"))
val codegen = new TypeScriptNodeClientCodegen()
val cm = codegen.fromModel("sample", model)
cm.name should be("sample")
cm.classname should be("Sample")
cm.description should be("an map model")
cm.vars.size should be(0)
cm.imports.size should be(1)
(cm.imports.asScala.toSet & Set("Children")).size should be(1)
}
}

View File

@ -397,6 +397,7 @@
<modules>
<module>modules/swagger-codegen</module>
<module>modules/swagger-codegen-cli</module>
<module>modules/swagger-codegen-maven-plugin</module>
<module>modules/swagger-generator</module>
</modules>
<reporting>

View File

@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@ -132,6 +133,62 @@ public class ApiInvoker {
}
}
/*
Format to {@code Pair} objects.
*/
public static List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
List<Pair> params = new ArrayList<Pair>();
// preconditions
if (name == null || name.isEmpty() || value == null) return params;
Collection valueCollection = null;
if (value instanceof Collection) {
valueCollection = (Collection) value;
} else {
params.add(new Pair(name, parameterToString(value)));
return params;
}
if (valueCollection.isEmpty()){
return params;
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
return params;
}
String delimiter = ",";
if (collectionFormat.equals("csv")) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
delimiter = "|";
}
StringBuilder sb = new StringBuilder() ;
for (Object item : valueCollection) {
sb.append(delimiter);
sb.append(parameterToString(item));
}
params.add(new Pair(name, sb.substring(1)));
return params;
}
public ApiInvoker() {
initConnectionManager();
}
@ -184,21 +241,24 @@ public class ApiInvoker {
}
}
public String invokeAPI(String host, String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
public String invokeAPI(String host, String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType) throws ApiException {
HttpClient client = getClient(host);
StringBuilder b = new StringBuilder();
for(String key : queryParams.keySet()) {
String value = queryParams.get(key);
if (value != null){
if(b.toString().length() == 0)
b.append("?");
else
b.append("?");
if (queryParams != null){
for (Pair queryParam : queryParams){
if (!queryParam.getName().isEmpty()) {
b.append(escapeString(queryParam.getName()));
b.append("=");
b.append(escapeString(queryParam.getValue()));
b.append("&");
b.append(escapeString(key)).append("=").append(escapeString(value));
}
}
}
String url = host + path + b.toString();
String querystring = b.substring(0, b.length() - 1);
String url = host + path + querystring;
HashMap<String, String> headers = new HashMap<String, String>();

View File

@ -0,0 +1,38 @@
package io.swagger.client;
public class Pair {
private String name = "";
private String value = "";
public Pair(String name, String value) {
setName(name);
setValue(value);
}
private void setName(String name) {
if (!isValidString(name)) return;
this.name = name;
}
private void setValue(String value) {
if (!isValidString(value)) return;
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
private boolean isValidString(String arg) {
if (arg == null) return false;
if (arg.trim().isEmpty()) return false;
return true;
}
}

View File

@ -2,6 +2,7 @@ package io.swagger.client.api;
import io.swagger.client.ApiException;
import io.swagger.client.ApiInvoker;
import io.swagger.client.Pair;
import io.swagger.client.model.*;
@ -52,7 +53,7 @@ public class PetApi {
String path = "/pet".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -106,7 +107,7 @@ public class PetApi {
String path = "/pet".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -160,14 +161,14 @@ public class PetApi {
String path = "/pet/findByStatus".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
Map<String, String> formParams = new HashMap<String, String>();
if (status != null)
queryParams.put("status", ApiInvoker.parameterToString(status));
queryParams.addAll(ApiInvoker.parameterToPairs("multi", "status", status));
@ -216,14 +217,14 @@ public class PetApi {
String path = "/pet/findByTags".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
Map<String, String> formParams = new HashMap<String, String>();
if (tags != null)
queryParams.put("tags", ApiInvoker.parameterToString(tags));
queryParams.addAll(ApiInvoker.parameterToPairs("multi", "tags", tags));
@ -277,7 +278,7 @@ public class PetApi {
String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -338,7 +339,7 @@ public class PetApi {
String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -408,7 +409,7 @@ public class PetApi {
String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -416,6 +417,7 @@ public class PetApi {
headerParams.put("api_key", ApiInvoker.parameterToString(apiKey));
@ -470,7 +472,7 @@ public class PetApi {
String path = "/pet/{petId}/uploadImage".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params

View File

@ -2,6 +2,7 @@ package io.swagger.client.api;
import io.swagger.client.ApiException;
import io.swagger.client.ApiInvoker;
import io.swagger.client.Pair;
import io.swagger.client.model.*;
@ -51,7 +52,7 @@ public class StoreApi {
String path = "/store/inventory".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -105,7 +106,7 @@ public class StoreApi {
String path = "/store/order".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -164,7 +165,7 @@ public class StoreApi {
String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -223,7 +224,7 @@ public class StoreApi {
String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params

View File

@ -2,6 +2,7 @@ package io.swagger.client.api;
import io.swagger.client.ApiException;
import io.swagger.client.ApiInvoker;
import io.swagger.client.Pair;
import io.swagger.client.model.*;
@ -52,7 +53,7 @@ public class UserApi {
String path = "/user".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -106,7 +107,7 @@ public class UserApi {
String path = "/user/createWithArray".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -160,7 +161,7 @@ public class UserApi {
String path = "/user/createWithList".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -215,16 +216,16 @@ public class UserApi {
String path = "/user/login".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
Map<String, String> formParams = new HashMap<String, String>();
if (username != null)
queryParams.put("username", ApiInvoker.parameterToString(username));
if (password != null)
queryParams.put("password", ApiInvoker.parameterToString(password));
queryParams.addAll(ApiInvoker.parameterToPairs("", "username", username));
queryParams.addAll(ApiInvoker.parameterToPairs("", "password", password));
@ -272,7 +273,7 @@ public class UserApi {
String path = "/user/logout".replaceAll("\\{format\\}","json");
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -331,7 +332,7 @@ public class UserApi {
String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -391,7 +392,7 @@ public class UserApi {
String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params
@ -450,7 +451,7 @@ public class UserApi {
String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString()));
// query params
Map<String, String> queryParams = new HashMap<String, String>();
List<Pair> queryParams = new ArrayList<Pair>();
// header params
Map<String, String> headerParams = new HashMap<String, String>();
// form params

View File

@ -0,0 +1,91 @@
package io.swagger.client;
import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;
public class ApiInvokerTest {
@Test
public void testParameterToPairsWhenNameIsInvalid() throws Exception {
List<Pair> pairs_a = ApiInvoker.parameterToPairs("csv", null, new Integer(1));
List<Pair> pairs_b = ApiInvoker.parameterToPairs("csv", "", new Integer(1));
assertTrue(pairs_a.isEmpty());
assertTrue(pairs_b.isEmpty());
}
@Test
public void testParameterToPairsWhenValueIsNull() throws Exception {
List<Pair> pairs = ApiInvoker.parameterToPairs("csv", "param-a", null);
assertTrue(pairs.isEmpty());
}
@Test
public void testParameterToPairsWhenValueIsEmptyStrings() throws Exception {
// single empty string
List<Pair> pairs = ApiInvoker.parameterToPairs("csv", "param-a", " ");
assertEquals(1, pairs.size());
// list of empty strings
List<String> strs = new ArrayList<String>();
strs.add(" ");
strs.add(" ");
strs.add(" ");
List<Pair> concatStrings = ApiInvoker.parameterToPairs("csv", "param-a", strs);
assertEquals(1, concatStrings.size());
assertFalse(concatStrings.get(0).getValue().isEmpty()); // should contain some delimiters
}
@Test
public void testParameterToPairsWhenValueIsNotCollection() throws Exception {
String name = "param-a";
Integer value = 1;
List<Pair> pairs = ApiInvoker.parameterToPairs("csv", name, value);
assertEquals(1, pairs.size());
assertEquals(value, Integer.valueOf(pairs.get(0).getValue()));
}
@Test
public void testParameterToPairsWhenValueIsCollection() throws Exception {
Map<String, String> collectionFormatMap = new HashMap<String, String>();
collectionFormatMap.put("csv", ",");
collectionFormatMap.put("tsv", "\t");
collectionFormatMap.put("ssv", " ");
collectionFormatMap.put("pipes", "\\|");
collectionFormatMap.put("", ","); // no format, must default to csv
collectionFormatMap.put("unknown", ","); // all other formats, must default to csv
String name = "param-a";
List<Object> values = new ArrayList<Object>();
values.add("value-a");
values.add(123);
values.add(new Date());
// check for multi separately
List<Pair> multiPairs = ApiInvoker.parameterToPairs("multi", name, values);
assertEquals(values.size(), multiPairs.size());
// all other formats
for (String collectionFormat : collectionFormatMap.keySet()) {
List<Pair> pairs = ApiInvoker.parameterToPairs(collectionFormat, name, values);
assertEquals(1, pairs.size());
String delimiter = collectionFormatMap.get(collectionFormat);
String[] pairValueSplit = pairs.get(0).getValue().split(delimiter);
// must equal input values
assertEquals(values.size(), pairValueSplit.length);
}
}
}

View File

@ -3,10 +3,10 @@ organization := ""
name := "-client"
libraryDependencies ++= Seq(
"com.wordnik" %% "swagger-async-httpclient" % "0.3.5",
"joda-time" % "joda-time" % "2.3",
"org.joda" % "joda-convert" % "1.3.1",
"ch.qos.logback" % "logback-classic" % "1.0.13" % "provided",
"org.scalatest" %% "scalatest" % "2.2.1" % "test",
"junit" % "junit" % "4.11" % "test"
"io.swagger" %% "swagger-async-httpclient" % "0.3.5",
"joda-time" % "joda-time" % "2.3",
"org.joda" % "joda-convert" % "1.3.1",
"ch.qos.logback" % "logback-classic" % "1.0.13" % "provided",
"org.scalatest" %% "scalatest" % "2.2.1" % "test",
"junit" % "junit" % "4.11" % "test"
)

View File

@ -7,21 +7,21 @@ import io.swagger.client._
import java.io.Closeable
class SwaggerClient(config: SwaggerConfig) extends Closeable {
val locator = config.locator
val name = config.name
val locator = config.locator
val name = config.name
private[this] val client = transportClient
private[this] val client = transportClient
protected def transportClient: TransportClient = new RestClient(config)
protected def transportClient: TransportClient = new RestClient(config)
val user = new UserApi(client, config)
val pet = new PetApi(client, config)
val store = new StoreApi(client, config)
val user = new UserApi(client, config)
val pet = new PetApi(client, config)
val store = new StoreApi(client, config)
def close() {
client.close()
}
def close() {
client.close()
}
}

View File

@ -7,187 +7,191 @@ import scala.concurrent.{ Future, Await }
import scala.concurrent.duration._
import collection.mutable
class PetApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {
class PetApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {
def updatePet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet"))
def updatePet(body: Option[Pet] = None
)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body))
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def addPet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body))
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def findPetsByStatus(status: List[String] = available)(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = {
// create path and map variables
val path = (addFmt("/pet/findByStatus"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
if(status != null) queryParams += "status" -> status.toString
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def findPetsByTags(tags: List[String])(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = {
// create path and map variables
val path = (addFmt("/pet/findByTags"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
if(tags != null) queryParams += "tags" -> tags.toString
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = {
// create path and map variables
val path = (addFmt("/pet/{petId}")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def updatePetWithForm(petId: String,
name: String,
status: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet/{petId}")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def deletePet(apiKey: String,
petId: Long)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet/{petId}")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
headerParams += "api_key" -> apiKey.toString
val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def uploadFile(petId: Long,
additionalMetadata: String,
file: File)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet/{petId}/uploadImage")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body))
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def addPet(body: Option[Pet] = None
)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body))
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def findPetsByStatus(status: Option[List[String]] = Some(available)
)(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = {
// create path and map variables
val path = (addFmt("/pet/findByStatus"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
if(status != null) status.foreach { v => queryParams += "status" -> v.toString }
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def findPetsByTags(tags: Option[List[String]] = None
)(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = {
// create path and map variables
val path = (addFmt("/pet/findByTags"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
if(tags != null) tags.foreach { v => queryParams += "tags" -> v.toString }
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = {
// create path and map variables
val path = (addFmt("/pet/{petId}")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def updatePetWithForm(petId: String,
name: Option[String] = None,
status: Option[String] = None
)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet/{petId}")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def deletePet(apiKey: Option[String] = None,
petId: Long)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet/{petId}")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
headerParams += "api_key" -> apiKey.toString
val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def uploadFile(petId: Long,
additionalMetadata: Option[String] = None,
file: Option[File] = None
)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/pet/{petId}/uploadImage")
replaceAll ("\\{" + "petId" + "\\}",petId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
}

View File

@ -6,94 +6,95 @@ import scala.concurrent.{ Future, Await }
import scala.concurrent.duration._
import collection.mutable
class StoreApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {
class StoreApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {
def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = {
// create path and map variables
val path = (addFmt("/store/inventory"))
def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = {
// create path and map variables
val path = (addFmt("/store/inventory"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def placeOrder(body: Order)(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = {
// create path and map variables
val path = (addFmt("/store/order"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body))
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def getOrderById(orderId: String)(implicit reader: ClientResponseReader[Order]): Future[Order] = {
// create path and map variables
val path = (addFmt("/store/order/{orderId}")
replaceAll ("\\{" + "orderId" + "\\}",orderId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/store/order/{orderId}")
replaceAll ("\\{" + "orderId" + "\\}",orderId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def placeOrder(body: Option[Order] = None
)(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = {
// create path and map variables
val path = (addFmt("/store/order"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body))
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def getOrderById(orderId: String)(implicit reader: ClientResponseReader[Order]): Future[Order] = {
// create path and map variables
val path = (addFmt("/store/order/{orderId}")
replaceAll ("\\{" + "orderId" + "\\}",orderId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/store/order/{orderId}")
replaceAll ("\\{" + "orderId" + "\\}",orderId.toString))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
}

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