Merge remote-tracking branch 'upstream/develop_2.0' into develop_2.0-RestSharp-path-params

Conflicts:
	modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache
	modules/swagger-codegen/src/main/resources/csharp/api.mustache
This commit is contained in:
Peter S. May 2015-07-17 21:45:54 -04:00
commit 1072c9d017
352 changed files with 15584 additions and 12673 deletions

9
.gitignore vendored
View File

@ -31,8 +31,10 @@ samples/client/petstore/qt5cpp/PetStore/PetStore
samples/client/petstore/qt5cpp/PetStore/Makefile
samples/client/petstore/java/hello.txt
samples/client/petstore/android-java/hello.txt
samples/client/petstore/objc/Build
samples/client/petstore/objc/Pods
samples/client/petstore/objc/SwaggerClientTests/Build
samples/client/petstore/objc/SwaggerClientTests/Pods
samples/client/petstore/objc/SwaggerClientTests/SwaggerClient.xcworkspace
samples/client/petstore/objc/SwaggerClientTests/Podfile.lock
samples/server/petstore/nodejs/node_modules
target
.idea
@ -45,3 +47,6 @@ samples/client/petstore/php/SwaggerClient-php/vendor/
samples/client/petstore/silex/SwaggerServer/composer.lock
samples/client/petstore/silex/SwaggerServer/venodr/
samples/client/petstore/python/.projectile
samples/client/petstore/python/.venv/

View File

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

View File

@ -18,22 +18,28 @@ if [ ! -d "${APP_DIR}" ]; then
fi
cd $APP_DIR
./bin/akka-scala-petstore.sh
./bin/android-java-petstore.sh
./bin/csharp-petstore.sh
./bin/dynamic-html.sh
./bin/html-petstore.sh
./bin/jaxrs-petstore-server.sh
./bin/java-petstore.sh
./bin/qt5-petstore.sh
./bin/jaxrs-petstore-server.sh
./bin/nodejs-petstore-server.sh
./bin/objc-petstore.sh
./bin/perl-petstore.sh
./bin/php-petstore.sh
./bin/python-petstore.sh
./bin/python3-petstore.sh
./bin/qt5-petstore.sh
./bin/retrofit-petstore.sh
./bin/ruby-petstore.sh
./bin/objc-petstore.sh
./bin/scala-async-petstore.sh
./bin/scala-petstore.sh
./bin/scalatra-petstore-server.sh
./bin/silex-petstore-server.sh
./bin/spring-mvc-petstore-server.sh
./bin/swift-petstore.sh
./bin/tizen-petstore.sh
./bin/typescript-angular-petstore.sh
./bin/typescript-node-petstore.sh

5
bin/ruby-petstore.json Normal file
View File

@ -0,0 +1,5 @@
{
"gemName": "petstore",
"moduleName": "Petstore",
"gemVersion": "1.0.0"
}

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/ruby -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -o samples/client/petstore/ruby"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/ruby -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -c bin/ruby-petstore.json -o samples/client/petstore/ruby"
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

@ -1,10 +1,18 @@
package io.swagger.codegen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
public class CodegenParameter {
public Boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
isCookieParam, isBodyParam, isFile, notFile, hasMore, isContainer, secondaryParam;
public String baseName, paramName, dataType, collectionFormat, description, baseType, defaultValue;
public String jsonSchema;
public boolean isEnum;
public List<String> _enum;
public Map<String, Object> allowableValues;
/**
* Determines whether this parameter is mandatory. If the parameter is in "path",
@ -35,6 +43,13 @@ public class CodegenParameter {
output.required = this.required;
output.jsonSchema = this.jsonSchema;
output.defaultValue = this.defaultValue;
output.isEnum = this.isEnum;
if (this._enum != null) {
output._enum = new ArrayList<String>(this._enum);
}
if (this.allowableValues != null) {
output.allowableValues = new HashMap<String, Object>(this.allowableValues);
}
return output;
}

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;
@ -36,6 +37,7 @@ import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.PropertyBuilder;
import io.swagger.models.properties.PropertyBuilder.PropertyId;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json;
@ -49,6 +51,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -850,6 +853,17 @@ public class DefaultCodegen {
}
op.bodyParam = bodyParam;
op.httpMethod = httpMethod.toUpperCase();
// move "required" parameters in front of "optional" parameters
Collections.sort(allParams, new Comparator<CodegenParameter>() {
@Override
public int compare(CodegenParameter one, CodegenParameter another) {
boolean oneRequired = one.required == null ? false : one.required;
boolean anotherRequired = another.required == null ? false : another.required;
if (oneRequired == anotherRequired) return 0;
else if (oneRequired) return -1;
else return 1;
}
});
op.allParams = addHasMore(allParams);
op.bodyParams = addHasMore(bodyParams);
op.pathParams = addHasMore(pathParams);
@ -964,7 +978,9 @@ public class DefaultCodegen {
p.baseType = pr.datatype;
imports.add(pr.baseType);
} else {
property = PropertyBuilder.build(qp.getType(), qp.getFormat(), null);
Map<PropertyId, Object> args = new HashMap<PropertyId, Object>();
args.put(PropertyId.ENUM, qp.getEnum());
property = PropertyBuilder.build(qp.getType(), qp.getFormat(), args);
}
if (property == null) {
LOGGER.warn("warning! Property type \"" + qp.getType() + "\" not found for parameter \"" + param.getName() + "\", using String");
@ -972,8 +988,11 @@ public class DefaultCodegen {
}
property.setRequired(param.getRequired());
CodegenProperty model = fromProperty(qp.getName(), property);
p.collectionFormat = collectionFormat;
p.dataType = model.datatype;
p.isEnum = model.isEnum;
p._enum = model._enum;
p.allowableValues = model.allowableValues;
p.collectionFormat = collectionFormat;
p.paramName = toParamName(qp.getName());
if (model.complexType != null) {
@ -1056,10 +1075,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;
@ -218,7 +219,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
bundle.put("models", allModels);
bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
bundle.put("modelPackage", config.modelPackage());
bundle.put("authMethods", config.fromSecurity(swagger.getSecurityDefinitions()));
List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions());
if (authMethods != null && !authMethods.isEmpty()) {
bundle.put("authMethods", authMethods);
bundle.put("hasAuthMethods", true);
}
if (swagger.getExternalDocs() != null) {
bundle.put("externalDocs", swagger.getExternalDocs());
}
@ -367,7 +372,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()) {
@ -393,6 +413,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Map<String, Object> operations = new HashMap<String, Object>();
Map<String, Object> objs = new HashMap<String, Object>();
objs.put("classname", config.toApiName(tag));
objs.put("pathPrefix", config.toApiVarName(tag));
// check for operationId uniqueness
Set<String> opIds = new HashSet<String>();
@ -430,6 +451,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
operations.put("imports", imports);
// add a flag to indicate whether there's any {{import}}
if (imports.size() > 0) {
operations.put("hasImport", true);
}
config.postProcessOperations(operations);
if (objs.size() > 0) {
List<CodegenOperation> os = (List<CodegenOperation>) objs.get("operation");

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

@ -37,6 +37,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"string",
"bool?",
"double?",
@ -53,6 +54,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"Integer",
"Long",
"Float",
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
@ -68,7 +70,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("number", "double?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "string"); // path to file
typeMapping.put("file", "Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
@ -110,6 +112,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
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"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
@ -163,8 +166,24 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(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(lower) 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

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"));

View File

@ -18,43 +18,60 @@ import java.util.Set;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
protected Set<String> foundationClasses = new HashSet<String>();
protected String sourceFolder = "client";
protected String podName = "SwaggerClient";
protected String podVersion = "1.0.0";
protected String classPrefix = "SWG";
protected String projectName = "SwaggerClient";
public ObjcClientCodegen() {
super();
outputFolder = "generated-code" + File.separator + "objc";
modelTemplateFiles.put("model-header.mustache", ".h");
modelTemplateFiles.put("model-body.mustache", ".m");
apiTemplateFiles.put("api-header.mustache", ".h");
apiTemplateFiles.put("api-body.mustache", ".m");
templateDir = "objc";
modelPackage = "";
defaultIncludes = new HashSet<String>(
Arrays.asList(
"bool",
"BOOL",
"int",
"NSString",
"NSObject",
"NSArray",
"NSNumber",
"NSDate",
"NSDictionary",
"NSMutableArray",
"NSMutableDictionary")
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"NSNumber",
"NSString",
"NSObject",
"NSDate",
"bool",
"BOOL")
);
defaultIncludes.clear();
defaultIncludes.add("bool");
defaultIncludes.add("BOOL");
defaultIncludes.add("int");
defaultIncludes.add("NSURL");
defaultIncludes.add("NSString");
defaultIncludes.add("NSObject");
defaultIncludes.add("NSArray");
defaultIncludes.add("NSNumber");
defaultIncludes.add("NSDate");
defaultIncludes.add("NSDictionary");
defaultIncludes.add("NSMutableArray");
defaultIncludes.add("NSMutableDictionary");
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("NSNumber");
languageSpecificPrimitives.add("NSString");
languageSpecificPrimitives.add("NSObject");
languageSpecificPrimitives.add("NSDate");
languageSpecificPrimitives.add("NSURL");
languageSpecificPrimitives.add("bool");
languageSpecificPrimitives.add("BOOL");
typeMapping.clear();
typeMapping.put("enum", "NSString");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "NSNumber");
typeMapping.put("string", "NSString");
typeMapping.put("integer", "NSNumber");
typeMapping.put("int", "NSNumber");
typeMapping.put("float", "NSNumber");
typeMapping.put("long", "NSNumber");
typeMapping.put("double", "NSNumber");
typeMapping.put("array", "NSArray");
typeMapping.put("map", "NSDictionary");
typeMapping.put("number", "NSNumber");
typeMapping.put("List", "NSArray");
typeMapping.put("object", "NSObject");
typeMapping.put("file", "NSURL");
// ref: http://www.tutorialspoint.com/objective_c/objective_c_basic_syntax.htm
reservedWords = new HashSet<String>(
@ -70,26 +87,10 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
"double", "protocol", "interface", "implementation",
"NSObject", "NSInteger", "NSNumber", "CGFloat",
"property", "nonatomic", "retain", "strong",
"weak", "unsafe_unretained", "readwrite", "readonly"
"weak", "unsafe_unretained", "readwrite", "readonly",
"description"
));
typeMapping = new HashMap<String, String>();
typeMapping.put("enum", "NSString");
typeMapping.put("Date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "BOOL");
typeMapping.put("string", "NSString");
typeMapping.put("integer", "NSNumber");
typeMapping.put("int", "NSNumber");
typeMapping.put("float", "NSNumber");
typeMapping.put("long", "NSNumber");
typeMapping.put("double", "NSNumber");
typeMapping.put("array", "NSArray");
typeMapping.put("map", "NSDictionary");
typeMapping.put("number", "NSNumber");
typeMapping.put("List", "NSArray");
typeMapping.put("object", "NSObject");
importMapping = new HashMap<String, String>();
foundationClasses = new HashSet<String>(
@ -98,15 +99,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
"NSObject",
"NSString",
"NSDate",
"NSURL",
"NSDictionary")
);
instantiationTypes.put("array", "NSMutableArray");
instantiationTypes.put("map", "NSMutableDictionary");
cliOptions.add(new CliOption("classPrefix", "prefix for generated classes"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
cliOptions.add(new CliOption("projectName", "name of the Xcode project in generated Podfile"));
cliOptions.clear();
cliOptions.add(new CliOption("classPrefix", "prefix for generated classes (convention: Abbreviation of pod name e.g. `HN` for `HackerNews`), default: `SWG`"));
cliOptions.add(new CliOption("podName", "cocoapods package name (convention: CameCase), default: `SwaggerClient`"));
cliOptions.add(new CliOption("podVersion", "cocoapods package version, default: `1.0.0`"));
}
public CodegenType getTag() {
@ -125,35 +128,43 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("sourceFolder")) {
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
if (additionalProperties.containsKey("podName")) {
setPodName((String) additionalProperties.get("podName"));
}
if (additionalProperties.containsKey("podVersion")) {
setPodVersion((String) additionalProperties.get("podVersion"));
}
if (additionalProperties.containsKey("classPrefix")) {
this.setClassPrefix((String) additionalProperties.get("classPrefix"));
setClassPrefix((String) additionalProperties.get("classPrefix"));
}
if (additionalProperties.containsKey("projectName")) {
this.setProjectName((String) additionalProperties.get("projectName"));
} else {
additionalProperties.put("projectName", projectName);
}
additionalProperties.put("podName", podName);
additionalProperties.put("podVersion", podVersion);
additionalProperties.put("classPrefix", classPrefix);
supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h"));
supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m"));
supportingFiles.add(new SupportingFile("SWGQueryParamCollection.h", sourceFolder, "SWGQueryParamCollection.h"));
supportingFiles.add(new SupportingFile("SWGQueryParamCollection.m", sourceFolder, "SWGQueryParamCollection.m"));
supportingFiles.add(new SupportingFile("SWGApiClient-header.mustache", sourceFolder, "SWGApiClient.h"));
supportingFiles.add(new SupportingFile("SWGApiClient-body.mustache", sourceFolder, "SWGApiClient.m"));
supportingFiles.add(new SupportingFile("SWGJSONResponseSerializer-header.mustache", sourceFolder, "SWGJSONResponseSerializer.h"));
supportingFiles.add(new SupportingFile("SWGJSONResponseSerializer-body.mustache", sourceFolder, "SWGJSONResponseSerializer.m"));
supportingFiles.add(new SupportingFile("SWGFile.h", sourceFolder, "SWGFile.h"));
supportingFiles.add(new SupportingFile("SWGFile.m", sourceFolder, "SWGFile.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", sourceFolder, "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", sourceFolder, "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("SWGConfiguration-body.mustache", sourceFolder, "SWGConfiguration.m"));
supportingFiles.add(new SupportingFile("SWGConfiguration-header.mustache", sourceFolder, "SWGConfiguration.h"));
supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile"));
String swaggerFolder = podName;
modelPackage = swaggerFolder;
apiPackage = swaggerFolder;
supportingFiles.add(new SupportingFile("Object-header.mustache", swaggerFolder, classPrefix + "Object.h"));
supportingFiles.add(new SupportingFile("Object-body.mustache", swaggerFolder, classPrefix + "Object.m"));
supportingFiles.add(new SupportingFile("QueryParamCollection-header.mustache", swaggerFolder, classPrefix + "QueryParamCollection.h"));
supportingFiles.add(new SupportingFile("QueryParamCollection-body.mustache", swaggerFolder, classPrefix + "QueryParamCollection.m"));
supportingFiles.add(new SupportingFile("ApiClient-header.mustache", swaggerFolder, classPrefix + "ApiClient.h"));
supportingFiles.add(new SupportingFile("ApiClient-body.mustache", swaggerFolder, classPrefix + "ApiClient.m"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-header.mustache", swaggerFolder, classPrefix + "JSONResponseSerializer.h"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-body.mustache", swaggerFolder, classPrefix + "JSONResponseSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-body.mustache", swaggerFolder, classPrefix + "JSONRequestSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-header.mustache", swaggerFolder, classPrefix + "JSONRequestSerializer.h"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", swaggerFolder, "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", swaggerFolder, "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("Configuration-body.mustache", swaggerFolder, classPrefix + "Configuration.m"));
supportingFiles.add(new SupportingFile("Configuration-header.mustache", swaggerFolder, classPrefix + "Configuration.h"));
supportingFiles.add(new SupportingFile("podspec.mustache", "", podName + ".podspec"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
@Override
@ -285,11 +296,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toModelImport(String name) {
if ("".equals(modelPackage())) {
return name;
} else {
return modelPackage() + "." + name;
}
return name;
}
@Override
@ -299,12 +306,12 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder;
return outputFolder + File.separatorChar + apiPackage();
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder;
return outputFolder + File.separatorChar + modelPackage();
}
@Override
@ -359,15 +366,15 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(operationId, true);
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
public void setClassPrefix(String classPrefix) {
this.classPrefix = classPrefix;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
public void setPodName(String podName) {
this.podName = podName;
}
public void setPodVersion(String podVersion) {
this.podVersion = podVersion;
}
}

View File

@ -17,10 +17,10 @@ import java.util.HashSet;
public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "Swagger\\Client";
protected String groupId = "swagger";
protected String artifactId = "swagger-client";
protected String composerVendorName = "swagger";
protected String composerProjectName = "swagger-client";
protected String packagePath = "SwaggerClient-php";
protected String artifactVersion = null;
protected String artifactVersion = "1.0.0";
protected String srcBasePath = "lib";
public PhpClientCodegen() {
@ -38,15 +38,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
"__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor")
);
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);
additionalProperties.put("artifactVersion", artifactVersion);
// ref: http://php.net/manual/en/language.types.intro.php
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
@ -79,15 +70,19 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("boolean", "bool");
typeMapping.put("date", "\\DateTime");
typeMapping.put("datetime", "\\DateTime");
typeMapping.put("file", "string");
typeMapping.put("file", "\\SplFileObject");
typeMapping.put("map", "map");
typeMapping.put("array", "array");
typeMapping.put("list", "array");
typeMapping.put("object", "object");
typeMapping.put("DateTime", "\\DateTime");
cliOptions.add(new CliOption("packagePath", "main package name for classes"));
cliOptions.add(new CliOption("srcBasePath", "directory directory under packagePath to serve as source root"));
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all classes."));
cliOptions.add(new CliOption("packagePath", "The main package name for classes."));
cliOptions.add(new CliOption("srcBasePath", "The directory under packagePath to serve as source root."));
cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name."));
cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name."));
cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field."));
}
public String getPackagePath() {
@ -141,23 +136,52 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
if (additionalProperties.containsKey("packagePath")) {
this.setPackagePath((String) additionalProperties.get("packagePath"));
} else {
additionalProperties.put("packagePath", packagePath);
}
if (additionalProperties.containsKey("srcBasePath")) {
this.setSrcBasePath((String) additionalProperties.get("srcBasePath"));
} else {
additionalProperties.put("srcBasePath", srcBasePath);
}
if (additionalProperties.containsKey("invokerPackage")) {
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
} else {
additionalProperties.put("invokerPackage", invokerPackage);
}
if (additionalProperties.containsKey("modelPackage")) {
this.setModelPackage((String) additionalProperties.get("modelPackage"));
} else {
additionalProperties.put("modelPackage", modelPackage);
}
if (additionalProperties.containsKey("apiPackage")) {
this.setApiPackage((String) additionalProperties.get("apiPackage"));
} else {
additionalProperties.put("apiPackage", apiPackage);
}
additionalProperties.put("srcBasePath", srcBasePath);
additionalProperties.put("modelPackage", modelPackage);
additionalProperties.put("apiPackage", apiPackage);
if (additionalProperties.containsKey("composerProjectName")) {
this.setComposerProjectName((String) additionalProperties.get("composerProjectName"));
} else {
additionalProperties.put("composerProjectName", composerProjectName);
}
if (additionalProperties.containsKey("composerVendorName")) {
this.setComposerVendorName((String) additionalProperties.get("composerVendorName"));
} else {
additionalProperties.put("composerVendorName", composerVendorName);
}
if (additionalProperties.containsKey("artifactVersion")) {
this.setArtifactVersion((String) additionalProperties.get("artifactVersion"));
} else {
additionalProperties.put("artifactVersion", artifactVersion);
}
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, srcBasePath), "Configuration.php"));
@ -235,6 +259,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setArtifactVersion(String artifactVersion) {
this.artifactVersion = artifactVersion;
}
public void setPackagePath(String packagePath) {
this.packagePath = packagePath;
@ -243,6 +271,14 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setSrcBasePath(String srcBasePath) {
this.srcBasePath = srcBasePath;
}
private void setComposerVendorName(String composerVendorName) {
this.composerVendorName = composerVendorName;
}
public void setComposerProjectName(String composerProjectName) {
this.composerProjectName = composerProjectName;
}
@Override
public String toVarName(String 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

@ -34,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");
@ -44,8 +45,10 @@ 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");
typeMapping.put("file", "file");
// from https://docs.python.org/release/2.5.4/ref/keywords.html
reservedWords = new HashSet<String>(

View File

@ -55,12 +55,14 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("float", "Float");
typeMapping.put("double", "Float");
typeMapping.put("number", "Float");
typeMapping.put("date", "Date");
typeMapping.put("DateTime", "DateTime");
typeMapping.put("boolean", "BOOLEAN");
typeMapping.put("array", "Array");
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();
@ -106,7 +108,6 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec"));
supportingFiles.add(new SupportingFile("swagger_client.mustache", libFolder, gemName + ".rb"));
String baseFolder = libFolder + File.separator + gemName;
supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb"));
supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb"));
String swaggerFolder = baseFolder + File.separator + "swagger";
supportingFiles.add(new SupportingFile("swagger" + File.separator + "request.mustache", swaggerFolder, "request.rb"));

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

@ -18,7 +18,7 @@ public class TypeScriptAngularClientCodegen extends TypeScriptNodeClientCodegen
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-Angular";
apiPackage = "api";
modelPackage = "api";
modelPackage = "model";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage + File.separator, "api.d.ts"));
}

View File

@ -77,6 +77,8 @@ public class TypeScriptNodeClientCodegen extends DefaultCodegen implements Codeg
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("DateTime", "Date");
}

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)
@ -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

@ -21,7 +21,7 @@ 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

View File

@ -12,7 +12,7 @@ module {{package}} {
*/
{{/description}}
export class {{classname}} {
private basePath = '{{basePath}}';
private basePath = '{{contextPath}}';
static $inject: string[] = ['$http'];
@ -22,7 +22,7 @@ module {{package}} {
}
}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}, {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
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}}));
@ -50,7 +50,7 @@ module {{package}} {
};
if (extraHttpRequestParams) {
for (var k in extraHttpRequestParams){
for (var k in extraHttpRequestParams) {
if (extraHttpRequestParams.hasOwnProperty(k)) {
httpRequestParams[k] = extraHttpRequestParams[k];
}
@ -61,8 +61,5 @@ module {{package}} {
}
{{/operation}}
}
angular.module('{{package}}_{{classname}}', ['$http'])
.service('{{classname}}', {{classname}});
}
{{/operations}}

View File

@ -7,7 +7,7 @@
*/
{{/description}}
export class {{classname}} {
private basePath = '{{basePath}}';
private basePath = '{{contextPath}}';
constructor(private url: string, private username: string, private password: string, basePath?: string) {
if (basePath) {
@ -16,7 +16,7 @@ export class {{classname}} {
}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}} ) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> {
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}}

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

