mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-06 00:26:08 +00:00
Merge branch 'develop_2.0' into Generic_API_Exception
Conflicts: modules/swagger-codegen/src/main/resources/csharp/apiException.mustache
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
public class CliOption {
|
||||
private final String opt;
|
||||
private String description;
|
||||
|
||||
public CliOption(String opt, String description) {
|
||||
this.opt = opt;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getOpt() {
|
||||
return opt;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
@@ -140,4 +140,4 @@ public class Codegen extends DefaultGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ public interface CodegenConfig {
|
||||
String getTypeDeclaration(Property p);
|
||||
String getTypeDeclaration(String name);
|
||||
void processOpts();
|
||||
List<CliOption> cliOptions();
|
||||
String generateExamplePath(String path, Operation operation);
|
||||
|
||||
Set<String> reservedWords();
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.*;
|
||||
public class CodegenOperation {
|
||||
public Boolean hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive,
|
||||
returnSimpleType, subresourceOperation, isMapContainer, isListContainer,
|
||||
hasMore = Boolean.TRUE;
|
||||
hasMore = Boolean.TRUE, isMultipart;
|
||||
public String path, operationId, returnType, httpMethod, returnBaseType,
|
||||
returnContainer, summary, notes, baseName, defaultResponse;
|
||||
|
||||
|
||||
@@ -77,11 +77,24 @@ public class DefaultCodegen {
|
||||
protected String templateDir;
|
||||
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
|
||||
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
|
||||
|
||||
public List<CliOption> cliOptions() {
|
||||
return cliOptions;
|
||||
}
|
||||
|
||||
public void processOpts(){
|
||||
if(additionalProperties.containsKey("templateDir")) {
|
||||
this.setTemplateDir((String)additionalProperties.get("templateDir"));
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("modelPackage")) {
|
||||
this.setModelPackage((String)additionalProperties.get("modelPackage"));
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("apiPackage")) {
|
||||
this.setApiPackage((String)additionalProperties.get("apiPackage"));
|
||||
}
|
||||
}
|
||||
|
||||
// override with any special post-processing
|
||||
@@ -178,6 +191,14 @@ public class DefaultCodegen {
|
||||
this.templateDir = templateDir;
|
||||
}
|
||||
|
||||
public void setModelPackage(String modelPackage) {
|
||||
this.modelPackage = modelPackage;
|
||||
}
|
||||
|
||||
public void setApiPackage(String apiPackage) {
|
||||
this.apiPackage = apiPackage;
|
||||
}
|
||||
|
||||
public String toApiFilename(String name) {
|
||||
return toApiName(name);
|
||||
}
|
||||
@@ -281,6 +302,9 @@ public class DefaultCodegen {
|
||||
importMapping.put("LocalDateTime", "org.joda.time.*");
|
||||
importMapping.put("LocalDate", "org.joda.time.*");
|
||||
importMapping.put("LocalTime", "org.joda.time.*");
|
||||
|
||||
cliOptions.add(new CliOption("modelPackage", "package for generated models"));
|
||||
cliOptions.add(new CliOption("apiPackage", "package for generated api classes"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,26 +47,6 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
|
||||
"native", "super", "while")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin);
|
||||
|
||||
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
|
||||
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
|
||||
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
|
||||
supportingFiles.add(new SupportingFile("httpPatch.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "HttpPatch.java"));
|
||||
supportingFiles.add(new SupportingFile("jsonUtil.mustache",
|
||||
(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"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"String",
|
||||
@@ -80,6 +60,13 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
|
||||
);
|
||||
instantiationTypes.put("array", "ArrayList");
|
||||
instantiationTypes.put("map", "HashMap");
|
||||
|
||||
cliOptions.add(new CliOption("invokerPackage", "root package to use for the generated code"));
|
||||
cliOptions.add(new CliOption("groupId", "groupId for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactId", "artifactId for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactVersion", "artifact version for use in the generated build.gradle and pom.xml"));
|
||||
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
|
||||
cliOptions.add(new CliOption("useAndroidMavenGradlePlugin", "A flag to toggle android-maven gradle plugin. Default is true."));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -177,6 +164,96 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
|
||||
|
||||
return camelize(operationId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if(additionalProperties.containsKey("invokerPackage")) {
|
||||
this.setInvokerPackage((String)additionalProperties.get("invokerPackage"));
|
||||
}
|
||||
else{
|
||||
//not set, use default to be passed to template
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("groupId")) {
|
||||
this.setGroupId((String)additionalProperties.get("groupId"));
|
||||
}
|
||||
else{
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("groupId", groupId);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("artifactId")) {
|
||||
this.setArtifactId((String)additionalProperties.get("artifactId"));
|
||||
}
|
||||
else{
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("artifactVersion")) {
|
||||
this.setArtifactVersion((String)additionalProperties.get("artifactVersion"));
|
||||
}
|
||||
else{
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("useAndroidMavenGradlePlugin")) {
|
||||
this.setUseAndroidMavenGradlePlugin((Boolean)additionalProperties.get("useAndroidMavenGradlePlugin"));
|
||||
}
|
||||
else{
|
||||
additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin);
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin);
|
||||
|
||||
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
|
||||
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
|
||||
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
|
||||
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
|
||||
supportingFiles.add(new SupportingFile("httpPatch.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "HttpPatch.java"));
|
||||
supportingFiles.add(new SupportingFile("jsonUtil.mustache",
|
||||
(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"));
|
||||
}
|
||||
|
||||
public Boolean getUseAndroidMavenGradlePlugin() {
|
||||
return useAndroidMavenGradlePlugin;
|
||||
}
|
||||
|
||||
public void setUseAndroidMavenGradlePlugin(Boolean useAndroidMavenGradlePlugin) {
|
||||
this.useAndroidMavenGradlePlugin = useAndroidMavenGradlePlugin;
|
||||
}
|
||||
|
||||
public void setInvokerPackage(String invokerPackage) {
|
||||
this.invokerPackage = invokerPackage;
|
||||
}
|
||||
|
||||
public void setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public void setArtifactId(String artifactId) {
|
||||
this.artifactId = artifactId;
|
||||
}
|
||||
|
||||
public void setArtifactVersion(String artifactVersion) {
|
||||
this.artifactVersion = artifactVersion;
|
||||
}
|
||||
|
||||
public void setSourceFolder(String sourceFolder) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,11 +41,14 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
|
||||
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.cs"));
|
||||
supportingFiles.add(new SupportingFile("apiException.mustache",
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiException.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.cs"));
|
||||
supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll"));
|
||||
supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll"));
|
||||
supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
@@ -59,7 +62,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
"byte[]",
|
||||
"List",
|
||||
"Dictionary",
|
||||
"DateTime",
|
||||
"DateTime?",
|
||||
"String",
|
||||
"Boolean",
|
||||
"Double",
|
||||
@@ -79,9 +82,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
typeMapping.put("long", "long?");
|
||||
typeMapping.put("double", "double?");
|
||||
typeMapping.put("number", "double?");
|
||||
typeMapping.put("Date", "DateTime");
|
||||
typeMapping.put("datetime", "DateTime?");
|
||||
typeMapping.put("date", "DateTime?");
|
||||
typeMapping.put("file", "string"); // path to file
|
||||
typeMapping.put("array", "List");
|
||||
typeMapping.put("list", "List");
|
||||
typeMapping.put("map", "Dictionary");
|
||||
typeMapping.put("object", "Object");
|
||||
|
||||
@@ -94,11 +99,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
return (outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/')).replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
return (outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/')).replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,8 +170,8 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if(typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if(typeMapping.containsKey(swaggerType.toLowerCase())) {
|
||||
type = typeMapping.get(swaggerType.toLowerCase());
|
||||
if(languageSpecificPrimitives.contains(type))
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -36,28 +36,15 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"abstract", "continue", "for", "new", "switch", "assert",
|
||||
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
|
||||
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
|
||||
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
|
||||
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
|
||||
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
|
||||
"abstract", "continue", "for", "new", "switch", "assert",
|
||||
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
|
||||
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
|
||||
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
|
||||
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
|
||||
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
|
||||
"native", "super", "while")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
|
||||
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
|
||||
(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"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"String",
|
||||
@@ -71,8 +58,67 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
);
|
||||
instantiationTypes.put("array", "ArrayList");
|
||||
instantiationTypes.put("map", "HashMap");
|
||||
|
||||
cliOptions.add(new CliOption("invokerPackage", "root package for generated code"));
|
||||
cliOptions.add(new CliOption("groupId", "groupId in generated pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml"));
|
||||
cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml"));
|
||||
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if(additionalProperties.containsKey("invokerPackage")) {
|
||||
this.setInvokerPackage((String)additionalProperties.get("invokerPackage"));
|
||||
}
|
||||
else{
|
||||
//not set, use default to be passed to template
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("groupId")) {
|
||||
this.setGroupId((String)additionalProperties.get("groupId"));
|
||||
}
|
||||
else{
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("groupId", groupId);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("artifactId")) {
|
||||
this.setArtifactId((String)additionalProperties.get("artifactId"));
|
||||
}
|
||||
else{
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("artifactVersion")) {
|
||||
this.setArtifactVersion((String)additionalProperties.get("artifactVersion"));
|
||||
}
|
||||
else{
|
||||
//not set, use to be passed to template
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
|
||||
}
|
||||
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.java"));
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.java"));
|
||||
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
|
||||
(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"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
@@ -169,5 +215,23 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return camelize(operationId, true);
|
||||
}
|
||||
|
||||
public void setInvokerPackage(String invokerPackage) {
|
||||
this.invokerPackage = invokerPackage;
|
||||
}
|
||||
|
||||
public void setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public void setArtifactId(String artifactId) {
|
||||
this.artifactId = artifactId;
|
||||
}
|
||||
|
||||
public void setArtifactVersion(String artifactVersion) {
|
||||
this.artifactVersion = artifactVersion;
|
||||
}
|
||||
|
||||
public void setSourceFolder(String sourceFolder) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.wordnik.swagger.codegen.languages;
|
||||
|
||||
import com.wordnik.swagger.util.Json;
|
||||
import com.wordnik.swagger.codegen.*;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
@@ -10,7 +9,8 @@ import java.io.File;
|
||||
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected Set<String> foundationClasses = new HashSet<String>();
|
||||
protected String sourceFolder = "client";
|
||||
protected static String PREFIX = "SWG";
|
||||
protected String classPrefix = "SWG";
|
||||
protected String projectName = "swaggerClient";
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
@@ -26,7 +26,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
public ObjcClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/objc";
|
||||
outputFolder = "generated-code" + File.separator + "objc";
|
||||
modelTemplateFiles.put("model-header.mustache", ".h");
|
||||
modelTemplateFiles.put("model-body.mustache", ".m");
|
||||
apiTemplateFiles.put("api-header.mustache", ".h");
|
||||
@@ -34,12 +34,6 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
templateDir = "objc";
|
||||
modelPackage = "";
|
||||
|
||||
String appName = System.getProperty("appName");
|
||||
if(appName == null) {
|
||||
appName = "swaggerClient";
|
||||
}
|
||||
additionalProperties.put("projectName", appName);
|
||||
|
||||
defaultIncludes = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"bool",
|
||||
@@ -111,7 +105,31 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if(additionalProperties.containsKey("sourceFolder")) {
|
||||
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("classPrefix")) {
|
||||
this.setClassPrefix((String)additionalProperties.get("classPrefix"));
|
||||
}
|
||||
|
||||
if(additionalProperties.containsKey("projectName")) {
|
||||
this.setProjectName((String)additionalProperties.get("projectName"));
|
||||
}
|
||||
else{
|
||||
additionalProperties.put("projectName", projectName);
|
||||
}
|
||||
|
||||
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"));
|
||||
@@ -122,6 +140,8 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
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"));
|
||||
}
|
||||
|
||||
@@ -220,7 +240,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
// custom classes
|
||||
else {
|
||||
return PREFIX + camelize(type);
|
||||
return classPrefix + camelize(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,11 +286,11 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
return PREFIX + camelize(name) + "Api";
|
||||
return classPrefix + camelize(name) + "Api";
|
||||
}
|
||||
|
||||
public String toApiFilename(String name) {
|
||||
return PREFIX + camelize(name) + "Api";
|
||||
return classPrefix + camelize(name) + "Api";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -313,4 +333,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
public PerlClientCodegen() {
|
||||
super();
|
||||
modelPackage = "Object";
|
||||
outputFolder = "generated-code/perl";
|
||||
modelPackage = File.separatorChar + "Object";
|
||||
outputFolder = "generated-code" + File.separatorChar + "perl";
|
||||
modelTemplateFiles.put("object.mustache", ".pm");
|
||||
apiTemplateFiles.put("api.mustache", ".pm");
|
||||
templateDir = "perl";
|
||||
@@ -63,6 +63,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
languageSpecificPrimitives.add("DateTime");
|
||||
languageSpecificPrimitives.add("ARRAY");
|
||||
languageSpecificPrimitives.add("HASH");
|
||||
languageSpecificPrimitives.add("object");
|
||||
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("long", "int");
|
||||
@@ -75,9 +76,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
typeMapping.put("password", "string");
|
||||
typeMapping.put("array", "ARRAY");
|
||||
typeMapping.put("map", "HASH");
|
||||
typeMapping.put("object", "object");
|
||||
|
||||
supportingFiles.add(new SupportingFile("APIClient.mustache", "lib/WWW/" + invokerPackage, "APIClient.pm"));
|
||||
supportingFiles.add(new SupportingFile("BaseObject.mustache", "lib/WWW/" + invokerPackage, "Object/BaseObject.pm"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "ApiClient.pm"));
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "Configuration.pm"));
|
||||
supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "Object/BaseObject.pm"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,11 +90,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/lib/WWW/" + invokerPackage + apiPackage().replace('.', File.separatorChar);
|
||||
return (outputFolder + "/lib/WWW/" + invokerPackage + apiPackage()).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/lib/WWW/" + invokerPackage + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
return (outputFolder + "/lib/WWW/" + invokerPackage + modelPackage()).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -82,12 +82,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
typeMapping.put("map", "map");
|
||||
typeMapping.put("array", "array");
|
||||
typeMapping.put("list", "array");
|
||||
typeMapping.put("object", "object");
|
||||
|
||||
supportingFiles.add(new SupportingFile("composer.mustache", packagePath, "composer.json"));
|
||||
supportingFiles.add(new SupportingFile("configuration.mustache", packagePath + "/lib", "Configuration.php"));
|
||||
supportingFiles.add(new SupportingFile("APIClient.mustache", packagePath + "/lib", "APIClient.php"));
|
||||
supportingFiles.add(new SupportingFile("APIClientException.mustache", packagePath + "/lib", "APIClientException.php"));
|
||||
supportingFiles.add(new SupportingFile("require.mustache", packagePath, invokerPackage + ".php"));
|
||||
supportingFiles.add(new SupportingFile("composer.mustache", packagePath.replace('/', File.separatorChar), "composer.json"));
|
||||
supportingFiles.add(new SupportingFile("configuration.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "Configuration.php"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "ApiClient.php"));
|
||||
supportingFiles.add(new SupportingFile("ApiException.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "ApiException.php"));
|
||||
supportingFiles.add(new SupportingFile("require.mustache", packagePath.replace('/', File.separatorChar), invokerPackage + ".php"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,11 +98,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
return (outputFolder + "/" + modelPackage()).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,6 +71,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
supportingFiles.add(new SupportingFile("swagger.mustache", invokerPackage, "swagger.py"));
|
||||
supportingFiles.add(new SupportingFile("rest.mustache", invokerPackage, "rest.py"));
|
||||
supportingFiles.add(new SupportingFile("util.mustache", invokerPackage, "util.py"));
|
||||
supportingFiles.add(new SupportingFile("config.mustache", invokerPackage, "config.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__package.mustache", invokerPackage, "__init__.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage.replace('.', File.separatorChar), "__init__.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage.replace('.', File.separatorChar), "__init__.py"));
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.wordnik.swagger.codegen.languages;
|
||||
|
||||
import com.wordnik.swagger.codegen.*;
|
||||
import com.wordnik.swagger.models.Operation;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "io.swagger.client";
|
||||
protected String groupId = "io.swagger";
|
||||
protected String artifactId = "swagger-java-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String sourceFolder = "src/main/java";
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "retrofit";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a Retrofit client library.";
|
||||
}
|
||||
|
||||
public RetrofitClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/java";
|
||||
modelTemplateFiles.put("model.mustache", ".java");
|
||||
apiTemplateFiles.put("api.mustache", ".java");
|
||||
templateDir = "retrofit";
|
||||
apiPackage = "io.swagger.client.api";
|
||||
modelPackage = "io.swagger.client.model";
|
||||
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"abstract", "continue", "for", "new", "switch", "assert",
|
||||
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
|
||||
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
|
||||
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
|
||||
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
|
||||
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
|
||||
"native", "super", "while")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
supportingFiles.add(new SupportingFile("service.mustache",
|
||||
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ServiceGenerator.java"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"String",
|
||||
"boolean",
|
||||
"Boolean",
|
||||
"Double",
|
||||
"Integer",
|
||||
"Long",
|
||||
"Float",
|
||||
"Object")
|
||||
);
|
||||
instantiationTypes.put("array", "ArrayList");
|
||||
instantiationTypes.put("map", "HashMap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_");
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$"))
|
||||
return name;
|
||||
|
||||
// camelize (lower first character) the variable name
|
||||
// pet_id => petId
|
||||
name = camelize(name, true);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if(reservedWords.contains(name) || name.matches("^\\d.*"))
|
||||
name = escapeReservedWord(name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// should be the same as variable name
|
||||
return toVarName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if(reservedWords.contains(name))
|
||||
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
// should be the same as the model name
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if(p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
|
||||
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if(typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if(languageSpecificPrimitives.contains(type))
|
||||
return toModelName(type);
|
||||
}
|
||||
else
|
||||
type = swaggerType;
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
if(reservedWords.contains(operationId))
|
||||
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
|
||||
|
||||
return camelize(operationId, true);
|
||||
}
|
||||
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
Map<String, Object> operations = (Map<String, Object>)objs.get("operations");
|
||||
if(operations != null) {
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
for(CodegenOperation operation : ops) {
|
||||
if (operation.hasConsumes == Boolean.TRUE) {
|
||||
Map<String, String> firstType = operation.consumes.get(0);
|
||||
if (firstType != null) {
|
||||
if ("multipart/form-data".equals(firstType.get("mediaType"))) {
|
||||
operation.isMultipart = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(operation.returnType == null) {
|
||||
operation.returnType = "Void";
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
moduleName = generateModuleName();
|
||||
modelPackage = gemName + "/models";
|
||||
apiPackage = gemName + "/api";
|
||||
outputFolder = "generated-code/ruby";
|
||||
outputFolder = "generated-code" + File.separatorChar + "ruby";
|
||||
modelTemplateFiles.put("model.mustache", ".rb");
|
||||
apiTemplateFiles.put("api.mustache", ".rb");
|
||||
templateDir = "ruby";
|
||||
@@ -69,17 +69,17 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
typeMapping.put("List", "array");
|
||||
typeMapping.put("map", "map");
|
||||
|
||||
String baseFolder = "lib/" + gemName;
|
||||
String swaggerFolder = baseFolder + "/swagger";
|
||||
String modelFolder = baseFolder + "/models";
|
||||
String baseFolder = "lib" + File.separatorChar + gemName;
|
||||
String swaggerFolder = baseFolder + File.separatorChar + "swagger";
|
||||
String modelFolder = baseFolder + File.separatorChar + "models";
|
||||
supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec"));
|
||||
supportingFiles.add(new SupportingFile("swagger_client.mustache", "lib", gemName + ".rb"));
|
||||
supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/request.mustache", swaggerFolder, "request.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/response.mustache", swaggerFolder, "response.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/version.mustache", swaggerFolder, "version.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/configuration.mustache", swaggerFolder, "configuration.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "request.mustache", swaggerFolder, "request.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "response.mustache", swaggerFolder, "response.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "version.mustache", swaggerFolder, "version.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "configuration.mustache", swaggerFolder, "configuration.rb"));
|
||||
supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb"));
|
||||
}
|
||||
|
||||
|
||||
33
modules/swagger-codegen/src/main/java/config/Config.java
Normal file
33
modules/swagger-codegen/src/main/java/config/Config.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package config;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Config {
|
||||
private Map<String, String> options;
|
||||
|
||||
public Config() {
|
||||
this.options = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
public Config(Map<String, String> properties) {
|
||||
this.options = properties;
|
||||
}
|
||||
|
||||
public Map<String, String> getOptions() {
|
||||
return ImmutableMap.copyOf(options);
|
||||
}
|
||||
|
||||
public boolean hasOption(String opt){
|
||||
return options.containsKey(opt);
|
||||
}
|
||||
|
||||
public String getOption(String opt){
|
||||
return options.get(opt);
|
||||
}
|
||||
|
||||
public void setOption(String opt, String value){
|
||||
options.put(opt, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package config;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.File;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigParser {
|
||||
|
||||
public static Config read(String location) {
|
||||
|
||||
System.out.println("reading config from " + location);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
Config config = new Config();
|
||||
|
||||
try {
|
||||
JsonNode rootNode = mapper.readTree(new File(location));
|
||||
Iterator<Map.Entry<String, JsonNode>> optionNodes = rootNode.fields();
|
||||
|
||||
while (optionNodes.hasNext()) {
|
||||
Map.Entry<String, JsonNode> optionNode = (Map.Entry<String, JsonNode>) optionNodes.next();
|
||||
|
||||
if(optionNode.getValue().isValueNode()){
|
||||
config.setOption(optionNode.getKey(), optionNode.getValue().asText());
|
||||
}
|
||||
else{
|
||||
System.out.println("omitting non-value node " + optionNode.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -29,69 +29,116 @@ import java.net.URLEncoder;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
public class ApiInvoker {
|
||||
private static ApiInvoker INSTANCE = new ApiInvoker();
|
||||
public class ApiClient {
|
||||
private Map<String, Client> hostMap = new HashMap<String, Client>();
|
||||
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
|
||||
private boolean isDebug = false;
|
||||
private boolean debugging = false;
|
||||
private String basePath = "{{basePath}}";
|
||||
|
||||
/**
|
||||
* ISO 8601 date time format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
private DateFormat dateFormat;
|
||||
|
||||
/**
|
||||
* ISO 8601 date format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
||||
public ApiClient() {
|
||||
// Use ISO 8601 format for date and datetime.
|
||||
// See https://en.wikipedia.org/wiki/ISO_8601
|
||||
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
static {
|
||||
// Use UTC as the default time zone.
|
||||
DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
// Set default User-Agent.
|
||||
setUserAgent("Java-Swagger");
|
||||
}
|
||||
|
||||
public static void setUserAgent(String userAgent) {
|
||||
INSTANCE.addDefaultHeader("User-Agent", userAgent);
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
public static Date parseDateTime(String str) {
|
||||
public ApiClient setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the User-Agent header's value (by adding to the default header map).
|
||||
*/
|
||||
public ApiClient setUserAgent(String userAgent) {
|
||||
addDefaultHeader("User-Agent", userAgent);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a default header.
|
||||
*
|
||||
* @param key The header's key
|
||||
* @param value The header's value
|
||||
*/
|
||||
public ApiClient addDefaultHeader(String key, String value) {
|
||||
defaultHeaderMap.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that whether debugging is enabled for this API client.
|
||||
*/
|
||||
public boolean isDebugging() {
|
||||
return debugging;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable debugging for this API client.
|
||||
*
|
||||
* @param debugging To enable (true) or disable (false) debugging
|
||||
*/
|
||||
public ApiClient setDebugging(boolean debugging) {
|
||||
this.debugging = debugging;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date format used to parse/format date parameters.
|
||||
*/
|
||||
public DateFormat getDateFormat() {
|
||||
return dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the date format used to parse/format date parameters.
|
||||
*/
|
||||
public ApiClient getDateFormat(DateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given string into Date object.
|
||||
*/
|
||||
public Date parseDate(String str) {
|
||||
try {
|
||||
return DATE_TIME_FORMAT.parse(str);
|
||||
return dateFormat.parse(str);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Date parseDate(String str) {
|
||||
try {
|
||||
return DATE_FORMAT.parse(str);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
/**
|
||||
* Format the given Date object into string.
|
||||
*/
|
||||
public String formatDate(Date date) {
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
public static String formatDateTime(Date datetime) {
|
||||
return DATE_TIME_FORMAT.format(datetime);
|
||||
}
|
||||
|
||||
public static String formatDate(Date date) {
|
||||
return DATE_FORMAT.format(date);
|
||||
}
|
||||
|
||||
public static String parameterToString(Object param) {
|
||||
/**
|
||||
* Format the given parameter object into string.
|
||||
*/
|
||||
public String parameterToString(Object param) {
|
||||
if (param == null) {
|
||||
return "";
|
||||
} else if (param instanceof Date) {
|
||||
return formatDateTime((Date) param);
|
||||
return formatDate((Date) param);
|
||||
} else if (param instanceof Collection) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for(Object o : (Collection)param) {
|
||||
@@ -105,28 +152,27 @@ public class ApiInvoker {
|
||||
return String.valueOf(param);
|
||||
}
|
||||
}
|
||||
public void enableDebug() {
|
||||
isDebug = true;
|
||||
}
|
||||
|
||||
public static ApiInvoker getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void addDefaultHeader(String key, String value) {
|
||||
defaultHeaderMap.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape the given string to be used as URL query value.
|
||||
*/
|
||||
public String escapeString(String str) {
|
||||
try{
|
||||
try {
|
||||
return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
|
||||
}
|
||||
catch(UnsupportedEncodingException e) {
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object deserialize(String json, String containerType, Class cls) throws ApiException {
|
||||
/**
|
||||
* Deserialize the given JSON string to Java object.
|
||||
*
|
||||
* @param json The JSON string
|
||||
* @param containerType The container type, one of "list", "array" or ""
|
||||
* @param cls The type of the Java object
|
||||
* @return The deserialized Java object
|
||||
*/
|
||||
public Object deserialize(String json, String containerType, Class cls) throws ApiException {
|
||||
if(null != containerType) {
|
||||
containerType = containerType.toLowerCase();
|
||||
}
|
||||
@@ -147,11 +193,14 @@ public class ApiInvoker {
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ApiException(500, e.getMessage());
|
||||
throw new ApiException(500, e.getMessage(), null, json);
|
||||
}
|
||||
}
|
||||
|
||||
public static String serialize(Object obj) throws ApiException {
|
||||
/**
|
||||
* Serialize the given Java object into JSON string.
|
||||
*/
|
||||
public String serialize(Object obj) throws ApiException {
|
||||
try {
|
||||
if (obj != null)
|
||||
return JsonUtil.getJsonMapper().writeValueAsString(obj);
|
||||
@@ -163,8 +212,20 @@ 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 {
|
||||
Client client = getClient(host);
|
||||
/**
|
||||
* Invoke API by sending HTTP request with the given options.
|
||||
*
|
||||
* @param path The sub-path of the HTTP URL
|
||||
* @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
|
||||
* @param queryParams The query parameters
|
||||
* @param body The request body object
|
||||
* @param headerParams The header parameters
|
||||
* @param formParams The form parameters
|
||||
* @param contentType The request Content-Type
|
||||
* @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 contentType) throws ApiException {
|
||||
Client client = getClient();
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
@@ -180,7 +241,7 @@ public class ApiInvoker {
|
||||
}
|
||||
String querystring = b.toString();
|
||||
|
||||
Builder builder = client.resource(host + path + querystring).accept("application/json");
|
||||
Builder builder = client.resource(basePath + path + querystring).accept("application/json");
|
||||
for(String key : headerParams.keySet()) {
|
||||
builder = builder.header(key, headerParams.get(key));
|
||||
}
|
||||
@@ -236,6 +297,7 @@ public class ApiInvoker {
|
||||
else {
|
||||
throw new ApiException(500, "unknown method type " + method);
|
||||
}
|
||||
|
||||
if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) {
|
||||
return null;
|
||||
}
|
||||
@@ -249,9 +311,11 @@ public class ApiInvoker {
|
||||
}
|
||||
else {
|
||||
String message = "error";
|
||||
String respBody = null;
|
||||
if(response.hasEntity()) {
|
||||
try{
|
||||
message = String.valueOf(response.getEntity(String.class));
|
||||
respBody = String.valueOf(response.getEntity(String.class));
|
||||
message = respBody;
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
// e.printStackTrace();
|
||||
@@ -259,16 +323,21 @@ public class ApiInvoker {
|
||||
}
|
||||
throw new ApiException(
|
||||
response.getClientResponseStatus().getStatusCode(),
|
||||
message);
|
||||
message,
|
||||
response.getHeaders(),
|
||||
respBody);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given form parameters as request body.
|
||||
*/
|
||||
private String getXWWWFormUrlencodedParams(Map<String, String> formParams) {
|
||||
StringBuilder formParamBuilder = new StringBuilder();
|
||||
|
||||
for (Entry<String, String> param : formParams.entrySet()) {
|
||||
String keyStr = ApiInvoker.parameterToString(param.getKey());
|
||||
String valueStr = ApiInvoker.parameterToString(param.getValue());
|
||||
String keyStr = parameterToString(param.getKey());
|
||||
String valueStr = parameterToString(param.getValue());
|
||||
|
||||
try {
|
||||
formParamBuilder.append(URLEncoder.encode(keyStr, "utf8"))
|
||||
@@ -287,14 +356,16 @@ public class ApiInvoker {
|
||||
return encodedFormParams;
|
||||
}
|
||||
|
||||
|
||||
private Client getClient(String host) {
|
||||
if(!hostMap.containsKey(host)) {
|
||||
/**
|
||||
* Get an existing client or create a new client to handle HTTP request.
|
||||
*/
|
||||
private Client getClient() {
|
||||
if(!hostMap.containsKey(basePath)) {
|
||||
Client client = Client.create();
|
||||
if(isDebug)
|
||||
if (debugging)
|
||||
client.addFilter(new LoggingFilter());
|
||||
hostMap.put(host, client);
|
||||
hostMap.put(basePath, client);
|
||||
}
|
||||
return hostMap.get(host);
|
||||
return hostMap.get(basePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
public class Configuration {
|
||||
private static ApiClient defaultApiClient = new ApiClient();
|
||||
|
||||
/**
|
||||
* Get the default API client, which would be used when creating API
|
||||
* instances without providing an API client.
|
||||
*/
|
||||
public static ApiClient getDefaultApiClient() {
|
||||
return defaultApiClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default API client, which would be used when creating API
|
||||
* instances without providing an API client.
|
||||
*/
|
||||
public static void setDefaultApiClient(ApiClient apiClient) {
|
||||
defaultApiClient = apiClient;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package {{package}};
|
||||
|
||||
import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.ApiInvoker;
|
||||
import {{invokerPackage}}.ApiClient;
|
||||
import {{invokerPackage}}.Configuration;
|
||||
|
||||
import {{modelPackage}}.*;
|
||||
|
||||
@@ -21,19 +22,22 @@ import java.util.HashMap;
|
||||
|
||||
{{#operations}}
|
||||
public class {{classname}} {
|
||||
String basePath = "{{basePath}}";
|
||||
ApiInvoker apiInvoker = ApiInvoker.getInstance();
|
||||
private ApiClient apiClient;
|
||||
|
||||
public ApiInvoker getInvoker() {
|
||||
return apiInvoker;
|
||||
public {{classname}}() {
|
||||
this(Configuration.getDefaultApiClient());
|
||||
}
|
||||
|
||||
public void setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
public {{classname}}(ApiClient apiClient) {
|
||||
this.apiClient = apiClient;
|
||||
}
|
||||
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
public ApiClient getApiClient() {
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
public void setApiClient(ApiClient apiClient) {
|
||||
this.apiClient = apiClient;
|
||||
}
|
||||
|
||||
{{#operation}}
|
||||
@@ -54,7 +58,7 @@ public class {{classname}} {
|
||||
|
||||
// create path and map variables
|
||||
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
|
||||
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}};
|
||||
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
|
||||
|
||||
// query params
|
||||
Map<String, String> queryParams = new HashMap<String, String>();
|
||||
@@ -62,9 +66,10 @@ public class {{classname}} {
|
||||
Map<String, String> formParams = new HashMap<String, String>();
|
||||
|
||||
{{#queryParams}}if ({{paramName}} != null)
|
||||
queryParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
|
||||
queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
|
||||
{{#headerParams}}if ({{paramName}} != null)
|
||||
headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
|
||||
{{/headerParams}}
|
||||
String[] contentTypes = {
|
||||
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
|
||||
@@ -76,25 +81,30 @@ public class {{classname}} {
|
||||
boolean hasFields = false;
|
||||
FormDataMultiPart mp = new FormDataMultiPart();
|
||||
{{#formParams}}{{#notFile}}
|
||||
hasFields = true;
|
||||
mp.field("{{baseName}}", ApiInvoker.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
if ({{paramName}} != null) {
|
||||
hasFields = true;
|
||||
mp.field("{{baseName}}", apiClient.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
}
|
||||
{{/notFile}}{{#isFile}}
|
||||
hasFields = true;
|
||||
mp.field("{{baseName}}", file.getName());
|
||||
mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE));
|
||||
if ({{paramName}} != null) {
|
||||
hasFields = true;
|
||||
mp.field("{{baseName}}", {{paramName}}.getName());
|
||||
mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE));
|
||||
}
|
||||
{{/isFile}}{{/formParams}}
|
||||
if(hasFields)
|
||||
postBody = mp;
|
||||
}
|
||||
else {
|
||||
{{#formParams}}{{#notFile}}formParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));{{/notFile}}
|
||||
{{#formParams}}{{#notFile}}if ({{paramName}} != null)
|
||||
formParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));{{/notFile}}
|
||||
{{/formParams}}
|
||||
}
|
||||
|
||||
try {
|
||||
String response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType);
|
||||
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType);
|
||||
if(response != null){
|
||||
return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
|
||||
return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
|
||||
}
|
||||
else {
|
||||
return {{#returnType}}null{{/returnType}};
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
public class ApiException extends Exception {
|
||||
int code = 0;
|
||||
String message = null;
|
||||
private int code = 0;
|
||||
private String message = null;
|
||||
private Map<String, List<String>> responseHeaders = null;
|
||||
private String responseBody = null;
|
||||
|
||||
public ApiException() {}
|
||||
|
||||
@@ -11,19 +16,32 @@ public class ApiException extends Exception {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.responseHeaders = responseHeaders;
|
||||
this.responseBody = responseBody;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
|
||||
/**
|
||||
* Get the HTTP response headers.
|
||||
*/
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return responseHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP response body.
|
||||
*/
|
||||
public String getResponseBody() {
|
||||
return responseBody;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ com.wordnik.swagger.codegen.languages.PhpClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.PythonClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.Python3ClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.Qt5CPPGenerator
|
||||
com.wordnik.swagger.codegen.languages.RetrofitClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.RubyClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.ScalaClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.ScalatraServerCodegen
|
||||
|
||||
@@ -60,10 +60,10 @@ dependencies {
|
||||
compile "com.google.code.gson:gson:$gson_version"
|
||||
compile "org.apache.httpcomponents:httpcore:$httpclient_version"
|
||||
compile "org.apache.httpcomponents:httpclient:$httpclient_version"
|
||||
compile ("org.apache.httpcomponents:httpcore:$httpcore_version") {
|
||||
compile ("org.apache.httpcomponents:httpcore:$httpclient_version") {
|
||||
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
|
||||
}
|
||||
compile ("org.apache.httpcomponents:httpmime:$httpmime_version") {
|
||||
compile ("org.apache.httpcomponents:httpmime:$httpclient_version") {
|
||||
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
|
||||
}
|
||||
testCompile "junit:junit:$junit_version"
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import io.swagger.client.model.*;
|
||||
import {{modelPackage}}.*;
|
||||
|
||||
public class JsonUtil {
|
||||
public static GsonBuilder gsonBuilder;
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using RestSharp;
|
||||
|
||||
namespace {{invokerPackage}} {
|
||||
/// <summary>
|
||||
/// API client is mainly responible for making the HTTP call to the API backend
|
||||
/// </summary>
|
||||
public class ApiClient {
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="basePath">The base path.</param>
|
||||
public ApiClient(String basePath="{{basePath}}") {
|
||||
this.basePath = basePath;
|
||||
this.restClient = new RestClient(this.basePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base path.
|
||||
/// </summary>
|
||||
/// <value>The base path.</value>
|
||||
public string basePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the RestClient
|
||||
/// </summary>
|
||||
/// <value>The RestClient.</value>
|
||||
public RestClient restClient { get; set; }
|
||||
|
||||
private Dictionary<String, String> defaultHeaderMap = new Dictionary<String, String>();
|
||||
|
||||
public Object CallApi(String Path, RestSharp.Method Method, Dictionary<String, String> QueryParams, String PostBody,
|
||||
Dictionary<String, String> HeaderParams, Dictionary<String, String> FormParams, Dictionary<String, String> FileParams, String[] AuthSettings) {
|
||||
var response = Task.Run(async () => {
|
||||
var resp = await CallApiAsync(Path, Method, QueryParams, PostBody, HeaderParams, FormParams, FileParams, AuthSettings);
|
||||
return resp;
|
||||
});
|
||||
return response.Result;
|
||||
}
|
||||
|
||||
public async Task<Object> CallApiAsync(String Path, RestSharp.Method Method, Dictionary<String, String> QueryParams, String PostBody,
|
||||
Dictionary<String, String> HeaderParams, Dictionary<String, String> FormParams, Dictionary<String, String> FileParams, String[] AuthSettings) {
|
||||
|
||||
var request = new RestRequest(Path, Method);
|
||||
|
||||
UpdateParamsForAuth(QueryParams, HeaderParams, AuthSettings);
|
||||
|
||||
// add default header, if any
|
||||
foreach(KeyValuePair<string, string> defaultHeader in this.defaultHeaderMap)
|
||||
request.AddHeader(defaultHeader.Key, defaultHeader.Value);
|
||||
|
||||
// add header parameter, if any
|
||||
foreach(KeyValuePair<string, string> param in HeaderParams)
|
||||
request.AddHeader(param.Key, param.Value);
|
||||
|
||||
// add query parameter, if any
|
||||
foreach(KeyValuePair<string, string> param in QueryParams)
|
||||
request.AddQueryParameter(param.Key, param.Value);
|
||||
|
||||
// add form parameter, if any
|
||||
foreach(KeyValuePair<string, string> param in FormParams)
|
||||
request.AddParameter(param.Key, param.Value);
|
||||
|
||||
// add file parameter, if any
|
||||
foreach(KeyValuePair<string, string> param in FileParams)
|
||||
request.AddFile(param.Key, param.Value);
|
||||
|
||||
if (PostBody != null) {
|
||||
request.AddParameter("application/json", PostBody, ParameterType.RequestBody); // http body (model) parameter
|
||||
}
|
||||
|
||||
return (Object) await restClient.ExecuteTaskAsync(request);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add default header
|
||||
/// </summary>
|
||||
/// <param name="key"> Header field name
|
||||
/// <param name="value"> Header field value
|
||||
/// <returns></returns>
|
||||
public void AddDefaultHeader(string key, string value) {
|
||||
defaultHeaderMap.Add(key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get default header
|
||||
/// </summary>
|
||||
/// <returns>Dictionary of default header</returns>
|
||||
public Dictionary<String, String> GetDefaultHeader() {
|
||||
return defaultHeaderMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// escape string (url-encoded)
|
||||
/// </summary>
|
||||
/// <param name="str"> String to be escaped
|
||||
/// <returns>Escaped string</returns>
|
||||
public string EscapeString(string str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
/// <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="json"> JSON string
|
||||
/// <param name="type"> Object type
|
||||
/// <returns>Object representation of the JSON string</returns>
|
||||
public object Deserialize(string content, Type type) {
|
||||
if (type.GetType() == typeof(Object))
|
||||
return (Object)content;
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(content, type);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ApiException(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize an object into JSON string
|
||||
/// </summary>
|
||||
/// <param name="obj"> Object
|
||||
/// <returns>JSON string</returns>
|
||||
public string Serialize(object obj) {
|
||||
try
|
||||
{
|
||||
return obj != null ? JsonConvert.SerializeObject(obj) : null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ApiException(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the API key with prefix
|
||||
/// </summary>
|
||||
/// <param name="obj"> Object
|
||||
/// <returns>API key with prefix</returns>
|
||||
public string GetApiKeyWithPrefix (string apiKey)
|
||||
{
|
||||
var apiKeyValue = "";
|
||||
Configuration.apiKey.TryGetValue (apiKey, out apiKeyValue);
|
||||
var apiKeyPrefix = "";
|
||||
if (Configuration.apiKeyPrefix.TryGetValue (apiKey, out apiKeyPrefix)) {
|
||||
return apiKeyPrefix + " " + apiKeyValue;
|
||||
} else {
|
||||
return apiKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update parameters based on authentication
|
||||
/// </summary>
|
||||
/// <param name="QueryParams">Query parameters</param>
|
||||
/// <param name="HeaderParams">Header parameters</param>
|
||||
/// <param name="AuthSettings">Authentication settings</param>
|
||||
public void UpdateParamsForAuth(Dictionary<String, String> QueryParams, Dictionary<String, String> HeaderParams, string[] AuthSettings) {
|
||||
if (AuthSettings == null || AuthSettings.Length == 0)
|
||||
return;
|
||||
|
||||
foreach (string auth in AuthSettings) {
|
||||
// determine which one to use
|
||||
switch(auth) {
|
||||
{{#authMethods}}
|
||||
case "{{name}}":
|
||||
{{#isApiKey}}{{#isKeyInHeader}}HeaderParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInHeader}}{{#isKeyInQuery}}QueryParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}HeaderParams["Authorization"] = "Basic " + Base64Encode(Configuration.username + ":" + Configuration.password);{{/isBasic}}
|
||||
{{#isOAuth}}//TODO support oauth{{/isOAuth}}
|
||||
break;
|
||||
{{/authMethods}}
|
||||
default:
|
||||
//TODO show warning about security definition not found
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode string in base64 format
|
||||
/// </summary>
|
||||
/// <param name="text">String to be encoded</param>
|
||||
public static string Base64Encode(string text) {
|
||||
var textByte = System.Text.Encoding.UTF8.GetBytes(text);
|
||||
return System.Convert.ToBase64String(textByte);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using {{invokerPackage}};
|
||||
|
||||
namespace {{invokerPackage}} {
|
||||
/// <summary>
|
||||
/// Represents a set of configuration settings
|
||||
/// </summary>
|
||||
public class Configuration{
|
||||
|
||||
/// <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>();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
BIN
modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll
Normal file
BIN
modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll
Normal file
Binary file not shown.
@@ -12,118 +12,155 @@ namespace {{package}} {
|
||||
|
||||
public interface I{{classname}} {
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}
|
||||
/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
|
||||
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}
|
||||
/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
|
||||
{{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}} {{nickname}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{/operation}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
public class {{classname}} : I{{classname}} {
|
||||
string basePath;
|
||||
protected RestClient restClient;
|
||||
|
||||
public {{classname}}(String basePath = "{{basePath}}")
|
||||
{
|
||||
this.basePath = basePath;
|
||||
this.restClient = new RestClient(basePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the endpoint base url for the services being accessed
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="basePath"> Base URL
|
||||
/// <param name="apiClient"> an instance of ApiClient (optional)
|
||||
/// <returns></returns>
|
||||
public void SetBasePath(string basePath) {
|
||||
this.basePath = basePath;
|
||||
public {{classname}}(ApiClient apiClient = null) {
|
||||
if (apiClient == null) { // use the default one in Configuration
|
||||
this.apiClient = Configuration.apiClient;
|
||||
} else {
|
||||
this.apiClient = apiClient;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the endpoint base url for the services being accessed
|
||||
/// <returns>Base URL</returns>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
public String GetBasePath() {
|
||||
return this.basePath;
|
||||
/// <returns></returns>
|
||||
public {{classname}}(String basePath)
|
||||
{
|
||||
this.apiClient = new ApiClient(basePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the base path of the API client.
|
||||
/// </summary>
|
||||
/// <value>The base path</value>
|
||||
public void SetBasePath(String basePath) {
|
||||
this.apiClient.basePath = basePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base path of the API client.
|
||||
/// </summary>
|
||||
/// <value>The base path</value>
|
||||
public String GetBasePath(String basePath) {
|
||||
return this.apiClient.basePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the API client.
|
||||
/// </summary>
|
||||
/// <value>The API client</value>
|
||||
public ApiClient apiClient {get; set;}
|
||||
|
||||
|
||||
{{#operation}}
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
{{#allParams}} /// <param name="{{paramName}}">{{description}}</param>
|
||||
{{/allParams}}
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}
|
||||
/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
|
||||
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
|
||||
|
||||
var _request = new RestRequest("{{path}}", Method.{{httpMethod}});
|
||||
|
||||
{{#allParams}}{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
|
||||
{{/required}}{{/allParams}}
|
||||
|
||||
// add default header, if any
|
||||
foreach(KeyValuePair<string, string> defaultHeader in ApiInvoker.GetDefaultHeader())
|
||||
{
|
||||
_request.AddHeader(defaultHeader.Key, defaultHeader.Value);
|
||||
}
|
||||
|
||||
_request.AddUrlSegment("format", "json"); // set format to json by default
|
||||
{{#pathParams}}_request.AddUrlSegment("{{baseName}}", ApiInvoker.ParameterToString({{{paramName}}})); // path (url segment) parameter
|
||||
var path = "{{path}}";
|
||||
path = path.Replace("{format}", "json");
|
||||
{{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", apiClient.ParameterToString({{{paramName}}}));
|
||||
{{/pathParams}}
|
||||
{{#queryParams}} if ({{paramName}} != null) _request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // query parameter
|
||||
|
||||
var queryParams = new Dictionary<String, String>();
|
||||
var headerParams = new Dictionary<String, String>();
|
||||
var formParams = new Dictionary<String, String>();
|
||||
var fileParams = new Dictionary<String, String>();
|
||||
String postBody = null;
|
||||
|
||||
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // query parameter
|
||||
{{/queryParams}}
|
||||
{{#headerParams}} if ({{paramName}} != null) _request.AddHeader("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // header parameter
|
||||
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // header parameter
|
||||
{{/headerParams}}
|
||||
{{#formParams}}if ({{paramName}} != null) {{#isFile}}_request.AddFile("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}_request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // form parameter{{/isFile}}
|
||||
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}_request.AddParameter("application/json", ApiInvoker.Serialize({{paramName}}), ParameterType.RequestBody); // http body (model) parameter
|
||||
{{#bodyParam}}postBody = apiClient.Serialize({{paramName}}); // http body (model) parameter
|
||||
{{/bodyParam}}
|
||||
|
||||
// authentication setting, if any
|
||||
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
|
||||
// make the HTTP request
|
||||
IRestResponse response = restClient.Execute(_request);
|
||||
IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
|
||||
|
||||
if (((int)response.StatusCode) >= 400) {
|
||||
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
|
||||
}
|
||||
{{#returnType}}return ({{{returnType}}}) ApiInvoker.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}}
|
||||
{{#returnType}}return ({{{returnType}}}) apiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}}
|
||||
return;{{/returnType}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
{{#allParams}} /// <param name="{{paramName}}">{{description}}</param>
|
||||
{{/allParams}}
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}
|
||||
/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
|
||||
public async {{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}} {{nickname}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
|
||||
|
||||
var _request = new RestRequest("{{path}}", Method.{{httpMethod}});
|
||||
|
||||
{{#allParams}}{{#required}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
|
||||
{{/required}}{{/allParams}}
|
||||
|
||||
// add default header, if any
|
||||
foreach(KeyValuePair<string, string> defaultHeader in ApiInvoker.GetDefaultHeader())
|
||||
{
|
||||
_request.AddHeader(defaultHeader.Key, defaultHeader.Value);
|
||||
}
|
||||
|
||||
_request.AddUrlSegment("format", "json"); // set format to json by default
|
||||
{{#pathParams}}_request.AddUrlSegment("{{baseName}}", ApiInvoker.ParameterToString({{{paramName}}})); // path (url segment) parameter
|
||||
var path = "{{path}}";
|
||||
path = path.Replace("{format}", "json");
|
||||
{{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", apiClient.ParameterToString({{{paramName}}}));
|
||||
{{/pathParams}}
|
||||
{{#queryParams}} if ({{paramName}} != null) _request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // query parameter
|
||||
|
||||
var queryParams = new Dictionary<String, String>();
|
||||
var headerParams = new Dictionary<String, String>();
|
||||
var formParams = new Dictionary<String, String>();
|
||||
var fileParams = new Dictionary<String, String>();
|
||||
String postBody = null;
|
||||
|
||||
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // query parameter
|
||||
{{/queryParams}}
|
||||
{{#headerParams}} if ({{paramName}} != null) _request.AddHeader("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // header parameter
|
||||
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // header parameter
|
||||
{{/headerParams}}
|
||||
{{#formParams}}if ({{paramName}} != null) {{#isFile}}_request.AddFile("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}_request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // form parameter{{/isFile}}
|
||||
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}_request.AddParameter("application/json", ApiInvoker.Serialize({{paramName}}), ParameterType.RequestBody); // http body (model) parameter
|
||||
{{#bodyParam}}postBody = apiClient.Serialize({{paramName}}); // http body (model) parameter
|
||||
{{/bodyParam}}
|
||||
|
||||
// authentication setting, if any
|
||||
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
|
||||
// make the HTTP request
|
||||
IRestResponse response = await restClient.ExecuteTaskAsync(_request);
|
||||
IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
|
||||
if (((int)response.StatusCode) >= 400) {
|
||||
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace {{invokerPackage}} {
|
||||
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
|
||||
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="errorCode">HTTP status code.</param>
|
||||
/// <param name="message">Error message.</param>
|
||||
public ApiException(int errorCode, string message) : base(message) {
|
||||
this.ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace {{invokerPackage}} {
|
||||
public class ApiInvoker {
|
||||
private static Dictionary<String, String> defaultHeaderMap = new Dictionary<String, String>();
|
||||
|
||||
/// <summary>
|
||||
/// Add default header
|
||||
/// </summary>
|
||||
/// <param name="key"> Header field name
|
||||
/// <param name="value"> Header field value
|
||||
/// <returns></returns>
|
||||
public static void AddDefaultHeader(string key, string value) {
|
||||
defaultHeaderMap.Add(key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get default header
|
||||
/// </summary>
|
||||
/// <returns>Dictionary of default header</returns>
|
||||
public static Dictionary<String, String> GetDefaultHeader() {
|
||||
return defaultHeaderMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// escape string (url-encoded)
|
||||
/// </summary>
|
||||
/// <param name="str"> String to be escaped
|
||||
/// <returns>Escaped string</returns>
|
||||
public static string EscapeString(string str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// if parameter is DateTime, output in ISO8601 format, otherwise just return the string
|
||||
/// </summary>
|
||||
/// <param name="obj"> The parameter (header, path, query, form)
|
||||
/// <returns>Formatted string</returns>
|
||||
public static string ParameterToString(object obj)
|
||||
{
|
||||
return (obj is DateTime) ? ((DateTime)obj).ToString ("u") : Convert.ToString (obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize the JSON string into a proper object
|
||||
/// </summary>
|
||||
/// <param name="json"> JSON string
|
||||
/// <param name="type"> Object type
|
||||
/// <returns>Object representation of the JSON string</returns>
|
||||
public static object Deserialize(string content, Type type) {
|
||||
if (type.GetType() == typeof(Object))
|
||||
return (Object)content;
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(content, type);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ApiException(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize an object into JSON string
|
||||
/// </summary>
|
||||
/// <param name="obj"> Object
|
||||
/// <returns>JSON string</returns>
|
||||
public static string Serialize(object obj) {
|
||||
try
|
||||
{
|
||||
return obj != null ? JsonConvert.SerializeObject(obj) : null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ApiException(500, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319
|
||||
%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/{{invokerPackage}}.dll /recurse:src\*.cs /doc:bin/{{invokerPackage}}.xml
|
||||
%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll;bin/RestSharp.dll /target:library /out:bin/{{invokerPackage}}.dll /recurse:src\*.cs /doc:bin/{{invokerPackage}}.xml
|
||||
|
||||
|
||||
@@ -3,10 +3,15 @@ using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
namespace {{package}} {
|
||||
|
||||
/// <summary>
|
||||
/// {{description}}
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class {{classname}} {
|
||||
{{#vars}}
|
||||
@@ -15,6 +20,11 @@ namespace {{package}} {
|
||||
public {{{datatype}}} {{name}} { get; set; }
|
||||
|
||||
{{/vars}}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>String presentation of the object</returns>
|
||||
public override string ToString() {
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("class {{classname}} {\n");
|
||||
@@ -24,7 +34,16 @@ namespace {{package}} {
|
||||
sb.Append("}\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the JSON string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>JSON string presentation of the object</returns>
|
||||
public string ToJson() {
|
||||
return JsonConvert.SerializeObject(this, Formatting.Indented);
|
||||
}
|
||||
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/**
|
||||
* A key for `NSError` user info dictionaries.
|
||||
*
|
||||
*
|
||||
* The corresponding value is the parsed response body for an HTTP error.
|
||||
*/
|
||||
extern NSString *const SWGResponseObjectErrorKey;
|
||||
@@ -20,56 +20,197 @@ extern NSString *const SWGResponseObjectErrorKey;
|
||||
@property(nonatomic, assign) BOOL logHTTP;
|
||||
@property(nonatomic, readonly) NSOperationQueue* queue;
|
||||
|
||||
/**
|
||||
* Get the Api Client instance from pool
|
||||
*
|
||||
* @param baseUrl The base url of api client.
|
||||
*
|
||||
* @return The SWGApiClient instance.
|
||||
*/
|
||||
+(SWGApiClient *)sharedClientFromPool:(NSString *)baseUrl;
|
||||
|
||||
/**
|
||||
* Get the operations queue
|
||||
*
|
||||
* @return The `shardQueue` static variable.
|
||||
*/
|
||||
+(NSOperationQueue*) sharedQueue;
|
||||
|
||||
/**
|
||||
* Turn on logging
|
||||
*
|
||||
* @param state logging state, must be `YES` or `NO`
|
||||
*/
|
||||
+(void)setLoggingEnabled:(bool) state;
|
||||
|
||||
/**
|
||||
* Clear Cache
|
||||
*/
|
||||
+(void)clearCache;
|
||||
|
||||
/**
|
||||
* Turn on cache
|
||||
*
|
||||
* @param enabled If the cached is enable, must be `YES` or `NO`
|
||||
*/
|
||||
+(void)setCacheEnabled:(BOOL) enabled;
|
||||
|
||||
/**
|
||||
* Get the request queue size
|
||||
*
|
||||
* @return The size of `queuedRequests` static variable.
|
||||
*/
|
||||
+(unsigned long)requestQueueSize;
|
||||
|
||||
/**
|
||||
* Set the client unreachable
|
||||
*
|
||||
* @param state off line state, must be `YES` or `NO`
|
||||
*/
|
||||
+(void) setOfflineState:(BOOL) state;
|
||||
|
||||
/**
|
||||
* Get the client reachability
|
||||
*
|
||||
* @return The client reachability.
|
||||
*/
|
||||
+(AFNetworkReachabilityStatus) getReachabilityStatus;
|
||||
|
||||
/**
|
||||
* Get the next request id
|
||||
*
|
||||
* @return The next executed request id.
|
||||
*/
|
||||
+(NSNumber*) nextRequestId;
|
||||
|
||||
/**
|
||||
* Generate request id and add it to the queue
|
||||
*
|
||||
* @return The next executed request id.
|
||||
*/
|
||||
+(NSNumber*) queueRequest;
|
||||
|
||||
/**
|
||||
* Remove request id from the queue
|
||||
*
|
||||
* @param requestId The request which will be removed.
|
||||
*/
|
||||
+(void) cancelRequest:(NSNumber*)requestId;
|
||||
|
||||
/**
|
||||
* URL encode NSString
|
||||
*
|
||||
* @param unescaped The string which will be escaped.
|
||||
*
|
||||
* @return The escaped string.
|
||||
*/
|
||||
+(NSString*) escape:(id)unescaped;
|
||||
|
||||
/**
|
||||
* Customize the behavior when the reachability changed
|
||||
*
|
||||
* @param changeBlock The block will be executed when the reachability changed.
|
||||
*/
|
||||
+(void) setReachabilityChangeBlock:(void(^)(int))changeBlock;
|
||||
|
||||
/**
|
||||
* Set the client reachability strategy
|
||||
*
|
||||
* @param host The host of SWGApiClient.
|
||||
*/
|
||||
+(void) configureCacheReachibilityForHost:(NSString*)host;
|
||||
|
||||
/**
|
||||
* Detect Accept header from accepts NSArray
|
||||
*
|
||||
* @param accepts NSArray of header
|
||||
*
|
||||
* @return The Accept header
|
||||
*/
|
||||
+(NSString *) selectHeaderAccept:(NSArray *)accepts;
|
||||
|
||||
/**
|
||||
* Detect Content-Type header from contentTypes NSArray
|
||||
*
|
||||
* @param contentTypes NSArray of header
|
||||
*
|
||||
* @return The Content-Type header
|
||||
*/
|
||||
+(NSString *) selectHeaderContentType:(NSArray *)contentTypes;
|
||||
|
||||
/**
|
||||
* Set header for request
|
||||
*
|
||||
* @param value The header value
|
||||
* @param forKey The header key
|
||||
*/
|
||||
-(void)setHeaderValue:(NSString*) value
|
||||
forKey:(NSString*) forKey;
|
||||
forKey:(NSString*) forKey;
|
||||
|
||||
/**
|
||||
* Update header parameters and query parameters for authentication
|
||||
*
|
||||
* @param headers The header parameter will be udpated, passed by pointer to pointer.
|
||||
* @param querys The query parameters will be updated, passed by pointer to pointer.
|
||||
* @param authSettings The authentication names NSArray.
|
||||
*/
|
||||
- (void) updateHeaderParams:(NSDictionary **)headers
|
||||
queryParams:(NSDictionary **)querys
|
||||
WithAuthSettings:(NSArray *)authSettings;
|
||||
|
||||
/**
|
||||
* Perform request
|
||||
*
|
||||
* Request with non-empty response
|
||||
*
|
||||
* @param path Request url.
|
||||
* @param method Request method.
|
||||
* @param queryParams Request query parameters.
|
||||
* @param body Request body.
|
||||
* @param headerParams Request header parameters.
|
||||
* @param authSettings Request authentication names.
|
||||
* @param requestContentType Request content-type.
|
||||
* @param responseContentType Response content-type.
|
||||
* @param completionBlock The block will be executed when the request completed.
|
||||
*
|
||||
* @return The request id.
|
||||
*/
|
||||
-(NSNumber*) dictionary:(NSString*) path
|
||||
method:(NSString*) method
|
||||
queryParams:(NSDictionary*) queryParams
|
||||
body:(id) body
|
||||
headerParams:(NSDictionary*) headerParams
|
||||
authSettings: (NSArray *) authSettings
|
||||
requestContentType:(NSString*) requestContentType
|
||||
responseContentType:(NSString*) responseContentType
|
||||
completionBlock:(void (^)(NSDictionary*, NSError *))completionBlock;
|
||||
|
||||
/**
|
||||
* Perform request
|
||||
*
|
||||
* Request with empty response
|
||||
*
|
||||
* @param path Request url.
|
||||
* @param method Request method.
|
||||
* @param queryParams Request query parameters.
|
||||
* @param body Request body.
|
||||
* @param headerParams Request header parameters.
|
||||
* @param authSettings Request authentication names.
|
||||
* @param requestContentType Request content-type.
|
||||
* @param responseContentType Response content-type.
|
||||
* @param completionBlock The block will be executed when the request completed.
|
||||
*
|
||||
* @return The request id.
|
||||
*/
|
||||
-(NSNumber*) stringWithCompletionBlock:(NSString*) path
|
||||
method:(NSString*) method
|
||||
queryParams:(NSDictionary*) queryParams
|
||||
body:(id) body
|
||||
headerParams:(NSDictionary*) headerParams
|
||||
authSettings: (NSArray *) authSettings
|
||||
requestContentType:(NSString*) requestContentType
|
||||
responseContentType:(NSString*) responseContentType
|
||||
completionBlock:(void (^)(NSString*, NSError *))completionBlock;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#import "SWGApiClient.h"
|
||||
#import "SWGFile.h"
|
||||
#import "SWGQueryParamCollection.h"
|
||||
#import "SWGConfiguration.h"
|
||||
|
||||
@implementation SWGApiClient
|
||||
|
||||
@@ -15,10 +16,22 @@ static NSOperationQueue* sharedQueue;
|
||||
static void (^reachabilityChangeBlock)(int);
|
||||
static bool loggingEnabled = true;
|
||||
|
||||
#pragma mark - Log Methods
|
||||
|
||||
+(void)setLoggingEnabled:(bool) state {
|
||||
loggingEnabled = state;
|
||||
}
|
||||
|
||||
- (void)logRequest:(NSURLRequest*)request {
|
||||
NSLog(@"request: %@", [self descriptionForRequest:request]);
|
||||
}
|
||||
|
||||
- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error {
|
||||
NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data );
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+(void)clearCache {
|
||||
[[NSURLCache sharedURLCache] removeAllCachedResponses];
|
||||
}
|
||||
@@ -134,10 +147,12 @@ static bool loggingEnabled = true;
|
||||
}
|
||||
|
||||
+(NSNumber*) nextRequestId {
|
||||
long nextId = ++requestId;
|
||||
if(loggingEnabled)
|
||||
NSLog(@"got id %ld", nextId);
|
||||
return [NSNumber numberWithLong:nextId];
|
||||
@synchronized(self) {
|
||||
long nextId = ++requestId;
|
||||
if(loggingEnabled)
|
||||
NSLog(@"got id %ld", nextId);
|
||||
return [NSNumber numberWithLong:nextId];
|
||||
}
|
||||
}
|
||||
|
||||
+(NSNumber*) queueRequest {
|
||||
@@ -303,19 +318,47 @@ static bool loggingEnabled = true;
|
||||
return [[request URL] absoluteString];
|
||||
}
|
||||
|
||||
- (void)logRequest:(NSURLRequest*)request {
|
||||
NSLog(@"request: %@", [self descriptionForRequest:request]);
|
||||
|
||||
/**
|
||||
* Update header and query params based on authentication settings
|
||||
*/
|
||||
- (void) updateHeaderParams:(NSDictionary *__autoreleasing *)headers
|
||||
queryParams:(NSDictionary *__autoreleasing *)querys
|
||||
WithAuthSettings:(NSArray *)authSettings {
|
||||
|
||||
if (!authSettings || [authSettings count] == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers];
|
||||
NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys];
|
||||
|
||||
SWGConfiguration *config = [SWGConfiguration sharedConfig];
|
||||
for (NSString *auth in authSettings) {
|
||||
NSDictionary *authSetting = [[config authSettings] objectForKey:auth];
|
||||
|
||||
if (authSetting) {
|
||||
if ([authSetting[@"in"] isEqualToString:@"header"]) {
|
||||
[headersWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]];
|
||||
}
|
||||
else if ([authSetting[@"in"] isEqualToString:@"query"]) {
|
||||
[querysWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*headers = [NSDictionary dictionaryWithDictionary:headersWithAuth];
|
||||
*querys = [NSDictionary dictionaryWithDictionary:querysWithAuth];
|
||||
}
|
||||
|
||||
- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error {
|
||||
NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data );
|
||||
}
|
||||
#pragma mark - Perform Request Methods
|
||||
|
||||
-(NSNumber*) dictionary: (NSString*) path
|
||||
method: (NSString*) method
|
||||
queryParams: (NSDictionary*) queryParams
|
||||
body: (id) body
|
||||
headerParams: (NSDictionary*) headerParams
|
||||
authSettings: (NSArray *) authSettings
|
||||
requestContentType: (NSString*) requestContentType
|
||||
responseContentType: (NSString*) responseContentType
|
||||
completionBlock: (void (^)(NSDictionary*, NSError *))completionBlock {
|
||||
@@ -340,6 +383,9 @@ static bool loggingEnabled = true;
|
||||
else {
|
||||
self.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
}
|
||||
|
||||
// auth setting
|
||||
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
|
||||
|
||||
NSMutableURLRequest * request = nil;
|
||||
if (body != nil && [body isKindOfClass:[NSArray class]]){
|
||||
@@ -474,6 +520,7 @@ static bool loggingEnabled = true;
|
||||
queryParams: (NSDictionary*) queryParams
|
||||
body: (id) body
|
||||
headerParams: (NSDictionary*) headerParams
|
||||
authSettings: (NSArray *) authSettings
|
||||
requestContentType: (NSString*) requestContentType
|
||||
responseContentType: (NSString*) responseContentType
|
||||
completionBlock: (void (^)(NSString*, NSError *))completionBlock {
|
||||
@@ -498,6 +545,9 @@ static bool loggingEnabled = true;
|
||||
else {
|
||||
self.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
}
|
||||
|
||||
// auth setting
|
||||
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
|
||||
|
||||
NSMutableURLRequest * request = nil;
|
||||
if (body != nil && [body isKindOfClass:[NSArray class]]){
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#import "SWGConfiguration.h"
|
||||
|
||||
@interface SWGConfiguration ()
|
||||
|
||||
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKey;
|
||||
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKeyPrefix;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SWGConfiguration
|
||||
|
||||
#pragma mark - Singletion Methods
|
||||
|
||||
+ (instancetype) sharedConfig {
|
||||
static SWGConfiguration *shardConfig = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
shardConfig = [[self alloc] init];
|
||||
});
|
||||
return shardConfig;
|
||||
}
|
||||
|
||||
#pragma mark - Initialize Methods
|
||||
|
||||
- (instancetype) init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.username = @"";
|
||||
self.password = @"";
|
||||
self.mutableApiKey = [NSMutableDictionary dictionary];
|
||||
self.mutableApiKeyPrefix = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Instance Methods
|
||||
|
||||
- (NSString *) getApiKeyWithPrefix:(NSString *)key {
|
||||
if ([self.apiKeyPrefix objectForKey:key] && [self.apiKey objectForKey:key]) {
|
||||
return [NSString stringWithFormat:@"%@ %@", [self.apiKeyPrefix objectForKey:key], [self.apiKey objectForKey:key]];
|
||||
}
|
||||
else if ([self.apiKey objectForKey:key]) {
|
||||
return [NSString stringWithFormat:@"%@", [self.apiKey objectForKey:key]];
|
||||
}
|
||||
else {
|
||||
return @"";
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) getBasicAuthToken {
|
||||
NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", self.username, self.password];
|
||||
NSData *data = [basicAuthCredentials dataUsingEncoding:NSUTF8StringEncoding];
|
||||
basicAuthCredentials = [NSString stringWithFormat:@"Basic %@", [data base64EncodedStringWithOptions:0]];
|
||||
|
||||
return basicAuthCredentials;
|
||||
}
|
||||
|
||||
#pragma mark - Setter Methods
|
||||
|
||||
- (void) setValue:(NSString *)value forApiKeyField:(NSString *)field {
|
||||
[self.mutableApiKey setValue:value forKey:field];
|
||||
}
|
||||
|
||||
- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field {
|
||||
[self.mutableApiKeyPrefix setValue:value forKey:field];
|
||||
}
|
||||
|
||||
#pragma mark - Getter Methods
|
||||
|
||||
- (NSDictionary *) apiKey {
|
||||
return [NSDictionary dictionaryWithDictionary:self.mutableApiKey];
|
||||
}
|
||||
|
||||
- (NSDictionary *) apiKeyPrefix {
|
||||
return [NSDictionary dictionaryWithDictionary:self.mutableApiKeyPrefix];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSDictionary *) authSettings {
|
||||
return @{ {{#authMethods}}{{#isApiKey}}
|
||||
@"{{name}}": @{
|
||||
@"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]
|
||||
},
|
||||
{{/isBasic}}{{/authMethods}}
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,56 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SWGConfiguration : NSObject
|
||||
|
||||
|
||||
/**
|
||||
* Api key values for Api Key type Authentication
|
||||
*
|
||||
* To add or remove api key, use `setValue:forApiKeyField:`.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSDictionary *apiKey;
|
||||
|
||||
/**
|
||||
* Api key prefix values to be prepend to the respective api key
|
||||
*
|
||||
* To add or remove prefix, use `setValue:forApiKeyPrefixField:`.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSDictionary *apiKeyPrefix;
|
||||
|
||||
/**
|
||||
* Usename and Password for Basic type Authentication
|
||||
*/
|
||||
@property (nonatomic) NSString *username;
|
||||
@property (nonatomic) NSString *password;
|
||||
|
||||
/**
|
||||
* Get configuration singleton instance
|
||||
*/
|
||||
+ (instancetype) sharedConfig;
|
||||
|
||||
/**
|
||||
* Sets field in `apiKey`
|
||||
*/
|
||||
- (void) setValue:(NSString *)value forApiKeyField:(NSString*)field;
|
||||
|
||||
/**
|
||||
* Sets field in `apiKeyPrefix`
|
||||
*/
|
||||
- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field;
|
||||
|
||||
/**
|
||||
* Get API key (with prefix if set)
|
||||
*/
|
||||
- (NSString *) getApiKeyWithPrefix:(NSString *) key;
|
||||
|
||||
/**
|
||||
* Get Basic Auth token
|
||||
*/
|
||||
- (NSString *) getBasicAuthToken;
|
||||
|
||||
/**
|
||||
* Get Authentication Setings
|
||||
*/
|
||||
- (NSDictionary *) authSettings;
|
||||
|
||||
@end
|
||||
@@ -13,4 +13,4 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#import "{{classname}}.h"
|
||||
#import "SWGFile.h"
|
||||
#import "SWGQueryParamCollection.h"
|
||||
#import "SWGApiClient.h"
|
||||
{{#imports}}#import "{{import}}.h"
|
||||
{{/imports}}
|
||||
{{newline}}
|
||||
@@ -12,8 +11,36 @@
|
||||
@end
|
||||
|
||||
@implementation {{classname}}
|
||||
|
||||
static NSString * basePath = @"{{basePath}}";
|
||||
|
||||
#pragma mark - Initialize methods
|
||||
|
||||
- (id) init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.apiClient = [SWGApiClient sharedClientFromPool:basePath];
|
||||
self.defaultHeaders = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithApiClient:(SWGApiClient *)apiClient {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (apiClient) {
|
||||
self.apiClient = apiClient;
|
||||
}
|
||||
else {
|
||||
self.apiClient = [SWGApiClient sharedClientFromPool:basePath];
|
||||
}
|
||||
self.defaultHeaders = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key {
|
||||
static {{classname}}* singletonAPI = nil;
|
||||
|
||||
@@ -32,21 +59,10 @@ static NSString * basePath = @"{{basePath}}";
|
||||
return basePath;
|
||||
}
|
||||
|
||||
-(SWGApiClient*) apiClient {
|
||||
return [SWGApiClient sharedClientFromPool:basePath];
|
||||
}
|
||||
|
||||
-(void) addHeader:(NSString*)value forKey:(NSString*)key {
|
||||
[self.defaultHeaders setValue:value forKey:key];
|
||||
}
|
||||
|
||||
-(id) init {
|
||||
self = [super init];
|
||||
self.defaultHeaders = [NSMutableDictionary dictionary];
|
||||
[self apiClient];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) setHeaderValue:(NSString*) value
|
||||
forKey:(NSString*)key {
|
||||
[self.defaultHeaders setValue:value forKey:key];
|
||||
@@ -115,6 +131,9 @@ static NSString * basePath = @"{{basePath}}";
|
||||
// request content type
|
||||
NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[{{#consumes}}@"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}]];
|
||||
|
||||
// Authentication setting
|
||||
NSArray *authSettings = @[{{#authMethods}}@"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}}];
|
||||
|
||||
id bodyDictionary = nil;
|
||||
{{#bodyParam}}
|
||||
id __body = {{paramName}};
|
||||
@@ -177,8 +196,6 @@ static NSString * basePath = @"{{basePath}}";
|
||||
{{/requiredParams}}
|
||||
{{/requiredParamCount}}
|
||||
|
||||
SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath];
|
||||
|
||||
{{#returnContainer}}
|
||||
// response is in a container
|
||||
{{>apiBodyResponseWithContainer}}{{/returnContainer}}
|
||||
@@ -206,3 +223,6 @@ static NSString * basePath = @"{{basePath}}";
|
||||
{{newline}}
|
||||
{{/operations}}
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
{{#imports}}#import "{{import}}.h"
|
||||
{{/imports}}
|
||||
#import "SWGObject.h"
|
||||
#import "SWGApiClient.h"
|
||||
{{newline}}
|
||||
|
||||
{{#operations}}
|
||||
@interface {{classname}}: NSObject
|
||||
|
||||
@property(nonatomic, assign)SWGApiClient *apiClient;
|
||||
|
||||
-(instancetype) initWithApiClient:(SWGApiClient *)apiClient;
|
||||
-(void) addHeader:(NSString*)value forKey:(NSString*)key;
|
||||
-(unsigned long) requestQueueSize;
|
||||
+({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key;
|
||||
@@ -34,4 +38,4 @@
|
||||
{{/operation}}
|
||||
|
||||
{{/operations}}
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// {{returnContainer}} container response type
|
||||
return [client dictionary: requestUrl
|
||||
return [self.apiClient dictionary: requestUrl
|
||||
method: @"{{httpMethod}}"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
authSettings: authSettings
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSDictionary *data, NSError *error) {
|
||||
@@ -34,4 +35,4 @@
|
||||
{{/returnBaseType}}
|
||||
{{/isListContainer}}
|
||||
}];
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{{^returnTypeIsPrimitive}}
|
||||
// comples response type
|
||||
return [client dictionary: requestUrl
|
||||
return [self.apiClient dictionary: requestUrl
|
||||
method: @"{{httpMethod}}"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
authSettings: authSettings
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSDictionary *data, NSError *error) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// primitive response type
|
||||
{{#returnBaseType}}return [client stringWithCompletionBlock: requestUrl
|
||||
{{#returnBaseType}}return [self.apiClient stringWithCompletionBlock: requestUrl
|
||||
method: @"{{httpMethod}}"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
authSettings: authSettings
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
@@ -17,7 +18,7 @@
|
||||
{{/returnBaseType}}
|
||||
{{^returnBaseType}}
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
return [self.apiClient stringWithCompletionBlock: requestUrl
|
||||
method: @"{{httpMethod}}"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
@@ -32,4 +33,4 @@
|
||||
completionBlock(nil);
|
||||
}];
|
||||
{{/returnBaseType}}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
return [self.apiClient stringWithCompletionBlock: requestUrl
|
||||
method: @"{{httpMethod}}"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
authSettings: authSettings
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package WWW::{{invokerPackage}}::Configuration;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Log::Any qw($log);
|
||||
use Carp;
|
||||
|
||||
# class/static variables
|
||||
our $api_client;
|
||||
our $http_timeout = 180;
|
||||
our $http_user_agent = 'Perl-Swagger';
|
||||
|
||||
# authenticaiton setting
|
||||
our $api_key = {};
|
||||
our $api_key_prefix = {};
|
||||
our $username;
|
||||
our $password;
|
||||
|
||||
|
||||
1;
|
||||
@@ -27,14 +27,10 @@ use Exporter;
|
||||
use Carp qw( croak );
|
||||
use Log::Any qw($log);
|
||||
|
||||
|
||||
#use WWW::Swagger::Model::Category;
|
||||
#use WWW::Swagger::Model::Pet;
|
||||
use WWW::{{invokerPackage}}::ApiClient;
|
||||
use WWW::{{invokerPackage}}::Configuration;
|
||||
|
||||
{{#operations}}
|
||||
|
||||
use WWW::{{invokerPackage}}::APIClient;
|
||||
|
||||
our @EXPORT_OK = qw(
|
||||
{{#operation}}{{{nickname}}}
|
||||
{{/operation}}
|
||||
@@ -42,7 +38,7 @@ our @EXPORT_OK = qw(
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $default_api_client = WWW::{{invokerPackage}}::APIClient->new;
|
||||
my $default_api_client = $WWW::{{invokerPackage}}::Configuration::api_client ? $WWW::{{invokerPackage}}::Configuration::api_client : WWW::{{invokerPackage}}::ApiClient->new;
|
||||
my (%self) = (
|
||||
'api_client' => $default_api_client,
|
||||
@_
|
||||
@@ -92,49 +88,49 @@ sub new {
|
||||
}
|
||||
$header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type({{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}});
|
||||
|
||||
{{#queryParams}} # query params
|
||||
{{#queryParams}}# query params
|
||||
if ( exists $args{'{{paramName}}'}) {
|
||||
$query_params->{'{{baseName}}'} = WWW::{{invokerPacakge}}::APIClient::to_query_value($args{'{{paramName}}'});
|
||||
$query_params->{'{{baseName}}'} = $self->{api_client}->to_query_value($args{'{{paramName}}'});
|
||||
}{{/queryParams}}
|
||||
{{#headerParams}} # header params
|
||||
{{#headerParams}}# header params
|
||||
if ( exists $args{'{{paramName}}'}) {
|
||||
$header_params->{'{{baseName}}'} = WWW::{{invokerPackage}}::APIClient::to_header_value($args{'{{paramName}}'});
|
||||
$header_params->{'{{baseName}}'} = $self->{api_client}->to_header_value($args{'{{paramName}}'});
|
||||
}{{/headerParams}}
|
||||
{{#pathParams}} # path params
|
||||
{{#pathParams}}# path params
|
||||
if ( exists $args{'{{paramName}}'}) {
|
||||
my $_base_variable = "{" . "{{baseName}}" . "}";
|
||||
my $_base_value = WWW::{{invokerPackage}}::APIClient::to_path_value($args{'{{paramName}}'});
|
||||
my $_base_value = $self->{api_client}->to_path_value($args{'{{paramName}}'});
|
||||
$_resource_path =~ s/$_base_variable/$_base_value/g;
|
||||
}{{/pathParams}}
|
||||
{{#formParams}} # form params
|
||||
{{#formParams}}# form params
|
||||
if ( exists $args{'{{paramName}}'} ) {
|
||||
{{#isFile}}$form_params->{'{{baseName}}'} = [] unless defined $form_params->{'{{baseName}}'};
|
||||
push $form_params->{'{{baseName}}'}, $args{'{{paramName}}'};
|
||||
{{/isFile}}
|
||||
{{^isFile}}$form_params->{'{{baseName}}'} = WWW::{{invokerPackage}}::APIClient::to_form_value($args{'{{paramName}}'});
|
||||
{{^isFile}}$form_params->{'{{baseName}}'} = $self->{api_client}->to_form_value($args{'{{paramName}}'});
|
||||
{{/isFile}}
|
||||
}{{/formParams}}
|
||||
my $_body_data;
|
||||
{{#bodyParams}} # body params
|
||||
{{#bodyParams}}# body params
|
||||
if ( exists $args{'{{paramName}}'}) {
|
||||
$_body_data = $args{'{{paramName}}'};
|
||||
}{{/bodyParams}}
|
||||
|
||||
# for HTTP post (form)
|
||||
#$_body_data = $_body ? undef : $form_params;
|
||||
# authentication setting, if any
|
||||
my $auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}];
|
||||
|
||||
# make the API Call
|
||||
{{#returnType}}my $response = $self->{api_client}->call_api($_resource_path, $_method,
|
||||
$query_params, $form_params,
|
||||
$header_params, $_body_data);
|
||||
$header_params, $_body_data, $auth_settings);
|
||||
if (!$response) {
|
||||
return;
|
||||
}
|
||||
my $_response_object = $self->{api_client}->deserialize('{{returnType}}', $response);
|
||||
return $_response_object;{{/returnType}}
|
||||
my $_response_object = $self->{api_client}->deserialize('{{returnType}}', $response);
|
||||
return $_response_object;{{/returnType}}
|
||||
{{^returnType}}$self->{api_client}->call_api($_resource_path, $_method,
|
||||
$query_params, $form_params,
|
||||
$header_params, $_body_data);
|
||||
$header_params, $_body_data, $auth_settings);
|
||||
return;
|
||||
{{/returnType}}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package WWW::{{invokerPackage}}::APIClient;
|
||||
package WWW::{{invokerPackage}}::ApiClient;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use MIME::Base64;
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Headers;
|
||||
use HTTP::Response;
|
||||
@@ -15,20 +16,18 @@ use URI::Escape;
|
||||
use Scalar::Util;
|
||||
use Log::Any qw($log);
|
||||
use Carp;
|
||||
use Switch;
|
||||
use Module::Runtime qw(use_module);
|
||||
|
||||
# class variables
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $http_user_agent = 'Perl-Swagger'; # HTTP user-agent
|
||||
my $http_timeout; #timeout
|
||||
my $base_url = "{{basePath}}";
|
||||
|
||||
use WWW::{{invokerPackage}}::Configuration;
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class = shift;
|
||||
my %args = @_;
|
||||
my (%args) = (
|
||||
'ua' => LWP::UserAgent->new,
|
||||
'base_url' => '{{basePath}}',
|
||||
@_
|
||||
);
|
||||
|
||||
return bless \%args, $class;
|
||||
}
|
||||
@@ -38,8 +37,8 @@ sub new
|
||||
# @param string $user_agent The user agent of the API client
|
||||
#
|
||||
sub set_user_agent {
|
||||
my $user_agent = shift;
|
||||
$http_user_agent= $user_agent;
|
||||
my ($self, $user_agent) = @_;
|
||||
$self->{http_user_agent}= $user_agent;
|
||||
}
|
||||
|
||||
# Set timeout
|
||||
@@ -47,11 +46,11 @@ sub set_user_agent {
|
||||
# @param integer $seconds Number of seconds before timing out [set to 0 for no timeout]
|
||||
#
|
||||
sub set_timeout {
|
||||
my $seconds = shift;
|
||||
my ($self, $seconds) = @_;
|
||||
if (!looks_like_number($seconds)) {
|
||||
croak('Timeout variable must be numeric.');
|
||||
}
|
||||
$http_timeout = $seconds;
|
||||
$self->{http_timeout} = $seconds;
|
||||
}
|
||||
|
||||
# make the HTTP request
|
||||
@@ -63,60 +62,63 @@ sub set_timeout {
|
||||
# @return mixed
|
||||
sub call_api {
|
||||
my $self = shift;
|
||||
my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data) = @_;
|
||||
my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_;
|
||||
|
||||
my $headers = HTTP::Headers->new(%$header_params);
|
||||
# update parameters based on authentication settings
|
||||
$self->update_params_for_auth($header_params, $query_params, $auth_settings);
|
||||
|
||||
my $_url = $base_url . $resource_path;
|
||||
|
||||
my $_url = $self->{base_url} . $resource_path;
|
||||
|
||||
# build query
|
||||
if (%$query_params) {
|
||||
$_url = ($_url . '?' . eval { URI::Query->new($query_params)->stringify });
|
||||
}
|
||||
|
||||
|
||||
# body data
|
||||
$body_data = to_json($body_data->to_hash) if defined $body_data && $body_data->can('to_hash'); # model to json string
|
||||
my $_body_data = %$post_params ? $post_params : $body_data;
|
||||
|
||||
# Make the HTTP request
|
||||
my $_request;
|
||||
switch ($method) {
|
||||
case 'POST' {
|
||||
if ($method eq 'POST') {
|
||||
# multipart
|
||||
my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ?
|
||||
$header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ?
|
||||
'form-data' : $header_params->{'Content-Type'};
|
||||
|
||||
$_request = POST($_url, Accept => $header_params->{Accept},
|
||||
Content_Type => $_content_type, Content => $_body_data);
|
||||
}
|
||||
case 'PUT' {
|
||||
# multipart
|
||||
my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ?
|
||||
'form-data' : $header_params->{'Content-Type'};
|
||||
$_request = PUT($_url, Accept => $header_params->{Accept},
|
||||
Content_Type => $_content_type, Content => $_body_data);
|
||||
}
|
||||
case 'GET' {
|
||||
$_request = GET($_url, Accept => $header_params->{'Accept'},
|
||||
Content_Type => $header_params->{'Content-Type'});
|
||||
}
|
||||
case 'HEAD' {
|
||||
$_request = HEAD($_url, Accept => $header_params->{'Accept'},
|
||||
Content_Type => $header_params->{'Content-Type'});
|
||||
}
|
||||
case 'DELETE' { #TODO support form data
|
||||
$_request = DELETE($_url, Accept => $header_params->{'Accept'},
|
||||
Content_Type => $header_params->{'Content-Type'}, Content => $_body_data);
|
||||
}
|
||||
case 'PATCH' { #TODO
|
||||
}
|
||||
|
||||
$_request = POST($_url, %$header_params, Content => $_body_data);
|
||||
|
||||
}
|
||||
elsif ($method eq 'PUT') {
|
||||
# multipart
|
||||
$header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ?
|
||||
'form-data' : $header_params->{'Content-Type'};
|
||||
|
||||
$_request = PUT($_url, %$header_params, Content => $_body_data);
|
||||
|
||||
}
|
||||
elsif ($method eq 'GET') {
|
||||
my $headers = HTTP::Headers->new(%$header_params);
|
||||
$_request = GET($_url, %$header_params);
|
||||
}
|
||||
elsif ($method eq 'HEAD') {
|
||||
my $headers = HTTP::Headers->new(%$header_params);
|
||||
$_request = HEAD($_url,%$header_params);
|
||||
}
|
||||
elsif ($method eq 'DELETE') { #TODO support form data
|
||||
my $headers = HTTP::Headers->new(%$header_params);
|
||||
$_request = DELETE($_url, %$headers);
|
||||
}
|
||||
elsif ($method eq 'PATCH') { #TODO
|
||||
}
|
||||
else {
|
||||
}
|
||||
|
||||
$ua->timeout($http_timeout);
|
||||
$ua->agent($http_user_agent);
|
||||
$self->{ua}->timeout($self->{http_timeout} || $WWW::{{invokerPackage}}::Configuration::http_timeout);
|
||||
$self->{ua}->agent($self->{http_user_agent} || $WWW::{{invokerPackage}}::Configuration::http_user_agent);
|
||||
|
||||
my $_response = $ua->request($_request);
|
||||
my $_response = $self->{ua}->request($_request);
|
||||
|
||||
unless ($_response->is_success) {
|
||||
croak("API Exception(".$_response->code."): ".$_response->message);
|
||||
@@ -126,41 +128,13 @@ sub call_api {
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Build a JSON POST object
|
||||
sub sanitize_for_serialization
|
||||
{
|
||||
# my $data = shift;
|
||||
# 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) {
|
||||
# $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property);
|
||||
# }
|
||||
# $sanitized = $values;
|
||||
# } else {
|
||||
# $sanitized = (string)$data;
|
||||
# }
|
||||
#
|
||||
# return $sanitized;
|
||||
}
|
||||
|
||||
|
||||
# Take value and turn it into a string suitable for inclusion in
|
||||
# the path, by url-encoding.
|
||||
# @param string $value a string which will be part of the path
|
||||
# @return string the serialized object
|
||||
sub to_path_value {
|
||||
my $value = shift;
|
||||
return uri_escape(to_string($value));
|
||||
my ($self, $value) = @_;
|
||||
return uri_escape($self->to_string($value));
|
||||
}
|
||||
|
||||
|
||||
@@ -171,11 +145,11 @@ sub to_path_value {
|
||||
# @param object $object an object to be serialized to a string
|
||||
# @return string the serialized object
|
||||
sub to_query_value {
|
||||
my $object = shift;
|
||||
my ($self, $object) = @_;
|
||||
if (is_array($object)) {
|
||||
return implode(',', $object);
|
||||
} else {
|
||||
return toString($object);
|
||||
return $self->to_string($object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,8 +160,8 @@ sub to_query_value {
|
||||
# @param string $value a string which will be part of the header
|
||||
# @return string the header string
|
||||
sub to_header_value {
|
||||
my $value = shift;
|
||||
return to_string($value);
|
||||
my ($self, $value) = @_;
|
||||
return $self->to_string($value);
|
||||
}
|
||||
|
||||
# Take value and turn it into a string suitable for inclusion in
|
||||
@@ -196,8 +170,8 @@ sub to_header_value {
|
||||
# @param string $value the value of the form parameter
|
||||
# @return string the form string
|
||||
sub to_form_value {
|
||||
my $value = shift;
|
||||
return to_string($value);
|
||||
my ($self, $value) = @_;
|
||||
return $self->to_string($value);
|
||||
}
|
||||
|
||||
# Take value and turn it into a string suitable for inclusion in
|
||||
@@ -206,7 +180,7 @@ sub to_form_value {
|
||||
# @param string $value the value of the parameter
|
||||
# @return string the header string
|
||||
sub to_string {
|
||||
my $value = shift;
|
||||
my ($self, $value) = @_;
|
||||
if (ref($value) eq "DateTime") { # datetime in ISO8601 format
|
||||
return $value->datetime();
|
||||
}
|
||||
@@ -242,7 +216,7 @@ sub deserialize
|
||||
$_result = \@_values;
|
||||
} elsif ($class eq 'DateTime') {
|
||||
$_result = DateTime->from_epoch(epoch => str2time($data));
|
||||
} elsif (grep /^$data$/, ('string', 'int', 'float', 'bool')) { #TODO revise the primitive type
|
||||
} elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type
|
||||
$_result= $data;
|
||||
} else { # model
|
||||
my $_instance = use_module("WWW::{{invokerPackage}}::Object::$class")->new;
|
||||
@@ -287,5 +261,44 @@ sub select_header_content_type
|
||||
|
||||
}
|
||||
|
||||
# Get API key (with prefix if set)
|
||||
# @param string key name
|
||||
# @return string API key with the prefix
|
||||
sub get_api_key_with_prefix
|
||||
{
|
||||
my ($self, $api_key) = @_;
|
||||
if ($WWW::{{invokerPackage}}::Configuration::api_key_prefix->{$api_key}) {
|
||||
return $WWW::{{invokerPackage}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{invokerPackage}}::Configuration::api_key->{$api_key};
|
||||
} else {
|
||||
return $WWW::{{invokerPackage}}::Configuration::api_key->{$api_key};
|
||||
}
|
||||
}
|
||||
|
||||
# update hearder and query param based on authentication setting
|
||||
#
|
||||
# @param array $headerParams header parameters (by ref)
|
||||
# @param array $queryParams query parameters (by ref)
|
||||
# @param array $authSettings array of authentication scheme (e.g ['api_key'])
|
||||
sub update_params_for_auth {
|
||||
my ($self, $header_params, $query_params, $auth_settings) = @_;
|
||||
|
||||
return if (!defined($auth_settings) || scalar(@$auth_settings) == 0);
|
||||
|
||||
# one endpoint can have more than 1 auth settings
|
||||
foreach my $auth (@$auth_settings) {
|
||||
# determine which one to use
|
||||
if (!defined($auth)) {
|
||||
}
|
||||
{{#authMethods}}elsif ($auth eq '{{name}}') {
|
||||
{{#isApiKey}}{{#isKeyInHeader}}$header_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$query_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$header_params->{'Authorization'} = 'Basic '.encode_base64($WWW::{{invokerPackage}}::Configuration::username.":".$WWW::{{invokerPackage}}::Configuration::password);{{/isBasic}}
|
||||
{{#isOAuth}}# TODO support oauth{{/isOAuth}}
|
||||
}
|
||||
{{/authMethods}}
|
||||
else {
|
||||
# TODO show warning about security definition not found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace {{invokerPackage}};
|
||||
|
||||
class APIClient {
|
||||
class ApiClient {
|
||||
|
||||
public static $PATCH = "PATCH";
|
||||
public static $POST = "POST";
|
||||
@@ -173,7 +173,7 @@ class APIClient {
|
||||
* @param array $headerParams parameters to be place in request header
|
||||
* @return mixed
|
||||
*/
|
||||
public function callAPI($resourcePath, $method, $queryParams, $postData,
|
||||
public function callApi($resourcePath, $method, $queryParams, $postData,
|
||||
$headerParams, $authSettings) {
|
||||
|
||||
$headers = array();
|
||||
@@ -182,13 +182,10 @@ class APIClient {
|
||||
$this->updateParamsForAuth($headerParams, $queryParams, $authSettings);
|
||||
|
||||
# construct the http header
|
||||
if ($headerParams != null) {
|
||||
# add default header
|
||||
$headerParams = array_merge((array)self::$default_header, $headerParams);
|
||||
$headerParams = array_merge((array)self::$default_header, (array)$headerParams);
|
||||
|
||||
foreach ($headerParams as $key => $val) {
|
||||
$headers[] = "$key: $val";
|
||||
}
|
||||
foreach ($headerParams as $key => $val) {
|
||||
$headers[] = "$key: $val";
|
||||
}
|
||||
|
||||
// form data
|
||||
@@ -228,35 +225,49 @@ class APIClient {
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
} else if ($method != self::$GET) {
|
||||
throw new APIClientException('Method ' . $method . ' is not recognized.');
|
||||
throw new ApiException('Method ' . $method . ' is not recognized.');
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
|
||||
// Set user agent
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
|
||||
|
||||
// debugging for curl
|
||||
if (Configuration::$debug) {
|
||||
error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file);
|
||||
|
||||
curl_setopt($curl, CURLOPT_VERBOSE, 1);
|
||||
curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, '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 (Configuration::$debug) {
|
||||
error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file);
|
||||
}
|
||||
|
||||
// Handle the response
|
||||
if ($response_info['http_code'] == 0) {
|
||||
throw new APIClientException("TIMEOUT: api call to " . $url .
|
||||
" took more than 5s to return", 0, $response_info, $response);
|
||||
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($response);
|
||||
$data = json_decode($http_body);
|
||||
if (json_last_error() > 0) { // if response is a string
|
||||
$data = $response;
|
||||
$data = $http_body;
|
||||
}
|
||||
} else if ($response_info['http_code'] == 401) {
|
||||
throw new APIClientException("Unauthorized API request to " . $url .
|
||||
": " . serialize($response), 0, $response_info, $response);
|
||||
} else if ($response_info['http_code'] == 404) {
|
||||
$data = null;
|
||||
} else {
|
||||
throw new APIClientException("Can't connect to the api: " . $url .
|
||||
" response code: " .
|
||||
$response_info['http_code'], 0, $response_info, $response);
|
||||
throw new ApiException("[".$response_info['http_code']."] Error connecting to the API ($url)",
|
||||
$response_info['http_code'], $http_header, $http_body);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
@@ -278,7 +289,9 @@ class APIClient {
|
||||
} else if (is_object($data)) {
|
||||
$values = array();
|
||||
foreach (array_keys($data::$swaggerTypes) as $property) {
|
||||
$values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property);
|
||||
if ($data->$property !== null) {
|
||||
$values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property);
|
||||
}
|
||||
}
|
||||
$sanitized = $values;
|
||||
} else {
|
||||
@@ -383,7 +396,7 @@ class APIClient {
|
||||
$deserialized = $values;
|
||||
} elseif ($class == 'DateTime') {
|
||||
$deserialized = new \DateTime($data);
|
||||
} elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool'))) {
|
||||
} elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) {
|
||||
settype($data, $class);
|
||||
$deserialized = $data;
|
||||
} else {
|
||||
|
||||
@@ -19,20 +19,40 @@ namespace {{invokerPackage}};
|
||||
|
||||
use \Exception;
|
||||
|
||||
class APIClientException extends Exception {
|
||||
protected $response, $response_info;
|
||||
class ApiException extends Exception {
|
||||
|
||||
public function __construct($message="", $code=0, $response_info=null, $response=null) {
|
||||
/**
|
||||
* The HTTP body of the server response.
|
||||
*/
|
||||
protected $response_body;
|
||||
|
||||
/**
|
||||
* The HTTP header of the server response.
|
||||
*/
|
||||
protected $response_headers;
|
||||
|
||||
public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) {
|
||||
parent::__construct($message, $code);
|
||||
$this->response_info = $response_info;
|
||||
$this->response = $response;
|
||||
$this->response_headers = $responseHeaders;
|
||||
$this->response_body = $responseBody;
|
||||
}
|
||||
|
||||
public function getResponse() {
|
||||
return $this->response;
|
||||
/**
|
||||
* Get the HTTP response header
|
||||
*
|
||||
* @return string HTTP response header
|
||||
*/
|
||||
public function getResponseHeaders() {
|
||||
return $this->response_headers;
|
||||
}
|
||||
|
||||
public function getResponseInfo() {
|
||||
return $this->response_info;
|
||||
/**
|
||||
* Get the HTTP response body
|
||||
*
|
||||
* @return string HTTP response body
|
||||
*/
|
||||
public function getResponseBody() {
|
||||
return $this->response_body;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class {{classname}} {
|
||||
function __construct($apiClient = null) {
|
||||
if (null === $apiClient) {
|
||||
if (Configuration::$apiClient === null) {
|
||||
Configuration::$apiClient = new APIClient(); // create a new API client if not present
|
||||
Configuration::$apiClient = new ApiClient(); // create a new API client if not present
|
||||
$this->apiClient = Configuration::$apiClient;
|
||||
}
|
||||
else
|
||||
@@ -38,7 +38,7 @@ class {{classname}} {
|
||||
}
|
||||
}
|
||||
|
||||
private $apiClient; // instance of the APIClient
|
||||
private $apiClient; // instance of the ApiClient
|
||||
|
||||
/**
|
||||
* get the API client
|
||||
|
||||
@@ -19,27 +19,47 @@ namespace {{invokerPackage}};
|
||||
|
||||
class Configuration {
|
||||
|
||||
public static $PATCH = "PATCH";
|
||||
public static $POST = "POST";
|
||||
public static $GET = "GET";
|
||||
public static $PUT = "PUT";
|
||||
public static $DELETE = "DELETE";
|
||||
|
||||
// authentication setting
|
||||
/**
|
||||
* Associate array to store API key(s)
|
||||
*/
|
||||
public static $apiKey = array();
|
||||
|
||||
/**
|
||||
* Associate array to store API prefix (e.g. Bearer)
|
||||
*/
|
||||
public static $apiKeyPrefix = array();
|
||||
|
||||
/**
|
||||
* Username for HTTP basic authentication
|
||||
*/
|
||||
public static $username = '';
|
||||
|
||||
/**
|
||||
* Password for HTTP basic authentication
|
||||
*/
|
||||
public static $password = '';
|
||||
|
||||
// an instance of APIClient
|
||||
/**
|
||||
* The default instance of ApiClient
|
||||
*/
|
||||
public static $apiClient;
|
||||
|
||||
/*
|
||||
* manually initalize API client
|
||||
*/
|
||||
/**
|
||||
* Debug switch (default set to false)
|
||||
*/
|
||||
public static $debug = false;
|
||||
|
||||
/**
|
||||
* Debug file location (log to STDOUT by default)
|
||||
*/
|
||||
public static $debug_file = 'php://output';
|
||||
|
||||
/*
|
||||
* manually initalize ApiClient
|
||||
*/
|
||||
public static function init() {
|
||||
if (self::$apiClient === null)
|
||||
self::$apiClient = new APIClient();
|
||||
self::$apiClient = new ApiClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,13 +29,16 @@ from six import iteritems
|
||||
|
||||
from ..util import remove_none
|
||||
|
||||
from ..swagger import ApiClient
|
||||
from .. import config
|
||||
|
||||
{{#operations}}
|
||||
class {{classname}}(object):
|
||||
|
||||
def __init__(self, api_client):
|
||||
self.api_client = api_client
|
||||
def __init__(self, api_client=None):
|
||||
if api_client:
|
||||
self.api_client = api_client
|
||||
else:
|
||||
self.api_client = config.api_client
|
||||
{{#operation}}
|
||||
def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs):
|
||||
"""
|
||||
@@ -71,12 +74,12 @@ class {{classname}}(object):
|
||||
body_params = {{#bodyParam}}params.get('{{paramName}}'){{/bodyParam}}{{^bodyParam}}None{{/bodyParam}}
|
||||
|
||||
# HTTP header `Accept`
|
||||
header_params['Accept'] = ApiClient.select_header_accept([{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}])
|
||||
header_params['Accept'] = self.api_client.select_header_accept([{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}])
|
||||
if not header_params['Accept']:
|
||||
del header_params['Accept']
|
||||
|
||||
# HTTP header `Content-Type`
|
||||
header_params['Content-Type'] = ApiClient.select_header_content_type([{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}])
|
||||
header_params['Content-Type'] = self.api_client.select_header_content_type([{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}])
|
||||
|
||||
response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params,
|
||||
body=body_params, post_params=form_params, files=files,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .swagger import ApiClient
|
||||
|
||||
# Configuration variables
|
||||
|
||||
api_client = ApiClient("{{basePath}}")
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
import sys
|
||||
import io
|
||||
import json
|
||||
import ssl
|
||||
import certifi
|
||||
|
||||
# python 2 and python 3 compatibility library
|
||||
from six import iteritems
|
||||
@@ -42,10 +44,30 @@ class RESTResponse(io.IOBase):
|
||||
class RESTClientObject(object):
|
||||
|
||||
def __init__(self, pools_size=4):
|
||||
# http pool manager
|
||||
self.pool_manager = urllib3.PoolManager(
|
||||
num_pools=pools_size
|
||||
)
|
||||
|
||||
# https pool manager
|
||||
# certificates validated using Mozilla’s root certificates
|
||||
self.ssl_pool_manager = urllib3.PoolManager(
|
||||
num_pools=pools_size,
|
||||
cert_reqs=ssl.CERT_REQUIRED,
|
||||
ca_certs=certifi.where()
|
||||
)
|
||||
|
||||
def agent(self, url):
|
||||
"""
|
||||
Return proper pool manager for the http\https schemes.
|
||||
"""
|
||||
url = urllib3.util.url.parse_url(url)
|
||||
scheme = url.scheme
|
||||
if scheme == 'https':
|
||||
return self.ssl_pool_manager
|
||||
else:
|
||||
return self.pool_manager
|
||||
|
||||
def request(self, method, url, query_params=None, headers=None,
|
||||
body=None, post_params=None):
|
||||
"""
|
||||
@@ -56,7 +78,6 @@ class RESTClientObject(object):
|
||||
:param body: request json body, for `application/json`
|
||||
:param post_params: request post parameters, `application/x-www-form-urlencode`
|
||||
and `multipart/form-data`
|
||||
:param raw_response: if return the raw response
|
||||
"""
|
||||
method = method.upper()
|
||||
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH']
|
||||
@@ -75,27 +96,27 @@ class RESTClientObject(object):
|
||||
if query_params:
|
||||
url += '?' + urlencode(query_params)
|
||||
if headers['Content-Type'] == 'application/json':
|
||||
r = self.pool_manager.request(method, url,
|
||||
body=json.dumps(body),
|
||||
headers=headers)
|
||||
r = self.agent(url).request(method, url,
|
||||
body=json.dumps(body),
|
||||
headers=headers)
|
||||
if headers['Content-Type'] == 'application/x-www-form-urlencoded':
|
||||
r = self.pool_manager.request(method, url,
|
||||
fields=post_params,
|
||||
encode_multipart=False,
|
||||
headers=headers)
|
||||
r = self.agent(url).request(method, url,
|
||||
fields=post_params,
|
||||
encode_multipart=False,
|
||||
headers=headers)
|
||||
if headers['Content-Type'] == 'multipart/form-data':
|
||||
# must del headers['Content-Type'], or the correct Content-Type
|
||||
# which generated by urllib3 will be overwritten.
|
||||
del headers['Content-Type']
|
||||
r = self.pool_manager.request(method, url,
|
||||
fields=post_params,
|
||||
encode_multipart=True,
|
||||
headers=headers)
|
||||
r = self.agent(url).request(method, url,
|
||||
fields=post_params,
|
||||
encode_multipart=True,
|
||||
headers=headers)
|
||||
# For `GET`, `HEAD`, `DELETE`
|
||||
else:
|
||||
r = self.pool_manager.request(method, url,
|
||||
fields=query_params,
|
||||
headers=headers)
|
||||
r = self.agent(url).request(method, url,
|
||||
fields=query_params,
|
||||
headers=headers)
|
||||
r = RESTResponse(r)
|
||||
|
||||
if r.status not in range(200, 206):
|
||||
|
||||
@@ -12,7 +12,7 @@ from setuptools import setup, find_packages
|
||||
# Try reading the setuptools documentation:
|
||||
# http://pypi.python.org/pypi/setuptools
|
||||
|
||||
REQUIRES = ["urllib3 >= 1.10", "six >= 1.9"]
|
||||
REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"]
|
||||
|
||||
setup(
|
||||
name="{{module}}",
|
||||
|
||||
@@ -66,28 +66,28 @@ class ApiClient(object):
|
||||
if self.cookie:
|
||||
headers['Cookie'] = self.cookie
|
||||
if headers:
|
||||
headers = ApiClient.sanitize_for_serialization(headers)
|
||||
headers = self.sanitize_for_serialization(headers)
|
||||
|
||||
# path parameters
|
||||
if path_params:
|
||||
path_params = ApiClient.sanitize_for_serialization(path_params)
|
||||
path_params = self.sanitize_for_serialization(path_params)
|
||||
for k, v in iteritems(path_params):
|
||||
replacement = quote(str(self.to_path_value(v)))
|
||||
resource_path = resource_path.replace('{' + k + '}', replacement)
|
||||
|
||||
# query parameters
|
||||
if query_params:
|
||||
query_params = ApiClient.sanitize_for_serialization(query_params)
|
||||
query_params = self.sanitize_for_serialization(query_params)
|
||||
query_params = {k: self.to_path_value(v) for k, v in iteritems(query_params)}
|
||||
|
||||
# post parameters
|
||||
if post_params:
|
||||
post_params = self.prepare_post_parameters(post_params, files)
|
||||
post_params = ApiClient.sanitize_for_serialization(post_params)
|
||||
post_params = self.sanitize_for_serialization(post_params)
|
||||
|
||||
# body
|
||||
if body:
|
||||
body = ApiClient.sanitize_for_serialization(body)
|
||||
body = self.sanitize_for_serialization(body)
|
||||
|
||||
# request url
|
||||
url = self.host + resource_path
|
||||
@@ -115,8 +115,7 @@ class ApiClient(object):
|
||||
else:
|
||||
return str(obj)
|
||||
|
||||
@staticmethod
|
||||
def sanitize_for_serialization(obj):
|
||||
def sanitize_for_serialization(self, obj):
|
||||
"""
|
||||
Sanitize an object for Request.
|
||||
|
||||
@@ -132,7 +131,7 @@ class ApiClient(object):
|
||||
elif isinstance(obj, (str, int, float, bool, tuple)):
|
||||
return obj
|
||||
elif isinstance(obj, list):
|
||||
return [ApiClient.sanitize_for_serialization(sub_obj) for sub_obj in obj]
|
||||
return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj]
|
||||
elif isinstance(obj, (datetime.datetime, datetime.date)):
|
||||
return obj.isoformat()
|
||||
else:
|
||||
@@ -145,7 +144,7 @@ class ApiClient(object):
|
||||
obj_dict = {obj.attribute_map[key]: val
|
||||
for key, val in iteritems(obj.__dict__)
|
||||
if key != 'swagger_types' and key != 'attribute_map' and val is not None}
|
||||
return {key: ApiClient.sanitize_for_serialization(val)
|
||||
return {key: self.sanitize_for_serialization(val)
|
||||
for key, val in iteritems(obj_dict)}
|
||||
|
||||
def deserialize(self, obj, obj_class):
|
||||
@@ -253,8 +252,7 @@ class ApiClient(object):
|
||||
|
||||
return params
|
||||
|
||||
@staticmethod
|
||||
def select_header_accept(accepts):
|
||||
def select_header_accept(self, accepts):
|
||||
"""
|
||||
Return `Accept` based on an array of accepts provided
|
||||
"""
|
||||
@@ -268,8 +266,7 @@ class ApiClient(object):
|
||||
else:
|
||||
return ', '.join(accepts)
|
||||
|
||||
@staticmethod
|
||||
def select_header_content_type(content_types):
|
||||
def select_header_content_type(self, content_types):
|
||||
"""
|
||||
Return `Content-Type` baseed on an array of content_types provided
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package {{package}};
|
||||
|
||||
import {{modelPackage}}.*;
|
||||
|
||||
import retrofit.http.*;
|
||||
import retrofit.mime.*;
|
||||
import java.util.*;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
{{#operations}}
|
||||
public interface {{classname}} {
|
||||
{{#operation}}
|
||||
/**
|
||||
* {{summary}}
|
||||
* {{notes}}
|
||||
{{#allParams}} * @param {{paramName}} {{description}}
|
||||
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
|
||||
*/
|
||||
{{#formParams}}{{#-first}}
|
||||
{{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
|
||||
@{{httpMethod}}("{{path}}")
|
||||
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}}
|
||||
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}}
|
||||
);{{/hasMore}}{{/allParams}}
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isBodyParam}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isFormParam}}{{#notFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") TypedFile {{paramName}}{{/isFile}}{{/isFormParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isHeaderParam}}@Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}}
|
||||
@@ -0,0 +1,50 @@
|
||||
package {{package}};
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
|
||||
import com.wordnik.swagger.annotations.*;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
{{#models}}
|
||||
|
||||
{{#model}}{{#description}}
|
||||
/**
|
||||
* {{description}}
|
||||
**/{{/description}}
|
||||
@ApiModel(description = "{{{description}}}")
|
||||
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
|
||||
{{#vars}}{{#isEnum}}
|
||||
public enum {{datatypeWithEnum}} {
|
||||
{{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}}
|
||||
};{{/isEnum}}
|
||||
|
||||
/**{{#description}}
|
||||
* {{{description}}}{{/description}}{{#minimum}}
|
||||
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
|
||||
* maximum: {{maximum}}{{/maximum}}
|
||||
**/
|
||||
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
|
||||
@SerializedName("{{baseName}}"){{#isEnum}}
|
||||
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{^isEnum}}
|
||||
private {{{datatype}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{/vars}}
|
||||
|
||||
{{#vars}}
|
||||
public {{{datatypeWithEnum}}} {{getter}}() {
|
||||
return {{name}};
|
||||
}
|
||||
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
this.{{name}} = {{name}};
|
||||
}
|
||||
{{/vars}}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class {{classname}} {\n");
|
||||
{{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}}
|
||||
{{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n");
|
||||
{{/vars}}sb.append("}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isPathParam}}@Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}
|
||||
143
modules/swagger-codegen/src/main/resources/retrofit/pom.mustache
Normal file
143
modules/swagger-codegen/src/main/resources/retrofit/pom.mustache
Normal file
@@ -0,0 +1,143 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>{{groupId}}</groupId>
|
||||
<artifactId>{{artifactId}}</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>{{artifactId}}</name>
|
||||
<version>{{artifactVersion}}</version>
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:wordnik/swagger-mustache.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:wordnik/swagger-codegen.git</developerConnection>
|
||||
<url>https://github.com/wordnik/swagger-codegen</url>
|
||||
</scm>
|
||||
<prerequisites>
|
||||
<maven>2.2.0</maven>
|
||||
</prerequisites>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>loggerPath</name>
|
||||
<value>conf/log4j.properties</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<argLine>-Xms512m -Xmx1500m</argLine>
|
||||
<parallel>methods</parallel>
|
||||
<forkMode>pertest</forkMode>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/lib</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- attach test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add_sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/main/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add_test_sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/test/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.wordnik</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>${swagger-annotations-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson-version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>${retrofit-version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<swagger-annotations-version>1.5.3-M1</swagger-annotations-version>
|
||||
<gson-version>2.3.1</gson-version>
|
||||
<retrofit-version>1.9.0</retrofit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
</properties>
|
||||
</project>
|
||||
@@ -0,0 +1 @@
|
||||
{{#isQueryParam}}@Query("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}}
|
||||
@@ -0,0 +1,23 @@
|
||||
package {{invokerPackage}};
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import retrofit.RestAdapter;
|
||||
import retrofit.converter.GsonConverter;
|
||||
|
||||
public class ServiceGenerator {
|
||||
// No need to instantiate this class.
|
||||
private ServiceGenerator() { }
|
||||
|
||||
public static <S> S createService(Class<S> serviceClass) {
|
||||
Gson gson = new GsonBuilder()
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
.create();
|
||||
RestAdapter adapter = new RestAdapter.Builder()
|
||||
.setEndpoint("{{basePath}}")
|
||||
.setConverter(new GsonConverter(gson))
|
||||
.build();
|
||||
|
||||
return adapter.create(serviceClass);
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,9 @@ module {{moduleName}}
|
||||
{{/bodyParam}}{{#bodyParam}}post_body = Swagger::Request.object_to_http_body({{#required}}{{{paramName}}}{{/required}}{{^required}}opts[:'{{{paramName}}}']{{/required}})
|
||||
{{/bodyParam}}
|
||||
|
||||
{{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body
|
||||
{{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make
|
||||
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.body
|
||||
{{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/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
|
||||
nil{{/returnType}}
|
||||
end
|
||||
{{/operation}}
|
||||
|
||||
@@ -16,9 +16,9 @@ module {{moduleName}}
|
||||
#
|
||||
# @example
|
||||
# Swagger.configure do |config|
|
||||
# config.api_key = '1234567890abcdef' # required
|
||||
# config.username = 'wordlover' # optional, but needed for user-related functions
|
||||
# config.password = 'i<3words' # optional, but needed for user-related functions
|
||||
# config.api_key['api_key'] = '1234567890abcdef' # api key authentication
|
||||
# config.username = 'wordlover' # http basic authentication
|
||||
# config.password = 'i<3words' # http basic authentication
|
||||
# config.format = 'json' # optional, defaults to 'json'
|
||||
# end
|
||||
#
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
module {{moduleName}}
|
||||
module Swagger
|
||||
class Configuration
|
||||
attr_accessor :format, :api_key, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent
|
||||
|
||||
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
|
||||
|
||||
# Defaults go in here..
|
||||
def initialize
|
||||
@format = 'json'
|
||||
@@ -13,6 +13,16 @@ module {{moduleName}}
|
||||
@inject_format = false
|
||||
@force_ending_format = false
|
||||
@camelize_params = true
|
||||
|
||||
# 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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ module {{moduleName}}
|
||||
require 'addressable/uri'
|
||||
require 'typhoeus'
|
||||
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names
|
||||
|
||||
# All requests must have an HTTP method and a path
|
||||
# Optionals parameters are :params, :headers, :body, :format, :host
|
||||
@@ -16,21 +16,9 @@ module {{moduleName}}
|
||||
# Set default headers
|
||||
default_headers = {
|
||||
'Content-Type' => "application/#{attributes[:format].downcase}",
|
||||
:api_key => Swagger.configuration.api_key,
|
||||
'User-Agent' => Swagger.configuration.user_agent
|
||||
}
|
||||
|
||||
# api_key from headers hash trumps the default, even if its value is blank
|
||||
if attributes[:headers].present? && attributes[:headers].has_key?(:api_key)
|
||||
default_headers.delete(:api_key)
|
||||
end
|
||||
|
||||
# api_key from params hash trumps all others (headers and default_headers)
|
||||
if attributes[:params].present? && attributes[:params].has_key?(:api_key)
|
||||
default_headers.delete(:api_key)
|
||||
attributes[:headers].delete(:api_key) if attributes[:headers].present?
|
||||
end
|
||||
|
||||
# Merge argument headers into defaults
|
||||
attributes[:headers] = default_headers.merge(attributes[:headers] || {})
|
||||
|
||||
@@ -44,6 +32,33 @@ module {{moduleName}}
|
||||
attributes.each do |name, value|
|
||||
send("#{name.to_s.underscore.to_sym}=", value)
|
||||
end
|
||||
|
||||
update_params_for_auth!
|
||||
end
|
||||
|
||||
# Update hearder and query params based on authentication settings.
|
||||
def update_params_for_auth!
|
||||
(@auth_names || []).each do |auth_name|
|
||||
case auth_name
|
||||
{{#authMethods}}when '{{name}}'
|
||||
{{#isApiKey}}{{#isKeyInHeader}}@headers ||= {}
|
||||
@headers['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInHeader}}{{#isKeyInQuery}}@params ||= {}
|
||||
@params['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}@headers ||= {}
|
||||
http_auth_header = 'Basic ' + ["#{Swagger.configuration.username}:#{Swagger.configuration.password}"].pack('m').delete("\r\n")
|
||||
@headers['Authorization'] = http_auth_header{{/isBasic}}{{#isOAuth}}# TODO: support oauth{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 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?
|
||||
"#{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
|
||||
@@ -58,9 +73,6 @@ module {{moduleName}}
|
||||
# Drop trailing question mark, if present
|
||||
u.sub! /\?$/, ''
|
||||
|
||||
# Obfuscate API key?
|
||||
u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated]
|
||||
|
||||
u
|
||||
end
|
||||
|
||||
@@ -108,14 +120,16 @@ module {{moduleName}}
|
||||
# For form parameters, remove empty value
|
||||
def outgoing_body
|
||||
# http form
|
||||
if @body.nil? && @form_params && !@form_params.empty?
|
||||
if headers['Content-Type'] == 'application/x-www-form-urlencoded'
|
||||
data = form_params.dup
|
||||
data.each do |key, value|
|
||||
data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter
|
||||
end
|
||||
data
|
||||
else # http body is JSON
|
||||
elsif @body # http body is JSON
|
||||
@body.is_a?(String) ? @body : @body.to_json
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -129,7 +143,7 @@ module {{moduleName}}
|
||||
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 unless key.to_sym == :api_key # api_key is not a camelCased param
|
||||
key = key.to_s.camelize(:lower).to_sym
|
||||
end
|
||||
query_values[key] = value.to_s
|
||||
end
|
||||
@@ -148,39 +162,40 @@ module {{moduleName}}
|
||||
#TODO use configuration setting to determine if debugging
|
||||
#logger = Logger.new STDOUT
|
||||
#logger.debug self.url
|
||||
|
||||
request_options = {
|
||||
:ssl_verifypeer => Swagger.configuration.verify_ssl,
|
||||
:headers => self.headers.stringify_keys
|
||||
}
|
||||
response = case self.http_method.to_sym
|
||||
when :get,:GET
|
||||
Typhoeus::Request.get(
|
||||
self.url,
|
||||
:headers => self.headers.stringify_keys,
|
||||
request_options
|
||||
)
|
||||
|
||||
when :post,:POST
|
||||
Typhoeus::Request.post(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
request_options.merge(:body => self.outgoing_body)
|
||||
)
|
||||
|
||||
when :patch,:PATCH
|
||||
Typhoeus::Request.patch(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
request_options.merge(:body => self.outgoing_body)
|
||||
)
|
||||
|
||||
when :put,:PUT
|
||||
Typhoeus::Request.put(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
request_options.merge(:body => self.outgoing_body)
|
||||
)
|
||||
|
||||
when :delete,:DELETE
|
||||
Typhoeus::Request.delete(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
request_options.merge(:body => self.outgoing_body)
|
||||
)
|
||||
end
|
||||
Response.new(response)
|
||||
|
||||
Reference in New Issue
Block a user