@ -50,7 +50,6 @@ namespace {{packageName}}.Client
get { return _defaultHeaderMap; }
}
<<<<<<< HEAD
// Creates and sets up a RestRequest prior to a call.
private RestRequest PrepareRequest(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
@ -58,9 +57,9 @@ namespace {{packageName}}.Client
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams, String[] authSettings)
{
var request = new RestRequest(path, method);
UpdateParamsForAuth(queryParams, headerParams, authSettings);
// add default header, if any
foreach(var defaultHeader in _defaultHeaderMap)
request.AddHeader(defaultHeader.Key, defaultHeader.Value);
@ -72,15 +71,15 @@ namespace {{packageName}}.Client
// add header parameter, if any
foreach(var param in headerParams)
request.AddHeader(param.Key, param.Value);
// add query parameter, if any
foreach(var param in queryParams)
request.AddQueryParameter(param.Key, param.Value);
// add form parameter, if any
foreach(var param in formParams)
request.AddParameter(param.Key, param.Value);
// add file parameter, if any
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
@ -208,173 +207,6 @@ namespace {{packageName}}.Client
? Path.GetTempPath()
: Configuration.TempFolderPath;
=======
/// <summary>
/// Makes the HTTP request (Sync).
/// </summary>
/// <param name="path">URL path.</param>
/// <param name="method">HTTP method.</param>
/// <param name="queryParams">Query parameters.</param>
/// <param name="postBody">HTTP body (POST request).</param>
/// <param name="headerParams">Header parameters.</param>
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="authSettings">Authentication settings.</param>
/// <returns>Object</returns>
public Object CallApi(String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, String[] authSettings)
{
var request = new RestRequest(path, method);
UpdateParamsForAuth(queryParams, headerParams, authSettings);
// add default header, if any
foreach(var defaultHeader in _defaultHeaderMap)
request.AddHeader(defaultHeader.Key, defaultHeader.Value);
// add header parameter, if any
foreach(var param in headerParams)
request.AddHeader(param.Key, param.Value);
// add query parameter, if any
foreach(var param in queryParams)
request.AddQueryParameter(param.Key, param.Value);
// add form parameter, if any
foreach(var param in formParams)
request.AddParameter(param.Key, param.Value);
// add file parameter, if any
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
if (postBody != null) // http body (model) parameter
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
return (Object)RestClient.Execute(request);
}
/// <summary>
/// Makes the asynchronous HTTP request.
/// </summary>
/// <param name="path">URL path.</param>
/// <param name="method">HTTP method.</param>
/// <param name="queryParams">Query parameters.</param>
/// <param name="postBody">HTTP body (POST request).</param>
/// <param name="headerParams">Header parameters.</param>
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="authSettings">Authentication settings.</param>
/// <returns>The Task instance.</returns>
public async System.Threading.Tasks.Task<Object> CallApiAsync(String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams, Dictionary<String, FileParameter> fileParams, String[] authSettings)
{
var request = new RestRequest(path, method);
UpdateParamsForAuth(queryParams, headerParams, authSettings);
// add default header, if any
foreach(var defaultHeader in _defaultHeaderMap)
request.AddHeader(defaultHeader.Key, defaultHeader.Value);
// add header parameter, if any
foreach(var param in headerParams)
request.AddHeader(param.Key, param.Value);
// add query parameter, if any
foreach(var param in queryParams)
request.AddQueryParameter(param.Key, param.Value);
// add form parameter, if any
foreach(var param in formParams)
request.AddParameter(param.Key, param.Value);
// add file parameter, if any
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
if (postBody != null) // http body (model) parameter
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
return (Object) await RestClient.ExecuteTaskAsync(request);
}
/// <summary>
/// Add default header.
/// </summary>
/// <param name="key">Header field name.</param>
/// <param name="value">Header field value.</param>
/// <returns></returns>
public void AddDefaultHeader(string key, string value)
{
_defaultHeaderMap.Add(key, value);
}
/// <summary>
/// Escape string (url-encoded).
/// </summary>
/// <param name="str">String to be escaped.</param>
/// <returns>Escaped string.</returns>
public string EscapeString(string str)
{
return HttpUtility.UrlEncode(str);
}
/// <summary>
/// Create FileParameter based on Stream.
/// </summary>
/// <param name="name">Parameter name.</param>
/// <param name="stream">Input stream.</param>
/// <returns>FileParameter.</returns>
public FileParameter ParameterToFile(string name, Stream stream)
{
if (stream is FileStream)
return FileParameter.Create(name, stream.ReadAsBytes(), Path.GetFileName(((FileStream)stream).Name));
else
return FileParameter.Create(name, stream.ReadAsBytes(), "no_file_name_provided");
}
/// <summary>
/// If parameter is DateTime, output in ISO8601 format.
/// If parameter is a list of string, join the list with ",".
/// Otherwise just return the string.
/// </summary>
/// <param name="obj">The parameter (header, path, query, form).</param>
/// <returns>Formatted string.</returns>
public string ParameterToString(object obj)
{
if (obj is DateTime)
return ((DateTime)obj).ToString ("u");
else if (obj is List<string>)
return String.Join(",", obj as List<string>);
else
return Convert.ToString (obj);
}
/// <summary>
/// Deserialize the JSON string into a proper object.
/// </summary>
/// <param name="content">HTTP body (e.g. string, JSON).</param>
/// <param name="type">Object type.</param>
/// <returns>Object representation of the JSON string.</returns>
public object Deserialize(string content, Type type, IList<Parameter> headers=null)
{
if (type == typeof(Object)) // return an object
{
return content;
}
if (type == typeof(Stream))
{
var filePath = String.IsNullOrEmpty(Configuration.TempFolderPath)
? Path.GetTempPath()
: Configuration.TempFolderPath;
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
var fileName = filePath + Guid.NewGuid();
if (headers != null)
{

View File

@ -5,37 +5,43 @@ namespace {{packageName}}.Client {
/// API Exception
/// </summary>
public class ApiException : Exception {
/// <summary>
/// Gets or sets the error code (HTTP status code)
/// </summary>
/// <value>The error code (HTTP status code).</value>
public int ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error code (HTTP status code)
/// </summary>
/// <value>The error code (HTTP status code).</value>
public int ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error content (body json object)
/// </summary>
/// <value>The error content (Http response body).</value>
public dynamic ErrorContent { get; private set; }
/// <summary>
/// Gets or sets the error content (body json object)
/// </summary>
/// <value>The error content (Http response body).</value>
public dynamic ErrorContent { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiException() {}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiException() {}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
public ApiException(int errorCode, string message) : base(message) {
this.ErrorCode = errorCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
public ApiException(int errorCode, string message) : base(message) {
this.ErrorCode = errorCode;
}
public ApiException(int errorCode, string message, dynamic errorContent = null) : base(message) {
this.ErrorCode = errorCode;
this.ErrorContent = errorContent;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
/// <param name="errorContent">Error content.</param>
public ApiException(int errorCode, string message, dynamic errorContent = null) : base(message) {
this.ErrorCode = errorCode;
this.ErrorContent = errorContent;
}
}

View File

@ -1,51 +1,99 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace {{packageName}}.Client {
/// <summary>
/// Represents a set of configuration settings
/// </summary>
public class Configuration{
namespace {{packageName}}.Client
{
/// <summary>
/// Version of the package
/// Represents a set of configuration settings
/// </summary>
public const string Version = "{{packageVersion}}";
/// <summary>
/// Gets or sets the API client. This is the default API client for making HTTP calls.
/// </summary>
/// <value>The API client.</value>
public static ApiClient apiClient = new ApiClient();
/// <summary>
/// Gets or sets the username (HTTP basic authentication)
/// </summary>
/// <value>The username.</value>
public static String username { get; set; }
/// <summary>
/// Gets or sets the password (HTTP basic authentication)
/// </summary>
/// <value>The password.</value>
public static String password { get; set; }
/// <summary>
/// Gets or sets the API key based on the authentication name
/// </summary>
/// <value>The API key.</value>
public static Dictionary<String, String> apiKey = new Dictionary<String, String>();
/// <summary>
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name
/// </summary>
/// <value>The prefix of the API key.</value>
public static Dictionary<String, String> apiKeyPrefix = new Dictionary<String, String>();
}
public class Configuration
{
/// <summary>
/// Version of the package.
/// </summary>
/// <value>Version of the package.</value>
public const string Version = "{{packageVersion}}";
/// <summary>
/// Gets or sets the default API client for making HTTP calls.
/// </summary>
/// <value>The API client.</value>
public static ApiClient DefaultApiClient = new ApiClient();
/// <summary>
/// Gets or sets the username (HTTP basic authentication).
/// </summary>
/// <value>The username.</value>
public static String Username { get; set; }
/// <summary>
/// Gets or sets the password (HTTP basic authentication).
/// </summary>
/// <value>The password.</value>
public static String Password { get; set; }
/// <summary>
/// Gets or sets the API key based on the authentication name.
/// </summary>
/// <value>The API key.</value>
public static Dictionary<String, String> ApiKey = new Dictionary<String, String>();
/// <summary>
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
/// </summary>
/// <value>The prefix of the API key.</value>
public static Dictionary<String, String> ApiKeyPrefix = new Dictionary<String, String>();
private static string _tempFolderPath = Path.GetTempPath();
/// <summary>
/// Gets or sets the temporary folder path to store the files downloaded from the server.
/// </summary>
/// <value>Folder path.</value>
public static String TempFolderPath
{
get { return _tempFolderPath; }
set
{
if (String.IsNullOrEmpty(value))
{
_tempFolderPath = value;
return;
}
// create the directory if it does not exist
if (!Directory.Exists(value))
Directory.CreateDirectory(value);
// check if the path contains directory separator at the end
if (value[value.Length - 1] == Path.DirectorySeparatorChar)
_tempFolderPath = value;
else
_tempFolderPath = value + Path.DirectorySeparatorChar;
}
}
/// <summary>
/// Returns a string with essential information for debugging.
/// </summary>
public static String ToDebugReport()
{
String report = "C# SDK ({{packageName}}) Debug Report:\n";
report += " OS: " + Environment.OSVersion + "\n";
report += " .NET Framework Version: " + Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Where(x => x.Name == "System.Core").First().Version.ToString() + "\n";
report += " Version of the API: {{version}}\n";
report += " SDK Package Version: {{packageVersion}}\n";
return report;
}
}
}

View File

@ -0,0 +1,15 @@
## Frameworks supported
- .NET 3.5 or later
- Windows Phone 7.1 (Mango)
## Dependencies
- [RestSharp] (https://www.nuget.org/packages/RestSharp)
- [Json.NET] (https://www.nuget.org/packages/Newtonsoft.Json/)
NOTE: The DLLs included in the package may not be the latest version. We recommned using [NuGet] (https://docs.nuget.org/consume/installing-nuget) to obtain the latest version of the packages:
```
Install-Package RestSharp
Install-Package Newtonsoft.Json
```

View File

@ -95,27 +95,17 @@ namespace {{packageName}}.Api
{{/required}}{{/allParams}}
var path = "{{path}}";
<<<<<<< HEAD
var pathParams = new Dictionary<String, String>();
=======
path = path.Replace("{format}", "json");
{{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", ApiClient.ParameterToString({{{paramName}}}));
{{/pathParams}}
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
var queryParams = new Dictionary<String, String>();
var headerParams = new Dictionary<String, String>();
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
<<<<<<< HEAD
pathParams.Add("format", "json");
{{#pathParams}} if ({{paramName}} != null) pathParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // path parameter
{{/pathParams}}
=======
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter
{{/queryParams}}
@ -130,11 +120,7 @@ namespace {{packageName}}.Api
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
// make the HTTP request
<<<<<<< HEAD
IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams, authSettings);
=======
IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
if (((int)response.StatusCode) >= 400)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
@ -156,30 +142,18 @@ namespace {{packageName}}.Api
{{/required}}{{/allParams}}
var path = "{{path}}";
<<<<<<< HEAD
var pathParams = new Dictionary<String, String>();
=======
path = path.Replace("{format}", "json");
{{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", ApiClient.ParameterToString({{{paramName}}}));
{{/pathParams}}
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
var queryParams = new Dictionary<String, String>();
var headerParams = new Dictionary<String, String>();
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
<<<<<<< HEAD
pathParams.Add("format", "json");
{{#pathParams}} if ({{paramName}} != null) pathParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // path parameter
{{/pathParams}}
=======
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter
{{/queryParams}}
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter
@ -193,11 +167,7 @@ namespace {{packageName}}.Api
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
// make the HTTP request
<<<<<<< HEAD
IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams, authSettings);
=======
IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
>>>>>>> e879268043b53fe30ea0238807b9519687c1e5f2
if (((int)response.StatusCode) >= 400)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);

View File

@ -15,7 +15,10 @@ namespace {{packageName}}.Model {
[DataContract]
public class {{classname}}{{#parent}} : {{{parent}}}{{/parent}} {
{{#vars}}
{{#description}}/* {{{description}}} */{{/description}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
/// </summary>{{#description}}
/// <value>{{{description}}}</value>{{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue=false)]
public {{{datatype}}} {{name}} { get; set; }

View File

@ -1,11 +1,8 @@
#import "SWGApiClient.h"
#import "SWGFile.h"
#import "SWGQueryParamCollection.h"
#import "SWGConfiguration.h"
#import "{{classPrefix}}ApiClient.h"
@implementation SWGApiClient
@implementation {{classPrefix}}ApiClient
NSString *const SWGResponseObjectErrorKey = @"SWGResponseObject";
NSString *const {{classPrefix}}ResponseObjectErrorKey = @"{{classPrefix}}ResponseObject";
static long requestId = 0;
static bool offlineState = false;
@ -14,31 +11,38 @@ static bool cacheEnabled = false;
static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable;
static NSOperationQueue* sharedQueue;
static void (^reachabilityChangeBlock)(int);
static bool loggingEnabled = true;
#pragma mark - Log Methods
+(void)setLoggingEnabled:(bool) state {
loggingEnabled = state;
- (void)logResponse:(AFHTTPRequestOperation *)operation
forRequest:(NSURLRequest *)request
error:(NSError*)error {
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
NSString *message = [NSString stringWithFormat:@"\n[DEBUG] Request body \n~BEGIN~\n %@\n~END~\n"\
"[DEBUG] HTTP Response body \n~BEGIN~\n %@\n~END~\n",
[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],
operation.responseString];
if (config.loggingFileHanlder) {
[config.loggingFileHanlder seekToEndOfFile];
[config.loggingFileHanlder writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(@"%@", message);
}
- (void)logRequest:(NSURLRequest*)request {
NSLog(@"request: %@", [self descriptionForRequest:request]);
}
#pragma mark - Cache Methods
- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error {
NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data );
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
#pragma mark -
+(void)clearCache {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
+(void)setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
#pragma mark -
+(void)configureCacheWithMemoryAndDiskCapacity: (unsigned long) memorySize
diskSize: (unsigned long) diskSize {
@ -58,7 +62,7 @@ static bool loggingEnabled = true;
return sharedQueue;
}
+(SWGApiClient *)sharedClientFromPool:(NSString *)baseUrl {
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl {
static NSMutableDictionary *_pool = nil;
if (queuedRequests == nil) {
queuedRequests = [[NSMutableSet alloc]init];
@ -72,21 +76,21 @@ static bool loggingEnabled = true;
_pool = [[NSMutableDictionary alloc] init];
// initialize URL cache
[SWGApiClient configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
[{{classPrefix}}ApiClient configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
// configure reachability
[SWGApiClient configureCacheReachibilityForHost:baseUrl];
[{{classPrefix}}ApiClient configureCacheReachibilityForHost:baseUrl];
}
@synchronized(self) {
SWGApiClient * client = [_pool objectForKey:baseUrl];
{{classPrefix}}ApiClient * client = [_pool objectForKey:baseUrl];
if (client == nil) {
client = [[SWGApiClient alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
client = [[{{classPrefix}}ApiClient alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
[_pool setValue:client forKey:baseUrl ];
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"new client for path %@", baseUrl);
}
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"returning client for path %@", baseUrl);
return client;
}
@ -149,15 +153,15 @@ static bool loggingEnabled = true;
+(NSNumber*) nextRequestId {
@synchronized(self) {
long nextId = ++requestId;
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"got id %ld", nextId);
return [NSNumber numberWithLong:nextId];
}
}
+(NSNumber*) queueRequest {
NSNumber* requestId = [SWGApiClient nextRequestId];
if(loggingEnabled)
NSNumber* requestId = [{{classPrefix}}ApiClient nextRequestId];
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"added %@ to request queue", requestId);
[queuedRequests addObject:requestId];
return requestId;
@ -190,7 +194,7 @@ static bool loggingEnabled = true;
}];
if(matchingItems.count == 1) {
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"removing request id %@", requestId);
[queuedRequests removeObject:requestId];
return true;
@ -221,31 +225,31 @@ static bool loggingEnabled = true;
}
+(void) configureCacheReachibilityForHost:(NSString*)host {
[[SWGApiClient sharedClientFromPool:host].reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
reachabilityStatus = status;
switch (status) {
case AFNetworkReachabilityStatusUnknown:
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"reachability changed to AFNetworkReachabilityStatusUnknown");
[SWGApiClient setOfflineState:true];
[{{classPrefix}}ApiClient setOfflineState:true];
break;
case AFNetworkReachabilityStatusNotReachable:
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"reachability changed to AFNetworkReachabilityStatusNotReachable");
[SWGApiClient setOfflineState:true];
[{{classPrefix}}ApiClient setOfflineState:true];
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"reachability changed to AFNetworkReachabilityStatusReachableViaWWAN");
[SWGApiClient setOfflineState:false];
[{{classPrefix}}ApiClient setOfflineState:false];
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
if(loggingEnabled)
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"reachability changed to AFNetworkReachabilityStatusReachableViaWiFi");
[SWGApiClient setOfflineState:false];
[{{classPrefix}}ApiClient setOfflineState:false];
break;
default:
break;
@ -255,7 +259,7 @@ static bool loggingEnabled = true;
reachabilityChangeBlock(status);
}
}];
[[SWGApiClient sharedClientFromPool:host].reachabilityManager startMonitoring];
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager startMonitoring];
}
-(NSString*) pathWithQueryParamsToString:(NSString*) path
@ -268,36 +272,35 @@ static bool loggingEnabled = true;
for(NSString * key in [queryParams keyEnumerator]){
if(counter == 0) separator = @"?";
else separator = @"&";
NSString * value;
id queryParam = [queryParams valueForKey:key];
if([queryParam isKindOfClass:[NSString class]]){
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[SWGApiClient escape:key], [SWGApiClient escape:[queryParams valueForKey:key]]]];
[{{classPrefix}}ApiClient escape:key], [{{classPrefix}}ApiClient escape:[queryParams valueForKey:key]]]];
}
else if([queryParam isKindOfClass:[SWGQueryParamCollection class]]){
SWGQueryParamCollection * coll = (SWGQueryParamCollection*) queryParam;
else if([queryParam isKindOfClass:[{{classPrefix}}QueryParamCollection class]]){
{{classPrefix}}QueryParamCollection * coll = ({{classPrefix}}QueryParamCollection*) queryParam;
NSArray* values = [coll values];
NSString* format = [coll format];
if([format isEqualToString:@"csv"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[SWGApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@","]]]];
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@","]]]];
}
else if([format isEqualToString:@"tsv"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[SWGApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"\t"]]]];
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"\t"]]]];
}
else if([format isEqualToString:@"pipes"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[SWGApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"|"]]]];
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"|"]]]];
}
else if([format isEqualToString:@"multi"]) {
for(id obj in values) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[SWGApiClient escape:key], [NSString stringWithFormat:@"%@", obj]]];
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", obj]]];
counter += 1;
}
@ -305,7 +308,7 @@ static bool loggingEnabled = true;
}
else {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[SWGApiClient escape:key], [NSString stringWithFormat:@"%@", [queryParams valueForKey:key]]]];
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [queryParams valueForKey:key]]]];
}
counter += 1;
@ -314,11 +317,6 @@ static bool loggingEnabled = true;
return requestUrl;
}
- (NSString*)descriptionForRequest:(NSURLRequest*)request {
return [[request URL] absoluteString];
}
/**
* Update header and query params based on authentication settings
*/
@ -333,7 +331,7 @@ static bool loggingEnabled = true;
NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers];
NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys];
SWGConfiguration *config = [SWGConfiguration sharedConfig];
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
for (NSString *auth in authSettings) {
NSDictionary *authSetting = [[config authSettings] objectForKey:auth];
@ -359,8 +357,8 @@ static bool loggingEnabled = true;
NSMutableArray *resultArray = nil;
NSMutableDictionary *resultDict = nil;
// return nil if data is nil
if (!data) {
// return nil if data is nil or class is nil
if (!data || !class) {
return nil;
}
@ -473,20 +471,112 @@ static bool loggingEnabled = true;
return nil;
}
#pragma mark - Operation Methods
- (void) operationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id response) {
if([self executeRequestWithId:requestId]) {
if([[{{classPrefix}}Configuration sharedConfig] debug]) {
[self logResponse:operation forRequest:request error:nil];
}
completionBlock(response, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if(operation.responseObject) {
// Add in the (parsed) response body.
userInfo[{{classPrefix}}ResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if([[{{classPrefix}}Configuration sharedConfig] debug])
[self logResponse:nil forRequest:request error:augmentedError];
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
}
- (void) downloadOperationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
NSString *directory = nil;
if (config.tempFolderPath) {
directory = config.tempFolderPath;
}
else {
directory = NSTemporaryDirectory();
}
NSDictionary *headers = operation.response.allHeaderFields;
NSString *filename = nil;
if ([headers objectForKey:@"Content-Disposition"]) {
NSString *pattern = @"filename=['\"]?([^'\"\\s]+)['\"]?";
NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:nil];
NSString *contentDispositionHeader = [headers objectForKey:@"Content-Disposition"];
NSTextCheckingResult *match = [regexp firstMatchInString:contentDispositionHeader
options:0
range:NSMakeRange(0, [contentDispositionHeader length])];
filename = [contentDispositionHeader substringWithRange:[match rangeAtIndex:1]];
}
else {
filename = [NSString stringWithFormat:@"%@", [[NSProcessInfo processInfo] globallyUniqueString]];
}
NSString *filepath = [directory stringByAppendingPathComponent:filename];
NSURL *file = [NSURL fileURLWithPath:filepath];
[operation.responseData writeToURL:file atomically:YES];
completionBlock(file, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if (operation.responseObject) {
userInfo[{{classPrefix}}ResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if ([[{{classPrefix}}Configuration sharedConfig] debug]) {
[self logResponse:nil forRequest:request error:augmentedError];
}
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
}
#pragma mark - Perform Request Methods
-(NSNumber*) requestWithCompletionBlock: (NSString*) path
method: (NSString*) method
queryParams: (NSDictionary*) queryParams
formParams: (NSDictionary *) formParams
files: (NSDictionary *) files
body: (id) body
headerParams: (NSDictionary*) headerParams
authSettings: (NSArray *) authSettings
requestContentType: (NSString*) requestContentType
responseContentType: (NSString*) responseContentType
responseType: (NSString *) responseType
completionBlock: (void (^)(id, NSError *))completionBlock {
// setting request serializer
if ([requestContentType isEqualToString:@"application/json"]) {
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.requestSerializer = [{{classPrefix}}JSONRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"application/x-www-form-urlencoded"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
@ -500,7 +590,7 @@ static bool loggingEnabled = true;
// setting response serializer
if ([responseContentType isEqualToString:@"application/json"]) {
self.responseSerializer = [SWGJSONResponseSerializer serializer];
self.responseSerializer = [{{classPrefix}}JSONResponseSerializer serializer];
}
else {
self.responseSerializer = [AFHTTPResponseSerializer serializer];
@ -510,68 +600,42 @@ static bool loggingEnabled = true;
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
NSMutableURLRequest * request = nil;
if (body != nil && [body isKindOfClass:[NSArray class]]){
SWGFile * file;
NSMutableDictionary * params = [[NSMutableDictionary alloc] init];
for(id obj in body) {
if([obj isKindOfClass:[SWGFile class]]) {
file = (SWGFile*) obj;
requestContentType = @"multipart/form-data";
}
else if([obj isKindOfClass:[NSDictionary class]]) {
for(NSString * key in obj) {
params[key] = obj[key];
}
}
}
NSString * urlString = [[NSURL URLWithString:path relativeToURL:self.baseURL] absoluteString];
// request with multipart form
if([requestContentType isEqualToString:@"multipart/form-data"]) {
request = [self.requestSerializer multipartFormRequestWithMethod: @"POST"
URLString: urlString
parameters: nil
constructingBodyWithBlock: ^(id<AFMultipartFormData> formData) {
for(NSString * key in params) {
NSData* data = [params[key] dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData: data name: key];
}
if (file) {
[formData appendPartWithFileData: [file data]
name: [file paramName]
fileName: [file name]
mimeType: [file mimeType]];
}
}
error:nil];
}
// request with form parameters or json
else {
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:params
error:nil];
}
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
if (files.count > 0) {
request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"
URLString:urlString
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSData *data = [obj dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData:data name:key];
}];
[files enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSURL *filePath = (NSURL *)obj;
[formData appendPartWithFileURL:filePath name:key error:nil];
}];
} error:nil];
}
else {
NSString * pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
NSString * urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
request = [self.requestSerializer requestWithMethod: method
URLString: urlString
parameters: body
error: nil];
if (formParams) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:formParams
error:nil];
}
if (body) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:body
error:nil];
}
}
BOOL hasHeaderParams = false;
if(headerParams != nil && [headerParams count] > 0)
if(headerParams != nil && [headerParams count] > 0) {
hasHeaderParams = true;
}
if(offlineState) {
NSLog(@"%@ cache forced", path);
[request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
@ -585,17 +649,7 @@ static bool loggingEnabled = true;
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
}
if(body != nil) {
if([body isKindOfClass:[NSDictionary class]] || [body isKindOfClass:[NSArray class]]){
[self.requestSerializer setValue:requestContentType forHTTPHeaderField:@"Content-Type"];
}
else if ([body isKindOfClass:[SWGFile class]]){}
else {
NSAssert(false, @"unsupported post type!");
}
}
if(headerParams != nil){
if(hasHeaderParams){
for(NSString * key in [headerParams keyEnumerator]){
[request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key];
}
@ -606,31 +660,17 @@ static bool loggingEnabled = true;
// Always disable cookies!
[request setHTTPShouldHandleCookies:NO];
NSNumber* requestId = [SWGApiClient queueRequest];
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id response) {
if([self executeRequestWithId:requestId]) {
if(self.logServerResponses) {
[self logResponse:response forRequest:request error:nil];
}
completionBlock(response, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if(operation.responseObject) {
// Add in the (parsed) response body.
userInfo[SWGResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if(self.logServerResponses)
[self logResponse:nil forRequest:request error:augmentedError];
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
NSNumber* requestId = [{{classPrefix}}ApiClient queueRequest];
if ([responseType isEqualToString:@"NSURL*"]) {
[self downloadOperationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock(data, error);
}];
}
else {
[self operationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock([self deserialize:data class:responseType], error);
}];
}
return requestId;
}
@ -639,8 +679,3 @@ static bool loggingEnabled = true;

View File

@ -1,7 +1,11 @@
#import <Foundation/Foundation.h>
#import <ISO8601/ISO8601.h>
#import "AFHTTPRequestOperationManager.h"
#import "SWGJSONResponseSerializer.h"
#import <AFNetworking/AFHTTPRequestOperationManager.h>
#import "{{classPrefix}}JSONResponseSerializer.h"
#import "{{classPrefix}}JSONRequestSerializer.h"
#import "{{classPrefix}}QueryParamCollection.h"
#import "{{classPrefix}}Configuration.h"
{{#models}}{{#model}}#import "{{classname}}.h"
{{/model}}{{/models}}
@ -11,18 +15,13 @@
*
* The corresponding value is the parsed response body for an HTTP error.
*/
extern NSString *const SWGResponseObjectErrorKey;
extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
@interface SWGApiClient : AFHTTPRequestOperationManager
@interface {{classPrefix}}ApiClient : AFHTTPRequestOperationManager
@property(nonatomic, assign) NSURLRequestCachePolicy cachePolicy;
@property(nonatomic, assign) NSTimeInterval timeoutInterval;
@property(nonatomic, assign) BOOL logRequests;
@property(nonatomic, assign) BOOL logCacheHits;
@property(nonatomic, assign) BOOL logServerResponses;
@property(nonatomic, assign) BOOL logJSON;
@property(nonatomic, assign) BOOL logHTTP;
@property(nonatomic, readonly) NSOperationQueue* queue;
/**
@ -30,9 +29,9 @@ extern NSString *const SWGResponseObjectErrorKey;
*
* @param baseUrl The base url of api client.
*
* @return The SWGApiClient instance.
* @return The {{classPrefix}}ApiClient instance.
*/
+(SWGApiClient *)sharedClientFromPool:(NSString *)baseUrl;
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl;
/**
* Get the operations queue
@ -41,13 +40,6 @@ extern NSString *const SWGResponseObjectErrorKey;
*/
+(NSOperationQueue*) sharedQueue;
/**
* Turn on logging
*
* @param state logging state, must be `YES` or `NO`
*/
+(void)setLoggingEnabled:(bool) state;
/**
* Clear Cache
*/
@ -121,7 +113,7 @@ extern NSString *const SWGResponseObjectErrorKey;
/**
* Set the client reachability strategy
*
* @param host The host of SWGApiClient.
* @param host The host of {{classPrefix}}ApiClient.
*/
+(void) configureCacheReachibilityForHost:(NSString*)host;
@ -171,6 +163,17 @@ extern NSString *const SWGResponseObjectErrorKey;
*/
- (id) deserialize:(id) data class:(NSString *) class;
/**
* Logging request and response
*
* @param operation AFHTTPRequestOperation for the HTTP request.
* @param request The HTTP request.
* @param error The error of the HTTP request.
*/
- (void)logResponse:(AFHTTPRequestOperation *)operation
forRequest:(NSURLRequest *)request
error:(NSError *)error;
/**
* Perform request
*
@ -189,15 +192,14 @@ extern NSString *const SWGResponseObjectErrorKey;
-(NSNumber*) requestWithCompletionBlock:(NSString*) path
method:(NSString*) method
queryParams:(NSDictionary*) queryParams
formParams:(NSDictionary *) formParams
files:(NSDictionary *) files
body:(id) body
headerParams:(NSDictionary*) headerParams
authSettings: (NSArray *) authSettings
requestContentType:(NSString*) requestContentType
responseContentType:(NSString*) responseContentType
responseType:(NSString *) responseType
completionBlock:(void (^)(id, NSError *))completionBlock;
@end

View File

@ -1,18 +1,18 @@
#import "SWGConfiguration.h"
#import "{{classPrefix}}Configuration.h"
@interface SWGConfiguration ()
@interface {{classPrefix}}Configuration ()
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKey;
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKeyPrefix;
@end
@implementation SWGConfiguration
@implementation {{classPrefix}}Configuration
#pragma mark - Singletion Methods
+ (instancetype) sharedConfig {
static SWGConfiguration *shardConfig = nil;
static {{classPrefix}}Configuration *shardConfig = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shardConfig = [[self alloc] init];
@ -27,6 +27,9 @@
if (self) {
self.username = @"";
self.password = @"";
self.tempFolderPath = nil;
self.debug = NO;
self.loggingFile = nil;
self.mutableApiKey = [NSMutableDictionary dictionary];
self.mutableApiKeyPrefix = [NSMutableDictionary dictionary];
}
@ -65,6 +68,20 @@
[self.mutableApiKeyPrefix setValue:value forKey:field];
}
- (void) setLoggingFile:(NSString *)loggingFile {
// close old file handler
if ([self.loggingFileHanlder isKindOfClass:[NSFileHandle class]]) {
[self.loggingFileHanlder closeFile];
}
_loggingFile = loggingFile;
self.loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
if (self.loggingFileHanlder == nil) {
[[NSFileManager defaultManager] createFileAtPath:_loggingFile contents:nil attributes:nil];
self.loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
}
}
#pragma mark - Getter Methods
- (NSDictionary *) apiKey {
@ -78,21 +95,14 @@
#pragma mark -
- (NSDictionary *) authSettings {
return @{ {{#authMethods}}{{#isApiKey}}
@"{{name}}": @{
return @{
@"api_key": @{
@"type": @"api_key",
@"in": {{#isKeyInHeader}}@"header"{{/isKeyInHeader}}{{#isKeyInQuery}}@"query"{{/isKeyInQuery}},
@"key": @"{{keyParamName}}",
@"value": [self getApiKeyWithPrefix:@"{{keyParamName}}"]
},
{{/isApiKey}}{{#isBasic}}
@"{{name}}": @{
@"type": @"basic",
@"in": @"header",
@"key": @"Authorization",
@"value": [self getBasicAuthToken]
@"key": @"api_key",
@"value": [self getApiKeyWithPrefix:@"api_key"]
},
{{/isBasic}}{{/authMethods}}
};
}

View File

@ -1,6 +1,6 @@
#import <Foundation/Foundation.h>
@interface SWGConfiguration : NSObject
@interface {{classPrefix}}Configuration : NSObject
/**
@ -23,6 +23,18 @@
@property (nonatomic) NSString *username;
@property (nonatomic) NSString *password;
/**
* Temp folder for file download
*/
@property (nonatomic) NSString *tempFolderPath;
/**
* Logging Settings
*/
@property (nonatomic) BOOL debug;
@property (nonatomic) NSString *loggingFile;
@property (nonatomic) NSFileHandle *loggingFileHanlder;
/**
* Get configuration singleton instance
*/

View File

@ -0,0 +1,35 @@
#import "{{classPrefix}}JSONRequestSerializer.h"
@implementation {{classPrefix}}JSONRequestSerializer
///
/// When customize a request serializer,
/// the serializer must conform the protocol `AFURLRequestSerialization`
/// and implements the protocol method `requestBySerializingRequest:withParameters:error:`
///
/// @param request The original request.
/// @param parameters The parameters to be encoded.
/// @param error The error that occurred while attempting to encode the request parameters.
///
/// @return A serialized request.
///
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(id)parameters
error:(NSError *__autoreleasing *)error
{
// If the body data which will be serialized isn't NSArray or NSDictionary
// then put the data in the http request body directly.
if ([parameters isKindOfClass:[NSArray class]] || [parameters isKindOfClass:[NSDictionary class]]) {
return [super requestBySerializingRequest:request withParameters:parameters error:error];
} else {
NSMutableURLRequest *mutableRequest = [request mutableCopy];
if (parameters) {
[mutableRequest setHTTPBody:[parameters dataUsingEncoding:self.stringEncoding]];
}
return mutableRequest;
}
}
@end

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
#import <AFNetworking/AFURLRequestSerialization.h>
@interface {{classPrefix}}JSONRequestSerializer : AFJSONRequestSerializer
@end

View File

@ -1,4 +1,4 @@
#import "SWGJSONResponseSerializer.h"
#import "{{classPrefix}}JSONResponseSerializer.h"
static BOOL JSONParseError(NSError *error) {
if ([error.domain isEqualToString:NSCocoaErrorDomain] && error.code == 3840) {
@ -8,7 +8,7 @@ static BOOL JSONParseError(NSError *error) {
return NO;
}
@implementation SWGJSONResponseSerializer
@implementation {{classPrefix}}JSONResponseSerializer
///
/// When customize a response serializer,

View File

@ -1,6 +1,6 @@
#import <Foundation/Foundation.h>
#import <AFNetworking/AFURLResponseSerialization.h>
@interface SWGJSONResponseSerializer : AFJSONResponseSerializer
@interface {{classPrefix}}JSONResponseSerializer : AFJSONResponseSerializer
@end

View File

@ -0,0 +1,4 @@
#import "{{classPrefix}}Object.h"
@implementation {{classPrefix}}Object
@end

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
#import <JSONModel/JSONModel.h>
@interface {{classPrefix}}Object : JSONModel
@end

View File

@ -1,5 +0,0 @@
platform :ios, '6.0'
xcodeproj '{{projectName}}/{{projectName}}.xcodeproj'
pod 'AFNetworking', '~> 2.1'
pod 'JSONModel', '~> 1.0'
pod 'ISO8601'

View File

@ -1,6 +1,6 @@
#import "SWGQueryParamCollection.h"
#import "{{classPrefix}}QueryParamCollection.h"
@implementation SWGQueryParamCollection
@implementation {{classPrefix}}QueryParamCollection
@synthesize values = _values;
@synthesize format = _format;

View File

@ -1,6 +1,6 @@
#import <Foundation/Foundation.h>
@interface SWGQueryParamCollection : NSObject
@interface {{classPrefix}}QueryParamCollection : NSObject
@property(nonatomic, readonly) NSArray* values;
@property(nonatomic, readonly) NSString* format;

View File

@ -0,0 +1,19 @@
# {{podName}}
## Requirements
The API client library requires ARC (Automatic Reference Counting) to be enabled in your Xcode project.
## Installation
To install it, put the API client library in your project and then simply add the following line to your Podfile:
```ruby
pod "{{podName}}", :path => "/path/to/lib"
```
## Author
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
{{/hasMore}}{{/apis}}{{/apiInfo}}

View File

@ -1,14 +0,0 @@
#import <Foundation/Foundation.h>
@interface SWGFile : NSObject
@property(nonatomic, readonly) NSString* name;
@property(nonatomic, readonly) NSString* mimeType;
@property(nonatomic, readonly) NSData* data;
@property(nonatomic) NSString* paramName;
- (id) initWithNameData: (NSString*) filename
mimeType: (NSString*) mimeType
data: (NSData*) data;
@end

View File

@ -1,26 +0,0 @@
#import "SWGFile.h"
@implementation SWGFile
@synthesize name = _name;
@synthesize mimeType = _mimeType;
@synthesize data = _data;
- (id) init {
self = [super init];
return self;
}
- (id) initWithNameData: (NSString*) filename
mimeType: (NSString*) fileMimeType
data: (NSData*) data {
self = [super init];
if(self) {
_name = filename;
_mimeType = fileMimeType;
_data = data;
}
return self;
}
@end

View File

@ -1,7 +1,6 @@
{{#operations}}
#import "{{classname}}.h"
#import "SWGFile.h"
#import "SWGQueryParamCollection.h"
#import "{{classPrefix}}QueryParamCollection.h"
{{#imports}}#import "{{import}}.h"
{{/imports}}
{{newline}}
@ -19,20 +18,20 @@ static NSString * basePath = @"{{basePath}}";
- (id) init {
self = [super init];
if (self) {
self.apiClient = [SWGApiClient sharedClientFromPool:basePath];
self.apiClient = [{{classPrefix}}ApiClient sharedClientFromPool:basePath];
self.defaultHeaders = [NSMutableDictionary dictionary];
}
return self;
}
- (id) initWithApiClient:(SWGApiClient *)apiClient {
- (id) initWithApiClient:({{classPrefix}}ApiClient *)apiClient {
self = [super init];
if (self) {
if (apiClient) {
self.apiClient = apiClient;
}
else {
self.apiClient = [SWGApiClient sharedClientFromPool:basePath];
self.apiClient = [{{classPrefix}}ApiClient sharedClientFromPool:basePath];
}
self.defaultHeaders = [NSMutableDictionary dictionary];
}
@ -69,7 +68,7 @@ static NSString * basePath = @"{{basePath}}";
}
-(unsigned long) requestQueueSize {
return [SWGApiClient requestQueueSize];
return [{{classPrefix}}ApiClient requestQueueSize];
}
#pragma mark - Api Methods
@ -84,12 +83,14 @@ static NSString * basePath = @"{{basePath}}";
///
-(NSNumber*) {{nickname}}WithCompletionBlock{{^allParams}}: {{/allParams}}{{#allParams}}{{#secondaryParam}} {{paramName}}{{/secondaryParam}}: ({{{dataType}}}) {{paramName}}
{{/allParams}}
{{#returnBaseType}}{{#hasParams}}completionHandler: {{/hasParams}}(void (^)({{{returnType}}} output, NSError* error))completionBlock{{/returnBaseType}}
{{^returnBaseType}}{{#hasParams}}completionHandler: {{/hasParams}}(void (^)(NSError* error))completionBlock{{/returnBaseType}} {
{{#returnBaseType}}{{#hasParams}}completionHandler: {{/hasParams}}(void (^)({{{returnType}}} output, NSError* error))completionBlock { {{/returnBaseType}}
{{^returnBaseType}}{{#hasParams}}completionHandler: {{/hasParams}}(void (^)(NSError* error))completionBlock { {{/returnBaseType}}
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
NSAssert({{paramName}} != nil, @"Missing the required parameter `{{paramName}}` when calling {{nickname}}");
if ({{paramName}} == nil) {
[NSException raise:@"Invalid parameter" format:@"Missing the required parameter `{{paramName}}` when calling `{{nickname}}`"];
}
{{/required}}{{/allParams}}
NSMutableString* requestUrl = [NSMutableString stringWithFormat:@"%@{{path}}", basePath];
@ -98,13 +99,13 @@ static NSString * basePath = @"{{basePath}}";
if ([requestUrl rangeOfString:@".{format}"].location != NSNotFound)
[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:@".{format}"] withString:@".json"];
{{#pathParams}}[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:[NSString stringWithFormat:@"%@%@%@", @"{", @"{{baseName}}", @"}"]] withString: [SWGApiClient escape:{{paramName}}]];
{{#pathParams}}[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:[NSString stringWithFormat:@"%@%@%@", @"{", @"{{baseName}}", @"}"]] withString: [{{classPrefix}}ApiClient escape:{{paramName}}]];
{{/pathParams}}
NSMutableDictionary* queryParams = [[NSMutableDictionary alloc] init];
{{#queryParams}}if({{paramName}} != nil) {
{{#collectionFormat}}
queryParams[@"{{baseName}}"] = [[SWGQueryParamCollection alloc] initWithValuesAndFormat: {{baseName}} format: @"{{collectionFormat}}"];
queryParams[@"{{baseName}}"] = [[{{classPrefix}}QueryParamCollection alloc] initWithValuesAndFormat: {{baseName}} format: @"{{collectionFormat}}"];
{{/collectionFormat}}
{{^collectionFormat}}queryParams[@"{{baseName}}"] = {{paramName}};{{/collectionFormat}}
}
@ -114,9 +115,9 @@ static NSString * basePath = @"{{basePath}}";
{{#headerParams}}if({{paramName}} != nil)
headerParams[@"{{baseName}}"] = {{paramName}};
{{/headerParams}}
// HTTP header `Accept`
headerParams[@"Accept"] = [SWGApiClient selectHeaderAccept:@[{{#produces}}@"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}]];
// HTTP header `Accept`
headerParams[@"Accept"] = [{{classPrefix}}ApiClient selectHeaderAccept:@[{{#produces}}@"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}]];
if ([headerParams[@"Accept"] length] == 0) {
[headerParams removeObjectForKey:@"Accept"];
}
@ -131,62 +132,39 @@ static NSString * basePath = @"{{basePath}}";
}
// request content type
NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[{{#consumes}}@"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}]];
NSString *requestContentType = [{{classPrefix}}ApiClient selectHeaderContentType:@[{{#consumes}}@"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}]];
// Authentication setting
NSArray *authSettings = @[{{#authMethods}}@"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}}];
id bodyDictionary = nil;
{{#bodyParam}}
id __body = {{paramName}};
if(__body != nil && [__body isKindOfClass:[NSArray class]]){
NSMutableArray * objs = [[NSMutableArray alloc] init];
for (id dict in (NSArray*)__body) {
id bodyParam = nil;
NSMutableDictionary *formParams = [[NSMutableDictionary alloc] init];
NSMutableDictionary *files = [[NSMutableDictionary alloc] init];
{{#bodyParam}}
bodyParam = {{paramName}};
if(bodyParam != nil && [bodyParam isKindOfClass:[NSArray class]]){
NSMutableArray *objs = [[NSMutableArray alloc] init];
for (id dict in (NSArray*)bodyParam) {
if([dict respondsToSelector:@selector(toDictionary)]) {
[objs addObject:[(SWGObject*)dict toDictionary]];
[objs addObject:[({{classPrefix}}Object*)dict toDictionary]];
}
else{
[objs addObject:dict];
}
}
bodyDictionary = objs;
bodyParam = objs;
}
else if([__body respondsToSelector:@selector(toDictionary)]) {
bodyDictionary = [(SWGObject*)__body toDictionary];
else if([bodyParam respondsToSelector:@selector(toDictionary)]) {
bodyParam = [({{classPrefix}}Object*)bodyParam toDictionary];
}
else if([__body isKindOfClass:[NSString class]]) {
// convert it to a dictionary
NSError * error;
NSString * str = (NSString*)__body;
NSDictionary *JSON =
[NSJSONSerialization JSONObjectWithData: [str dataUsingEncoding: NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
bodyDictionary = JSON;
}
{{/bodyParam}}
{{^bodyParam}}
NSMutableDictionary * formParams = [[NSMutableDictionary alloc]init];
{{/bodyParam}}{{^bodyParam}}
{{#formParams}}
{{#notFile}}
formParams[@"{{paramName}}"] = {{paramName}};
{{/notFile}}{{#isFile}}
requestContentType = @"multipart/form-data";
if(bodyDictionary == nil) {
bodyDictionary = [[NSMutableArray alloc] init];
}
if({{paramName}} != nil) {
[bodyDictionary addObject:{{paramName}}];
{{paramName}}.paramName = @"{{baseName}}";
}
files[@"{{paramName}}"] = {{paramName}};
{{/isFile}}
if(bodyDictionary == nil) {
bodyDictionary = [[NSMutableArray alloc] init];
}
[bodyDictionary addObject:formParams];
{{/formParams}}
{{/bodyParam}}
@ -200,14 +178,17 @@ static NSString * basePath = @"{{basePath}}";
return [self.apiClient requestWithCompletionBlock: requestUrl
method: @"{{httpMethod}}"
queryParams: queryParams
body: bodyDictionary
formParams: formParams
files: files
body: bodyParam
headerParams: headerParams
authSettings: authSettings
requestContentType: requestContentType
responseContentType: responseContentType
responseType: {{^returnType}}nil{{/returnType}}{{#returnType}}@"{{{ returnType }}}"{{/returnType}}
completionBlock: ^(id data, NSError *error) {
{{^returnType}}completionBlock(error);{{/returnType}}
{{#returnType}}completionBlock([self.apiClient deserialize: data class:@"{{{returnType}}}"], error);{{/returnType}}
{{#returnType}}completionBlock(({{{ returnType }}})data, error);{{/returnType}}
}
];
}
@ -217,6 +198,3 @@ static NSString * basePath = @"{{basePath}}";
{{newline}}
{{/operations}}
@end

View File

@ -1,16 +1,16 @@
#import <Foundation/Foundation.h>
{{#imports}}#import "{{import}}.h"
{{/imports}}
#import "SWGObject.h"
#import "SWGApiClient.h"
#import "{{classPrefix}}Object.h"
#import "{{classPrefix}}ApiClient.h"
{{newline}}
{{#operations}}
@interface {{classname}}: NSObject
@property(nonatomic, assign)SWGApiClient *apiClient;
@property(nonatomic, assign){{classPrefix}}ApiClient *apiClient;
-(instancetype) initWithApiClient:(SWGApiClient *)apiClient;
-(instancetype) initWithApiClient:({{classPrefix}}ApiClient *)apiClient;
-(void) addHeader:(NSString*)value forKey:(NSString*)key;
-(unsigned long) requestQueueSize;
+({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key;

View File

@ -1,5 +1,5 @@
#import <Foundation/Foundation.h>
#import "SWGObject.h"
#import "{{classPrefix}}Object.h"
{{#imports}}#import "{{import}}.h"
{{/imports}}
{{newline}}
@ -9,7 +9,7 @@
@protocol {{classname}}
@end
@interface {{classname}} : SWGObject
@interface {{classname}} : {{classPrefix}}Object
{{#vars}}
{{#description}}/* {{{description}}} {{^required}}[optional]{{/required}}

View File

@ -0,0 +1,31 @@
#
# Be sure to run `pod lib lint {{podName}}.podspec' to ensure this is a
# valid spec and remove all comments before submitting the spec.
#
# Any lines starting with a # are optional, but encouraged
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = "{{podName}}"
s.version = "{{podVersion}}"
{{#apiInfo}}{{#apis}}{{^hasMore}}
s.summary = "{{appName}}"
s.description = <<-DESC
{{appDescription}}
DESC
{{/hasMore}}{{/apis}}{{/apiInfo}}
s.platform = :ios, '7.0'
s.requires_arc = true
s.framework = 'SystemConfiguration'
s.source_files = '{{podName}}/**/*'
s.public_header_files = '{{podName}}/**/*.h'
s.dependency 'AFNetworking', '~> 2.3'
s.dependency 'JSONModel', '~> 1.1'
s.dependency 'ISO8601', '~> 0.3'
end

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

@ -1,4 +1,15 @@
<?php
/**
* ApiClient
*
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
*
@ -14,206 +25,248 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{invokerPackage}};
class ApiClient {
/**
* ApiClient Class Doc Comment
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
class ApiClient
{
public static $PATCH = "PATCH";
public static $POST = "POST";
public static $GET = "GET";
public static $PUT = "PUT";
public static $DELETE = "DELETE";
/** @var Configuration */
protected $config;
/** @var ObjectSerializer */
protected $serializer;
/**
* @param Configuration $config config for this ApiClient
*/
function __construct(Configuration $config = null) {
if ($config == null) {
$config = Configuration::getDefaultConfiguration();
public static $PATCH = "PATCH";
public static $POST = "POST";
public static $GET = "GET";
public static $PUT = "PUT";
public static $DELETE = "DELETE";
/**
* Configuration
* @var Configuration
*/
protected $config;
/**
* Object Serializer
* @var ObjectSerializer
*/
protected $serializer;
/**
* Constructor of the class
* @param Configuration $config config for this ApiClient
*/
function __construct(Configuration $config = null)
{
if ($config == null) {
$config = Configuration::getDefaultConfiguration();
}
$this->config = $config;
$this->serializer = new ObjectSerializer();
}
/**
* Get the config
* @return Configuration
*/
public function getConfig()
{
return $this->config;
}
/**
* Get the serializer
* @return ObjectSerializer
*/
public function getSerializer()
{
return $this->serializer;
}
/**
* Get API key (with prefix if set)
* @param string $apiKeyIdentifier name of apikey
* @return string API key with the prefix
*/
public function getApiKeyWithPrefix($apiKeyIdentifier)
{
$prefix = $this->config->getApiKeyPrefix($apiKeyIdentifier);
$apiKey = $this->config->getApiKey($apiKeyIdentifier);
if (!isset($apiKey)) {
return null;
}
if (isset($prefix)) {
$keyWithPrefix = $prefix." ".$apiKey;
} else {
$keyWithPrefix = $apiKey;
}
return $keyWithPrefix;
}
$this->config = $config;
$this->serializer = new ObjectSerializer();
}
/**
* get the config
* @return Configuration
*/
public function getConfig() {
return $this->config;
}
/**
* get the serializer
* @return ObjectSerializer
*/
public function getSerializer() {
return $this->serializer;
}
/**
* Get API key (with prefix if set)
* @param string $apiKey name of apikey
* @return string API key with the prefix
*/
public function getApiKeyWithPrefix($apiKey) {
$prefix = $this->config->getApiKeyPrefix($apiKey);
$apiKey = $this->config->getApiKey($apiKey);
if (!isset($apiKey)) {
return null;
}
if (isset($prefix)) {
$keyWithPrefix = $prefix." ".$apiKey;
} else {
$keyWithPrefix = $apiKey;
}
return $keyWithPrefix;
}
/**
* Make the HTTP call (Sync)
* @param string $resourcePath path to method endpoint
* @param string $method method to call
* @param array $queryParams parameters to be place in query URL
* @param array $postData parameters to be placed in POST body
* @param array $headerParams parameters to be place in request header
* @param string $responseType expected response type of the endpoint
* @throws \{{invokerPackage}}\ApiException on a non 2xx response
* @return mixed
*/
public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams, $responseType=null)
{
/**
* @param string $resourcePath path to method endpoint
* @param string $method method to call
* @param array $queryParams parameters to be place in query URL
* @param array $postData parameters to be placed in POST body
* @param array $headerParams parameters to be place in request header
* @throws \{{invokerPackage}}\ApiException on a non 2xx response
* @return mixed
*/
public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) {
$headers = array();
# construct the http header
$headerParams = array_merge((array)$this->config->getDefaultHeaders(), (array)$headerParams);
foreach ($headerParams as $key => $val) {
$headers[] = "$key: $val";
$headers = array();
// construct the http header
$headerParams = array_merge(
(array)$this->config->getDefaultHeaders(),
(array)$headerParams
);
foreach ($headerParams as $key => $val) {
$headers[] = "$key: $val";
}
// form data
if ($postData and in_array('Content-Type: application/x-www-form-urlencoded', $headers)) {
$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->serializer->sanitizeForSerialization($postData));
}
$url = $this->config->getHost() . $resourcePath;
$curl = curl_init();
// set timeout, if needed
if ($this->config->getCurlTimeout() != 0) {
curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout());
}
// return the result on success, rather than just TRUE
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if (! empty($queryParams)) {
$url = ($url . '?' . http_build_query($queryParams));
}
if ($method == self::$POST) {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method == self::$PATCH) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method == self::$PUT) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method == self::$DELETE) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method != self::$GET) {
throw new ApiException('Method ' . $method . ' is not recognized.');
}
curl_setopt($curl, CURLOPT_URL, $url);
// Set user agent
curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent());
// debugging for curl
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile());
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a'));
} else {
curl_setopt($curl, CURLOPT_VERBOSE, 0);
}
// obtain the HTTP response headers
curl_setopt($curl, CURLOPT_HEADER, 1);
// Make the request
$response = curl_exec($curl);
$http_header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$http_header = substr($response, 0, $http_header_size);
$http_body = substr($response, $http_header_size);
$response_info = curl_getinfo($curl);
// debug HTTP response body
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile());
}
// Handle the response
if ($response_info['http_code'] == 0) {
throw new ApiException("API call to $url timed out: ".serialize($response_info), 0, null, null);
} else if ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299 ) {
// return raw body if response is a file
if ($responseType == '\SplFileObject') {
return array($http_body, $http_header);
}
$data = json_decode($http_body);
if (json_last_error() > 0) { // if response is a string
$data = $http_body;
}
} else {
throw new ApiException(
"[".$response_info['http_code']."] Error connecting to the API ($url)",
$response_info['http_code'], $http_header, $http_body
);
}
return array($data, $http_header);
}
// form data
if ($postData and in_array('Content-Type: application/x-www-form-urlencoded', $headers)) {
$postData = http_build_query($postData);
/**
* Return the header 'Accept' based on an array of Accept provided
*
* @param string[] $accept Array of header
*
* @return string Accept (e.g. application/json)
*/
public static function selectHeaderAccept($accept)
{
if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) {
return null;
} elseif (preg_grep("/application\/json/i", $accept)) {
return 'application/json';
} else {
return implode(',', $accept);
}
}
else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model
$postData = json_encode($this->serializer->sanitizeForSerialization($postData));
/**
* Return the content type based on an array of content-type provided
*
* @param string[] $content_type Array fo content-type
*
* @return string Content-Type (e.g. application/json)
*/
public 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)) {
return 'application/json';
} else {
return implode(',', $content_type);
}
}
$url = $this->config->getHost() . $resourcePath;
$curl = curl_init();
// set timeout, if needed
if ($this->config->getCurlTimeout() != 0) {
curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout());
}
// return the result on success, rather than just TRUE
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if (! empty($queryParams)) {
$url = ($url . '?' . http_build_query($queryParams));
}
if ($method == self::$POST) {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method == self::$PATCH) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method == self::$PUT) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method == self::$DELETE) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
} else if ($method != self::$GET) {
throw new ApiException('Method ' . $method . ' is not recognized.');
}
curl_setopt($curl, CURLOPT_URL, $url);
// Set user agent
curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent());
// debugging for curl
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile());
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a'));
} else {
curl_setopt($curl, CURLOPT_VERBOSE, 0);
}
// obtain the HTTP response headers
curl_setopt($curl, CURLOPT_HEADER, 1);
// Make the request
$response = curl_exec($curl);
$http_header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$http_header = substr($response, 0, $http_header_size);
$http_body = substr($response, $http_header_size);
$response_info = curl_getinfo($curl);
// debug HTTP response body
if ($this->config->getDebug()) {
error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile());
}
// Handle the response
if ($response_info['http_code'] == 0) {
throw new ApiException("API call to $url timed out: ".serialize($response_info), 0, null, null);
} else if ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299 ) {
$data = json_decode($http_body);
if (json_last_error() > 0) { // if response is a string
$data = $http_body;
}
} else {
throw new ApiException("[".$response_info['http_code']."] Error connecting to the API ($url)",
$response_info['http_code'], $http_header, $http_body);
}
return $data;
}
/*
* return the header 'Accept' based on an array of Accept provided
*
* @param string[] $accept Array of header
* @return string Accept (e.g. application/json)
*/
public static function selectHeaderAccept($accept) {
if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) {
return NULL;
} elseif (preg_grep("/application\/json/i", $accept)) {
return 'application/json';
} else {
return implode(',', $accept);
}
}
/*
* return the content type based on an array of content-type provided
*
* @param string[] content_type_array Array fo content-type
* @return string Content-Type (e.g. application/json)
*/
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)) {
return 'application/json';
} else {
return implode(',', $content_type);
}
}
}

View File

@ -1,4 +1,14 @@
<?php
/**
* ApiException
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
*
@ -14,57 +24,97 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{invokerPackage}};
use \Exception;
class ApiException extends Exception {
/**
* ApiException Class Doc Comment
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
class ApiException extends Exception
{
/** @var string The HTTP body of the server response. */
protected $responseBody;
/**
* The HTTP body of the server response.
* @var string
*/
protected $responseBody;
/**
* The HTTP header of the server response.
* @var string[]
*/
protected $responseHeaders;
/**
* The deserialized response object
* @var $responseObject;
*/
protected $responseObject;
/**
* Constructor
* @param string $message Error message
* @param string $code HTTP status code
* @param string $responseHeaders HTTP response header
* @param string $responseBody Deseralized response object
*/
public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null)
{
parent::__construct($message, $code);
$this->responseHeaders = $responseHeaders;
$this->responseBody = $responseBody;
}
/**
* Gets the HTTP response header
*
* @return string HTTP response header
*/
public function getResponseHeaders()
{
return $this->responseHeaders;
}
/**
* Gets the HTTP response body
*
* @return string HTTP response body
*/
public function getResponseBody()
{
return $this->responseBody;
}
/**
* Sets the deseralized response object (during deserialization)
* @param mixed $obj Deserialized response object
* @return void
*/
public function setResponseObject($obj)
{
$this->responseObject = $obj;
}
/** @var string[] The HTTP header of the server response. */
protected $responseHeaders;
/**
* The deserialized response object
*/
protected $responseObject;
public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) {
parent::__construct($message, $code);
$this->responseHeaders = $responseHeaders;
$this->responseBody = $responseBody;
}
/**
* Get the HTTP response header
*
* @return string HTTP response header
*/
public function getResponseHeaders() {
return $this->responseHeaders;
}
/**
* Get the HTTP response body
*
* @return string HTTP response body
*/
public function getResponseBody() {
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;
}
/**
* Gets the deseralized response object (during deserialization)
*
* @return mixed the deserialized response object
*/
public function getResponseObject()
{
return $this->responseObject;
}
}

View File

@ -1,47 +1,95 @@
<?php
/**
* ObjectSerializer
*
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
*
* 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.
*/
/**
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{invokerPackage}};
class ObjectSerializer {
/**
* ObjectSerializer Class Doc Comment
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
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);
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;
}
$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;
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));
public function toPathValue($value)
{
return rawurlencode($this->toString($value));
}
/**
@ -49,103 +97,133 @@ class ObjectSerializer {
* 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);
}
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);
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);
public function toFormValue($value)
{
if ($value instanceof SplFileObject) {
return $value->getRealPath();
} else {
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;
}
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
* @param mixed $data object or primitive to be deserialized
* @param string $class class name is passed as a string
* @param string $httpHeader HTTP headers
*
* @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);
}
public function deserialize($data, $class, $httpHeader=null)
{
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;
} elseif ($class === '\SplFileObject') {
// determine file name
if (preg_match('/Content-Disposition: inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeader, $match)) {
$filename = Configuration::getDefaultConfiguration()->getTempFolderPath().$match[1];
} else {
$filename = tempnam(Configuration::getDefaultConfiguration()->getTempFolderPath(), '');
}
$deserialized = new \SplFileObject($filename, "w");
$byte_written = $deserialized->fwrite($data);
error_log("[INFO] Written $byte_written byte to $filename. Please move the file to a proper folder or delete the temp file after processing.\n", 3, Configuration::getDefaultConfiguration()->getDebugFile());
} 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;
}
} 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;
return $deserialized;
}
}
}

View File

@ -1,4 +1,14 @@
<?php
/**
* {{classname}}
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
*
@ -16,8 +26,9 @@
*/
/**
*
* NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{apiPackage}};
@ -27,135 +38,156 @@ use \{{invokerPackage}}\ApiClient;
use \{{invokerPackage}}\ApiException;
use \{{invokerPackage}}\ObjectSerializer;
{{#operations}}
class {{classname}} {
/**
* {{classname}} Class Doc Comment
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
{{#operations}}class {{classname}}
{
/** @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
*/
public function getApiClient() {
return $this->apiClient;
}
/**
* @param \{{invokerPackage}}\ApiClient $apiClient set the API client
* @return {{classname}}
*/
public function setApiClient(ApiClient $apiClient) {
$this->apiClient = $apiClient;
return $this;
}
{{#operation}}
/**
* {{{nickname}}}
*
* {{{summary}}}
*
{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}}
{{/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}}) {
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if (${{paramName}} === null) {
throw new \InvalidArgumentException('Missing the required parameter ${{paramName}} when calling {{nickname}}');
}
{{/required}}{{/allParams}}
// parse inputs
$resourcePath = "{{path}}";
$resourcePath = str_replace("{format}", "json", $resourcePath);
$method = "{{httpMethod}}";
$httpBody = '';
$queryParams = array();
$headerParams = array();
$formParams = array();
$_header_accept = ApiClient::selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}));
if (!is_null($_header_accept)) {
$headerParams['Accept'] = $_header_accept;
}
$headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}}));
{{#queryParams}}// query params
if(${{paramName}} !== null) {
$queryParams['{{baseName}}'] = $this->apiClient->getSerializer()->toQueryValue(${{paramName}});
}{{/queryParams}}
{{#headerParams}}// header params
if(${{paramName}} !== null) {
$headerParams['{{baseName}}'] = $this->apiClient->getSerializer()->toHeaderValue(${{paramName}});
}{{/headerParams}}
{{#pathParams}}// path params
if(${{paramName}} !== null) {
$resourcePath = str_replace("{" . "{{baseName}}" . "}",
$this->apiClient->getSerializer()->toPathValue(${{paramName}}),
$resourcePath);
}{{/pathParams}}
{{#formParams}}// form params
if (${{paramName}} !== null) {
$formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->getSerializer()->toFormValue(${{paramName}});
}{{/formParams}}
{{#bodyParams}}// body params
$_tempBody = null;
if (isset(${{paramName}})) {
$_tempBody = ${{paramName}};
}{{/bodyParams}}
// for model (json/xml)
if (isset($_tempBody)) {
$httpBody = $_tempBody; // $_tempBody is the method argument, if present
} else if (count($formParams) > 0) {
// for HTTP post (form)
$httpBody = $formParams;
}
{{#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
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}}
/**
* API Client
* @var \{{invokerPackage}}\ApiClient instance of the ApiClient
*/
protected $apiClient;
/**
* Constructor
* @param \{{invokerPackage}}\ApiClient|null $apiClient The api client to use
*/
function __construct($apiClient = null)
{
if ($apiClient == null) {
$apiClient = new ApiClient();
$apiClient->getConfig()->setHost('{{basePath}}');
}
throw $e;
}
{{#returnType}}
if (!$response) {
return null;
}
$responseObject = $this->apiClient->getSerializer()->deserialize($response,'{{returnType}}');
return $responseObject;
{{/returnType}}
}
{{/operation}}
$this->apiClient = $apiClient;
}
/**
* Get API client
* @return \{{invokerPackage}}\ApiClient get the API client
*/
public function getApiClient()
{
return $this->apiClient;
}
/**
* Set the API client
* @param \{{invokerPackage}}\ApiClient $apiClient set the API client
* @return {{classname}}
*/
public function setApiClient(ApiClient $apiClient)
{
$this->apiClient = $apiClient;
return $this;
}
{{#operation}}
/**
* {{{nickname}}}
*
* {{{summary}}}
*
{{#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}}{{^required}}=null{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if (${{paramName}} === null) {
throw new \InvalidArgumentException('Missing the required parameter ${{paramName}} when calling {{nickname}}');
}{{/required}}{{/allParams}}
// parse inputs
$resourcePath = "{{path}}";
$resourcePath = str_replace("{format}", "json", $resourcePath);
$method = "{{httpMethod}}";
$httpBody = '';
$queryParams = array();
$headerParams = array();
$formParams = array();
$_header_accept = ApiClient::selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}));
if (!is_null($_header_accept)) {
$headerParams['Accept'] = $_header_accept;
}
$headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}}));
{{#queryParams}}// query params
if (${{paramName}} !== null) {
$queryParams['{{baseName}}'] = $this->apiClient->getSerializer()->toQueryValue(${{paramName}});
}{{/queryParams}}
{{#headerParams}}// header params
if (${{paramName}} !== null) {
$headerParams['{{baseName}}'] = $this->apiClient->getSerializer()->toHeaderValue(${{paramName}});
}{{/headerParams}}
{{#pathParams}}// path params
if (${{paramName}} !== null) {
$resourcePath = str_replace(
"{" . "{{baseName}}" . "}",
$this->apiClient->getSerializer()->toPathValue(${{paramName}}),
$resourcePath
);
}{{/pathParams}}
{{#formParams}}// form params
if (${{paramName}} !== null) {
$formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->getSerializer()->toFormValue(${{paramName}});
}{{/formParams}}
{{#bodyParams}}// body params
$_tempBody = null;
if (isset(${{paramName}})) {
$_tempBody = ${{paramName}};
}{{/bodyParams}}
// for model (json/xml)
if (isset($_tempBody)) {
$httpBody = $_tempBody; // $_tempBody is the method argument, if present
} else if (count($formParams) > 0) {
$httpBody = $formParams; // for HTTP post (form)
}
{{#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
try
{
list($response, $httpHeader) = $this->apiClient->callApi(
$resourcePath, $method,
$queryParams, $httpBody,
$headerParams{{#returnType}}, '{{returnType}}'{{/returnType}}
);
} catch (ApiException $e) {
switch ($e->getCode()) { {{#responses}}{{#dataType}}
case {{code}}:
$data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '{{dataType}}', $httpHeader);
$e->setResponseObject($data);
break;{{/dataType}}{{/responses}}
}
throw $e;
}
{{#returnType}}
if (!$response) {
return null;
}
return $this->apiClient->getSerializer()->deserialize($response, '{{returnType}}');
{{/returnType}}
}
{{/operation}}
}
{{/operations}}

View File

@ -1,33 +1,33 @@
{
"name": "{{groupId}}/{{artifactId}}",{{#artifactVersion}}
"version": "{{artifactVersion}}",{{/artifactVersion}}
"description": "{{description}}",
"keywords": [
"swagger",
"php",
"sdk",
"api"
],
"homepage": "http://swagger.io",
"license": "Apache v2",
"authors": [
{
"name": "Swagger and contributors",
"homepage": "https://github.com/swagger-api/swagger-codegen"
"name": "{{composerVendorName}}/{{composerProjectName}}",{{#artifactVersion}}
"version": "{{artifactVersion}}",{{/artifactVersion}}
"description": "{{description}}",
"keywords": [
"swagger",
"php",
"sdk",
"api"
],
"homepage": "http://swagger.io",
"license": "Apache v2",
"authors": [
{
"name": "Swagger and contributors",
"homepage": "https://github.com/swagger-api/swagger-codegen"
}
],
"require": {
"php": ">=5.3.3",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"satooshi/php-coveralls": "~0.6.1",
"squizlabs/php_codesniffer": "~2.0"
},
"autoload": {
"psr-4": { "{{escapedInvokerPackage}}\\" : "{{srcBasePath}}/" }
}
],
"require": {
"php": ">=5.3.3",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"satooshi/php-coveralls": "~0.6.1",
"squizlabs/php_codesniffer": "~2.0"
},
"autoload": {
"psr-4": { "{{escapedInvokerPackage}}\\" : "{{srcBasePath}}/" }
}
}

View File

@ -1,4 +1,15 @@
<?php
/**
* Configuration
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
*
@ -15,252 +26,439 @@
* limitations under the License.
*/
/**
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{invokerPackage}};
class Configuration {
/**
* Configuration Class Doc Comment
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
class Configuration
{
private static $defaultConfiguration = null;
private static $_defaultConfiguration = null;
/**
* Associate array to store API key(s)
*
* @var string[]
*/
protected $apiKeys = array();
/**
* Associate array to store API prefix (e.g. Bearer)
*
* @var string[]
*/
protected $apiKeyPrefixes = array();
/**
* Username for HTTP basic authentication
*
* @var string
*/
protected $username = '';
/**
* Password for HTTP basic authentication
*
* @var string
*/
protected $password = '';
/**
* The default instance of ApiClient
*
* @var \{{invokerPackage}}\ApiClient
*/
protected $defaultHeaders = array();
/**
* The host
*
* @var string
*/
protected $host = 'http://localhost';
/**
* Timeout (second) of the HTTP request, by default set to 0, no timeout
*
* @var string
*/
protected $curlTimeout = 0;
/**
* User agent of the HTTP request, set to "PHP-Swagger" by default
*
* @var string
*/
protected $userAgent = "PHP-Swagger";
/**
* Debug switch (default set to false)
*
* @var bool
*/
protected $debug = false;
/**
* Debug file location (log to STDOUT by default)
*
* @var string
*/
protected $debugFile = 'php://output';
/** @var string[] Associate array to store API key(s) */
protected $apiKeys = array();
/**
* Debug file location (log to STDOUT by default)
*
* @var string
*/
protected $tempFolderPath;
/** string[] Associate array to store API prefix (e.g. Bearer) */
protected $apiKeyPrefixes = array();
/** @var string Username for HTTP basic authentication */
protected $username = '';
/** @var string Password for HTTP basic authentication */
protected $password = '';
/** @var \{{invokerPackage}}\ApiClient The default instance of 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) */
protected $debug = false;
/** @var string Debug file location (log to STDOUT by default) */
protected $debugFile = 'php://output';
/**
* @param string $key
* @param string $value
* @return Configuration
*/
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.');
/**
* Constructor
*/
public function __construct()
{
$this->tempFolderPath = sys_get_temp_dir();
}
$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.');
/**
* Sets API key
*
* @param string $apiKeyIdentifier API key identifier (authentication scheme)
* @param string $key API key or token
*
* @return Configuration
*/
public function setApiKey($apiKeyIdentifier, $key)
{
$this->apiKeys[$apiKeyIdentifier] = $key;
return $this;
}
$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.');
/**
* Gets API key
*
* @param string $apiKeyIdentifier API key identifier (authentication scheme)
*
* @return string API key or token
*/
public function getApiKey($apiKeyIdentifier)
{
return isset($this->apiKeys[$apiKeyIdentifier]) ? $this->apiKeys[$apiKeyIdentifier] : null;
}
$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();
/**
* Sets the prefix for API key (e.g. Bearer)
*
* @param string $apiKeyIdentifier API key identifier (authentication scheme)
* @param string $prefix API key prefix, e.g. Bearer
*
* @return Configuration
*/
public function setApiKeyPrefix($apiKeyIdentifier, $prefix)
{
$this->apiKeyPrefixes[$apiKeyIdentifier] = $prefix;
return $this;
}
return self::$defaultConfiguration;
}
public static function setDefaultConfiguration(Configuration $config) {
self::$defaultConfiguration = $config;
}
/**
* Gets API key prefix
*
* @param string $apiKeyIdentifier API key identifier (authentication scheme)
*
* @return string
*/
public function getApiKeyPrefix($apiKeyIdentifier)
{
return isset($this->apiKeyPrefixes[$apiKeyIdentifier]) ? $this->apiKeyPrefixes[$apiKeyIdentifier] : null;
}
/**
* Sets the username for HTTP basic authentication
*
* @param string $username Username for HTTP basic authentication
*
* @return Configuration
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Gets the username for HTTP basic authentication
*
* @return string Username for HTTP basic authentication
*/
public function getUsername()
{
return $this->username;
}
/**
* Sets the password for HTTP basic authentication
*
* @param string $password Password for HTTP basic authentication
*
* @return Configuration
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Gets the password for HTTP basic authentication
*
* @return string Password for HTTP basic authentication
*/
public function getPassword()
{
return $this->password;
}
/**
* Adds a 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;
}
/**
* Gets the default header
*
* @return array An array of default header(s)
*/
public function getDefaultHeaders()
{
return $this->defaultHeaders;
}
/**
* Deletes a default header
*
* @param string $headerName the header to delete
*
* @return Configuration
*/
public function deleteDefaultHeader($headerName)
{
unset($this->defaultHeaders[$headerName]);
}
/**
* Sets the host
*
* @param string $host Host
*
* @return Configuration
*/
public function setHost($host)
{
$this->host = $host;
return $this;
}
/**
* Gets the host
*
* @return string Host
*/
public function getHost()
{
return $this->host;
}
/**
* Sets 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;
}
/**
* Gets the user agent of the api client
*
* @return string user agent
*/
public function getUserAgent()
{
return $this->userAgent;
}
/**
* Sets 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;
}
/**
* Gets the HTTP timeout value
*
* @return string HTTP timeout value
*/
public function getCurlTimeout()
{
return $this->curlTimeout;
}
/**
* Sets debug flag
*
* @param bool $debug Debug flag
*
* @return Configuration
*/
public function setDebug($debug)
{
$this->debug = $debug;
return $this;
}
/**
* Gets the debug flag
*
* @return bool
*/
public function getDebug()
{
return $this->debug;
}
/**
* Sets the debug file
*
* @param string $debugFile Debug file
*
* @return Configuration
*/
public function setDebugFile($debugFile)
{
$this->debugFile = $debugFile;
return $this;
}
/**
* Gets the debug file
*
* @return string
*/
public function getDebugFile()
{
return $this->debugFile;
}
/**
* Sets the temp folder path
*
* @param string $tempFolderPath Temp folder path
*
* @return Configuration
*/
public function setTempFolderPath($tempFolderPath)
{
$this->tempFolderPath = $tempFolderPath;
return $this;
}
/**
* Gets the temp folder path
*
* @return string Temp folder path
*/
public function getTempFolderPath()
{
return $this->tempFolderPath;
}
/**
* Gets the default configuration instance
*
* @return Configuration
*/
public static function getDefaultConfiguration()
{
if (self::$_defaultConfiguration == null) {
self::$_defaultConfiguration = new Configuration();
}
return self::$_defaultConfiguration;
}
/**
* Sets the detault configuration instance
*
* @param Configuration $config An instance of the Configuration Object
*
* @return void
*/
public static function setDefaultConfiguration(Configuration $config)
{
self::$_defaultConfiguration = $config;
}
/**
* Gets the essential information for debugging
*
* @return string The report for debugging
*/
public static function toDebugReport()
{
$report = "PHP SDK ({{invokerPackage}}) Debug Report:\n";
$report .= " OS: ".php_uname()."\n";
$report .= " PHP Version: ".phpversion()."\n";
$report .= " Swagger Spec Version: {{version}}\n";
$report .= " SDK Package Version: {{artifactVersion}}\n";
$report .= " Temp Folder Path: ".self::getDefaultConfiguration()->getTempFolderPath()."\n";
return $report;
}
}

View File

@ -1,4 +1,17 @@
<?php
{{#models}}
{{#model}}
/**
* {{classname}}
*
* PHP version 5
*
* @category Class
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
*
@ -14,97 +27,160 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{{#models}}
{{#model}}
/**
* {{description}}
*
* NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace {{modelPackage}};
use \ArrayAccess;
/**
* {{classname}} Class Doc Comment
*
* @category Class
* @description {{description}}
* @package {{invokerPackage}}
* @author http://github.com/swagger-api/swagger-codegen
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Licene v2
* @link https://github.com/swagger-api/swagger-codegen
*/
class {{classname}} implements ArrayAccess
{
/**
* Array of property to type mappings. Used for (de)serialization
* @var string[]
*/
static $swaggerTypes = array(
{{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
/**
* Array of attributes where the key is the local name, and the value is the original name
* @var string[]
*/
static $attributeMap = array(
{{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
/**
* Array of attributes to setter functions (for deserialization of responses)
* @var string[]
*/
static $setters = array(
{{#vars}}'{{name}}' => '{{setter}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
/**
* Array of attributes to getter functions (for serialization of requests)
* @var string[]
*/
static $getters = array(
{{#vars}}'{{name}}' => '{{getter}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
{{#vars}}
/**
* ${{name}} {{#description}}{{{description}}}{{/description}}
* @var {{datatype}}
*/
protected ${{name}};
{{/vars}}
class {{classname}} implements ArrayAccess {
/** @var string[] Array of property to type mappings. Used for (de)serialization */
static $swaggerTypes = array(
{{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
);
/** @var string[] Array of attributes where the key is the local name, and the value is the original name */
static $attributeMap = array(
{{#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}}*/
protected ${{name}};
{{/vars}}
public function __construct(array $data = null) {
if ($data != null) {
{{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}}
{{/hasMore}}{{/vars}}
/**
* Constructor
* @param mixed[] $data Associated array of property value initalizing the model
*/
public function __construct(array $data = null)
{
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);
}
public function offsetGet($offset) {
return $this->$offset;
}
public function offsetSet($offset, $value) {
$this->$offset = $value;
}
public function offsetUnset($offset) {
unset($this->$offset);
}
public function __toString() {
if (defined('JSON_PRETTY_PRINT')) {
return json_encode($this, JSON_PRETTY_PRINT);
} else {
return json_encode($this);
{{#vars}}
/**
* Gets {{name}}
* @return {{datatype}}
*/
public function {{getter}}()
{
return $this->{{name}};
}
/**
* Sets {{name}}
* @param {{datatype}} ${{name}} {{#description}}{{{description}}}{{/description}}
* @return $this
*/
public function {{setter}}(${{name}})
{
{{#isEnum}}$allowed_values = array({{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}});
if (!in_array(${{{name}}}, $allowed_values)) {
throw new \InvalidArgumentException("Invalid value for '{{name}}', must be one of {{#allowableValues}}{{#values}}'{{{this}}}'{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}");
}{{/isEnum}}
$this->{{name}} = ${{name}};
return $this;
}
{{/vars}}
/**
* Returns true if offset exists. False otherwise.
* @param integer $offset Offset
* @return boolean
*/
public function offsetExists($offset)
{
return isset($this->$offset);
}
/**
* Gets offset.
* @param integer $offset Offset
* @return mixed
*/
public function offsetGet($offset)
{
return $this->$offset;
}
/**
* Sets value based on offset.
* @param integer $offset Offset
* @param mixed $value Value to be set
* @return void
*/
public function offsetSet($offset, $value)
{
$this->$offset = $value;
}
/**
* Unsets offset.
* @param integer $offset Offset
* @return void
*/
public function offsetUnset($offset)
{
unset($this->$offset);
}
/**
* Gets the string presentation of the object
* @return string
*/
public function __toString()
{
if (defined('JSON_PRETTY_PRINT')) {
return json_encode(get_object_vars($this), JSON_PRETTY_PRINT);
} else {
return json_encode(get_object_vars($this));
}
}
}
}
{{/model}}
{{/models}}

View File

@ -11,13 +11,13 @@ python setup.py install
Or you can install from Github via pip:
```sh
pip install git+https://github.com/geekerzp/SwaggerPetstore-python.git
pip install git+https://github.com/geekerzp/swagger_client.git
```
To use the bindings, import the pacakge:
```python
import SwaggerPetstore
import swagger_client
```
## Manual Installation
@ -25,7 +25,7 @@ If you do not wish to use setuptools, you can download the latest release.
Then, to use the bindings, import the package:
```python
import path.to.SwaggerPetstore-python.SwaggerPetstore
import path.to.swagger_client
```
## Getting Started
@ -38,9 +38,9 @@ TODO
## Tests
(Make sure you are running it inside of a [virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/))
(Please make sure you have [virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/) installed)
You can run the tests in the current python platform:
Execute the following command to run the tests in the current Python (v2 or v3) environment:
```sh
$ make test
@ -71,4 +71,3 @@ $ make test-all
py34: commands succeeded
congratulations :)
```

View File

@ -8,3 +8,7 @@ from __future__ import absolute_import
{{/apis}}{{/apiInfo}}
# import ApiClient
from .api_client import ApiClient
from .configuration import Configuration
configuration = Configuration()

View File

@ -27,19 +27,20 @@ import os
# python 2 and python 3 compatibility library
from six import iteritems
from .. import configuration
from ..configuration import Configuration
from ..api_client import ApiClient
{{#operations}}
class {{classname}}(object):
def __init__(self, api_client=None):
config = Configuration()
if api_client:
self.api_client = api_client
else:
if not configuration.api_client:
configuration.api_client = ApiClient('{{basePath}}')
self.api_client = configuration.api_client
if not config.api_client:
config.api_client = ApiClient('{{basePath}}')
self.api_client = config.api_client
{{#operation}}
def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs):
@ -47,9 +48,18 @@ class {{classname}}(object):
{{{summary}}}
{{{notes}}}
SDK also supports asynchronous requests in which you can define a `callback` function
to be passed along and invoked when receiving response:
>>> def callback_function(response):
>>> pprint(response)
>>>
>>> thread = api.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}callback=callback_function)
:param callback function: The callback function for asynchronous request. (optional)
{{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}}
{{/allParams}}
:return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}
If the method is called asynchronously, returns the request thread.
"""
{{#allParams}}{{#required}}
# verify the required parameter '{{paramName}}' is set
@ -57,6 +67,7 @@ class {{classname}}(object):
raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{nickname}}`")
{{/required}}{{/allParams}}
all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}]
all_params.append('callback')
params = locals()
for key, val in iteritems(params['kwargs']):
@ -107,17 +118,7 @@ class {{classname}}(object):
response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params,
body=body_params, post_params=form_params, files=files,
response={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, auth_settings=auth_settings)
{{#returnType}}
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, auth_settings=auth_settings, callback=params.get('callback'))
return response
{{/returnType}}{{/operation}}
{{/operation}}
{{/operations}}

View File

@ -9,14 +9,19 @@ templates."""
from __future__ import absolute_import
from . import models
from .rest import RESTClient
from .rest import ApiException
import os
import re
import urllib
import json
import datetime
import mimetypes
import random
import tempfile
import threading
from datetime import datetime
from datetime import date
# python 2 and python 3 compatibility library
from six import iteritems
@ -28,7 +33,7 @@ except ImportError:
# for python2
from urllib import quote
from . import configuration
from .configuration import Configuration
class ApiClient(object):
"""
@ -38,7 +43,7 @@ class ApiClient(object):
:param header_name: a header to pass when making calls to the API
:param header_value: a header value to pass when making calls to the API
"""
def __init__(self, host=configuration.host, header_name=None, header_value=None):
def __init__(self, host=Configuration().host, header_name=None, header_value=None):
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
@ -58,8 +63,8 @@ class ApiClient(object):
def set_default_header(self, header_name, header_value):
self.default_headers[header_name] = header_value
def call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None, response=None, auth_settings=None):
def __call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None):
# headers parameters
header_params = header_params or {}
@ -100,11 +105,18 @@ class ApiClient(object):
response_data = self.request(method, url, query_params=query_params, headers=header_params,
post_params=post_params, body=body)
self.last_response = response_data
# deserialize response data
if response:
return self.deserialize(response_data, response)
if response_type:
deserialized_data = self.deserialize(response_data, response_type)
else:
return None
deserialized_data = None
if callback:
callback(deserialized_data)
else:
return deserialized_data
def to_path_value(self, obj):
"""
@ -136,7 +148,7 @@ class ApiClient(object):
return obj
elif isinstance(obj, list):
return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj]
elif isinstance(obj, (datetime.datetime, datetime.date)):
elif isinstance(obj, (datetime, date)):
return obj.isoformat()
else:
if isinstance(obj, dict):
@ -151,84 +163,106 @@ class ApiClient(object):
return {key: self.sanitize_for_serialization(val)
for key, val in iteritems(obj_dict)}
def deserialize(self, obj, obj_class):
def deserialize(self, response, response_type):
"""
Derialize a JSON string into an object.
Derialize response into an object.
:param obj: string or object to be deserialized
:param obj_class: class literal for deserialzied object, or string of class name
:param response: RESTResponse object to be deserialized
:param response_type: class literal for deserialzied object, or string of class name
:return object: deserialized object
:return: deserialized object
"""
# Have to accept obj_class as string or actual type. Type could be a
# native Python type, or one of the model classes.
if type(obj_class) == str:
if 'list[' in obj_class:
match = re.match('list\[(.*)\]', obj_class)
sub_class = match.group(1)
return [self.deserialize(sub_obj, sub_class) for sub_obj in obj]
# handle file downloading - save response body into a tmp file and return the instance
if "file" == response_type:
return self.__deserialize_file(response)
if 'dict(' in obj_class:
match = re.match('dict\((.*), (.*)\)', obj_class)
sub_class = match.group(2)
return {k: self.deserialize(v, sub_class) for k, v in iteritems(obj)}
if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime', "object"]:
obj_class = eval(obj_class)
else: # not a native type, must be model class
obj_class = eval('models.' + obj_class)
if obj_class in [int, float, dict, list, str, bool]:
return obj_class(obj)
elif obj_class == object:
return object()
elif obj_class == datetime:
return self.__parse_string_to_datetime(obj)
instance = obj_class()
for attr, attr_type in iteritems(instance.swagger_types):
if obj is not None and instance.attribute_map[attr] in obj and type(obj) in [list, dict]:
value = obj[instance.attribute_map[attr]]
if attr_type in ['str', 'int', 'float', 'bool']:
attr_type = eval(attr_type)
try:
value = attr_type(value)
except UnicodeEncodeError:
value = unicode(value)
except TypeError:
value = value
setattr(instance, attr, value)
elif attr_type == 'datetime':
setattr(instance, attr, self.__parse_string_to_datetime(value))
elif 'list[' in attr_type:
match = re.match('list\[(.*)\]', attr_type)
sub_class = match.group(1)
sub_values = []
if not value:
setattr(instance, attr, None)
else:
for sub_value in value:
sub_values.append(self.deserialize(sub_value, sub_class))
setattr(instance, attr, sub_values)
else:
setattr(instance, attr, self.deserialize(value, attr_type))
return instance
def __parse_string_to_datetime(self, string):
"""
Parse datetime in string to datetime.
The string should be in iso8601 datetime format.
"""
# fetch data from response object
try:
from dateutil.parser import parse
return parse(string)
except ImportError:
return string
data = json.loads(response.data)
except ValueError:
data = response.data
def request(self, method, url, query_params=None, headers=None, post_params=None, body=None):
return self.__deserialize(data, response_type)
def __deserialize(self, data, klass):
"""
:param data: dict, list or str
:param klass: class literal, or string of class name
:return: object
"""
if data is None:
return None
if type(klass) == str:
if 'list[' in klass:
sub_kls = re.match('list\[(.*)\]', klass).group(1)
return [self.__deserialize(sub_data, sub_kls) for sub_data in data]
if 'dict(' in klass:
sub_kls = re.match('dict\((.*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls) for k, v in iteritems(data)}
# convert str to class
# for native types
if klass in ['int', 'float', 'str', 'bool', "date", 'datetime', "object"]:
klass = eval(klass)
# for model types
else:
klass = eval('models.' + klass)
if klass in [int, float, str, bool]:
return self.__deserialize_primitive(data, klass)
elif klass == object:
return self.__deserialize_object()
elif klass == date:
return self.__deserialize_date(data)
elif klass == datetime:
return self.__deserialize_datatime(data)
else:
return self.__deserialize_model(data, klass)
def call_api(self, resource_path, method,
path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=None):
"""
Perform http request and return deserialized data
:param resource_path: Path to method endpoint.
:param method: Method to call.
:param path_params: Path parameters in the url.
:param query_params: Query parameters in the url.
:param header_params: Header parameters to be placed in the request header.
:param body: Request body.
:param post_params dict: Request post form parameters, for `application/x-www-form-urlencoded`, `multipart/form-data`.
:param auth_settings list: Auth Settings names for the request.
:param response: Response data type.
:param files dict: key -> filename, value -> filepath, for `multipart/form-data`.
:param callback function: Callback function for asynchronous request.
If provide this parameter, the request will be called asynchronously.
:return:
If provide parameter callback, the request will be called asynchronously.
The method will return the request thread.
If parameter callback is None, then the method will return the response directly.
"""
if callback is None:
return self.__call_api(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback)
else:
thread = threading.Thread(target=self.__call_api,
args=(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback))
thread.start()
return thread
def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None):
"""
Perform http request using RESTClient.
"""
@ -296,11 +330,13 @@ class ApiClient(object):
"""
Update header and query params based on authentication setting
"""
config = Configuration()
if not auth_settings:
return
for auth in auth_settings:
auth_setting = configuration.auth_settings().get(auth)
auth_setting = config.auth_settings().get(auth)
if auth_setting:
if auth_setting['in'] == 'header':
headers[auth_setting['key']] = auth_setting['value']
@ -308,3 +344,98 @@ class ApiClient(object):
querys[auth_setting['key']] = auth_setting['value']
else:
raise ValueError('Authentication token must be in `query` or `header`')
def __deserialize_file(self, response):
"""
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.
:param response: RESTResponse
:return: file path
"""
fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path)
os.close(fd)
os.remove(path)
content_disposition = response.getheader("Content-Disposition")
if content_disposition:
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).group(1)
path = os.path.join(os.path.dirname(path), filename)
with open(path, "w") as f:
f.write(response.data)
return path
def __deserialize_primitive(self, data, klass):
"""
Deserialize string to primitive type
:param data: str
:param klass: class literal
:return: int, float, str, bool
"""
try:
value = klass(data)
except UnicodeEncodeError:
value = unicode(data)
except TypeError:
value = data
return value
def __deserialize_object(self):
"""
Deserialize empty object
"""
return object()
def __deserialize_date(self, string):
"""
Deserialize string to date
:param string: str
:return: date
"""
try:
from dateutil.parser import parse
return parse(string).date()
except ImportError:
return string
except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a date object".format(string))
def __deserialize_datatime(self, string):
"""
Deserialize string to datetime.
The string should be in iso8601 datetime format.
:param string: str
:return: datetime
"""
try:
from dateutil.parser import parse
return parse(string)
except ImportError:
return string
except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a datetime object".format(string))
def __deserialize_model(self, data, klass):
"""
Deserialize list or dict to model
:param data: dict, list
:param klass: class literal
"""
instance = klass()
for attr, attr_type in iteritems(instance.swagger_types):
if data is not None \
and instance.attribute_map[attr] in data\
and isinstance(data, (list, dict)):
value = data[instance.attribute_map[attr]]
setattr(instance, attr, self.__deserialize(value, attr_type))
return instance

View File

@ -1,51 +1,121 @@
from __future__ import absolute_import
import base64
import urllib3
import httplib
import sys
import logging
def get_api_key_with_prefix(key):
global api_key
global api_key_prefix
def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton
@singleton
class Configuration(object):
def __init__(self):
# Default Base url
self.host = "{{basePath}}"
# Default api client
self.api_client = None
# Authentication Settings
self.api_key = {}
self.api_key_prefix = {}
self.username = ""
self.password = ""
# Logging Settings
self.logging_format = '%(asctime)s %(levelname)s %(message)s'
self.__logging_file = None
self.__debug = False
self.init_logger()
def init_logger(self):
self.logger = logging.getLogger()
formatter = logging.Formatter(self.logging_format)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
self.logger.addHandler(stream_handler)
if self.__debug:
self.logger.setLevel(logging.DEBUG)
else:
self.logger.setLevel(logging.WARNING)
if self.__logging_file:
file_handler = logging.FileHandler(self.__logging_file)
file_handler.setFormatter(formatter)
self.logger.addFilter(file_handler)
@property
def logging_file(self):
return self.__logging_file
@logging_file.setter
def logging_file(self, value):
self.__logging_file = value
if self.__logging_file:
formater = logging.Formatter(self.logging_format)
file_handler = logging.FileHandler(self.__logging_file)
file_handler.setFormatter(formater)
self.logger.addHandler(file_handler)
@property
def debug(self):
return self.__debug
@debug.setter
def debug(self, value):
self.__debug = value
if self.__debug:
# if debug status is True, turn on debug logging
self.logger.setLevel(logging.DEBUG)
# turn on httplib debug
httplib.HTTPConnection.debuglevel = 1
else:
# if debug status is False, turn off debug logging,
# setting log level to default `logging.WARNING`
self.logger.setLevel(logging.WARNING)
def get_api_key_with_prefix(self, key):
""" Return api key prepend prefix for key """
if self.api_key.get(key) and self.api_key_prefix.get(key):
return self.api_key_prefix[key] + ' ' + self.api_key[key]
elif self.api_key.get(key):
return self.api_key[key]
def get_basic_auth_token(self):
""" Return basic auth header string """
return urllib3.util.make_headers(basic_auth=self.username + ':' + self.password)\
.get('authorization')
def auth_settings(self):
""" Return Auth Settings for api client """
return { {{#authMethods}}{{#isApiKey}}
'{{name}}': {
'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}',
'value': self.get_api_key_with_prefix('{{keyParamName}}')
},
{{/isApiKey}}{{#isBasic}}
'{{name}}': {
'type': 'basic',
'in': 'header',
'key': 'Authorization',
'value': self.get_basic_auth_token()
},
{{/isBasic}}{{/authMethods}}
}
def to_debug_report(self):
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\
"Version of the API: {{version}}\n"\
"SDK Package Version: {{packageVersion}}".format(env=sys.platform, pyversion=sys.version)
if api_key.get(key) and api_key_prefix.get(key):
return api_key_prefix[key] + ' ' + api_key[key]
elif api_key.get(key):
return api_key[key]
def get_basic_auth_token():
global username
global password
return urllib3.util.make_headers(basic_auth=username + ':' + password).get('authorization')
def auth_settings():
return { {{#authMethods}}{{#isApiKey}}
'{{name}}': {
'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}',
'value': get_api_key_with_prefix('{{keyParamName}}')
},
{{/isApiKey}}{{#isBasic}}
'{{name}}': {
'type': 'basic',
'in': 'header',
'key': 'Authorization',
'value': get_basic_auth_token()
},
{{/isBasic}}{{/authMethods}}
}
# Default Base url
host = "{{basePath}}"
# Default api client
api_client = None
# Authentication settings
api_key = {}
api_key_prefix = {}
username = ''
password = ''

View File

@ -10,6 +10,7 @@ import io
import json
import ssl
import certifi
import logging
# python 2 and python 3 compatibility library
from six import iteritems
@ -27,6 +28,9 @@ except ImportError:
from urllib import urlencode
logger = logging.getLogger(__name__)
class RESTResponse(io.IOBase):
def __init__(self, resp):
@ -65,9 +69,10 @@ class RESTClientObject(object):
def agent(self, url):
"""
Return proper pool manager for the http\https schemes.
Use `urllib3.util.parse_url` for backward compatibility.
Return proper pool manager for the http/https schemes.
"""
url = urllib3.util.url.parse_url(url)
url = urllib3.util.parse_url(url)
scheme = url.scheme
if scheme == 'https':
return self.ssl_pool_manager
@ -125,24 +130,18 @@ class RESTClientObject(object):
headers=headers)
r = RESTResponse(r)
if r.status not in range(200, 206):
raise ApiException(r)
return self.process_response(r)
def process_response(self, response):
# In the python 3, the response.data is bytes.
# we need to decode it to string.
if sys.version_info > (3,):
data = response.data.decode('utf8')
else:
data = response.data
try:
resp = json.loads(data)
except ValueError:
resp = data
r.data = r.data.decode('utf8')
return resp
# log response body
logger.debug("response body: %s" % r.data)
if r.status not in range(200, 206):
raise ApiException(http_resp=r)
return r
def GET(self, url, headers=None, query_params=None):
return self.request("GET", url, headers=headers, query_params=query_params)
@ -164,37 +163,32 @@ class RESTClientObject(object):
class ApiException(Exception):
"""
Non-2xx HTTP response
"""
def __init__(self, http_resp):
self.status = http_resp.status
self.reason = http_resp.reason
self.body = http_resp.data
self.headers = http_resp.getheaders()
# In the python 3, the self.body is bytes.
# we need to decode it to string.
if sys.version_info > (3,):
data = self.body.decode('utf8')
def __init__(self, status=None, reason=None, http_resp=None):
if http_resp:
self.status = http_resp.status
self.reason = http_resp.reason
self.body = http_resp.data
self.headers = http_resp.getheaders()
else:
data = self.body
try:
self.body = json.loads(data)
except ValueError:
self.body = data
self.status = status
self.reason = reason
self.body = None
self.headers = None
def __str__(self):
"""
Custom error response messages
Custom error messages for exception
"""
return "({0})\n"\
"Reason: {1}\n"\
"HTTP response headers: {2}\n"\
"HTTP response body: {3}\n".\
format(self.status, self.reason, self.headers, self.body)
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}".format(self.headers)
if self.body:
error_message += "HTTP response body: {0}".format(self.body)
return error_message
class RESTClient(object):
"""

View File

@ -15,7 +15,7 @@ VERSION = "{{packageVersion}}"
# Try reading the setuptools documentation:
# http://pypi.python.org/pypi/setuptools
REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"]
REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi", "python-dateutil"]
setup(
name=NAME,

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,8 +3,6 @@ require "uri"
module {{moduleName}}
{{#operations}}
class {{classname}}
basePath = "{{basePath}}"
# apiInvoker = APIInvoker
{{#operation}}
{{newline}}
# {{summary}}
@ -14,11 +12,20 @@ module {{moduleName}}
{{#allParams}}{{^required}} # @option opts [{{{dataType}}}] :{{paramName}} {{description}}
{{/required}}{{/allParams}} # @return [{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}nil{{/returnType}}]
def self.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}opts = {})
if Swagger.configuration.debug
Swagger.logger.debug "Calling API: {{classname}}#{{nickname}} ..."
end
{{#allParams}}{{#required}}
# verify the required parameter '{{paramName}}' is set
raise "Missing the required parameter '{{paramName}}' when calling {{nickname}}" if {{{paramName}}}.nil?
{{/required}}{{/allParams}}
fail "Missing the required parameter '{{paramName}}' when calling {{nickname}}" if {{{paramName}}}.nil?{{#isEnum}}
unless [{{#allowableValues}}{{#values}}'{{{this}}}'{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}].include?({{{paramName}}})
fail "invalid value for '{{{paramName}}}', must be one of {{#allowableValues}}{{#values}}{{{this}}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}"
end{{/isEnum}}
{{/required}}{{^required}}{{#isEnum}}
if opts[:'{{{paramName}}}'] && ![{{#allowableValues}}{{#values}}'{{{this}}}'{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}].include?(opts[:'{{{paramName}}}'])
fail 'invalid value for "{{{paramName}}}", must be one of {{#allowableValues}}{{#values}}{{{this}}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}'
end
{{/isEnum}}{{/required}}{{/allParams}}
# resource path
path = "{{path}}".sub('{format}','json'){{#pathParams}}.sub('{' + '{{baseName}}' + '}', {{paramName}}.to_s){{/pathParams}}
@ -52,7 +59,14 @@ module {{moduleName}}
auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]
{{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
response.deserialize('{{{returnType}}}'){{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
result = response.deserialize('{{{returnType}}}')
if Swagger.configuration.debug
Swagger.logger.debug "API called: {{classname}}#{{nickname}}. Result: #{result.inspect}"
end
result{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
if Swagger.configuration.debug
Swagger.logger.debug "API called: {{classname}}#{{nickname}}"
end
nil{{/returnType}}
end
{{/operation}}

View File

@ -1,3 +1,5 @@
require 'date'
module {{moduleName}}
# base class containing fundamental method such as to_hash, build_from_hash and more
class BaseObject
@ -26,6 +28,8 @@ module {{moduleName}}
case type.to_sym
when :DateTime
DateTime.parse(value)
when :Date
Date.parse(value)
when :String
value.to_s
when :Integer

View File

@ -29,11 +29,20 @@ module {{moduleName}}
{{#vars}}
if attributes[:'{{{baseName}}}']
{{#isContainer}}if (value = attributes[:'{{{baseName}}}']).is_a?(Array)
@{{{name}}} = value
end{{/isContainer}}{{^isContainer}}@{{{name}}} = attributes[:'{{{baseName}}}']{{/isContainer}}
self.{{{name}}} = value
end{{/isContainer}}{{^isContainer}}self.{{{name}}} = attributes[:'{{{baseName}}}']{{/isContainer}}
end
{{/vars}}
end
{{#vars}}{{#isEnum}}
def {{{name}}}=({{{name}}})
allowed_values = [{{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}]
if {{{name}}} && !allowed_values.include?({{{name}}})
fail "invalid value for '{{{name}}}', must be one of #{allowed_values}"
end
@{{{name}}} = {{{name}}}
end
{{/isEnum}}{{/vars}}
end
{{/model}}
{{/models}}

View File

@ -1,82 +0,0 @@
class Object
unless Object.method_defined? :blank?
def blank?
respond_to?(:empty?) ? empty? : !self
end
end
unless Object.method_defined? :present?
def present?
!blank?
end
end
end
class String
unless String.method_defined? :underscore
def underscore
self.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
end
unless String.method_defined? :camelize
def camelize(first_letter_in_uppercase = true)
if first_letter_in_uppercase != :lower
self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
else
self.to_s[0].chr.downcase + camelize(self)[1..-1]
end
end
end
end
class Hash
unless Hash.method_defined? :stringify_keys
def stringify_keys
inject({}) do |options, (key, value)|
options[key.to_s] = value
options
end
end
end
unless Hash.method_defined? :stringify_keys!
def stringify_keys!
self.replace(self.stringify_keys)
end
end
unless Hash.method_defined? :symbolize_keys
def symbolize_keys
inject({}) do |options, (key, value)|
options[(key.to_sym rescue key) || key] = value
options
end
end
end
unless Hash.method_defined? :symbolize_keys!
def symbolize_keys!
self.replace(self.symbolize_keys)
end
end
unless Hash.method_defined? :symbolize_and_underscore_keys
def symbolize_and_underscore_keys
inject({}) do |options, (key, value)|
options[(key.to_s.underscore.to_sym rescue key) || key] = value
options
end
end
end
unless Hash.method_defined? :symbolize_and_underscore_keys!
def symbolize_and_underscore_keys!
self.replace(self.symbolize_and_underscore_keys)
end
end
end

View File

@ -1,6 +1,3 @@
require 'logger'
require 'json'
module {{moduleName}}
module Swagger
class << self
@ -25,8 +22,7 @@ module {{moduleName}}
def configure
yield(configuration) if block_given?
# Configure logger. Default to use Rails
self.logger ||= configuration.logger || (defined?(Rails) ? Rails.logger : Logger.new(STDOUT))
self.logger = configuration.logger
# remove :// from scheme
configuration.scheme.sub!(/:\/\//, '')
@ -41,7 +37,7 @@ module {{moduleName}}
end
def authenticated?
Swagger.configuration.auth_token.present?
!Swagger.configuration.auth_token.nil?
end
def de_authenticate
@ -51,7 +47,7 @@ module {{moduleName}}
def authenticate
return if Swagger.authenticated?
if Swagger.configuration.username.blank? || Swagger.configuration.password.blank?
if Swagger.configuration.username.nil? || Swagger.configuration.password.nil?
raise ApiError, "Username and password are required to authenticate."
end
@ -67,6 +63,14 @@ module {{moduleName}}
response_body = request.response.body
Swagger.configuration.auth_token = response_body['token']
end
def last_response
Thread.current[:swagger_last_response]
end
def last_response=(response)
Thread.current[:swagger_last_response] = response
end
end
end
end

View File

@ -1,7 +1,76 @@
require 'logger'
module {{moduleName}}
module Swagger
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
attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format
# Defines the username used with HTTP basic authentication.
#
# @return [String]
attr_accessor :username
# Defines the password used with HTTP basic authentication.
#
# @return [String]
attr_accessor :password
# Defines API keys used with API Key authentications.
#
# @return [Hash] key: parameter name, value: parameter value (API key)
#
# @example parameter name is "api_key", API key is "xxx" (e.g. "api_key=xxx" in query string)
# config.api_key['api_key'] = 'xxx'
attr_accessor :api_key
# Defines API key prefixes used with API Key authentications.
#
# @return [Hash] key: parameter name, value: API key prefix
#
# @example parameter name is "Authorization", API key prefix is "Token" (e.g. "Authorization: Token xxx" in headers)
# config.api_key_prefix['api_key'] = 'Token'
attr_accessor :api_key_prefix
# Set this to false to skip verifying SSL certificate when calling API from https server.
# Default to true.
#
# @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
#
# @return [true, false]
attr_accessor :verify_ssl
# Set this to customize the certificate file to verify the peer.
#
# @return [String] the path to the certificate file
#
# @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code:
# https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145
attr_accessor :ssl_ca_cert
# Set this to enable/disable debugging. When enabled (set to true), HTTP request/response
# details will be logged with `logger.debug` (see the `logger` attribute).
# Default to false.
#
# @return [true, false]
attr_accessor :debug
# Defines the logger used for debugging.
# Default to `Rails.logger` (when in Rails) or logging to STDOUT.
#
# @return [#debug]
attr_accessor :logger
# 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
@ -12,17 +81,20 @@ module {{moduleName}}
@user_agent = "ruby-swagger-#{Swagger::VERSION}"
@inject_format = false
@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)
@api_key_prefix = {}
# whether to verify SSL certificate, default to true
# Note: do NOT set it to false in production code, otherwise you would
# face multiple types of cryptographic attacks
@verify_ssl = true
@debug = false
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
end
end
end

View File

@ -1,41 +1,35 @@
require 'uri'
require 'typhoeus'
module {{moduleName}}
module Swagger
class Request
require 'uri'
require 'addressable/uri'
require 'typhoeus'
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names, :response
# 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] ||= {}
def initialize(http_method, path, attributes = {})
@http_method = http_method.to_sym.downcase
@path = path
# Set default headers
default_headers = {
'Content-Type' => "application/#{attributes[:format].downcase}",
'User-Agent' => Swagger.configuration.user_agent
}
attributes.each { |name, value| send "#{name}=", value }
# 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})
@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)
end
{{#hasAuthMethods}}
update_params_for_auth!
{{/hasAuthMethods}}
end
{{#hasAuthMethods}}
# Update hearder and query params based on authentication settings.
def update_params_for_auth!
(@auth_names || []).each do |auth_name|
@ -50,30 +44,23 @@ module {{moduleName}}
end
end
end
{{/hasAuthMethods}}
# Get API key (with prefix if set).
# @param [String] param_name the parameter name of API key auth
def get_api_key_with_prefix(param_name)
if Swagger.configuration.api_key_prefix[param_name].present?
if Swagger.configuration.api_key_prefix[param_name]
"#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}"
else
Swagger.configuration.api_key[param_name]
end
end
# Construct a base URL
# Construct the request URL.
def url(options = {})
u = Addressable::URI.new(
:scheme => Swagger.configuration.scheme,
:host => Swagger.configuration.host,
:path => self.interpreted_path,
:query => self.query_string.sub(/\?/, '')
).to_s
# Drop trailing question mark, if present
u.sub! /\?$/, ''
u
_path = self.interpreted_path
_path = "/#{_path}" unless _path.start_with?('/')
"#{Swagger.configuration.scheme}://#{Swagger.configuration.host}#{_path}"
end
# Iterate over the params hash, injecting any path values into the path string
@ -104,18 +91,6 @@ module {{moduleName}}
URI.encode [Swagger.configuration.base_path, p].join("/").gsub(/\/+/, '/')
end
# Massage the request body into a state of readiness
# If body is a hash, camelize all keys then convert to a json string
def body=(value)
if value.is_a?(Hash)
value = value.inject({}) do |memo, (k,v)|
memo[k.to_s.camelize(:lower).to_sym] = v
memo
end
end
@body = value
end
# If body is an object, JSONify it before making the actual request.
# For form parameters, remove empty value
def outgoing_body
@ -125,93 +100,60 @@ module {{moduleName}}
data.each do |key, value|
data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter
end
data
elsif @body # http body is JSON
@body.is_a?(String) ? @body : @body.to_json
data = @body.is_a?(String) ? @body : @body.to_json
else
nil
end
end
# Construct a query string from the query-string-type params
def query_string
# Iterate over all params,
# .. removing the ones that are part of the path itself.
# .. stringifying values so Addressable doesn't blow up.
query_values = {}
self.params.each_pair do |key, value|
next if self.path.include? "{#{key}}" # skip path params
next if value.blank? && value.class != FalseClass # skip empties
if Swagger.configuration.camelize_params
key = key.to_s.camelize(:lower).to_sym
end
query_values[key] = value.to_s
data = nil
end
# We don't want to end up with '?' as our query string
# if there aren't really any params
return "" if query_values.blank?
if Swagger.configuration.debug
Swagger.logger.debug "HTTP request body param ~BEGIN~\n#{data}\n~END~\n"
end
# Addressable requires query_values to be set after initialization..
qs = Addressable::URI.new
qs.query_values = query_values
qs.to_s
data
end
def make
#TODO use configuration setting to determine if debugging
#logger = Logger.new STDOUT
#logger.debug self.url
request_options = {
:method => self.http_method,
:headers => self.headers,
:params => self.params,
:ssl_verifypeer => Swagger.configuration.verify_ssl,
:headers => self.headers.stringify_keys
:cainfo => Swagger.configuration.ssl_ca_cert,
:verbose => Swagger.configuration.debug
}
response = case self.http_method.to_sym
when :get,:GET
Typhoeus::Request.get(
self.url,
request_options
)
when :post,:POST
Typhoeus::Request.post(
self.url,
request_options.merge(:body => self.outgoing_body)
)
when :patch,:PATCH
Typhoeus::Request.patch(
self.url,
request_options.merge(:body => self.outgoing_body)
)
when :put,:PUT
Typhoeus::Request.put(
self.url,
request_options.merge(:body => self.outgoing_body)
)
when :delete,:DELETE
Typhoeus::Request.delete(
self.url,
request_options.merge(:body => self.outgoing_body)
)
if [:post, :patch, :put, :delete].include?(self.http_method)
request_options.update :body => self.outgoing_body
end
Response.new(response)
end
def response
self.make
raw = Typhoeus::Request.new(self.url, request_options).run
@response = Response.new(raw)
if Swagger.configuration.debug
Swagger.logger.debug "HTTP response body ~BEGIN~\n#{@response.body}\n~END~\n"
end
# record as last response
Swagger.last_response = @response
unless @response.success?
fail ApiError.new(:code => @response.code,
:response_headers => @response.headers,
:response_body => @response.body),
@response.status_message
end
@response
end
def response_code_pretty
return unless @response.present?
return unless @response
@response.code.to_s
end
def response_headers_pretty
return unless @response.present?
return unless @response
# JSON.pretty_generate(@response.headers).gsub(/\n/, '<br/>') # <- This was for RestClient
@response.headers.gsub(/\n/, '<br/>') # <- This is for Typhoeus
end

View File

@ -3,76 +3,89 @@ module {{moduleName}}
class Response
require 'json'
require 'date'
require 'tempfile'
attr_accessor :raw
def initialize(raw)
self.raw = raw
unless raw.success?
fail ApiError.new(:code => code,
:response_headers => headers,
:response_body => body),
raw.status_message
end
end
def code
raw.code
end
def status_message
raw.status_message
end
def body
raw.body
end
def success?
raw.success?
end
# Deserialize the raw response body to the given return type.
#
# @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
def deserialize(return_type)
return nil if body.blank?
return nil if body.nil? || body.empty?
# 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}"
end
begin
data = JSON.parse(body, :symbolize_names => true)
data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
rescue JSON::ParserError => e
if return_type == 'String'
return body
if %w(String Date DateTime).include?(return_type)
data = body
else
raise e
end
end
build_models data, return_type
convert_to_type data, return_type
end
# Walk through the given data and, when necessary, build model(s) from
# Hash data for array/hash values of the response.
def build_models(data, return_type)
# Convert data to the given return type.
def convert_to_type(data, return_type)
return nil if data.nil?
case return_type
when 'String', 'Integer', 'Float', 'BOOLEAN'
# primitives, return directly
data
when 'String'
data.to_s
when 'Integer'
data.to_i
when 'Float'
data.to_f
when 'BOOLEAN'
data == true
when 'DateTime'
# parse date time (expecting ISO 8601 format)
DateTime.parse data
when 'Date'
# parse date time (expecting ISO 8601 format)
Date.parse data
when 'Object'
# generic object, return directly
data
when /\AArray<(.+)>\z/
# e.g. Array<Pet>
sub_type = $1
data.map {|item| build_models(item, sub_type) }
data.map {|item| convert_to_type(item, sub_type) }
when /\AHash\<String, (.+)\>\z/
# e.g. Hash<String, Integer>
sub_type = $1
{}.tap do |hash|
data.each {|k, v| hash[k] = build_models(v, sub_type) }
data.each {|k, v| hash[k] = convert_to_type(v, sub_type) }
end
else
# models, e.g. Pet
@ -82,6 +95,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
@ -105,9 +140,11 @@ module {{moduleName}}
end
def pretty_body
return unless body.present?
case format
when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '<br/>')
return unless body
if format == 'json'
JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '<br/>')
else
body
end
end

View File

@ -14,7 +14,6 @@ Gem::Specification.new do |s|
s.license = "Apache-2.0"
s.add_runtime_dependency 'typhoeus', '~> 0.2', '>= 0.2.1'
s.add_runtime_dependency 'addressable', '~> 2.2', '>= 2.2.4'
s.add_runtime_dependency 'json', '~> 1.4', '>= 1.4.6'
s.add_development_dependency 'rspec', '~> 3.2', '>= 3.2.0'

View File

@ -1,5 +1,4 @@
# Swagger common files
require '{{gemName}}/monkey'
require '{{gemName}}/swagger'
require '{{gemName}}/swagger/configuration'
require '{{gemName}}/swagger/api_error'
@ -22,5 +21,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

@ -15,18 +15,18 @@ MyApp.add_route('{{httpMethod}}', '{{path}}', {
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"dataType" => "{{dataType}}",
"paramType" => "query",
"allowMultiple" => {{allowMultiple}},
{{#collectionFormat}}"collectionFormat" => "{{collectionFormat}}",{{/collectionFormat}}
"allowableValues" => "{{allowableValues}}",
{{#defaultValue}}"defaultValue" => {{{defaultValue}}}{{/defaultValue}}
{{#defaultValue}}"defaultValue" => "{{{defaultValue}}}"{{/defaultValue}}
},
{{/queryParams}}
{{#pathParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"dataType" => "{{dataType}}",
"paramType" => "path",
},
{{/pathParams}}
@ -34,7 +34,7 @@ MyApp.add_route('{{httpMethod}}', '{{path}}', {
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"dataType" => "{{dataType}}",
"paramType" => "header",
},
{{/headerParams}}
@ -42,7 +42,7 @@ MyApp.add_route('{{httpMethod}}', '{{path}}', {
{
"name" => "body",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"dataType" => "{{dataType}}",
"paramType" => "body",
}
{{/bodyParams}}

View File

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

View File

@ -5,17 +5,16 @@
//
import Foundation
import PromiseKit
class {{projectName}}API {
static let basePath = "{{^basePathOverride}}{{basePath}}{{/basePathOverride}}{{basePathOverride}}"
static let basePath = "{{basePath}}"
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}}

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