From d2a82d56aaa4e63780c1515e8c6bc924720a308b Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 9 Jun 2015 10:16:52 +0800 Subject: [PATCH 001/499] Enable CLI options for Ruby generator --- .../codegen/languages/RubyClientCodegen.java | 98 +++++++++++++++---- .../resources/ruby/swagger/version.mustache | 2 +- .../resources/ruby/swagger_client.mustache | 2 +- 3 files changed, 79 insertions(+), 23 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 01fe6c6eed4..df48b512bf2 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -1,5 +1,6 @@ package io.swagger.codegen.languages; +import io.swagger.codegen.CliOption; import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenType; import io.swagger.codegen.DefaultCodegen; @@ -13,16 +14,16 @@ import java.util.Arrays; import java.util.HashSet; public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { - protected String gemName = "swagger_client"; + protected String gemName = null; protected String moduleName = null; + protected String gemVersion = "1.0.0"; protected String libFolder = "lib"; public RubyClientCodegen() { super(); - moduleName = generateModuleName(); - modelPackage = gemName + "/models"; - apiPackage = gemName + "/api"; - outputFolder = "generated-code" + File.separatorChar + "ruby"; + modelPackage = "models"; + apiPackage = "api"; + outputFolder = "generated-code" + File.separator + "ruby"; modelTemplateFiles.put("model.mustache", ".rb"); apiTemplateFiles.put("api.mustache", ".rb"); templateDir = "ruby"; @@ -39,9 +40,6 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { "if", "not", "return", "undef", "yield") ); - additionalProperties.put("gemName", gemName); - additionalProperties.put("moduleName", moduleName); - languageSpecificPrimitives.add("int"); languageSpecificPrimitives.add("array"); languageSpecificPrimitives.add("map"); @@ -55,17 +53,57 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("List", "array"); typeMapping.put("map", "map"); - String baseFolder = "lib" + File.separatorChar + gemName; - String swaggerFolder = baseFolder + File.separatorChar + "swagger"; - String modelFolder = baseFolder + File.separatorChar + "models"; + // remove modelPackage and apiPackage added by default + cliOptions.clear(); + cliOptions.add(new CliOption("gemName", "gem name, default: swagger_client")); + cliOptions.add(new CliOption("moduleName", "top module name, usually corresponding to gem name, default: SwaggerClient")); + cliOptions.add(new CliOption("gemVersion", "gem version, default: 1.0.0")); + } + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey("gemName")) { + setGemName((String) additionalProperties.get("gemName")); + } + if (additionalProperties.containsKey("moduleName")) { + setModuleName((String) additionalProperties.get("moduleName")); + } + + if (gemName == null && moduleName == null) { + setGemName("swagger_client"); + setModuleName(generateModuleName(gemName)); + } else if (gemName == null) { + setGemName(generateGemName(moduleName)); + } else if (moduleName == null) { + setModuleName(generateModuleName(gemName)); + } + + additionalProperties.put("gemName", gemName); + additionalProperties.put("moduleName", moduleName); + + if (additionalProperties.containsKey("gemVersion")) { + setGemVersion((String) additionalProperties.get("gemVersion")); + } else { + // not set, pass the default value to template + additionalProperties.put("gemVersion", gemVersion); + } + + // use constant model/api package (folder path) + setModelPackage("models"); + setApiPackage("api"); supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec")); - supportingFiles.add(new SupportingFile("swagger_client.mustache", "lib", gemName + ".rb")); + supportingFiles.add(new SupportingFile("swagger_client.mustache", libFolder, gemName + ".rb")); + String baseFolder = libFolder + File.separator + gemName; supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb")); supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb")); - 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")); + String swaggerFolder = baseFolder + File.separator + "swagger"; + supportingFiles.add(new SupportingFile("swagger" + File.separator + "request.mustache", swaggerFolder, "request.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separator + "response.mustache", swaggerFolder, "response.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separator + "version.mustache", swaggerFolder, "version.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separator + "configuration.mustache", swaggerFolder, "configuration.rb")); + String modelFolder = baseFolder + File.separator + modelPackage.replace("/", File.separator); supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb")); } @@ -84,10 +122,17 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { /** * Generate Ruby module name from the gem name, e.g. use "SwaggerClient" for "swagger_client". */ - public String generateModuleName() { + public String generateModuleName(String gemName) { return camelize(gemName.replaceAll("[^\\w]+", "_")); } + /** + * Generate Ruby gem name from the module name, e.g. use "swagger_client" for "SwaggerClient". + */ + public String generateGemName(String moduleName) { + return underscore(moduleName.replaceAll("[^\\w]+", "")); + } + @Override public String escapeReservedWord(String name) { return "_" + name; @@ -95,11 +140,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return outputFolder + File.separatorChar + "lib" + File.separatorChar + gemName + File.separatorChar + "api"; + return outputFolder + File.separator + libFolder + File.separator + gemName + File.separator + apiPackage.replace("/", File.separator); } public String modelFileFolder() { - return outputFolder + File.separatorChar + "lib" + File.separatorChar + gemName + File.separatorChar + "models"; + return outputFolder + File.separator + libFolder + File.separator + gemName + File.separator + modelPackage.replace("/", File.separator); } @Override @@ -220,12 +265,23 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String toModelImport(String name) { - return modelPackage() + "/" + toModelFilename(name); + return gemName + "/" + modelPackage() + "/" + toModelFilename(name); } @Override public String toApiImport(String name) { - return apiPackage() + "/" + toApiFilename(name); + return gemName + "/" + apiPackage() + "/" + toApiFilename(name); } + public void setGemName(String gemName) { + this.gemName = gemName; + } + + public void setModuleName(String moduleName) { + this.moduleName = moduleName; + } + + public void setGemVersion(String gemVersion) { + this.gemVersion = gemVersion; + } } diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/version.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/version.mustache index a3c42972c3d..ee83f29c13b 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/version.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/version.mustache @@ -1,5 +1,5 @@ module {{moduleName}} module Swagger -VERSION = "{{appVersion}}" +VERSION = "{{gemVersion}}" end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache index 5268a42657f..426a7324acf 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache @@ -7,7 +7,7 @@ require '{{gemName}}/swagger/response' require '{{gemName}}/swagger/version' # Models -require '{{modelPackage}}/base_object' +require '{{gemName}}/{{modelPackage}}/base_object' {{#models}} require '{{importPath}}' {{/models}} From 1315e2d72c0e7e78a828f349ac1057f9d4953ca0 Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 9 Jun 2015 15:47:37 +0800 Subject: [PATCH 002/499] Add new line to make code more readable --- .../java/io/swagger/codegen/languages/RubyClientCodegen.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index df48b512bf2..9141f61253e 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -93,6 +93,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { // use constant model/api package (folder path) setModelPackage("models"); setApiPackage("api"); + supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec")); supportingFiles.add(new SupportingFile("swagger_client.mustache", libFolder, gemName + ".rb")); String baseFolder = libFolder + File.separator + gemName; From 3768932ba2360d8be238009cf8c0eaaba5ab5150 Mon Sep 17 00:00:00 2001 From: fehguy Date: Tue, 9 Jun 2015 01:36:48 -0700 Subject: [PATCH 003/499] updated dev version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 40a709fc1b8..ca707056230 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ swagger-codegen-project pom swagger-codegen-project - 2.1.2 + 2.1.3-SNAPSHOT https://github.com/swagger-api/swagger-codegen scm:git:git@github.com:swagger-api/swagger-codegen.git From 672fcd5a14c6331123c7843ce8452594cff87699 Mon Sep 17 00:00:00 2001 From: fehguy Date: Tue, 9 Jun 2015 01:36:52 -0700 Subject: [PATCH 004/499] updated dev version --- modules/swagger-codegen-cli/pom.xml | 2 +- modules/swagger-codegen/pom.xml | 2 +- modules/swagger-generator/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen-cli/pom.xml b/modules/swagger-codegen-cli/pom.xml index 5a9efbdd59d..29daf274138 100644 --- a/modules/swagger-codegen-cli/pom.xml +++ b/modules/swagger-codegen-cli/pom.xml @@ -3,7 +3,7 @@ io.swagger swagger-codegen-project - 2.1.2 + 2.1.3-SNAPSHOT ../.. 4.0.0 diff --git a/modules/swagger-codegen/pom.xml b/modules/swagger-codegen/pom.xml index 195c0c0fe07..aca706455e2 100644 --- a/modules/swagger-codegen/pom.xml +++ b/modules/swagger-codegen/pom.xml @@ -3,7 +3,7 @@ io.swagger swagger-codegen-project - 2.1.2 + 2.1.3-SNAPSHOT ../.. 4.0.0 diff --git a/modules/swagger-generator/pom.xml b/modules/swagger-generator/pom.xml index a7c3caf45dc..69e7802c487 100644 --- a/modules/swagger-generator/pom.xml +++ b/modules/swagger-generator/pom.xml @@ -4,7 +4,7 @@ io.swagger swagger-codegen-project - 2.1.2 + 2.1.3-SNAPSHOT ../.. swagger-generator From 3f194d3288c5010d196110493d67d61b8eab7a3e Mon Sep 17 00:00:00 2001 From: Alexey Nechaev Date: Tue, 9 Jun 2015 19:34:09 +0300 Subject: [PATCH 005/499] Fixed #837: Generation of default values for complex arrays and maps has been improved. --- .../io/swagger/codegen/DefaultCodegen.java | 8 ----- .../codegen/languages/JavaClientCodegen.java | 12 +++++++ .../src/test/scala/Java/JavaModelTest.scala | 32 +++++++++++++++---- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 71b6295c9be..6ab3fe440ca 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -422,14 +422,6 @@ public class DefaultCodegen { return dp.getDefault().toString(); } return "null"; - } else if (p instanceof MapProperty) { - MapProperty ap = (MapProperty) p; - String inner = getSwaggerType(ap.getAdditionalProperties()); - return "new HashMap() "; - } else if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - String inner = getSwaggerType(ap.getItems()); - return "new ArrayList<" + inner + ">() "; } else { return "null"; } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java index fcec455e9b3..d7311b840e6 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java @@ -200,6 +200,18 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { return super.getTypeDeclaration(p); } + @Override + public String toDefaultValue(Property p) { + if (p instanceof ArrayProperty) { + final ArrayProperty ap = (ArrayProperty) p; + return String.format("new ArrayList<%s>()", getTypeDeclaration(ap.getItems())); + } else if (p instanceof MapProperty) { + final MapProperty ap = (MapProperty) p; + return String.format("new HashMap()", getTypeDeclaration(ap.getAdditionalProperties())); + } + return super.toDefaultValue(p); + } + @Override public String getSwaggerType(Property p) { String swaggerType = super.getSwaggerType(p); diff --git a/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala b/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala index fc819f1f195..09bc8edf0ab 100644 --- a/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala +++ b/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala @@ -85,7 +85,7 @@ class JavaModelTest extends FlatSpec with Matchers { vars.get(1).setter should be("setUrls") vars.get(1).datatype should be("List") vars.get(1).name should be("urls") - vars.get(1).defaultValue should be("new ArrayList() ") + vars.get(1).defaultValue should be("new ArrayList()") vars.get(1).baseType should be("List") vars.get(1).containerType should be("array") vars.get(1).required should equal(null) @@ -113,7 +113,7 @@ class JavaModelTest extends FlatSpec with Matchers { vars.get(0).setter should be("setTranslations") vars.get(0).datatype should be("Map") vars.get(0).name should be("translations") - vars.get(0).defaultValue should be("new HashMap() ") + vars.get(0).defaultValue should be("new HashMap()") vars.get(0).baseType should be("Map") vars.get(0).containerType should be("map") vars.get(0).required should equal(null) @@ -121,7 +121,7 @@ class JavaModelTest extends FlatSpec with Matchers { } - ignore should "convert a model with a map with complex list property" in { + it should "convert a model with a map with complex list property" in { val model = new ModelImpl() .description("a sample model") .property("translations", new MapProperty() @@ -144,13 +144,33 @@ class JavaModelTest extends FlatSpec with Matchers { vars.get(0).setter should be("setTranslations") vars.get(0).datatype should be("Map>") vars.get(0).name should be("translations") - vars.get(0).defaultValue should be("new HashMap>() ") + vars.get(0).defaultValue should be("new HashMap>()") vars.get(0).baseType should be("Map") vars.get(0).containerType should be("map") vars.get(0).required should equal(null) vars.get(0).isContainer should equal(true) } + it should "convert a model with a 2D list property" in { + val model = new ModelImpl().name("sample").property("list2D", new ArrayProperty().items( + new ArrayProperty().items(new RefProperty("Pet")))) + val codegen = new JavaClientCodegen() + val cm = codegen.fromModel("sample", model) + val vars = cm.vars + vars.size should be (1) + val list = vars.get(0) + list.baseName should be("list2D") + list.getter should be("getList2D") + list.setter should be("setList2D") + list.datatype should be("List>") + list.name should be("list2D") + list.defaultValue should be ("new ArrayList>()") + list.baseType should be("List") + list.containerType should be("array") + list.required should equal(null) + list.isContainer should equal(true) + } + it should "convert a model with complex properties" in { val model = new ModelImpl() .description("a sample model") @@ -197,7 +217,7 @@ class JavaModelTest extends FlatSpec with Matchers { vars.get(0).setter should be("setChildren") vars.get(0).datatype should be("List") vars.get(0).name should be("children") - vars.get(0).defaultValue should be("new ArrayList() ") + vars.get(0).defaultValue should be("new ArrayList()") vars.get(0).baseType should be("List") vars.get(0).containerType should be("array") vars.get(0).required should equal(null) @@ -226,7 +246,7 @@ class JavaModelTest extends FlatSpec with Matchers { vars.get(0).setter should be("setChildren") vars.get(0).datatype should be("Map") vars.get(0).name should be("children") - vars.get(0).defaultValue should be("new HashMap() ") + vars.get(0).defaultValue should be("new HashMap()") vars.get(0).baseType should be("Map") vars.get(0).containerType should be("map") vars.get(0).required should equal(null) From d7b10a17c1d7fafd6a3c8903b6ae1f555240a6b0 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Wed, 10 Jun 2015 10:53:16 +0800 Subject: [PATCH 006/499] Renamed objc client from `PetstoreClient` to `SwaggerClient` --- .../codegen/languages/ObjcClientCodegen.java | 2 +- .../xcshareddata/PetstoreClient.xccheckout | 41 -------- samples/client/petstore/objc/Podfile | 2 +- samples/client/petstore/objc/Podfile.lock | 14 +-- .../contents.xcworkspacedata | 2 +- .../UserInterfaceState.xcuserstate | Bin 0 -> 7666 bytes .../SwaggerClient.xcodeproj}/project.pbxproj | 90 +++++++++--------- .../contents.xcworkspacedata | 0 .../xcshareddata/PetstoreClient.xccheckout | 0 .../UserInterfaceState.xcuserstate | Bin .../xcschemes/SwaggerClient.xcscheme} | 36 +++---- .../xcschemes/xcschememanagement.plist | 2 +- .../xcschemes/PetstoreClient.xcscheme | 0 .../xcschemes/xcschememanagement.plist | 0 .../SwaggerClient}/AppDelegate.h | 0 .../SwaggerClient}/AppDelegate.m | 0 .../Base.lproj/Main_iPad.storyboard | 0 .../Base.lproj/Main_iPhone.storyboard | 0 .../AppIcon.appiconset/Contents.json | 0 .../LaunchImage.launchimage/Contents.json | 0 .../SwaggerClient/SwaggerClient-Info.plist} | 0 .../SwaggerClient/SwaggerClient-Prefix.pch} | 0 .../SwaggerClient}/ViewController.h | 0 .../SwaggerClient}/ViewController.m | 0 .../SwaggerClient}/en.lproj/InfoPlist.strings | 0 .../SwaggerClient}/main.m | 0 .../SwaggerClient}/test-1.png | Bin .../SwaggerClientTests}/PetApiTest.h | 0 .../SwaggerClientTests}/PetApiTest.m | 0 .../SwaggerClientTests}/SWGApiClientTest.m | 0 .../SwaggerClientTests-Info.plist} | 0 .../en.lproj/InfoPlist.strings | 0 .../{PetstoreClient => SwaggerClient}/pom.xml | 0 samples/client/petstore/objc/client/SWGPet.h | 2 +- .../client/petstore/objc/client/SWGPetApi.m | 2 +- samples/client/petstore/objc/pom.xml | 4 +- 36 files changed, 78 insertions(+), 119 deletions(-) delete mode 100644 samples/client/petstore/objc/PetstoreClient.xcworkspace/xcshareddata/PetstoreClient.xccheckout rename samples/client/petstore/objc/{PetstoreClient.xcworkspace => SwaggerClient.xcworkspace}/contents.xcworkspacedata (73%) create mode 100644 samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/UserInterfaceState.xcuserstate rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/project.pbxproj (91%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/project.xcworkspace/xcshareddata/PetstoreClient.xccheckout (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/project.xcworkspace/xcuserdata/tony.xcuserdatad/UserInterfaceState.xcuserstate (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/PetstoreClient.xcscheme => SwaggerClient/SwaggerClient.xcodeproj/xcshareddata/xcschemes/SwaggerClient.xcscheme} (75%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist (91%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/xcuserdata/tony.xcuserdatad/xcschemes/PetstoreClient.xcscheme (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient.xcodeproj => SwaggerClient/SwaggerClient.xcodeproj}/xcuserdata/tony.xcuserdatad/xcschemes/xcschememanagement.plist (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/AppDelegate.h (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/AppDelegate.m (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/Base.lproj/Main_iPad.storyboard (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/Base.lproj/Main_iPhone.storyboard (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/Images.xcassets/AppIcon.appiconset/Contents.json (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/Images.xcassets/LaunchImage.launchimage/Contents.json (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient/PetstoreClient-Info.plist => SwaggerClient/SwaggerClient/SwaggerClient-Info.plist} (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient/PetstoreClient-Prefix.pch => SwaggerClient/SwaggerClient/SwaggerClient-Prefix.pch} (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/ViewController.h (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/ViewController.m (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/en.lproj/InfoPlist.strings (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/main.m (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClient => SwaggerClient/SwaggerClient}/test-1.png (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests => SwaggerClient/SwaggerClientTests}/PetApiTest.h (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests => SwaggerClient/SwaggerClientTests}/PetApiTest.m (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests => SwaggerClient/SwaggerClientTests}/SWGApiClientTest.m (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests/PetstoreClientTests-Info.plist => SwaggerClient/SwaggerClientTests/SwaggerClientTests-Info.plist} (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests => SwaggerClient/SwaggerClientTests}/en.lproj/InfoPlist.strings (100%) rename samples/client/petstore/objc/{PetstoreClient => SwaggerClient}/pom.xml (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java index f0c0a8ffa80..01f72040bf5 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java @@ -20,7 +20,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { protected Set foundationClasses = new HashSet(); protected String sourceFolder = "client"; protected String classPrefix = "SWG"; - protected String projectName = "swaggerClient"; + protected String projectName = "SwaggerClient"; public ObjcClientCodegen() { super(); diff --git a/samples/client/petstore/objc/PetstoreClient.xcworkspace/xcshareddata/PetstoreClient.xccheckout b/samples/client/petstore/objc/PetstoreClient.xcworkspace/xcshareddata/PetstoreClient.xccheckout deleted file mode 100644 index fafd21fb8eb..00000000000 --- a/samples/client/petstore/objc/PetstoreClient.xcworkspace/xcshareddata/PetstoreClient.xccheckout +++ /dev/null @@ -1,41 +0,0 @@ - - - - - IDESourceControlProjectFavoriteDictionaryKey - - IDESourceControlProjectIdentifier - 81EB09FA-DD8C-4FE1-82D3-1FB6FF0D9C43 - IDESourceControlProjectName - PetstoreClient - IDESourceControlProjectOriginsDictionary - - E5BBF0AA85077C865C95437976D06D819733A208 - ssh://github.com/wordnik/swagger-codegen.git - - IDESourceControlProjectPath - samples/client/petstore/objc/PetstoreClient.xcworkspace - IDESourceControlProjectRelativeInstallPathDictionary - - E5BBF0AA85077C865C95437976D06D819733A208 - ../../../../.. - - IDESourceControlProjectURL - ssh://github.com/wordnik/swagger-codegen.git - IDESourceControlProjectVersion - 111 - IDESourceControlProjectWCCIdentifier - E5BBF0AA85077C865C95437976D06D819733A208 - IDESourceControlProjectWCConfigurations - - - IDESourceControlRepositoryExtensionIdentifierKey - public.vcs.git - IDESourceControlWCCIdentifierKey - E5BBF0AA85077C865C95437976D06D819733A208 - IDESourceControlWCCName - swagger-codegen - - - - diff --git a/samples/client/petstore/objc/Podfile b/samples/client/petstore/objc/Podfile index 69e4c26ca1b..ad41463f60c 100644 --- a/samples/client/petstore/objc/Podfile +++ b/samples/client/petstore/objc/Podfile @@ -1,5 +1,5 @@ platform :ios, '6.0' -xcodeproj 'swaggerClient/PetstoreClient.xcodeproj' +xcodeproj 'SwaggerClient/SwaggerClient.xcodeproj' pod 'AFNetworking', '~> 2.1' pod 'JSONModel', '~> 1.0' pod 'ISO8601' diff --git a/samples/client/petstore/objc/Podfile.lock b/samples/client/petstore/objc/Podfile.lock index ceb0fad1a42..48b1f809658 100644 --- a/samples/client/petstore/objc/Podfile.lock +++ b/samples/client/petstore/objc/Podfile.lock @@ -1,11 +1,11 @@ PODS: - AFNetworking (2.5.4): - - AFNetworking/NSURLConnection - - AFNetworking/NSURLSession - - AFNetworking/Reachability - - AFNetworking/Security - - AFNetworking/Serialization - - AFNetworking/UIKit + - AFNetworking/NSURLConnection (= 2.5.4) + - AFNetworking/NSURLSession (= 2.5.4) + - AFNetworking/Reachability (= 2.5.4) + - AFNetworking/Security (= 2.5.4) + - AFNetworking/Serialization (= 2.5.4) + - AFNetworking/UIKit (= 2.5.4) - AFNetworking/NSURLConnection (2.5.4): - AFNetworking/Reachability - AFNetworking/Security @@ -33,4 +33,4 @@ SPEC CHECKSUMS: ISO8601: 8d8a22d5edf0554a1cf75bac028c76c1dc0ffaef JSONModel: ec77e9865236a7a09d9cf7668df6b4b328d9ec1d -COCOAPODS: 0.33.1 +COCOAPODS: 0.37.1 diff --git a/samples/client/petstore/objc/PetstoreClient.xcworkspace/contents.xcworkspacedata b/samples/client/petstore/objc/SwaggerClient.xcworkspace/contents.xcworkspacedata similarity index 73% rename from samples/client/petstore/objc/PetstoreClient.xcworkspace/contents.xcworkspacedata rename to samples/client/petstore/objc/SwaggerClient.xcworkspace/contents.xcworkspacedata index 4ea15119171..4fa5c7f565b 100644 --- a/samples/client/petstore/objc/PetstoreClient.xcworkspace/contents.xcworkspacedata +++ b/samples/client/petstore/objc/SwaggerClient.xcworkspace/contents.xcworkspacedata @@ -2,7 +2,7 @@ + location = "group:SwaggerClient/SwaggerClient.xcodeproj"> diff --git a/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/UserInterfaceState.xcuserstate b/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..79012184db63a3743953f712c7514d98f2b40464 GIT binary patch literal 7666 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 z + BuildableName = "SwaggerClient.app" + BlueprintName = "SwaggerClient" + ReferencedContainer = "container:SwaggerClient.xcodeproj"> + BuildableName = "SwaggerClientTests.xctest" + BlueprintName = "SwaggerClientTests" + ReferencedContainer = "container:SwaggerClient.xcodeproj"> @@ -47,9 +47,9 @@ + BuildableName = "SwaggerClientTests.xctest" + BlueprintName = "SwaggerClientTests" + ReferencedContainer = "container:SwaggerClient.xcodeproj"> @@ -57,9 +57,9 @@ + BuildableName = "SwaggerClient.app" + BlueprintName = "SwaggerClient" + ReferencedContainer = "container:SwaggerClient.xcodeproj"> @@ -77,9 +77,9 @@ + BuildableName = "SwaggerClient.app" + BlueprintName = "SwaggerClient" + ReferencedContainer = "container:SwaggerClient.xcodeproj"> @@ -96,9 +96,9 @@ + BuildableName = "SwaggerClient.app" + BlueprintName = "SwaggerClient" + ReferencedContainer = "container:SwaggerClient.xcodeproj"> diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist similarity index 91% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist index 912710bdccc..a0145d5cea8 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,7 +4,7 @@ SchemeUserState - PetstoreClient.xcscheme + SwaggerClient.xcscheme_^#shared#^_ orderHint 4 diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/PetstoreClient.xcscheme b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/PetstoreClient.xcscheme similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/PetstoreClient.xcscheme rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/PetstoreClient.xcscheme diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/xcschememanagement.plist b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/xcschememanagement.plist similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/xcschememanagement.plist rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/xcuserdata/tony.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/AppDelegate.h b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/AppDelegate.h similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/AppDelegate.h rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/AppDelegate.h diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/AppDelegate.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/AppDelegate.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/AppDelegate.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/AppDelegate.m diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/Base.lproj/Main_iPad.storyboard b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/Base.lproj/Main_iPad.storyboard similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/Base.lproj/Main_iPad.storyboard rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/Base.lproj/Main_iPad.storyboard diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/Base.lproj/Main_iPhone.storyboard b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/Base.lproj/Main_iPhone.storyboard similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/Base.lproj/Main_iPhone.storyboard rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/Base.lproj/Main_iPhone.storyboard diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/Images.xcassets/AppIcon.appiconset/Contents.json b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/Images.xcassets/AppIcon.appiconset/Contents.json rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/Images.xcassets/AppIcon.appiconset/Contents.json diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/Images.xcassets/LaunchImage.launchimage/Contents.json b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/Images.xcassets/LaunchImage.launchimage/Contents.json similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/Images.xcassets/LaunchImage.launchimage/Contents.json rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/Images.xcassets/LaunchImage.launchimage/Contents.json diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/PetstoreClient-Info.plist b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/SwaggerClient-Info.plist similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/PetstoreClient-Info.plist rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/SwaggerClient-Info.plist diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/PetstoreClient-Prefix.pch b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/SwaggerClient-Prefix.pch similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/PetstoreClient-Prefix.pch rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/SwaggerClient-Prefix.pch diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.h b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.h similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.h rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.h diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/en.lproj/InfoPlist.strings b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/en.lproj/InfoPlist.strings similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/en.lproj/InfoPlist.strings rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/en.lproj/InfoPlist.strings diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/main.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/main.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/main.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/main.m diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/test-1.png b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/test-1.png similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClient/test-1.png rename to samples/client/petstore/objc/SwaggerClient/SwaggerClient/test-1.png diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.h b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/PetApiTest.h similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.h rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/PetApiTest.h diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/PetApiTest.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/PetApiTest.m diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/SWGApiClientTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/SWGApiClientTest.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetstoreClientTests-Info.plist b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SwaggerClientTests-Info.plist similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetstoreClientTests-Info.plist rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SwaggerClientTests-Info.plist diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/en.lproj/InfoPlist.strings b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/en.lproj/InfoPlist.strings similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/en.lproj/InfoPlist.strings rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/en.lproj/InfoPlist.strings diff --git a/samples/client/petstore/objc/PetstoreClient/pom.xml b/samples/client/petstore/objc/SwaggerClient/pom.xml similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/pom.xml rename to samples/client/petstore/objc/SwaggerClient/pom.xml diff --git a/samples/client/petstore/objc/client/SWGPet.h b/samples/client/petstore/objc/client/SWGPet.h index 73ff540386d..edd54e9f31a 100644 --- a/samples/client/petstore/objc/client/SWGPet.h +++ b/samples/client/petstore/objc/client/SWGPet.h @@ -1,7 +1,7 @@ #import #import "SWGObject.h" -#import "SWGCategory.h" #import "SWGTag.h" +#import "SWGCategory.h" @protocol SWGPet diff --git a/samples/client/petstore/objc/client/SWGPetApi.m b/samples/client/petstore/objc/client/SWGPetApi.m index e35e462c733..c14da125af5 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.m +++ b/samples/client/petstore/objc/client/SWGPetApi.m @@ -544,7 +544,7 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; // Authentication setting - NSArray *authSettings = @[@"petstore_auth", @"api_key"]; + NSArray *authSettings = @[@"api_key", @"petstore_auth"]; id bodyDictionary = nil; diff --git a/samples/client/petstore/objc/pom.xml b/samples/client/petstore/objc/pom.xml index 718ef5e1d6f..85fc5ff6139 100644 --- a/samples/client/petstore/objc/pom.xml +++ b/samples/client/petstore/objc/pom.xml @@ -49,9 +49,9 @@ xcodebuild -workspace - PetstoreClient.xcworkspace + SwaggerClient.xcworkspace -scheme - PetstoreClient + SwaggerClient test -destination platform=iOS Simulator,name=iPhone 6,OS=8.3 From 303dbe7730694ba0f74584e06bc7b00d2860bacd Mon Sep 17 00:00:00 2001 From: wing328 Date: Wed, 10 Jun 2015 10:53:21 +0800 Subject: [PATCH 007/499] fix array,map for perl, add test case --- .../main/resources/perl/ApiClient.mustache | 50 +++++++---- .../perl/lib/WWW/SwaggerClient/ApiClient.pm | 48 +++++++--- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 2 +- samples/client/petstore/perl/pom.xml | 15 +++- samples/client/petstore/perl/t/02_store_api.t | 88 +++++++++++++++++++ samples/client/petstore/perl/test.pl | 27 ++++++ .../php-coveralls/build/config/apigen.neon | 5 ++ .../php-coveralls/build/config/phpcs.xml | 31 +++++++ .../php-coveralls/build/config/phpmd.xml | 45 ++++++++++ .../satooshi/php-coveralls/travis/empty | 0 10 files changed, 280 insertions(+), 31 deletions(-) create mode 100644 samples/client/petstore/perl/t/02_store_api.t create mode 100644 samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/apigen.neon create mode 100644 samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpcs.xml create mode 100644 samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpmd.xml create mode 100644 samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/travis/empty diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index 2bcdd6da690..f57642ff293 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -198,33 +198,53 @@ sub deserialize { my ($self, $class, $data) = @_; $log->debugf("deserializing %s for %s", $data, $class); - my $_result; if (not defined $data) { return undef; - } elsif ( lc(substr($class, 0, 4)) eq 'map[') { #hash - $_result = \(json_decode $data); - } elsif ( lc(substr($class, 0, 6)) eq 'array[' ) { # array of data + } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash + if ($class =~ /^HASH\[(.*),(.*)\]$/) { + my ($key_type, $type) = ($1, $2); + my %hash; + my $decoded_data = decode_json $data; + foreach my $key (keys %$decoded_data) { + if (ref $decoded_data->{$key} eq 'HASH') { + $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + } else { + $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + } + } + return \%hash; + } else { + #TODO log error + } + + } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data return $data if $data eq '[]'; # return if empty array my $_sub_class = substr($class, 6, -1); - my @_json_data = json_decode $data; + my $_json_data = decode_json $data; my @_values = (); - foreach my $_value (@_json_data) { - push @_values, $self->deserialize($_sub_class, $_value); + foreach my $_value (@$_json_data) { + if (ref $_value eq 'ARRAY') { + push @_values, $self->deserialize($_sub_class, encode_json $_value); + } else { + push @_values, $self->deserialize($_sub_class, $_value); + } } - $_result = \@_values; + return \@_values; } elsif ($class eq 'DateTime') { - $_result = DateTime->from_epoch(epoch => str2time($data)); - } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type - $_result= $data; + return DateTime->from_epoch(epoch => str2time($data)); + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { + return $data; } else { # model - my $_instance = use_module("WWW::{{invokerPackage}}::Object::$class")->new; - $_result = $_instance->from_hash(decode_json $data); + my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; + if (ref $data eq "HASH") { + return $_instance->from_hash($data); + } else { # string, need to json decode first + return $_instance->from_hash(decode_json $data); + } } - return $_result; - } # return 'Accept' based on an array of accept provided diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm index da29b3e246a..3a69adbad4d 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm @@ -198,33 +198,53 @@ sub deserialize { my ($self, $class, $data) = @_; $log->debugf("deserializing %s for %s", $data, $class); - my $_result; if (not defined $data) { return undef; - } elsif ( lc(substr($class, 0, 4)) eq 'map[') { #hash - $_result = \(json_decode $data); - } elsif ( lc(substr($class, 0, 6)) eq 'array[' ) { # array of data + } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash + if ($class =~ /^HASH\[(.*),(.*)\]$/) { + my ($key_type, $type) = ($1, $2); + my %hash; + my $decoded_data = decode_json $data; + foreach my $key (keys %$decoded_data) { + if (ref $decoded_data->{$key} eq 'HASH') { + $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + } else { + $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + } + } + return \%hash; + } else { + #TODO log error + } + + } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data return $data if $data eq '[]'; # return if empty array my $_sub_class = substr($class, 6, -1); - my @_json_data = json_decode $data; + my $_json_data = decode_json $data; my @_values = (); - foreach my $_value (@_json_data) { - push @_values, $self->deserialize($_sub_class, $_value); + foreach my $_value (@$_json_data) { + if (ref $_value eq 'ARRAY') { + push @_values, $self->deserialize($_sub_class, encode_json $_value); + } else { + push @_values, $self->deserialize($_sub_class, $_value); + } } - $_result = \@_values; + return \@_values; } elsif ($class eq 'DateTime') { - $_result = DateTime->from_epoch(epoch => str2time($data)); - } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type - $_result= $data; + return DateTime->from_epoch(epoch => str2time($data)); + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { + return $data; } else { # model my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; - $_result = $_instance->from_hash(decode_json $data); + if (ref $data eq "HASH") { + return $_instance->from_hash($data); + } else { # string, need to json decode first + return $_instance->from_hash(decode_json $data); + } } - return $_result; - } # return 'Accept' based on an array of accept provided diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index dd5ff29a803..0a926625b74 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -317,7 +317,7 @@ sub new { # authentication setting, if any - my $auth_settings = ['petstore_auth', 'api_key']; + my $auth_settings = ['api_key', 'petstore_auth']; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, diff --git a/samples/client/petstore/perl/pom.xml b/samples/client/petstore/perl/pom.xml index f92eaacb134..00d192b1e54 100644 --- a/samples/client/petstore/perl/pom.xml +++ b/samples/client/petstore/perl/pom.xml @@ -27,7 +27,7 @@ 1.2.1 - Test::More + Test::More for Pet integration-test exec @@ -39,6 +39,19 @@ + + Test::More for Store + integration-test + + exec + + + perl + + t/02_store_api.t + + + diff --git a/samples/client/petstore/perl/t/02_store_api.t b/samples/client/petstore/perl/t/02_store_api.t new file mode 100644 index 00000000000..f4687daad41 --- /dev/null +++ b/samples/client/petstore/perl/t/02_store_api.t @@ -0,0 +1,88 @@ +use Test::More tests => 22; +use Test::Exception; + +use lib 'lib'; +use strict; +use warnings; + +use JSON; + +use_ok('WWW::SwaggerClient::StoreApi'); +use_ok('WWW::SwaggerClient::ApiClient'); +use_ok('WWW::SwaggerClient::Object::Pet'); +use_ok('WWW::SwaggerClient::Object::Tag'); +use_ok('WWW::SwaggerClient::Object::Category'); + +my $api_client = WWW::SwaggerClient::ApiClient->new(); +my $store_api = WWW::SwaggerClient::StoreApi->new('api_client' => $api_client); + +is $store_api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client'; + +my $get_inventory_response = $store_api->get_inventory(); + +like ($get_inventory_response->{pending}, qr/^\d+$/, "pending is numeric"); +like ($get_inventory_response->{sold}, qr/^\d+$/, "sold is numeric"); + +my $pet_json = <deserialize("HASH[string,Pet]", $pet_json)->{pet}, "WWW::SwaggerClient::Object::Pet", "get Pet object from hash"; +is $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{name}, "doggie", "get the name of the Pet object"; +is $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{category}->{name}, "string", "get the category name of the Pet object"; +is ref $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{category}, "WWW::SwaggerClient::Object::Category", "get the Category the Pet object"; +is ref $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{tags}[0], "WWW::SwaggerClient::Object::Tag", "get the Tag of the Pet object"; +is $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{tags}[0]->{name}, "tag string", "get the Tag name of the Pet object"; + +my $array_json = <deserialize("ARRAY[Pet]", $array_json)->[0], "WWW::SwaggerClient::Object::Pet", "get Pet object from hash"; +is $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{name}, "doggie", "get the name of the Pet object"; +is $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{category}->{name}, "string", "get the category name of the Pet object"; +is ref $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{category}, "WWW::SwaggerClient::Object::Category", "get the Category the Pet object"; +is ref $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{tags}->[0], "WWW::SwaggerClient::Object::Tag", "get the Tag[0] the Pet object"; +is $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{tags}->[0]->{name}, "tag string", "get the tag name the Pet object"; + + diff --git a/samples/client/petstore/perl/test.pl b/samples/client/petstore/perl/test.pl index d4f3fbb6f4b..b12105c9054 100755 --- a/samples/client/petstore/perl/test.pl +++ b/samples/client/petstore/perl/test.pl @@ -5,6 +5,7 @@ use lib 'lib'; use strict; use warnings; use WWW::SwaggerClient::PetApi; +use WWW::SwaggerClient::StoreApi; use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; use WWW::SwaggerClient::Object::Pet; @@ -45,4 +46,30 @@ print "\nget_pet_by_id:".Dumper $api->get_pet_by_id(pet_id => $pet_id); print "\nupdate_pet_with_form:".Dumper $api->update_pet_with_form(pet_id => $pet_id, name => 'test_name', status => 'test status'); print "\ndelete_pet:".Dumper $api->delete_pet(pet_id => $pet_id); +my $store_api = WWW::SwaggerClient::StoreApi->new(); +print "\nget_inventory:".Dumper $store_api->get_inventory(); +my $pet_json = <deserialize:".Dumper($api->{api_client}->deserialize("HASH[string,Pet]", $pet_json)); diff --git a/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/apigen.neon b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/apigen.neon new file mode 100644 index 00000000000..c067c2c290f --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/apigen.neon @@ -0,0 +1,5 @@ +main: Contrib +title: php-coveralls +internal: yes +todo: yes +wipeout: yes diff --git a/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpcs.xml b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpcs.xml new file mode 100644 index 00000000000..82a58e1b324 --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpcs.xml @@ -0,0 +1,31 @@ + + + The coding standard for standard PHP application + */img/* + */images/* + */less/* + */css/* + */js/* + *.html + *.twig + *.yml + *.xml + *.txt + *.less + *.css + *.js + *.jpg + *.jpeg + *.png + *.gif + + + + + + + + + + + diff --git a/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpmd.xml b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpmd.xml new file mode 100644 index 00000000000..27d3193e749 --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/build/config/phpmd.xml @@ -0,0 +1,45 @@ + + + + My custom rule set that checks my code... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/travis/empty b/samples/client/petstore/php/SwaggerClient/vendor/satooshi/php-coveralls/travis/empty new file mode 100644 index 00000000000..e69de29bb2d From e2d441e862732b2333263ea59126c18be0d32dab Mon Sep 17 00:00:00 2001 From: geekerzp Date: Wed, 10 Jun 2015 11:55:12 +0800 Subject: [PATCH 008/499] support map type response for python client --- .../languages/PythonClientCodegen.java | 4 +-- .../main/resources/python/api_client.mustache | 5 +++ .../SwaggerPetstore/__init__.py | 2 +- .../SwaggerPetstore/api_client.py | 5 +++ .../SwaggerPetstore/apis/__init__.py | 2 +- .../SwaggerPetstore/apis/pet_api.py | 2 +- .../SwaggerPetstore/apis/store_api.py | 4 +-- .../tests/test_api_client.py | 36 +++++++++++++++++++ .../tests/test_store_api.py | 31 ++++++++++++++++ 9 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index 9553f4ad133..632b4289bb7 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -46,7 +46,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.put("long", "int"); typeMapping.put("double", "float"); typeMapping.put("array", "list"); - typeMapping.put("map", "map"); + typeMapping.put("map", "dict"); typeMapping.put("boolean", "bool"); typeMapping.put("string", "str"); typeMapping.put("date", "datetime"); @@ -111,7 +111,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig MapProperty mp = (MapProperty) p; Property inner = mp.getAdditionalProperties(); - return getSwaggerType(p) + "(String, " + getTypeDeclaration(inner) + ")"; + return getSwaggerType(p) + "(str, " + getTypeDeclaration(inner) + ")"; } return super.getTypeDeclaration(p); } diff --git a/modules/swagger-codegen/src/main/resources/python/api_client.mustache b/modules/swagger-codegen/src/main/resources/python/api_client.mustache index b8cc4cc2a84..76ede445992 100644 --- a/modules/swagger-codegen/src/main/resources/python/api_client.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api_client.mustache @@ -168,6 +168,11 @@ class ApiClient(object): sub_class = match.group(1) return [self.deserialize(sub_obj, sub_class) for sub_obj in obj] + if 'dict(' in obj_class: + match = re.match('dict\((.*), (.*)\)', obj_class) + sub_class = match.group(2) + return {k: self.deserialize(v, sub_class) for k, v in iteritems(obj)} + if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime']: obj_class = eval(obj_class) else: # not a native type, must be model class diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py index 30e93608274..3e7b51b8467 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py @@ -9,8 +9,8 @@ from .models.order import Order # import apis into sdk package from .apis.user_api import UserApi -from .apis.store_api import StoreApi from .apis.pet_api import PetApi +from .apis.store_api import StoreApi # import ApiClient from .api_client import ApiClient diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py index b8cc4cc2a84..76ede445992 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py @@ -168,6 +168,11 @@ class ApiClient(object): sub_class = match.group(1) return [self.deserialize(sub_obj, sub_class) for sub_obj in obj] + if 'dict(' in obj_class: + match = re.match('dict\((.*), (.*)\)', obj_class) + sub_class = match.group(2) + return {k: self.deserialize(v, sub_class) for k, v in iteritems(obj)} + if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime']: obj_class = eval(obj_class) else: # not a native type, must be model class diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py index 67ab226c734..128b25dad82 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py @@ -2,6 +2,6 @@ from __future__ import absolute_import # import apis into api package from .user_api import UserApi -from .store_api import StoreApi from .pet_api import PetApi +from .store_api import StoreApi diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py index 19f11fea66b..5f5c2fe81fa 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py @@ -298,7 +298,7 @@ class PetApi(object): header_params['Content-Type'] = self.api_client.select_header_content_type([]) # Authentication setting - auth_settings = ['petstore_auth', 'api_key'] + auth_settings = ['api_key', 'petstore_auth'] response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py index 1523e3b4be4..1e024cfbb5b 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py @@ -47,7 +47,7 @@ class StoreApi(object): Returns a map of status codes to quantities - :return: map(String, int) + :return: dict(str, int) """ all_params = [] @@ -86,7 +86,7 @@ class StoreApi(object): response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, - response='map(String, int)', auth_settings=auth_settings) + response='dict(str, int)', auth_settings=auth_settings) return response diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py index 0ef4314d0f4..720cc2f5329 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py @@ -88,3 +88,39 @@ class ApiClientTests(unittest.TestCase): content_types = [] content_type = self.api_client.select_header_content_type(content_types) self.assertEqual(content_type, 'application/json') + + def test_deserialize_to_dict(self): + # dict(str, Pet) + json = { + 'pet': { + "id": 0, + "category": { + "id": 0, + "name": "string" + }, + "name": "doggie", + "photoUrls": [ + "string" + ], + "tags": [ + { + "id": 0, + "name": "string" + } + ], + "status": "available" + } + } + + data = self.api_client.deserialize(json, 'dict(str, Pet)') + self.assertTrue(isinstance(data, dict)) + self.assertTrue(isinstance(data['pet'], SwaggerPetstore.Pet)) + + # dict(str, int) + json = { + 'integer': 1 + } + + data = self.api_client.deserialize(json, 'dict(str, int)') + self.assertTrue(isinstance(data, dict)) + self.assertTrue(isinstance(data['integer'], int)) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py new file mode 100644 index 00000000000..740e2bdc8ad --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py @@ -0,0 +1,31 @@ +# coding: utf-8 + +""" +Run the tests. +$ pip install nose (optional) +$ cd SwaggerPetstore-python +$ nosetests -v +""" + +import os +import time +import unittest + +import SwaggerPetstore +from SwaggerPetstore.rest import ApiException + + +class StoreApiTests(unittest.TestCase): + + def setUp(self): + self.store_api = SwaggerPetstore.StoreApi() + + def tearDown(self): + # sleep 1 sec between two every 2 tests + time.sleep(1) + + def test_get_inventory(self): + data = self.store_api.get_inventory() + self.assertIsNotNone(data) + self.assertTrue(isinstance(data, dict)) + self.assertItemsEqual(data.keys(), ['available', 'string', 'sold', 'pending', 'confused', 'active', 'na']) From 4982784d7cb60b02391ee6b74054f5ba20f6119c Mon Sep 17 00:00:00 2001 From: wing328 Date: Wed, 10 Jun 2015 15:57:07 +0800 Subject: [PATCH 009/499] upgrade restsharp to 105.1.0 --- .../src/main/resources/csharp/RestSharp.dll | Bin 150016 -> 167936 bytes .../client/petstore/csharp/bin/RestSharp.dll | Bin 150016 -> 167936 bytes .../src/main/csharp/io/swagger/Api/PetApi.cs | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll b/modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll index c1da1b588cd958eec6ceeb4d5be40b3c0c65b17e..a7331ed6e2379bbb0b9680ff82d86ce4cb1b03bc 100644 GIT binary patch literal 167936 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 z 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%0DIhxI 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≠0S1>^uhm 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 z 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%0DIhxI zy5(pUj${|bhNXql!N(yQ!2YXMiBSbw;M^yCLaB&}MQJlXRR^?}WXKx>DI8{HE7(If zSUuzvSAQfXB$q9##$mQh>0Jcd1a!78A_8GHV%3rgYs9v$fy5TD1fzQfYte^2JOa^3 zF`QHOd1g)laR3VXQ0cD_rlJGih?{9*!3bIm{$`6l*St07nj5{hgg%=kqyV&oKoh?1 z@tjVJq6zSp;ui^oCdF6*0u}6V@(&C>-Lu)R#C0?QNUECXL)vaxi)^;tvNd4axFV>< zVcURAYfXg(6XdR}?#i3m_z~02yX5MzY=~0TIEoV1E`g=Ic16E-g~;QPNP?2A$%;@- zUhe}?%1g>lulsC@Nj>j5#VQ*yhzgYz*sFk;qiK|MBxe83N=l|q!%>YGpZRp6vI$Q@ zOQ)+Xc?!O$S@B)F27_1tL3?~L87<&8aK;sh(&&cCsG?Y^kkOq|g;beIgIb7|F32uf=2h_r13Md-j|)hhh@3d$W5*g?(nbh>^sK%77mEur)~}EJ8&v z!HVKEa)Hqcl{l_q=ORgc0~y!irE#o9Oe_dj85@ZC3O>mdRyYXQ#8p&(6NHFTLr}O{ z42r`uixy!OiwxY7Ett&C$}F;h+CCn~HcAw=QNl@#c4kbC%G&*c_1~;=Vjn8Z9?KpZ zqr>(xGZl{kWR~MTn6@0+dSnh0gDz5sB7&3pW;AxelkmmU?Z6FHH>**MjMBEF!4Cp~bEs@kp z6F^)^ykl68tC2#NXc~w+%W8ye+Okdw+JGE4G8C!aUBq7PAB4f{==CU=i|Shr@zn{u zFrH7EMdQ4|*qOe!q;>S?NbwFFm_MbFch#K#nj7Crc+zZPC-@km-zapG}Y#$f8%kt}}??v*onPOFkOd()^I zi~Lc-`AKg%Vyk<5e2j`-nSf1^WeR(S_ zNJ%7~YDTw-$fZ8s5}ZV2>TRGulLEh7x~#WhTw3qAu?cstIxbKB_q1(0VKh_t{Y1$# z$D@^E6tE~!pi+PN?-#T`tw`!*Ph>kP3Cc`;1R<_6Ymy9O zD=n5gT^Wz-_$$^nsW7G3b4gNxcLlEswJObclqURPy5!$b46-0np#Yylh#F7NOPX|M z;oI%r9_h(WrEM)38B@r1uF91z=;;}NfbUc=9*>|v$bto7%a~I#5auV2flXm-__iy! z6ov{jNw7{nCu}JiBdK?4I-LNtO(fAEM62;AG<{}YNlj_58jb6;lOe_nhG4@^fhCD61nJS#Lf&8ezvoW%GX!Q1F(unGh;%q10^GsOOrk?B;* zhZ=hCWW7^a?}x1v_9szB2t6i+hv0y^Me zbM>K~XHx>yty zP0klh&Ko&;9~wE%XC!(bdP}tsFrh7AixZ~XNEG?&M8U=W@)gAwY)tLYnsgEn-7o$I znrvR+yXWy-yBD*-S&wMZ7?~qbm5~6?IzuD7Jn6Y!_x1|-4$!FrdmGZ z!}rNbAJ5xXiqB;syoU6J*E48_?3{M5AXS>k2Eog566c^@)@eCFhHp^L_QDlxi*%H5d9dN{Q8mL&{UJc4!_cK1VMpKc=AL z6j17&!)h8zI#~L-f-wUWr77}@#VES-F{eQXp|IGmTrphf_$@LLBHHYIn)N=0vWV>p1XjKh)3w|+AZfWAAc7(0{!5Ov|HN;wNQ^da zzrY;>ODhMMB%~vtI-cpu6l|&TMZsqDWGR+ja^y0e{S)7RW74}4rv16lHT7ub{BZ_xh!^8EX8SjOKo}B zYE{N!jECYdiT-79Hb+Uzwu)4b$<6nO$7DT~=$)=aNxhC6qp%|pN9d9$vOC<8P|2WM zBVkLGw9@egd%H?fnTki`AZkdvrrC1E1R?Sfgq|2%EowzZa`sA`&2hNMsG!cit*WED z3Y4@H4=FTGXG{p6Rr;kO%{jf7yCKYXtH3JDg6o&G5Lpe%g31RC2jxhvS=xLz0t4z< zzT3GgpLXubr*Bl4)T@k%mvf+1Fp%ByX?=V^&T)UV#vq9|L*GGuO#y9C@&!QIh~Yn$ zJF}ErZ+SlpmumT@b-JnhWVXG|Uc&UJqHESC5MoQ zqs9qC%PQ+SZP(`&m?qTO>i(PfYbi^-U7`0r8z_L25B^>=kQ}8f0Sw0g*e=9o66xO- z(Kr6oyN}sGt_C<>E5%U_ld+MDBsLWKWyCD9y7r`s|LN~$TOS+4ml)evkOo#DQ_zHr ziz|uMk};6#Pmwa4kM6@Ah`rDd(-sDkFYJ3--w4S|-)D}z#Jf>TCE`J<_c*%kr*h{& zKISNBK)_ve}Q7o)dYEOomKI=Md4uo_E-B|t!^sL(N%X%x--UeS|*IVTTu}Lr#>^{NA8jckxXm*B%)s$#h zrX_dN(J)Me%sRE#0Of#Nv)-)ozIZ7gpvds0oKE?29clm~Z;Kztm=K5bme{1n&=->G6?Amo#0~aG-PJ1J6BssI%kQefxNo`mLQloDQ$AJ$Quo1M|SzOc<=`e_eg&Pv0GC#n(=L z2kp?gW8J!YX6{(WYmYTOCO8%b@$KvGT8qoUV*n7K$S8}sOw9dUp{8@ub>HS|mH95i z{u_+>CL`XF?aoQ=M>LCvlf%k1EbeE0LdeQOtZ3$T9v`zrcRUK_&y ziKQ4V(7GWAx=XQhcNhM7SK#O1(O?HJk9d>^5%pqMe|^J~ z+#lj0!H2EokE;Lmzv=TXArHdor@ZqvT>GhV9ju6#ZR8dLbq|l<{S*4>tps}XQ|~j- z&&oi(=8A_U{WWU+2hpv?A65fBY6DJ#NBFLWbdiBWKDbx@&hl_7G~mUw9m@4UyI!&3 z&oZM-fTq_d=>Pcojpy)5$)PuQKKjSRuj-g&8sW(5MkAi#oB!1YZ+D2duKW<(; ztWUeE;RU?oVYu(3^ws0egFZ_?fwmSZNx85FcU}#oXkFyp!*sHd{cny8^ zq5wS#d%)(SS6b?!OFb8c8oowZCwTV@=%JUBJ;&q4{$hd-4{~Z{@8O{YrR)Whylh1H zK3t5UM@ltv$s6UnFRn$O0p3n0A8mn0YxPot;dQ)v&Z2F?xJ&z7N#UjRE!WZ?a@A{- j^wKdssQ!2N^L2rA{_}RkgTXz{FWx0mj3H||b7HuJu=gCCoD z)EQ?sde_&3x7AO6d+(_yuUi*v=so51-ulLMy=SiL-T$z+_P#wh?eu|c)|(SXefR-} zad4Yu%(&#uhwIc{G|ZXlHrFurH4Vd2=!}y=_kteBler@elKJL8{WKl`NEZCFj3w_j zjLGu9^$eYg#n^h1X}pE>xM@5?K}`I2gK1=dtpwk+iGKge-D?;qLGzyr_tK`zFa|c9 ze(nai=j?;b!cWQ?=3BD?K53xdsGkZz@`gN0LHCa{E-{QH1NGC_24G}f4dmG%%hDbA z_N901ALWXF%$sQ>j5}U6jJwvg8Eu08_dmy&ez#$Grag*yZPOY>M0Ry z)Sw3pWkj8yXB%hX2{dO1KQIkv3^icaa-G{9)Th&!3dV6lg8SgB)Ry?uf!6V}-W*}% z<_J^rX8;XK`0;!3vTxPW z^?eXQ18VARLMf0PySxBtkqBN!JmneYNP_4rcnbjl%Blb%03Zzo2mt^(p#UKOq%<2mq*K6^9T2vKkNqK)VKn05C}dLI6OkP;m$WAg2K#0CZ?T2mpBv2qE=n z8oS{M`R5vgkY+kr2#_ZS4gbnU=o`V9&7w z)Su%h{V!(L&&QNlzITYPTY3Kn;*N_0Qde@g6Xk#|=NjKfYH3svD%A-- z&7{qsi}Ys{4W)B}uPPeqrh13BIQ2KGF}7_RvHfe;&wk*$k$kA1Q8ci;@?b!71?d55`X|ryTVa zXubg=@yZ42(p1##;iiEe&d6DI@F-d^1?_oGY3~4<=cSWf11YDF41A(?@I!EHMutpb z3!o}qw(&QlkhiViYw#R{s;Itd2&n3-2np^ZsY*~mpuAi0b8b*2naJ6>g!F`X^q?RT zcjH8a4}OIo@YTRq`|h?(&aEcl9Dwurux~`IsPuMgrblRuKauoONH3+*bC8~+(sOp2 zUaFN|3hAX(dS-xD>EykfcK}pGMiQi9?14WB$EX~baDs=ykw~H2{x*nAWg(z%Xy`G4 z`lHa}0_7RP3BD^1r!g0W+hhjRuzWg~J^(Uf{TPsyF?<7la(4Y~s75zEoYCRuTj$49gGcVk2g+8a33wW5+DXIpQ+5wWdd|wUOs8(lA=g> zoP&RswsEiVnDnYpoQZbFd*!?Co{F=rK#_pYM8I%Bc)||JO zDKthw>Zv8a0kj6ApoKmVBaQrvs_~$y@^CN$)cPjsbW_XU)70{!*7JmsZ9^bPuYL`O zFldYCnE{5Eu!WSJ`pxhtUIwEvW{M6 zeI-$U3Xi-E-R)L6baQSYB{I7)=N3~U7f_LGB04CiSG#Rndq;A60fWv|RY9tOq1`3e z2eiS%G_EyPzGk#j;4{=<4;w()EY>JGBbx)eJTb8Q$gopB(ysp!c`})2rx;oht3zK? zq-^a}!19aICZpE_mCLrhhmXo_EUB4R&_7-bxWtH%6FDxu zucpJ24bYD^6WW%6PBT~9-Z&B%YGd@RcskbTQG9^MGN4iHj9^yi9HCz#KgtPsty3 zv5NF3v3`TqfYX)sWbiifSxx{cdr383{c4++tU5{68H$dZC{oW%W?k8VKAuqhoE4nO zcnX@F{zW{;s7Qrmxh@N%Su%WVqaaXbi@Fb=!4pp+bE~XvgMo8&E zz6=Y@#z1dJ#}Ta?rcpEwTBXK%&Kc$*KY8TG+>Bg>_F{naJ*Pf}g;@_8=H)!oDLcvf zY(gl4YRkJIY$wC^dDUL0z6(74Iy`HWocbP3hh4D?QTNO_{~uLJ*S;Qv@#ptvZc&F@i8sOqoml*Ci!V&l#JJQApN5(9JrH zi@-QeNN^uEU1e;B=0FGRG%%`qxfbLw%zKpr^eSd_ZHt0(o^OE&9 zCX4kzp566^Jg3ypk!MdG%VO{!->VrY;}+@{5Oj<6_sFxm{(gB*sb3?{p8ECj9AAt; zJ(scRcwWwnylJKAv4Cz_hmaw{~B->(v^O6 zc()?vF$O9K8C(mm;KTgcf}iW8`*+aAKfTR!t4_-Q2+-%9#z*lehjx@_ELo<;tO5Tz z;66Gt%DjzZpwY{^@>c<(8h=c}vHe17?6=@I224$akf*6*luQyMk~_9osNj0|t8qyD zkeTPg@#d8JtH{3TyJ$SMlv(QA-p05!GI6$tX(phVo`Hd z|7K*U)}fdz#YzavF{gkz!i2Kh#t8C+2ADG&e}yjuu#Ya?g>b9+AtAwKewc=h@-qDT zow0p2@4Lu*3nf8Fa6b)6IAi;1mW#-;fGmUrmpLh{B9O4;k_Bdc$=Ov!~S64`sctY zLu?fYxk`s`Z>zKwvZ4Q%n*NiNfA1ID3`1Bj>rHASr3S;Nnyh~l+?6&rL`|-&d7&d5 zsi+60aRSPUF0E-3(f&|sa0G;uw)~^;@Hg@2Z2YvmGPZxNMzhW2b%Lo_S_5XmvOE0? zz+WCfmz)UcvRS}t=qO>z{d33*dedCHElYCMr1Ybc!NQ~`Tfl{|O0FKds5CG6=sUSiCSgrvf z0Ibk}5CG7#sUSjVs}UX;4wQ!w09I;12mnx0#UTU$^w|m!0>FtH5CXtS8V~{idM6b` z2mq&OKnMV*YCs48r)fY402t9#96|tCtpOnbptDpQLI5~J13~~eQv*T(Sfc?UV5fA- z+GttXQrn^2yRa|vw?a+rT2j`MCyRORcs^`*CvBqn`%ip(_Z*1W~rc1V>9uaNLD(!6o>~!7)K*Kw2`x`lJ#X`b-g;<0_$n>vn{nAT*%& zGU^Y7QB#6SX7Fjr433t}q;5m~DK=&GBtrg&vicraF){3C|0ue&Gg*l){W~euVQQ?W z+LQ$6cqAZUH z3!xT^Bg=rY21VOMwt%x^i6=}{znyO$@sVFiB zGwe;M?8^Gb0`Ni8az)SbC!s31gHgl|MiyIC6iJE$r*~p&3*)CwHHoc^!gfBU}hI6(2|~|$?{dC)be_Ou0-lK6N8f>G`C~XBC*C9URYxZP3C{>Q6vSzEo&3n& zs1N`!15$tx$mXLg06aEm4PUgqak?DyJ35(8Kr|K_L(E+ z=7OhNRhnC#?bE+bZ1#JnTq{O_(a0Tw;Sm;g-Otbj>u_c6VnT`AlE@u^rLM`cy}`f+tX@ zDq6Jo1y90N7ESIZg*FLuUm60=i=Zc^K68sA8g=(1AUT z#~5bWYCM{Q%r(9TXq=GXKBQXlJJ_=%gYUyDpBlaz`R+*hKY$BoTAslp>jpohALh8G z--B3uEP6Y+WNlIogT;3^SfCl==u0l?=Mfht?KP{j(w=iim>(PmW2tx;r@Al|JP*3s zn+h;md0R08w24moXr|ayN(C4pyuy~OYndsW)|rKrI)fL1Ax~)1-lCJcDX z2Fv>|;R%HS^)e{Q0~Rka)8TZ;10!aQ#aTW$gmeK08RLw&*DDSy2 zF#Ew6I(wsjdDBfPc_pw!qBxK^<+bP>R@|JNv+)!}PGy1Y!p(cfbZrTyLa+&ivOLDP z?58q>Ngwem6lfvjr1kK(h!=uVg>vdkVVFl_+u9 z+6oy)HPCemjo*V2J`;q14Q^{|SB$&XVQn3aA=NX{y&+=NJ#`^1y22D+LA;p?o4RCR z3w$yYqpT)fo~LL-TJe|{B3Fj%zlu0E(+3P=@uWL+#D5?UJ;8H9oM);UEo!dQ_#?O~ ziLuwnOfE1N;>;Px{}X))Lw=&lr&^-Q+0@o_oH@l^O!mIz)K=(nTclO@t2S5I!Y*W@ zSf?@^dsrOZv3;B$h!CAn1da{JfU&6AJ}_*nwj1`h7-Aq0HRcEb0Hs%e5CBj@1qcCP zTmwSHN2MBbfi$`9@?|{tVA?X!)Y2Wc8fLNJ7mhD~hK$hL{sj*VPW=e0YQIlm)#>V~ zyi6ZQ;T-=q`~-hhAq3!XR!hPl!M2|xV<38>$gmd^_~qcKPBUE@B$FxWo>Tr1P&JxY zvf9s|56~^6Bl=$?RzpYhH#~#C;?wVgg_j@v`4EXlh$f(o&P^wWq()_=c(&VDZ`dt@|DC-cQZzI*t? z@XQr+-COh!n+h@rxNroxDgZO*A;{D(y}OdfVC=YWQ84N91~_&AZ@IL%am{7mz!ZOD+7Z3Gv|EwA4>K zWA;*<&v-JrTDi0usE6-GuyB~4zw=?fN2i^|2*9yKOxQ(yt0uMe z!g%MgOUM#TVg@i_&1L+_AUBgQOp&h)rPMGm6%5Ig=~s~_pMzS+GE-P&2$+)!qYSw? z5aeNS-8__$Le(lbDf^;U-~-j~!JU7b!E7Z28rh z%`6cMGsf{k1_PWbp3-EHlI17?Mwm}V(%DneL6;Zpef@aI=HL(u33Wk{(Kkjz&I&`y zP$6SPEX?C*!(lxKjmKz$Vuj!Z%H{I8T+o5sbM>V%%7zmHx%_tL zaT=4bkv)G3RlLK@P0DrTCTk6wtmIiaHahx9XE+0c2kbNIlIjTaosdgs$iItSozu!g zSFWqt1?#fQ-;Fh20AoQh=DM-c-JR>s6)!(?@0G8=@do-ut`RIiNf)EV+R}SvD&4N? zx=hQFIMRuvvRuN|i5KI`0%8A=H0D%P|G{wum22#cIPqdl7YZB-4t*P&eA@AQAb^Zp zMF*i8xY?hCkeT}dI{t@Qo{{≠0S1>^uhm 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 Date: Wed, 10 Jun 2015 21:18:48 +0800 Subject: [PATCH 010/499] change static method to instance method, update test case to remove php warning --- .../src/main/resources/php/APIClient.mustache | 40 +++++++++---------- .../src/main/resources/php/api.mustache | 2 +- .../php/SwaggerClient-php/lib/APIClient.php | 40 +++++++++---------- .../php/SwaggerClient-php/lib/PetApi.php | 4 +- .../SwaggerClient-php/tests/PetApiTest.php | 26 +++++++----- samples/client/petstore/php/test.php | 4 ++ 6 files changed, 62 insertions(+), 54 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/APIClient.mustache b/modules/swagger-codegen/src/main/resources/php/APIClient.mustache index 6356143f914..b116eee0829 100644 --- a/modules/swagger-codegen/src/main/resources/php/APIClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/APIClient.mustache @@ -25,7 +25,7 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - private static $default_header = array(); + private $default_header = array(); /* * @var string timeout (second) of the HTTP request, by default set to 0, no timeout @@ -58,7 +58,7 @@ class ApiClient { if (!is_string($header_name)) throw new \InvalidArgumentException('Header name must be a string.'); - self::$default_header[$header_name] = $header_value; + $this->default_header[$header_name] = $header_value; } /** @@ -67,7 +67,7 @@ class ApiClient { * @return array default header */ public function getDefaultHeader() { - return self::$default_header; + return $this->default_header; } /** @@ -76,7 +76,7 @@ class ApiClient { * @param string $header_name header name (e.g. Token) */ public function deleteDefaultHeader($header_name) { - unset(self::$default_header[$header_name]); + unset($this->default_header[$header_name]); } /** @@ -182,7 +182,7 @@ class ApiClient { $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); # construct the http header - $headerParams = array_merge((array)self::$default_header, (array)$headerParams); + $headerParams = array_merge((array)$this->default_header, (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -307,8 +307,8 @@ class ApiClient { * @param string $value a string which will be part of the path * @return string the serialized object */ - public static function toPathValue($value) { - return rawurlencode(self::toString($value)); + public function toPathValue($value) { + return rawurlencode($this->toString($value)); } /** @@ -319,11 +319,11 @@ class ApiClient { * @param object $object an object to be serialized to a string * @return string the serialized object */ - public static function toQueryValue($object) { + public function toQueryValue($object) { if (is_array($object)) { return implode(',', $object); } else { - return self::toString($object); + return $this->toString($object); } } @@ -334,8 +334,8 @@ class ApiClient { * @param string $value a string which will be part of the header * @return string the header string */ - public static function toHeaderValue($value) { - return self::toString($value); + public function toHeaderValue($value) { + return $this->toString($value); } /** @@ -345,8 +345,8 @@ class ApiClient { * @param string $value the value of the form parameter * @return string the form string */ - public static function toFormValue($value) { - return self::toString($value); + public function toFormValue($value) { + return $this->toString($value); } /** @@ -356,7 +356,7 @@ class ApiClient { * @param string $value the value of the parameter * @return string the header string */ - public static function toString($value) { + public function toString($value) { if ($value instanceof \DateTime) { // datetime in ISO8601 format return $value->format(\DateTime::ISO8601); } @@ -372,7 +372,7 @@ class ApiClient { * @param string $class class name is passed as a string * @return object an instance of $class */ - public static function deserialize($data, $class) + public function deserialize($data, $class) { if (null === $data) { $deserialized = null; @@ -383,14 +383,14 @@ class ApiClient { $subClass_array = explode(',', $inner, 2); $subClass = $subClass_array[1]; foreach ($data as $key => $value) { - $deserialized[$key] = self::deserialize($value, $subClass); + $deserialized[$key] = $this->deserialize($value, $subClass); } } } elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) { $subClass = substr($class, 6, -1); $values = array(); foreach ($data as $key => $value) { - $values[] = self::deserialize($value, $subClass); + $values[] = $this->deserialize($value, $subClass); } $deserialized = $values; } elseif ($class == 'DateTime') { @@ -404,7 +404,7 @@ class ApiClient { foreach ($instance::$swaggerTypes as $property => $type) { $original_property_name = $instance::$attributeMap[$property]; if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = self::deserialize($data->$original_property_name, $type); + $instance->$property = $this->deserialize($data->$original_property_name, $type); } } $deserialized = $instance; @@ -419,7 +419,7 @@ class ApiClient { * @param array[string] $accept Array of header * @return string Accept (e.g. application/json) */ - public static function selectHeaderAccept($accept) { + public function selectHeaderAccept($accept) { if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) { return NULL; } elseif (preg_grep("/application\/json/i", $accept)) { @@ -435,7 +435,7 @@ class ApiClient { * @param array[string] content_type_array Array fo content-type * @return string Content-Type (e.g. application/json) */ - public static function selectHeaderContentType($content_type) { + public function selectHeaderContentType($content_type) { if (count($content_type) === 0 or (count($content_type) === 1 and $content_type[0] === '')) { return 'application/json'; } elseif (preg_grep("/application\/json/i", $content_type)) { diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 12d2eb80744..755d0e70452 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -100,7 +100,7 @@ class {{classname}} { }{{/pathParams}} {{#formParams}}// form params if (${{paramName}} !== null) { - $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->toFormValue(${{paramName}}); + $formParams['{{baseName}}'] = {{#isFile}}'@'.{{/isFile}}$this->apiClient->toFormValue(${{paramName}}); }{{/formParams}} {{#bodyParams}}// body params $_tempBody = null; diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php b/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php index b8357f9b479..280fe9bdd71 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php @@ -25,7 +25,7 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - private static $default_header = array(); + private $default_header = array(); /* * @var string timeout (second) of the HTTP request, by default set to 0, no timeout @@ -58,7 +58,7 @@ class ApiClient { if (!is_string($header_name)) throw new \InvalidArgumentException('Header name must be a string.'); - self::$default_header[$header_name] = $header_value; + $this->default_header[$header_name] = $header_value; } /** @@ -67,7 +67,7 @@ class ApiClient { * @return array default header */ public function getDefaultHeader() { - return self::$default_header; + return $this->default_header; } /** @@ -76,7 +76,7 @@ class ApiClient { * @param string $header_name header name (e.g. Token) */ public function deleteDefaultHeader($header_name) { - unset(self::$default_header[$header_name]); + unset($this->default_header[$header_name]); } /** @@ -187,7 +187,7 @@ class ApiClient { $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); # construct the http header - $headerParams = array_merge((array)self::$default_header, (array)$headerParams); + $headerParams = array_merge((array)$this->default_header, (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -312,8 +312,8 @@ class ApiClient { * @param string $value a string which will be part of the path * @return string the serialized object */ - public static function toPathValue($value) { - return rawurlencode(self::toString($value)); + public function toPathValue($value) { + return rawurlencode($this->toString($value)); } /** @@ -324,11 +324,11 @@ class ApiClient { * @param object $object an object to be serialized to a string * @return string the serialized object */ - public static function toQueryValue($object) { + public function toQueryValue($object) { if (is_array($object)) { return implode(',', $object); } else { - return self::toString($object); + return $this->toString($object); } } @@ -339,8 +339,8 @@ class ApiClient { * @param string $value a string which will be part of the header * @return string the header string */ - public static function toHeaderValue($value) { - return self::toString($value); + public function toHeaderValue($value) { + return $this->toString($value); } /** @@ -350,8 +350,8 @@ class ApiClient { * @param string $value the value of the form parameter * @return string the form string */ - public static function toFormValue($value) { - return self::toString($value); + public function toFormValue($value) { + return $this->toString($value); } /** @@ -361,7 +361,7 @@ class ApiClient { * @param string $value the value of the parameter * @return string the header string */ - public static function toString($value) { + public function toString($value) { if ($value instanceof \DateTime) { // datetime in ISO8601 format return $value->format(\DateTime::ISO8601); } @@ -377,7 +377,7 @@ class ApiClient { * @param string $class class name is passed as a string * @return object an instance of $class */ - public static function deserialize($data, $class) + public function deserialize($data, $class) { if (null === $data) { $deserialized = null; @@ -388,14 +388,14 @@ class ApiClient { $subClass_array = explode(',', $inner, 2); $subClass = $subClass_array[1]; foreach ($data as $key => $value) { - $deserialized[$key] = self::deserialize($value, $subClass); + $deserialized[$key] = $this->deserialize($value, $subClass); } } } elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) { $subClass = substr($class, 6, -1); $values = array(); foreach ($data as $key => $value) { - $values[] = self::deserialize($value, $subClass); + $values[] = $this->deserialize($value, $subClass); } $deserialized = $values; } elseif ($class == 'DateTime') { @@ -409,7 +409,7 @@ class ApiClient { foreach ($instance::$swaggerTypes as $property => $type) { $original_property_name = $instance::$attributeMap[$property]; if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = self::deserialize($data->$original_property_name, $type); + $instance->$property = $this->deserialize($data->$original_property_name, $type); } } $deserialized = $instance; @@ -424,7 +424,7 @@ class ApiClient { * @param array[string] $accept Array of header * @return string Accept (e.g. application/json) */ - public static function selectHeaderAccept($accept) { + public function selectHeaderAccept($accept) { if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) { return NULL; } elseif (preg_grep("/application\/json/i", $accept)) { @@ -440,7 +440,7 @@ class ApiClient { * @param array[string] content_type_array Array fo content-type * @return string Content-Type (e.g. application/json) */ - public static function selectHeaderContentType($content_type) { + public function selectHeaderContentType($content_type) { if (count($content_type) === 0 or (count($content_type) === 1 and $content_type[0] === '')) { return 'application/json'; } elseif (preg_grep("/application\/json/i", $content_type)) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php index 2e1b2aa262e..4d1cba21c3e 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php @@ -327,7 +327,7 @@ class PetApi { } // authentication setting, if any - $authSettings = array('petstore_auth', 'api_key'); + $authSettings = array('api_key', 'petstore_auth'); // make the API Call $response = $this->apiClient->callAPI($resourcePath, $method, @@ -516,7 +516,7 @@ class PetApi { $formParams['additionalMetadata'] = $this->apiClient->toFormValue($additional_metadata); }// form params if ($file !== null) { - $formParams['file'] = '@' . $this->apiClient->toFormValue($file); + $formParams['file'] = '@'.$this->apiClient->toFormValue($file); } diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index 390cf332b23..d463243accc 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -7,6 +7,9 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // add a new pet (id 10005) to ensure the pet object is available for all the tests public static function setUpBeforeClass() { + ini_set('display_errors', 1); + error_reporting(~0); + // enable debugging //SwaggerClient\Configuration::$debug = true; @@ -38,25 +41,26 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testApiClient() { // test selectHeaderAccept - $this->assertSame('application/json', SwaggerClient\ApiClient::selectHeaderAccept(array('application/xml','application/json'))); - $this->assertSame(NULL, SwaggerClient\ApiClient::selectHeaderAccept(array())); - $this->assertSame('application/yaml,application/xml', SwaggerClient\ApiClient::selectHeaderAccept(array('application/yaml','application/xml'))); + $api_client = new SwaggerClient\ApiClient(); + $this->assertSame('application/json', $api_client->selectHeaderAccept(array('application/xml','application/json'))); + $this->assertSame(NULL, $api_client->selectHeaderAccept(array())); + $this->assertSame('application/yaml,application/xml', $api_client->selectHeaderAccept(array('application/yaml','application/xml'))); // test selectHeaderContentType - $this->assertSame('application/json', SwaggerClient\ApiClient::selectHeaderContentType(array('application/xml','application/json'))); - $this->assertSame('application/json', SwaggerClient\ApiClient::selectHeaderContentType(array())); - $this->assertSame('application/yaml,application/xml', SwaggerClient\ApiClient::selectHeaderContentType(array('application/yaml','application/xml'))); + $this->assertSame('application/json', $api_client->selectHeaderContentType(array('application/xml','application/json'))); + $this->assertSame('application/json', $api_client->selectHeaderContentType(array())); + $this->assertSame('application/yaml,application/xml', $api_client->selectHeaderContentType(array('application/yaml','application/xml'))); // test addDefaultHeader and getDefaultHeader - SwaggerClient\ApiClient::addDefaultHeader('test1', 'value1'); - SwaggerClient\ApiClient::addDefaultHeader('test2', 200); - $defaultHeader = SwaggerClient\ApiClient::getDefaultHeader(); + $api_client->addDefaultHeader('test1', 'value1'); + $api_client->addDefaultHeader('test2', 200); + $defaultHeader = $api_client->getDefaultHeader(); $this->assertSame('value1', $defaultHeader['test1']); $this->assertSame(200, $defaultHeader['test2']); // test deleteDefaultHeader - SwaggerClient\ApiClient::deleteDefaultHeader('test2'); - $defaultHeader = SwaggerClient\ApiClient::getDefaultHeader(); + $api_client->deleteDefaultHeader('test2'); + $defaultHeader = $api_client->getDefaultHeader(); $this->assertFalse(isset($defaultHeader['test2'])); $pet_api = new SwaggerClient\PetAPI(); diff --git a/samples/client/petstore/php/test.php b/samples/client/petstore/php/test.php index f39e0dae4cf..8fb2cf9201b 100644 --- a/samples/client/petstore/php/test.php +++ b/samples/client/petstore/php/test.php @@ -2,6 +2,10 @@ //require_once('vendor/autoload.php'); require_once('SwaggerClient-php/SwaggerClient.php'); +// show error reporting +ini_set('display_errors', 1); +error_reporting(~0); + // initialize the API client //$api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); //$api_client->addDefaultHeader("test1", "value1"); From a0c55693dcbfe191f62a944e3bc10feecc6106cd Mon Sep 17 00:00:00 2001 From: wing328 Date: Wed, 10 Jun 2015 21:59:48 +0800 Subject: [PATCH 011/499] add test case for loginUser, separate test cases into different files --- .../SwaggerClient-php/tests/PetApiTest.php | 5 +-- .../SwaggerClient-php/tests/StoreApiTest.php | 32 +++++++++++++++++++ .../SwaggerClient-php/tests/UserApiTest.php | 32 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php create mode 100644 samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index d463243accc..69536879d7d 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -7,8 +7,9 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // add a new pet (id 10005) to ensure the pet object is available for all the tests public static function setUpBeforeClass() { - ini_set('display_errors', 1); - error_reporting(~0); + // for error reporting (need to run with php5.3 to get no warning) + //ini_set('display_errors', 1); + //error_reporting(~0); // enable debugging //SwaggerClient\Configuration::$debug = true; diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php new file mode 100644 index 00000000000..a92149fbaf3 --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php @@ -0,0 +1,32 @@ +getInventory(); + + $this->assertInternalType("int", $get_response['sold']); + $this->assertInternalType("int", $get_response['pending']); + + } + +} + +?> + diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php new file mode 100644 index 00000000000..181e8a1249e --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php @@ -0,0 +1,32 @@ +loginUser("xxxxx", "yyyyyyyy"); + + $this->assertInternalType("string", $response); + $this->assertRegExp("/^logged in user session/", $response, "response string starts with 'logged in user session'"); + + } + +} + +?> + From 7aab1eaffbe3726650968b06400d311ba59a8861 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Wed, 10 Jun 2015 23:53:56 +0800 Subject: [PATCH 012/499] update test.php to put exception test at last --- samples/client/petstore/php/test.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/client/petstore/php/test.php b/samples/client/petstore/php/test.php index 8fb2cf9201b..efb6ccaf8f5 100644 --- a/samples/client/petstore/php/test.php +++ b/samples/client/petstore/php/test.php @@ -3,8 +3,8 @@ require_once('SwaggerClient-php/SwaggerClient.php'); // show error reporting -ini_set('display_errors', 1); -error_reporting(~0); +//ini_set('display_errors', 1); +//error_reporting(~0); // initialize the API client //$api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); @@ -25,9 +25,6 @@ try { $response = $pet_api->getPetById($petId); var_dump($response); - // test upload file (exception) - $upload_response = $pet_api->uploadFile($petId, "test meta", NULL); - // add pet (post json) $new_pet_id = 10005; $new_pet = new SwaggerClient\models\Pet; @@ -49,6 +46,9 @@ try { // add a new pet (model) $add_response = $pet_api->addPet($new_pet); + // test upload file (exception) + $upload_response = $pet_api->uploadFile($petId, "test meta", NULL); + } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; echo 'HTTP response headers: ', $e->getResponseHeaders(), "\n"; From 2fdae91cbcb77946d0c2cf7ab1ac6c4f21e28142 Mon Sep 17 00:00:00 2001 From: wing328 Date: Fri, 12 Jun 2015 16:12:54 +0800 Subject: [PATCH 013/499] fix a typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cace22c92e9..f2c44ebf718 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ Supported config options can be different per language. Running `config-help -l {lang}` will show available options. ``` -java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jarr config-help -l java +java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar config-help -l java ``` Output From e38fc2c3daeb119235b5cf88d5389bd7fc2ae938 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 20:15:48 +0800 Subject: [PATCH 014/499] Deserialize response for "object" type in Ruby client --- .../codegen/languages/RubyClientCodegen.java | 25 ++++--- .../src/main/resources/ruby/api.mustache | 4 +- .../main/resources/ruby/base_object.mustache | 10 +-- .../resources/ruby/swagger/response.mustache | 68 +++++++++++++++---- 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 01fe6c6eed4..2ee227fea29 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -48,12 +48,21 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { languageSpecificPrimitives.add("string"); languageSpecificPrimitives.add("DateTime"); - typeMapping.put("long", "int"); - typeMapping.put("integer", "int"); - typeMapping.put("Array", "array"); - typeMapping.put("String", "string"); - typeMapping.put("List", "array"); - typeMapping.put("map", "map"); + typeMapping.put("string", "String"); + typeMapping.put("char", "String"); + typeMapping.put("int", "Integer"); + typeMapping.put("integer", "Integer"); + typeMapping.put("long", "Integer"); + typeMapping.put("short", "Integer"); + typeMapping.put("float", "Float"); + typeMapping.put("double", "Float"); + typeMapping.put("number", "Float"); + typeMapping.put("DateTime", "DateTime"); + typeMapping.put("boolean", "BOOLEAN"); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Hash"); + typeMapping.put("object", "Hash"); String baseFolder = "lib" + File.separatorChar + gemName; String swaggerFolder = baseFolder + File.separatorChar + "swagger"; @@ -107,11 +116,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { if (p instanceof ArrayProperty) { ArrayProperty ap = (ArrayProperty) p; Property inner = ap.getItems(); - return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + 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 getSwaggerType(p) + ""; } return super.getTypeDeclaration(p); } diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index 3e1ac14014e..2b0f17c63f7 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -51,8 +51,8 @@ module {{moduleName}} {{/bodyParam}} 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 + {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('{{{returnType}}}'){{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil{{/returnType}} end {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache index c0e563a0bb7..2f1e1064a5b 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache @@ -15,7 +15,7 @@ module {{moduleName}} def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) self.class.swagger_types.each_pair do |key, type| - if type =~ /^array\[(.*)\]/i + if type =~ /^Array<(.*)>/i if attributes[self.class.attribute_map[key]].is_a?(Array) self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) else @@ -35,13 +35,13 @@ module {{moduleName}} case type.to_sym when :DateTime DateTime.parse(value) - when :string + when :String value.to_s - when :int + when :Integer value.to_i - when :double + when :Float value.to_f - when :boolean + when :BOOLEAN if value =~ /^(true|t|yes|y|1)$/i true else diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index e7bb482fb66..3abc7df40d7 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -2,6 +2,7 @@ module {{moduleName}} module Swagger class Response require 'json' + require 'date' attr_accessor :raw @@ -9,8 +10,8 @@ module {{moduleName}} self.raw = raw case self.code - when 500..510 then raise(ServerError, self.error_message) - when 299..426 then raise(ClientError, self.error_message) + when 500..510 then raise(ServerError, self.body) + when 299..426 then raise(ClientError, self.body) end end @@ -18,19 +19,58 @@ module {{moduleName}} raw.code end - # Account for error messages that take different forms... - def error_message - body['message'] - rescue - body + def body + raw.body end - # If body is JSON, parse it - # Otherwise return raw string - def body - JSON.parse(raw.body, :symbolize_names => true) - rescue - raw.body + # Deserialize the raw response body to the given return type. + # + # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" + def deserialize(return_type) + return nil if body.blank? + + # ensuring a default content type + content_type = raw.headers_hash['Content-Type'] || 'application/json' + + unless content_type.start_with?('application/json') + fail "Content-Type is not supported: #{content_type}" + end + + begin + data = JSON.parse(body, :symbolize_names => true) + rescue JSON::ParserError => e + if return_type == 'String' + return body + else + raise e + end + end + + build_models data, return_type + end + + # Build model(s) from Hash data for array/hash values of the response. + def build_models(data, return_type) + case return_type + when /\AArray<(.+)>\z/ + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end + when 'String', 'Integer', 'Float', 'BOOLEAN' + # primitives, return directly + data + when 'DateTime' + DateTime.parse data + else + # models + {{moduleName}}.const_get(return_type).new.tap do |model| + model.build_from_hash data + end + end end # `headers_hash` is a Typhoeus-specific extension of Hash, @@ -58,7 +98,7 @@ module {{moduleName}} def pretty_body return unless body.present? case format - when 'json' then JSON.pretty_generate(body).gsub(/\n/, '
') + when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') end end From 4c8c6c3880748ad9bcf3a692ba9c17b18ae93801 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 20:18:50 +0800 Subject: [PATCH 015/499] Rebuild Ruby Petstore sample --- .../src/main/resources/ruby/api.mustache | 2 +- .../petstore/ruby/lib/swagger_client.rb | 2 +- .../ruby/lib/swagger_client/api/pet_api.rb | 30 ++++---- .../ruby/lib/swagger_client/api/store_api.rb | 14 ++-- .../ruby/lib/swagger_client/api/user_api.rb | 18 ++--- .../lib/swagger_client/models/base_object.rb | 10 +-- .../lib/swagger_client/models/category.rb | 4 +- .../ruby/lib/swagger_client/models/order.rb | 10 +-- .../ruby/lib/swagger_client/models/pet.rb | 10 +-- .../ruby/lib/swagger_client/models/tag.rb | 4 +- .../ruby/lib/swagger_client/models/user.rb | 16 ++--- .../lib/swagger_client/swagger/response.rb | 68 +++++++++++++++---- 12 files changed, 114 insertions(+), 74 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index 2b0f17c63f7..531f8710e69 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -11,7 +11,7 @@ module {{moduleName}} # {{notes}} {{#allParams}}{{#required}} # @param {{paramName}} {{description}} {{/required}}{{/allParams}} # @param [Hash] opts the optional parameters -{{#allParams}}{{^required}} # @option opts [{{dataType}}] :{{paramName}} {{description}} +{{#allParams}}{{^required}} # @option opts [{{{dataType}}}] :{{paramName}} {{description}} {{/required}}{{/allParams}} # @return [{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}nil{{/returnType}}] def self.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}opts = {}) {{#allParams}}{{#required}} diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 998658c8b6e..6d239185005 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -16,8 +16,8 @@ require 'swagger_client/models/order' # APIs require 'swagger_client/api/user_api' -require 'swagger_client/api/store_api' require 'swagger_client/api/pet_api' +require 'swagger_client/api/store_api' module SwaggerClient # Initialize the default configuration diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 2ce4fb04ecd..4a421faef86 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -82,8 +82,8 @@ module SwaggerClient # Finds Pets by status # Multiple status values can be provided with comma seperated strings # @param [Hash] opts the optional parameters - # @option opts [array[string]] :status Status values that need to be considered for filter - # @return [array[Pet]] + # @option opts [Array] :status Status values that need to be considered for filter + # @return [Array] def self.find_pets_by_status(opts = {}) @@ -113,15 +113,15 @@ module SwaggerClient auth_names = ['petstore_auth'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Array') end # Finds Pets by tags # Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. # @param [Hash] opts the optional parameters - # @option opts [array[string]] :tags Tags to filter by - # @return [array[Pet]] + # @option opts [Array] :tags Tags to filter by + # @return [Array] def self.find_pets_by_tags(opts = {}) @@ -151,8 +151,8 @@ module SwaggerClient auth_names = ['petstore_auth'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Array') end # Find pet by ID @@ -190,17 +190,17 @@ module SwaggerClient post_body = nil - auth_names = ['petstore_auth', 'api_key'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = Pet.new() and obj.build_from_hash(response) + auth_names = ['api_key', 'petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Pet') end # Updates a pet in the store with form data # # @param pet_id ID of pet that needs to be updated # @param [Hash] opts the optional parameters - # @option opts [string] :name Updated name of the pet - # @option opts [string] :status Updated status of the pet + # @option opts [String] :name Updated name of the pet + # @option opts [String] :status Updated status of the pet # @return [nil] def self.update_pet_with_form(pet_id, opts = {}) @@ -243,7 +243,7 @@ module SwaggerClient # # @param pet_id Pet id to delete # @param [Hash] opts the optional parameters - # @option opts [string] :api_key + # @option opts [String] :api_key # @return [nil] def self.delete_pet(pet_id, opts = {}) @@ -285,7 +285,7 @@ module SwaggerClient # # @param pet_id ID of pet to update # @param [Hash] opts the optional parameters - # @option opts [string] :additional_metadata Additional data to pass to server + # @option opts [String] :additional_metadata Additional data to pass to server # @option opts [file] :file file to upload # @return [nil] def self.upload_file(pet_id, opts = {}) diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb index 010d170945b..a97f981f878 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb @@ -8,7 +8,7 @@ module SwaggerClient # Returns pet inventories by status # Returns a map of status codes to quantities # @param [Hash] opts the optional parameters - # @return [map[string,int]] + # @return [Hash] def self.get_inventory(opts = {}) @@ -37,8 +37,8 @@ module SwaggerClient auth_names = ['api_key'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - response.map {|response| obj = map.new() and obj.build_from_hash(response) } + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Hash') end # Place an order for a pet @@ -74,8 +74,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = Order.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Order') end # Find purchase order by ID @@ -114,8 +114,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = Order.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Order') end # Delete purchase order by ID diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb index a3a57503b01..8337a8b9dd0 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb @@ -45,7 +45,7 @@ module SwaggerClient # Creates list of users with given input array # # @param [Hash] opts the optional parameters - # @option opts [array[User]] :body List of user object + # @option opts [Array] :body List of user object # @return [nil] def self.create_users_with_array_input(opts = {}) @@ -82,7 +82,7 @@ module SwaggerClient # Creates list of users with given input array # # @param [Hash] opts the optional parameters - # @option opts [array[User]] :body List of user object + # @option opts [Array] :body List of user object # @return [nil] def self.create_users_with_list_input(opts = {}) @@ -119,9 +119,9 @@ module SwaggerClient # Logs user into the system # # @param [Hash] opts the optional parameters - # @option opts [string] :username The user name for login - # @option opts [string] :password The password for login in clear text - # @return [string] + # @option opts [String] :username The user name for login + # @option opts [String] :password The password for login in clear text + # @return [String] def self.login_user(opts = {}) @@ -152,8 +152,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = string.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('String') end # Logs out current logged in user session @@ -228,8 +228,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = User.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('User') end # Updated user diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb index 642e4769e55..a14e90350db 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb @@ -15,7 +15,7 @@ module SwaggerClient def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) self.class.swagger_types.each_pair do |key, type| - if type =~ /^array\[(.*)\]/i + if type =~ /^Array<(.*)>/i if attributes[self.class.attribute_map[key]].is_a?(Array) self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) else @@ -35,13 +35,13 @@ module SwaggerClient case type.to_sym when :DateTime DateTime.parse(value) - when :string + when :String value.to_s - when :int + when :Integer value.to_i - when :double + when :Float value.to_f - when :boolean + when :BOOLEAN if value =~ /^(true|t|yes|y|1)$/i true else diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/category.rb b/samples/client/petstore/ruby/lib/swagger_client/models/category.rb index fe195c7ac87..d856563b11d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/category.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/category.rb @@ -18,8 +18,8 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'name' => :'string' + :'id' => :'Integer', + :'name' => :'String' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/order.rb b/samples/client/petstore/ruby/lib/swagger_client/models/order.rb index 3fe0282ed9b..2cd1ff18f5d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/order.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/order.rb @@ -30,12 +30,12 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'pet_id' => :'int', - :'quantity' => :'int', + :'id' => :'Integer', + :'pet_id' => :'Integer', + :'quantity' => :'Integer', :'ship_date' => :'DateTime', - :'status' => :'string', - :'complete' => :'boolean' + :'status' => :'String', + :'complete' => :'BOOLEAN' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb b/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb index 32f95646c72..f1f1d1434f4 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb @@ -30,12 +30,12 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', + :'id' => :'Integer', :'category' => :'Category', - :'name' => :'string', - :'photo_urls' => :'array[string]', - :'tags' => :'array[Tag]', - :'status' => :'string' + :'name' => :'String', + :'photo_urls' => :'Array', + :'tags' => :'Array', + :'status' => :'String' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb b/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb index 9c5cdde1af6..677c828aede 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb @@ -18,8 +18,8 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'name' => :'string' + :'id' => :'Integer', + :'name' => :'String' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/user.rb b/samples/client/petstore/ruby/lib/swagger_client/models/user.rb index 2d723da54c4..ed7a21e167f 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/user.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/user.rb @@ -36,14 +36,14 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'username' => :'string', - :'first_name' => :'string', - :'last_name' => :'string', - :'email' => :'string', - :'password' => :'string', - :'phone' => :'string', - :'user_status' => :'int' + :'id' => :'Integer', + :'username' => :'String', + :'first_name' => :'String', + :'last_name' => :'String', + :'email' => :'String', + :'password' => :'String', + :'phone' => :'String', + :'user_status' => :'Integer' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 538821bea69..212f1fd15ab 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -2,6 +2,7 @@ module SwaggerClient module Swagger class Response require 'json' + require 'date' attr_accessor :raw @@ -9,8 +10,8 @@ module SwaggerClient self.raw = raw case self.code - when 500..510 then raise(ServerError, self.error_message) - when 299..426 then raise(ClientError, self.error_message) + when 500..510 then raise(ServerError, self.body) + when 299..426 then raise(ClientError, self.body) end end @@ -18,19 +19,58 @@ module SwaggerClient raw.code end - # Account for error messages that take different forms... - def error_message - body['message'] - rescue - body + def body + raw.body end - # If body is JSON, parse it - # Otherwise return raw string - def body - JSON.parse(raw.body, :symbolize_names => true) - rescue - raw.body + # Deserialize the raw response body to the given return type. + # + # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" + def deserialize(return_type) + return nil if body.blank? + + # ensuring a default content type + content_type = raw.headers_hash['Content-Type'] || 'application/json' + + unless content_type.start_with?('application/json') + fail "Content-Type is not supported: #{content_type}" + end + + begin + data = JSON.parse(body, :symbolize_names => true) + rescue JSON::ParserError => e + if return_type == 'String' + return body + else + raise e + end + end + + build_models data, return_type + end + + # Build model(s) from Hash data for array/hash values of the response. + def build_models(data, return_type) + case return_type + when /\AArray<(.+)>\z/ + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end + when 'String', 'Integer', 'Float', 'BOOLEAN' + # primitives, return directly + data + when 'DateTime' + DateTime.parse data + else + # models + SwaggerClient.const_get(return_type).new.tap do |model| + model.build_from_hash data + end + end end # `headers_hash` is a Typhoeus-specific extension of Hash, @@ -58,7 +98,7 @@ module SwaggerClient def pretty_body return unless body.present? case format - when 'json' then JSON.pretty_generate(body).gsub(/\n/, '
') + when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') end end From 36f0ed6d0c8fdcd3f773e01fbcca71a148a07588 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 22:44:52 +0800 Subject: [PATCH 016/499] Add test cases for Response#deserialize --- .../petstore/ruby/spec/response_spec.rb | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/samples/client/petstore/ruby/spec/response_spec.rb b/samples/client/petstore/ruby/spec/response_spec.rb index 528b67e1fa7..8d75c6d1fae 100644 --- a/samples/client/petstore/ruby/spec/response_spec.rb +++ b/samples/client/petstore/ruby/spec/response_spec.rb @@ -8,7 +8,6 @@ describe SwaggerClient::Swagger::Response do end before(:each) do - VCR.use_cassette('pet_resource', :record => :new_episodes) do @raw = Typhoeus::Request.get("http://petstore.swagger.io/v2/pet/10002") end @@ -18,8 +17,10 @@ describe SwaggerClient::Swagger::Response do describe "initialization" do it "sets body" do - @response.body.class.should == Hash - @response.body.has_key?(:'name').should == true + @response.body.should be_a(String) + data = JSON.parse(@response.body) + data.should be_a(Hash) + data['id'].should == 10002 end it "sets code" do @@ -30,9 +31,8 @@ describe SwaggerClient::Swagger::Response do @response.headers.class.should == Hash end end - - describe "format" do + describe "format" do it "recognizes json" do @response.format.should == 'json' @response.json?.should == true @@ -47,19 +47,36 @@ describe SwaggerClient::Swagger::Response do @response.format.should == 'xml' @response.xml?.should == true end - end - + describe "prettiness" do - it "has a pretty json body" do @response.pretty_body.should =~ /\{.*\}/ end - + it "has pretty headers" do @response.pretty_headers.should =~ /\{.*\}/ end + end + describe "deserialize" do + it "handles Hash" do + @response.stub(:body) { '{"message": "Hello"}' } + data = @response.deserialize('Hash') + data.should be_a(Hash) + data.should == {:message => 'Hello'} + end + + it "handles Hash" do + json = @response.body + @response.stub(:body) { "{\"pet\": #{json}}" } + data = @response.deserialize('Hash') + data.should be_a(Hash) + data.keys.should == [:pet] + pet = data[:pet] + pet.should be_a(SwaggerClient::Pet) + pet.id.should == 10002 + end end end From 80616b4c2baac0b6a4e45b634c27e0f52bb8518f Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 23:03:17 +0800 Subject: [PATCH 017/499] Add test cases for StoreApi#get_inventory --- samples/client/petstore/ruby/spec/pet_spec.rb | 21 +++++++++++++------ .../client/petstore/ruby/spec/store_spec.rb | 10 +++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/samples/client/petstore/ruby/spec/pet_spec.rb b/samples/client/petstore/ruby/spec/pet_spec.rb index 68858c7b6cd..e05dd726f13 100644 --- a/samples/client/petstore/ruby/spec/pet_spec.rb +++ b/samples/client/petstore/ruby/spec/pet_spec.rb @@ -13,9 +13,14 @@ describe "Pet" do tag2 = SwaggerClient::Tag.new({'id' => 2, 'name'=> 'tag2'}) category1 = SwaggerClient::Category.new({:id => 1, :name => 'category unknown'}) # initalize using both string and symbol key - pet_hash = {:'id' => 10002, :'name' => "RUBY UNIT TESTING", :'status' => "pending", - :'photo_urls' => ["url1", "url2"], :'category' => category1, - :'tags' => [tag1, tag2]} + pet_hash = { + :id => 10002, + :name => "RUBY UNIT TESTING", + :status => "pending", + :photo_urls => ["url1", "url2"], + :category => category1, + :tags => [tag1, tag2] + } pet = SwaggerClient::Pet.new(pet_hash) # test new pet.name.should == "RUBY UNIT TESTING" @@ -48,6 +53,10 @@ describe "Pet" do it "should find pets by status" do pets = SwaggerClient::PetApi.find_pets_by_status(:status => 'available') pets.length.should >= 3 + pets.each do |pet| + pet.should be_a(SwaggerClient::Pet) + pet.status.should == 'available' + end end it "should not find a pet with invalid status" do @@ -57,11 +66,11 @@ describe "Pet" do it "should find a pet by status" do pets = SwaggerClient::PetApi.find_pets_by_status(:status => "available,sold") - pets.map {|pet| - if(pet.status != 'available' && pet.status != 'sold') + pets.each do |pet| + if pet.status != 'available' && pet.status != 'sold' raise "pet status wasn't right" end - } + end end it "should update a pet" do diff --git a/samples/client/petstore/ruby/spec/store_spec.rb b/samples/client/petstore/ruby/spec/store_spec.rb index 1b37400bc5c..3ad09f1ad61 100644 --- a/samples/client/petstore/ruby/spec/store_spec.rb +++ b/samples/client/petstore/ruby/spec/store_spec.rb @@ -10,4 +10,14 @@ describe "Store" do item = SwaggerClient::StoreApi.get_order_by_id(10002) item.id.should == 10002 end + + it "should featch the inventory" do + result = SwaggerClient::StoreApi.get_inventory + result.should be_a(Hash) + result.should_not be_empty + result.each do |k, v| + k.should be_a(Symbol) + v.should be_a(Integer) + end + end end From ff9623fb5c8c7b83f48f4802c7b78d4fbb3c1ada Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 18:58:27 +0800 Subject: [PATCH 018/499] Support pure object response for python client. --- .../io/swagger/codegen/languages/PythonClientCodegen.java | 1 + .../src/main/resources/python/api_client.mustache | 4 +++- .../SwaggerPetstore-python/SwaggerPetstore/api_client.py | 4 +++- .../python/SwaggerPetstore-python/tests/test_api_client.py | 7 +++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index 632b4289bb7..a14fa71f425 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -50,6 +50,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.put("boolean", "bool"); typeMapping.put("string", "str"); typeMapping.put("date", "datetime"); + typeMapping.put("object", "object"); // from https://docs.python.org/release/2.5.4/ref/keywords.html reservedWords = new HashSet( diff --git a/modules/swagger-codegen/src/main/resources/python/api_client.mustache b/modules/swagger-codegen/src/main/resources/python/api_client.mustache index 76ede445992..e493074ba6d 100644 --- a/modules/swagger-codegen/src/main/resources/python/api_client.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api_client.mustache @@ -173,13 +173,15 @@ class ApiClient(object): sub_class = match.group(2) return {k: self.deserialize(v, sub_class) for k, v in iteritems(obj)} - if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime']: + if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime', "object"]: obj_class = eval(obj_class) else: # not a native type, must be model class obj_class = eval('models.' + obj_class) if obj_class in [int, float, dict, list, str, bool]: return obj_class(obj) + elif obj_class == object: + return object() elif obj_class == datetime: return self.__parse_string_to_datetime(obj) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py index 76ede445992..e493074ba6d 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py @@ -173,13 +173,15 @@ class ApiClient(object): sub_class = match.group(2) return {k: self.deserialize(v, sub_class) for k, v in iteritems(obj)} - if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime']: + if obj_class in ['int', 'float', 'dict', 'list', 'str', 'bool', 'datetime', "object"]: obj_class = eval(obj_class) else: # not a native type, must be model class obj_class = eval('models.' + obj_class) if obj_class in [int, float, dict, list, str, bool]: return obj_class(obj) + elif obj_class == object: + return object() elif obj_class == datetime: return self.__parse_string_to_datetime(obj) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py index 720cc2f5329..b318d5ab9ce 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py @@ -124,3 +124,10 @@ class ApiClientTests(unittest.TestCase): data = self.api_client.deserialize(json, 'dict(str, int)') self.assertTrue(isinstance(data, dict)) self.assertTrue(isinstance(data['integer'], int)) + + def test_deserialize_to_object(self): + data = self.api_client.deserialize("", "object") + self.assertTrue(isinstance(data, object)) + + + From 718a9a79ed2573997e2f4a688194bb2291648f41 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 19:05:15 +0800 Subject: [PATCH 019/499] Update test case `test_deserialize_to_object` of python client. --- .../python/SwaggerPetstore-python/tests/test_api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py index b318d5ab9ce..42d838417fd 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py @@ -127,7 +127,7 @@ class ApiClientTests(unittest.TestCase): def test_deserialize_to_object(self): data = self.api_client.deserialize("", "object") - self.assertTrue(isinstance(data, object)) + self.assertTrue(type(data) == object) From 7a560865a0b1ea957d9a56c2830346cd1b12cf31 Mon Sep 17 00:00:00 2001 From: wing328 Date: Sun, 14 Jun 2015 00:59:40 +0800 Subject: [PATCH 020/499] fix jar path in windows --- .../src/main/java/io/swagger/codegen/AbstractGenerator.java | 4 ++-- .../src/main/java/io/swagger/codegen/DefaultGenerator.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java index 54a2f7efae0..ac377153625 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/AbstractGenerator.java @@ -60,10 +60,10 @@ public abstract class AbstractGenerator { throw new RuntimeException("can't load template " + name); } - private String getCPResourcePath(String name) { + public String getCPResourcePath(String name) { if (!"/".equals(File.separator)) { return name.replaceAll(Pattern.quote(File.separator), "/"); } return name; } -} \ No newline at end of file +} diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index a04e517bee5..27e10db125f 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -268,7 +268,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { // continue } if (in == null) { - in = this.getClass().getClassLoader().getResourceAsStream(config.templateDir() + File.separator + support.templateFile); + in = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(config.templateDir() + File.separator + support.templateFile)); } File outputFile = new File(outputFilename); OutputStream out = new FileOutputStream(outputFile, false); From 24b110be9d18d7dd78fc6dd4c98dd6028c5b415d Mon Sep 17 00:00:00 2001 From: wing328 Date: Sun, 14 Jun 2015 01:27:47 +0800 Subject: [PATCH 021/499] show writing file for non-template file --- .../src/main/java/io/swagger/codegen/DefaultGenerator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index 27e10db125f..0ad05b0762b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -273,6 +273,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { File outputFile = new File(outputFilename); OutputStream out = new FileOutputStream(outputFile, false); if (in != null && out != null) { + System.out.println("writing file " + outputFile); IOUtils.copy(in, out); } else { if (in == null) { From e9c1dd78428714bb94f907a7485501aaaa5bd57c Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 12:49:17 +0800 Subject: [PATCH 022/499] Regard bare "object" type as Object, add comments The handling of base "object" type (without definions of "additionalProperties") is similar to Java generator now. --- .../codegen/languages/RubyClientCodegen.java | 2 +- .../resources/ruby/swagger/response.mustache | 27 ++++++++++++------- .../lib/swagger_client/swagger/response.rb | 27 ++++++++++++------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 2ee227fea29..46c0f70a4b6 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -62,7 +62,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("array", "Array"); typeMapping.put("List", "Array"); typeMapping.put("map", "Hash"); - typeMapping.put("object", "Hash"); + typeMapping.put("object", "Object"); String baseFolder = "lib" + File.separatorChar + gemName; String swaggerFolder = baseFolder + File.separatorChar + "swagger"; diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index 3abc7df40d7..717ce49c3d5 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -49,24 +49,31 @@ module {{moduleName}} build_models data, return_type end - # Build model(s) from Hash data for array/hash values of the response. + # Walk through the given data and, when necessary, build model(s) from + # Hash data for array/hash values of the response. def build_models(data, return_type) case return_type - when /\AArray<(.+)>\z/ - sub_type = $1 - data.map {|item| build_models(item, sub_type) } - when /\AHash\\z/ - sub_type = $1 - {}.tap do |hash| - data.each {|k, v| hash[k] = build_models(v, sub_type) } - end when 'String', 'Integer', 'Float', 'BOOLEAN' # primitives, return directly data when 'DateTime' + # parse date time (expecting ISO 8601 format) DateTime.parse data + when 'Object' + # generic object, return directly + data + when /\AArray<(.+)>\z/ + # e.g. Array + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + # e.g. Hash + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end else - # models + # models, e.g. Pet {{moduleName}}.const_get(return_type).new.tap do |model| model.build_from_hash data end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 212f1fd15ab..53b60205a75 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -49,24 +49,31 @@ module SwaggerClient build_models data, return_type end - # Build model(s) from Hash data for array/hash values of the response. + # Walk through the given data and, when necessary, build model(s) from + # Hash data for array/hash values of the response. def build_models(data, return_type) case return_type - when /\AArray<(.+)>\z/ - sub_type = $1 - data.map {|item| build_models(item, sub_type) } - when /\AHash\\z/ - sub_type = $1 - {}.tap do |hash| - data.each {|k, v| hash[k] = build_models(v, sub_type) } - end when 'String', 'Integer', 'Float', 'BOOLEAN' # primitives, return directly data when 'DateTime' + # parse date time (expecting ISO 8601 format) DateTime.parse data + when 'Object' + # generic object, return directly + data + when /\AArray<(.+)>\z/ + # e.g. Array + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + # e.g. Hash + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end else - # models + # models, e.g. Pet SwaggerClient.const_get(return_type).new.tap do |model| model.build_from_hash data end From 839f0971f0c9573757034b4de5ca3004d34fb056 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 15 Jun 2015 15:50:40 +0800 Subject: [PATCH 023/499] rename php ApiClient --- .../main/resources/php/{APIClient.mustache => ApiClient.mustache} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/swagger-codegen/src/main/resources/php/{APIClient.mustache => ApiClient.mustache} (100%) diff --git a/modules/swagger-codegen/src/main/resources/php/APIClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache similarity index 100% rename from modules/swagger-codegen/src/main/resources/php/APIClient.mustache rename to modules/swagger-codegen/src/main/resources/php/ApiClient.mustache From 9d5928551bdcf49c62215a4285a0d1ce6553ff8f Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 16:38:08 +0800 Subject: [PATCH 024/499] Unify ClientError and ServerError into ApiError in Ruby generator --- .../codegen/languages/RubyClientCodegen.java | 1 + .../src/main/resources/ruby/swagger.mustache | 8 +----- .../resources/ruby/swagger/api_error.mustache | 26 +++++++++++++++++++ .../resources/ruby/swagger/response.mustache | 8 +++--- .../resources/ruby/swagger_client.mustache | 1 + .../petstore/ruby/lib/swagger_client.rb | 1 + .../ruby/lib/swagger_client/swagger.rb | 8 +----- .../lib/swagger_client/swagger/api_error.rb | 26 +++++++++++++++++++ .../lib/swagger_client/swagger/response.rb | 8 +++--- 9 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache create mode 100644 samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 46c0f70a4b6..41d9f494a7c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -73,6 +73,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.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 + "api_error.mustache", swaggerFolder, "api_error.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")); diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index dd2f630a8c9..239e3cfac26 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -52,7 +52,7 @@ module {{moduleName}} return if Swagger.authenticated? if Swagger.configuration.username.blank? || Swagger.configuration.password.blank? - raise ClientError, "Username and password are required to authenticate." + raise ApiError, "Username and password are required to authenticate." end request = Swagger::Request.new( @@ -69,10 +69,4 @@ module {{moduleName}} end end end - - class ServerError < StandardError - end - - class ClientError < StandardError - end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache new file mode 100644 index 00000000000..552161238a0 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache @@ -0,0 +1,26 @@ +module {{moduleName}} + module Swagger + class ApiError < StandardError + attr_reader :code, :response_headers, :response_body + + # Usage examples: + # ApiError.new + # ApiError.new("message") + # ApiError.new(:code => 500, :response_headers => {}, :response_body => "") + # ApiError.new(:code => 404, :message => "Not Found") + def initialize(arg = nil) + if arg.is_a? Hash + arg.each do |k, v| + if k.to_s == 'message' + super v + else + instance_variable_set "@#{k}", v + end + end + else + super arg + end + end + end + end +end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index 717ce49c3d5..b621110935a 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -9,9 +9,11 @@ module {{moduleName}} def initialize(raw) self.raw = raw - case self.code - when 500..510 then raise(ServerError, self.body) - when 299..426 then raise(ClientError, self.body) + unless raw.success? + fail ApiError.new(:code => code, + :response_headers => headers, + :response_body => body), + raw.status_message end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache index df675ddf26e..69454179283 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache @@ -2,6 +2,7 @@ require '{{gemName}}/monkey' require '{{gemName}}/swagger' require '{{gemName}}/swagger/configuration' +require '{{gemName}}/swagger/api_error' require '{{gemName}}/swagger/request' require '{{gemName}}/swagger/response' require '{{gemName}}/swagger/version' diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 6d239185005..42380927f82 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -2,6 +2,7 @@ require 'swagger_client/monkey' require 'swagger_client/swagger' require 'swagger_client/swagger/configuration' +require 'swagger_client/swagger/api_error' require 'swagger_client/swagger/request' require 'swagger_client/swagger/response' require 'swagger_client/swagger/version' diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index 2e2632c169d..477ec89ba81 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -52,7 +52,7 @@ module SwaggerClient return if Swagger.authenticated? if Swagger.configuration.username.blank? || Swagger.configuration.password.blank? - raise ClientError, "Username and password are required to authenticate." + raise ApiError, "Username and password are required to authenticate." end request = Swagger::Request.new( @@ -69,10 +69,4 @@ module SwaggerClient end end end - - class ServerError < StandardError - end - - class ClientError < StandardError - end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb new file mode 100644 index 00000000000..12319927ace --- /dev/null +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb @@ -0,0 +1,26 @@ +module SwaggerClient + module Swagger + class ApiError < StandardError + attr_reader :code, :response_headers, :response_body + + # Usage examples: + # ApiError.new + # ApiError.new("message") + # ApiError.new(:code => 500, :response_headers => {}, :response_body => "") + # ApiError.new(:code => 404, :message => "Not Found") + def initialize(arg = nil) + if arg.is_a? Hash + arg.each do |k, v| + if k.to_s == 'message' + super v + else + instance_variable_set "@#{k}", v + end + end + else + super arg + end + end + end + end +end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 53b60205a75..f560006de6d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -9,9 +9,11 @@ module SwaggerClient def initialize(raw) self.raw = raw - case self.code - when 500..510 then raise(ServerError, self.body) - when 299..426 then raise(ClientError, self.body) + unless raw.success? + fail ApiError.new(:code => code, + :response_headers => headers, + :response_body => body), + raw.status_message end end From ec8e5179cbc487f3895ac6e79738cb707a779503 Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 16:46:30 +0800 Subject: [PATCH 025/499] Remove unused comments --- .../src/main/resources/ruby/monkey.mustache | 152 +++++++++--------- .../ruby/lib/swagger_client/monkey.rb | 152 +++++++++--------- 2 files changed, 144 insertions(+), 160 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache index 28932890af9..0751d42ce63 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache @@ -1,90 +1,82 @@ -# module Swagger - class Object - - unless Object.method_defined? :blank? - def blank? - respond_to?(:empty?) ? empty? : !self - end +class Object + unless Object.method_defined? :blank? + def blank? + respond_to?(:empty?) ? empty? : !self end - - unless Object.method_defined? :present? - def present? - !blank? - end - end - end - class String - - unless String.method_defined? :underscore - def underscore - self.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end - - unless String.method_defined? :camelize - def camelize(first_letter_in_uppercase = true) - if first_letter_in_uppercase != :lower - self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } - else - self.to_s[0].chr.downcase + camelize(self)[1..-1] - end - end + unless Object.method_defined? :present? + def present? + !blank? end + end +end +class String + unless String.method_defined? :underscore + def underscore + self.gsub(/::/, '/'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end end - class Hash - - unless Hash.method_defined? :stringify_keys - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end + unless String.method_defined? :camelize + def camelize(first_letter_in_uppercase = true) + if first_letter_in_uppercase != :lower + self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } + else + self.to_s[0].chr.downcase + camelize(self)[1..-1] end end - - unless Hash.method_defined? :stringify_keys! - def stringify_keys! - self.replace(self.stringify_keys) - end - end - - unless Hash.method_defined? :symbolize_keys - def symbolize_keys - inject({}) do |options, (key, value)| - options[(key.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_keys! - def symbolize_keys! - self.replace(self.symbolize_keys) - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys - def symbolize_and_underscore_keys - inject({}) do |options, (key, value)| - options[(key.to_s.underscore.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys! - def symbolize_and_underscore_keys! - self.replace(self.symbolize_and_underscore_keys) - end - end - end -# end \ No newline at end of file +end + +class Hash + unless Hash.method_defined? :stringify_keys + def stringify_keys + inject({}) do |options, (key, value)| + options[key.to_s] = value + options + end + end + end + + unless Hash.method_defined? :stringify_keys! + def stringify_keys! + self.replace(self.stringify_keys) + end + end + + unless Hash.method_defined? :symbolize_keys + def symbolize_keys + inject({}) do |options, (key, value)| + options[(key.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_keys! + def symbolize_keys! + self.replace(self.symbolize_keys) + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys + def symbolize_and_underscore_keys + inject({}) do |options, (key, value)| + options[(key.to_s.underscore.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys! + def symbolize_and_underscore_keys! + self.replace(self.symbolize_and_underscore_keys) + end + end +end diff --git a/samples/client/petstore/ruby/lib/swagger_client/monkey.rb b/samples/client/petstore/ruby/lib/swagger_client/monkey.rb index 28932890af9..0751d42ce63 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/monkey.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/monkey.rb @@ -1,90 +1,82 @@ -# module Swagger - class Object - - unless Object.method_defined? :blank? - def blank? - respond_to?(:empty?) ? empty? : !self - end +class Object + unless Object.method_defined? :blank? + def blank? + respond_to?(:empty?) ? empty? : !self end - - unless Object.method_defined? :present? - def present? - !blank? - end - end - end - class String - - unless String.method_defined? :underscore - def underscore - self.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end - - unless String.method_defined? :camelize - def camelize(first_letter_in_uppercase = true) - if first_letter_in_uppercase != :lower - self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } - else - self.to_s[0].chr.downcase + camelize(self)[1..-1] - end - end + unless Object.method_defined? :present? + def present? + !blank? end + end +end +class String + unless String.method_defined? :underscore + def underscore + self.gsub(/::/, '/'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end end - class Hash - - unless Hash.method_defined? :stringify_keys - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end + unless String.method_defined? :camelize + def camelize(first_letter_in_uppercase = true) + if first_letter_in_uppercase != :lower + self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } + else + self.to_s[0].chr.downcase + camelize(self)[1..-1] end end - - unless Hash.method_defined? :stringify_keys! - def stringify_keys! - self.replace(self.stringify_keys) - end - end - - unless Hash.method_defined? :symbolize_keys - def symbolize_keys - inject({}) do |options, (key, value)| - options[(key.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_keys! - def symbolize_keys! - self.replace(self.symbolize_keys) - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys - def symbolize_and_underscore_keys - inject({}) do |options, (key, value)| - options[(key.to_s.underscore.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys! - def symbolize_and_underscore_keys! - self.replace(self.symbolize_and_underscore_keys) - end - end - end -# end \ No newline at end of file +end + +class Hash + unless Hash.method_defined? :stringify_keys + def stringify_keys + inject({}) do |options, (key, value)| + options[key.to_s] = value + options + end + end + end + + unless Hash.method_defined? :stringify_keys! + def stringify_keys! + self.replace(self.stringify_keys) + end + end + + unless Hash.method_defined? :symbolize_keys + def symbolize_keys + inject({}) do |options, (key, value)| + options[(key.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_keys! + def symbolize_keys! + self.replace(self.symbolize_keys) + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys + def symbolize_and_underscore_keys + inject({}) do |options, (key, value)| + options[(key.to_s.underscore.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys! + def symbolize_and_underscore_keys! + self.replace(self.symbolize_and_underscore_keys) + end + end +end From a59d4ba346ebf40e46f0661e5a091e231d35ef05 Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 16:51:38 +0800 Subject: [PATCH 026/499] Add test case for finding nonexistent pet --- samples/client/petstore/ruby/spec/pet_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/samples/client/petstore/ruby/spec/pet_spec.rb b/samples/client/petstore/ruby/spec/pet_spec.rb index e05dd726f13..52030b7bf51 100644 --- a/samples/client/petstore/ruby/spec/pet_spec.rb +++ b/samples/client/petstore/ruby/spec/pet_spec.rb @@ -50,6 +50,19 @@ describe "Pet" do pet.category.name.should == "category test" end + it "should not find a pet that does not exist" do + begin + SwaggerClient::PetApi.get_pet_by_id(-1) + fail 'it should raise error' + rescue SwaggerClient::Swagger::ApiError => e + e.code.should == 404 + e.message.should == 'Not Found' + e.response_body.should == '{"code":1,"type":"error","message":"Pet not found"}' + e.response_headers.should be_a(Hash) + e.response_headers['Content-Type'].should == 'application/json' + end + end + it "should find pets by status" do pets = SwaggerClient::PetApi.find_pets_by_status(:status => 'available') pets.length.should >= 3 From d2d5cf0d57bec4998d369578acfb205003078665 Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 16 Jun 2015 12:17:11 +0800 Subject: [PATCH 027/499] Add convention notes to Ruby CLI options --- .../java/io/swagger/codegen/languages/RubyClientCodegen.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 9141f61253e..6ddd111f5ac 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -55,8 +55,8 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { // remove modelPackage and apiPackage added by default cliOptions.clear(); - cliOptions.add(new CliOption("gemName", "gem name, default: swagger_client")); - cliOptions.add(new CliOption("moduleName", "top module name, usually corresponding to gem name, default: SwaggerClient")); + cliOptions.add(new CliOption("gemName", "gem name (convention: underscore_case), default: swagger_client")); + cliOptions.add(new CliOption("moduleName", "top module name (convention: CamelCase, usually corresponding to gem name), default: SwaggerClient")); cliOptions.add(new CliOption("gemVersion", "gem version, default: 1.0.0")); } From f87bb12ebb3264097c81598e0bb1aec0fdc879a5 Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Tue, 16 Jun 2015 10:44:05 +0200 Subject: [PATCH 028/499] Added support for TypeScript generation for AngularJS and Node.js --- .../TypeScriptAngularClientCodegen.java | 25 +++ .../TypeScriptNodeClientCodegen.java | 169 ++++++++++++++++++ .../services/io.swagger.codegen.CodegenConfig | 2 + .../TypeScript-Angular/api.d.mustache | 13 ++ .../resources/TypeScript-Angular/api.mustache | 68 +++++++ .../TypeScript-Angular/model.mustache | 30 ++++ .../resources/TypeScript-node/api.mustache | 73 ++++++++ .../resources/TypeScript-node/model.mustache | 24 +++ 8 files changed, 404 insertions(+) create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java create mode 100644 modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache create mode 100644 modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache create mode 100644 modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache create mode 100644 modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache create mode 100644 modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java new file mode 100644 index 00000000000..a31e15878cf --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java @@ -0,0 +1,25 @@ +package io.swagger.codegen.languages; + +import java.io.File; + +import io.swagger.codegen.SupportingFile; + +public class TypeScriptAngularClientCodegen extends TypeScriptNodeClientCodegen { + + @Override + public String getName() { + return "typescript-angular"; + } + + public TypeScriptAngularClientCodegen() { + super(); + outputFolder = "generated-code/typescript-angular"; + modelTemplateFiles.put("model.mustache", ".ts"); + apiTemplateFiles.put("api.mustache", ".ts"); + templateDir = "TypeScript-Angular"; + apiPackage = "api"; + modelPackage = "api"; + + supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage + File.separator, "api.d.ts")); + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java new file mode 100644 index 00000000000..19b8514f8e3 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java @@ -0,0 +1,169 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.*; +import io.swagger.models.properties.*; + +import java.util.*; +import java.io.File; + +public class TypeScriptNodeClientCodegen extends DefaultCodegen implements CodegenConfig { + protected String invokerPackage = "io.swagger.client"; + protected String groupId = "io.swagger"; + protected String artifactId = "swagger-typescript-node-client"; + protected String artifactVersion = "1.0.0"; + protected String sourceFolder = "src/main/typescript"; + + @Override + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + @Override + public String getName() { + return "typescript-node"; + } + + @Override + public String getHelp() { + return "Generates a TypeScript nodejs client library."; + } + + public TypeScriptNodeClientCodegen() { + super(); + outputFolder = "generated-code/typescript-node"; + modelTemplateFiles.put("model.mustache", ".ts"); + apiTemplateFiles.put("api.mustache", ".ts"); + templateDir = "TypeScript-node"; + apiPackage = "api"; + modelPackage = "model"; + + reservedWords = new HashSet(Arrays.asList("abstract", + "continue", "for", "new", "switch", "assert", "default", "if", + "package", "synchronized", "do", "goto", "private", + "this", "break", "double", "implements", "protected", "throw", + "byte", "else", "import", "public", "throws", "case", "enum", + "instanceof", "return", "transient", "catch", "extends", "int", + "short", "try", "char", "final", "interface", "static", "void", + "class", "finally", "const", "super", "while")); + + additionalProperties.put("invokerPackage", invokerPackage); + additionalProperties.put("groupId", groupId); + additionalProperties.put("artifactId", artifactId); + additionalProperties.put("artifactVersion", artifactVersion); + + languageSpecificPrimitives = new HashSet(Arrays.asList( + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float", + "Object")); + instantiationTypes.put("array", "Array"); + + typeMapping = new HashMap(); + typeMapping.put("Array", "Array"); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("boolean", "boolean"); + typeMapping.put("string", "string"); + typeMapping.put("int", "number"); + typeMapping.put("float", "number"); + typeMapping.put("number", "number"); + typeMapping.put("long", "number"); + typeMapping.put("short", "number"); + typeMapping.put("char", "string"); + typeMapping.put("double", "number"); + typeMapping.put("object", "any"); + typeMapping.put("integer", "number"); + + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + apiPackage().replace('.', File.separatorChar); + } + + public String modelFileFolder() { + return outputFolder + "/" + modelPackage().replace('.', File.separatorChar); + } + + @Override + public String toVarName(String name) { + // replace - with _ e.g. created-at => created_at + name = name.replaceAll("-", "_"); + + // if it's all uppper case, do nothing + if (name.matches("^[A-Z_]*$")) + return name; + + // camelize the variable name + // pet_id => PetId + name = camelize(name, true); + + // for reserved word or word starting with number, append _ + if (reservedWords.contains(name) || name.matches("^\\d.*")) + name = escapeReservedWord(name); + + return name; + } + + @Override + public String toParamName(String name) { + // should be the same as variable name + return toVarName(name); + } + + @Override + public String toModelName(String name) { + // model name cannot use reserved keyword, e.g. return + if (reservedWords.contains(name)) + throw new RuntimeException(name + + " (reserved word) cannot be used as a model name"); + + // camelize the model name + // phone_number => PhoneNumber + return camelize(name); + } + + @Override + public String toModelFilename(String name) { + // should be the same as the model name + return toModelName(name); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + + return getSwaggerType(p) + ""; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) + return type; + } else + type = swaggerType; + return type; + } +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 8bbdbc8d140..2a037204976 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -21,4 +21,6 @@ io.swagger.codegen.languages.SwaggerGenerator io.swagger.codegen.languages.SwaggerYamlGenerator io.swagger.codegen.languages.SwiftGenerator io.swagger.codegen.languages.TizenClientCodegen +io.swagger.codegen.languages.TypeScriptAngularClientCodegen +io.swagger.codegen.languages.TypeScriptNodeClientCodegen io.swagger.codegen.languages.AkkaScalaClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache new file mode 100644 index 00000000000..a8bf1c58267 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache @@ -0,0 +1,13 @@ +{{#models}} +{{#model}} +/// +{{/model}} +{{/models}} + +{{#apiInfo}} +{{#apis}} +{{#operations}} +/// +{{/operations}} +{{/apis}} +{{/apiInfo}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache new file mode 100644 index 00000000000..3b53e816891 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache @@ -0,0 +1,68 @@ +/// + +/* tslint:disable:no-unused-variable member-ordering */ + +{{#operations}} +module {{package}} { + 'use strict'; + + {{#description}} + /** + * {{&description}} + */ + {{/description}} + export class {{classname}} { + private basePath = '{{basePath}}'; + + static $inject: string[] = ['$http']; + + constructor(private $http: ng.IHttpService, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + {{#operation}} + public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}, {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> { + var path = this.basePath + '{{path}}'; + {{#pathParams}} + path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}})); + {{/pathParams}} + var queryParameters: any = {}; + var headers: any = {}; + {{#requiredParamCount}} + // verify required params are set + if ({{/requiredParamCount}}{{#requiredParams}} !{{paramName}} {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) { + throw new Error('Missing required parameter: {{¶mName}}'); + } + {{/requiredParamCount}} + {{#queryParams}}if ({{paramName}} !== undefined) { + queryParameters['{{paramName}}'] = {{paramName}}; + }{{/queryParams}} + {{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};{{/headerParams}} + var httpRequestParams: any = { + method: '{{httpMethod}}', + url: path, + json: true, + {{#bodyParam}}data: body, + {{/bodyParam}} + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + {{/operation}} + } + + angular.module('{{package}}_{{classname}}', ['$http']) + .service('{{classname}}', {{classname}}); +} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache new file mode 100644 index 00000000000..bbda64b37da --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache @@ -0,0 +1,30 @@ +/// + +module {{package}} { + 'use strict'; +{{#models}} +{{#model}} + {{#description}}/** + * {{{description}}} + */{{/description}} + export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ +{{#vars}} + {{#description}}/** + * {{{description}}} + */{{/description}} + {{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}}; +{{/vars}} + } + +{{#hasEnums}} + export module {{classname}} { +{{#vars}} + {{#isEnum}}export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}} + {{.}} = '{{.}}',{{/values}}{{/allowableValues}} + }{{/isEnum}} +{{/vars}} + } +{{/hasEnums}} +{{/model}} +{{/models}} +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache new file mode 100644 index 00000000000..4b329799ad5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache @@ -0,0 +1,73 @@ +/* tslint:disable:no-unused-variable */ + +{{#operations}} +{{#description}} + /** + * {{&description}} + */ +{{/description}} +export class {{classname}} { + private basePath = '{{basePath}}'; + + constructor(private url: string, private username: string, private password: string, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + {{#operation}} + public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}} ) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> { + var path = this.url + this.basePath + '{{path}}'; + + {{#pathParams}} + path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}})); + {{/pathParams}} + + var queryParameters: any = {}; + var headers: any = {}; + + {{#requiredParamCount}} + // verify required params are set + if ({{/requiredParamCount}}{{#requiredParams}} !{{paramName}} {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) { + throw new Error('Missing required parameter: {{¶mName}}'); + } + {{/requiredParamCount}} + + {{#queryParams}}if ({{paramName}} !== undefined) { + queryParameters['{{paramName}}'] = {{paramName}}; + } + {{/queryParams}} + + {{#headerParams}}headerParams['{{paramName}}'] = {{paramName}}; + {{/headerParams}} + + var deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>(); + + request({ + method: '{{httpMethod}}', + qs: queryParameters, + uri: path, + json: true, + {{#bodyParam}}body: body, + {{/bodyParam}} + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + {{/operation}} +} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache new file mode 100644 index 00000000000..f187ac3e40f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache @@ -0,0 +1,24 @@ +{{#models}} +{{#model}} +{{#description}}/** +* {{{description}}} +*/{{/description}} +export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ + {{#vars}}{{#description}}/** + * {{{description}}} + */ + {{/description}} + {{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};{{/vars}} +} + +{{#hasEnums}} +export module {{classname}} { +{{#vars}} + {{#isEnum}}export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}} + {{.}} = '{{.}}',{{/values}}{{/allowableValues}} + }{{/isEnum}} +{{/vars}} +} +{{/hasEnums}} +{{/model}} +{{/models}} From 7b5b874fdca5699ae3a5c67900610e6c3e9c3354 Mon Sep 17 00:00:00 2001 From: Nadezhda Makarkina Date: Mon, 15 Jun 2015 14:57:30 +0300 Subject: [PATCH 029/499] Fixed #798: original jar generation has been fixed. --- modules/swagger-codegen-cli/pom.xml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/swagger-codegen-cli/pom.xml b/modules/swagger-codegen-cli/pom.xml index 29daf274138..93ecc78a951 100644 --- a/modules/swagger-codegen-cli/pom.xml +++ b/modules/swagger-codegen-cli/pom.xml @@ -41,7 +41,7 @@ 2.3 - reduced-pom + process-resources package shade @@ -52,15 +52,6 @@ ${java.io.tmpdir}/dependency-reduced-pom.xml - - - - process-resources - package - - shade - - From 7c355030f47c827a6231d4dc1173fb7a452a283e Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 16 Jun 2015 18:41:51 +0800 Subject: [PATCH 030/499] Add to_s method for models --- .../main/resources/ruby/base_object.mustache | 20 +++++++++---------- .../lib/swagger_client/models/base_object.rb | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache index 2f1e1064a5b..eda92028f78 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache @@ -2,15 +2,6 @@ module {{moduleName}} # base class containing fundamental method such as to_hash, build_from_hash and more class BaseObject - # return the object in the form of hash - def to_body - body = {} - self.class.attribute_map.each_pair do |key, value| - body[value] = self.send(key) unless self.send(key).nil? - end - body - end - # build the object from hash def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) @@ -53,7 +44,16 @@ module {{moduleName}} end end - # to_body is an alias to to_body (backward compatibility) + def to_s + to_hash.to_s + end + + # to_body is an alias to to_body (backward compatibility)) + def to_body + to_hash + end + + # return the object in the form of hash def to_hash hash = {} self.class.attribute_map.each_pair do |key, value| diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb index a14e90350db..b0fa43c8359 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb @@ -2,15 +2,6 @@ module SwaggerClient # base class containing fundamental method such as to_hash, build_from_hash and more class BaseObject - # return the object in the form of hash - def to_body - body = {} - self.class.attribute_map.each_pair do |key, value| - body[value] = self.send(key) unless self.send(key).nil? - end - body - end - # build the object from hash def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) @@ -53,7 +44,16 @@ module SwaggerClient end end - # to_body is an alias to to_body (backward compatibility) + def to_s + to_hash.to_s + end + + # to_body is an alias to to_body (backward compatibility)) + def to_body + to_hash + end + + # return the object in the form of hash def to_hash hash = {} self.class.attribute_map.each_pair do |key, value| From 24a2de7389e42070e428f825d0c8aedb276e6d6d Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 17 Jun 2015 16:00:16 +0800 Subject: [PATCH 031/499] Sort parameters to move required ones in front of optional ones --- .../main/java/io/swagger/codegen/DefaultCodegen.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 71b6295c9be..59e7078be2d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -49,6 +49,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -850,6 +851,17 @@ public class DefaultCodegen { } op.bodyParam = bodyParam; op.httpMethod = httpMethod.toUpperCase(); + // move "required" parameters in front of "optional" parameters + Collections.sort(allParams, new Comparator() { + @Override + public int compare(CodegenParameter one, CodegenParameter another) { + boolean oneRequired = one.required == null ? false : one.required; + boolean anotherRequired = another.required == null ? false : another.required; + if (oneRequired == anotherRequired) return 0; + else if (oneRequired) return -1; + else return 1; + } + }); op.allParams = addHasMore(allParams); op.bodyParams = addHasMore(bodyParams); op.pathParams = addHasMore(pathParams); From 7f4586a47f871e7119bf4c2a9c242ba0ff8b3fa9 Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 17 Jun 2015 16:00:59 +0800 Subject: [PATCH 032/499] Fix comment regarding required parameter in PHP generator --- modules/swagger-codegen/src/main/resources/php/api.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 12d2eb80744..5166889fc3f 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -60,7 +60,7 @@ class {{classname}} { * * {{{summary}}} * -{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} +{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}}{{#required}} (required){{/required}} {{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} */ public function {{nickname}}({{#allParams}}${{paramName}}{{#optional}}=null{{/optional}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { From ce40da0f7124d42611898ebe5e49a5aaa9af44e1 Mon Sep 17 00:00:00 2001 From: wing328 Date: Wed, 17 Jun 2015 16:01:24 +0800 Subject: [PATCH 033/499] add php silex server side codegen --- .gitignore | 3 + bin/all-petstore.sh | 1 + bin/silex-petstore-server.sh | 31 +++ .../codegen/languages/SilexServerCodegen.java | 192 ++++++++++++++++++ .../services/io.swagger.codegen.CodegenConfig | 1 + .../src/main/resources/silex/.htaccess | 5 + .../src/main/resources/silex/README.mustache | 10 + .../src/main/resources/silex/composer.json | 5 + .../src/main/resources/silex/index.mustache | 26 +++ .../petstore/silex/SwaggerServer/.htaccess | 5 + .../petstore/silex/SwaggerServer/README.md | 10 + .../silex/SwaggerServer/composer.json | 5 + .../petstore/silex/SwaggerServer/index.php | 184 +++++++++++++++++ samples/client/petstore/silex/silex/.htaccess | 5 + samples/client/petstore/silex/silex/README.md | 10 + .../client/petstore/silex/silex/composer.json | 5 + samples/client/petstore/silex/silex/index.php | 184 +++++++++++++++++ 17 files changed, 682 insertions(+) create mode 100755 bin/silex-petstore-server.sh create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java create mode 100644 modules/swagger-codegen/src/main/resources/silex/.htaccess create mode 100644 modules/swagger-codegen/src/main/resources/silex/README.mustache create mode 100644 modules/swagger-codegen/src/main/resources/silex/composer.json create mode 100644 modules/swagger-codegen/src/main/resources/silex/index.mustache create mode 100644 samples/client/petstore/silex/SwaggerServer/.htaccess create mode 100644 samples/client/petstore/silex/SwaggerServer/README.md create mode 100644 samples/client/petstore/silex/SwaggerServer/composer.json create mode 100644 samples/client/petstore/silex/SwaggerServer/index.php create mode 100644 samples/client/petstore/silex/silex/.htaccess create mode 100644 samples/client/petstore/silex/silex/README.md create mode 100644 samples/client/petstore/silex/silex/composer.json create mode 100644 samples/client/petstore/silex/silex/index.php diff --git a/.gitignore b/.gitignore index 8f160116e5b..24bb9709fc3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,6 @@ atlassian-ide-plugin.xml samples/client/petstore/php/SwaggerClient-php/composer.lock samples/client/petstore/php/SwaggerClient-php/vendor/ + +samples/client/petstore/silex/SwaggerServer/composer.lock +samples/client/petstore/silex/SwaggerServer/venodr/ diff --git a/bin/all-petstore.sh b/bin/all-petstore.sh index 8937200c77f..ea5aad656b5 100755 --- a/bin/all-petstore.sh +++ b/bin/all-petstore.sh @@ -32,5 +32,6 @@ cd $APP_DIR ./bin/ruby-petstore.sh ./bin/objc-petstore.sh ./bin/scala-petstore.sh +./bin/silex-petstore-server.sh ./bin/spring-mvc-petstore-server.sh ./bin/tizen-petstore.sh diff --git a/bin/silex-petstore-server.sh b/bin/silex-petstore-server.sh new file mode 100755 index 00000000000..5ead9db0002 --- /dev/null +++ b/bin/silex-petstore-server.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/client/petstore/silex" + +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java new file mode 100644 index 00000000000..fb5005566c6 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SilexServerCodegen.java @@ -0,0 +1,192 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.CodegenType; +import io.swagger.codegen.DefaultCodegen; +import io.swagger.codegen.SupportingFile; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.Property; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; + +public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig { + protected String invokerPackage; + protected String groupId = "io.swagger"; + protected String artifactId = "swagger-server"; + protected String artifactVersion = "1.0.0"; + + public SilexServerCodegen() { + super(); + + invokerPackage = camelize("SwaggerServer"); + + String packagePath = "SwaggerServer"; + + modelPackage = packagePath + "/lib/models"; + apiPackage = packagePath + "/lib"; + outputFolder = "generated-code/silex"; + + // no model, api files + modelTemplateFiles.clear(); + apiTemplateFiles.clear(); + + templateDir = "silex"; + + reservedWords = new HashSet( + Arrays.asList( + "__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor") + ); + + additionalProperties.put("invokerPackage", invokerPackage); + additionalProperties.put("groupId", groupId); + additionalProperties.put("artifactId", artifactId); + additionalProperties.put("artifactVersion", artifactVersion); + + // ref: http://php.net/manual/en/language.types.intro.php + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "boolean", + "int", + "integer", + "double", + "float", + "string", + "object", + "DateTime", + "mixed", + "number") + ); + + instantiationTypes.put("array", "array"); + instantiationTypes.put("map", "map"); + + // ref: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types + typeMapping = new HashMap(); + typeMapping.put("integer", "int"); + typeMapping.put("long", "int"); + typeMapping.put("float", "float"); + typeMapping.put("double", "double"); + typeMapping.put("string", "string"); + typeMapping.put("byte", "int"); + typeMapping.put("boolean", "boolean"); + typeMapping.put("date", "DateTime"); + typeMapping.put("datetime", "DateTime"); + typeMapping.put("file", "string"); + typeMapping.put("map", "map"); + typeMapping.put("array", "array"); + typeMapping.put("list", "array"); + typeMapping.put("object", "object"); + + supportingFiles.add(new SupportingFile("README.mustache", packagePath.replace('/', File.separatorChar), "README.md")); + supportingFiles.add(new SupportingFile("composer.json", packagePath.replace('/', File.separatorChar), "composer.json")); + supportingFiles.add(new SupportingFile("index.mustache", packagePath.replace('/', File.separatorChar), "index.php")); + supportingFiles.add(new SupportingFile(".htaccess", packagePath.replace('/', File.separatorChar), ".htaccess")); + } + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "silex"; + } + + public String getHelp() { + return "Generates a Silex server library."; + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar); + } + + public String modelFileFolder() { + return (outputFolder + "/" + modelPackage()).replace('/', File.separatorChar); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) { + return type; + } else if (instantiationTypes.containsKey(type)) { + return type; + } + } else { + type = swaggerType; + } + if (type == null) { + return null; + } + return toModelName(type); + } + + public String toDefaultValue(Property p) { + return "null"; + } + + + @Override + public String toVarName(String name) { + // parameter name starting with number won't compile + // need to escape it by appending _ at the beginning + if (name.matches("^[0-9]")) { + name = "_" + name; + } + + // return the name in underscore style + // PhoneNumber => phone_number + return underscore(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 + if (reservedWords.contains(name)) { + escapeReservedWord(name); // e.g. return => _return + } + + // 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); + } + +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 8bbdbc8d140..ce3edfd1359 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -14,6 +14,7 @@ io.swagger.codegen.languages.RetrofitClientCodegen io.swagger.codegen.languages.RubyClientCodegen io.swagger.codegen.languages.ScalaClientCodegen io.swagger.codegen.languages.ScalatraServerCodegen +io.swagger.codegen.languages.SilexServerCodegen io.swagger.codegen.languages.SpringMVCServerCodegen io.swagger.codegen.languages.StaticDocCodegen io.swagger.codegen.languages.StaticHtmlGenerator diff --git a/modules/swagger-codegen/src/main/resources/silex/.htaccess b/modules/swagger-codegen/src/main/resources/silex/.htaccess new file mode 100644 index 00000000000..e47b5fb8a0c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/silex/.htaccess @@ -0,0 +1,5 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] + \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/silex/README.mustache b/modules/swagger-codegen/src/main/resources/silex/README.mustache new file mode 100644 index 00000000000..9f35636b3f8 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/silex/README.mustache @@ -0,0 +1,10 @@ +# Swagger generated server + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This +is an example of building a PHP server. + +This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: + +[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/) diff --git a/modules/swagger-codegen/src/main/resources/silex/composer.json b/modules/swagger-codegen/src/main/resources/silex/composer.json new file mode 100644 index 00000000000..466cd3fbc77 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/silex/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "silex/silex": "~1.2" + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/silex/index.mustache b/modules/swagger-codegen/src/main/resources/silex/index.mustache new file mode 100644 index 00000000000..9fbfca6049e --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/silex/index.mustache @@ -0,0 +1,26 @@ +{{httpMethod}}('{{path}}', function(Application $app, Request $request{{#pathParams}}, ${{paramName}}{{/pathParams}}) { + {{#queryParams}}${{paramName}} = $request->get('{{paramName}}');{{newline}} {{/queryParams}} + {{#formParams}}${{paramName}} = $request->get('{{paramName}}');{{newline}} {{/formParams}} + return new Response('How about implementing {{nickname}} as a {{httpMethod}} method ?'); + }); + + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + +$app->run(); diff --git a/samples/client/petstore/silex/SwaggerServer/.htaccess b/samples/client/petstore/silex/SwaggerServer/.htaccess new file mode 100644 index 00000000000..e47b5fb8a0c --- /dev/null +++ b/samples/client/petstore/silex/SwaggerServer/.htaccess @@ -0,0 +1,5 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] + \ No newline at end of file diff --git a/samples/client/petstore/silex/SwaggerServer/README.md b/samples/client/petstore/silex/SwaggerServer/README.md new file mode 100644 index 00000000000..9f35636b3f8 --- /dev/null +++ b/samples/client/petstore/silex/SwaggerServer/README.md @@ -0,0 +1,10 @@ +# Swagger generated server + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This +is an example of building a PHP server. + +This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: + +[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/) diff --git a/samples/client/petstore/silex/SwaggerServer/composer.json b/samples/client/petstore/silex/SwaggerServer/composer.json new file mode 100644 index 00000000000..466cd3fbc77 --- /dev/null +++ b/samples/client/petstore/silex/SwaggerServer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "silex/silex": "~1.2" + } +} \ No newline at end of file diff --git a/samples/client/petstore/silex/SwaggerServer/index.php b/samples/client/petstore/silex/SwaggerServer/index.php new file mode 100644 index 00000000000..1526f3cb8f3 --- /dev/null +++ b/samples/client/petstore/silex/SwaggerServer/index.php @@ -0,0 +1,184 @@ +POST('/user', function(Application $app, Request $request) { + + + return new Response('How about implementing createUser as a POST method ?'); + }); + + + +$app->POST('/user/createWithArray', function(Application $app, Request $request) { + + + return new Response('How about implementing createUsersWithArrayInput as a POST method ?'); + }); + + + +$app->POST('/user/createWithList', function(Application $app, Request $request) { + + + return new Response('How about implementing createUsersWithListInput as a POST method ?'); + }); + + + +$app->GET('/user/login', function(Application $app, Request $request) { + $username = $request->get('username'); $password = $request->get('password'); + + return new Response('How about implementing loginUser as a GET method ?'); + }); + + + +$app->GET('/user/logout', function(Application $app, Request $request) { + + + return new Response('How about implementing logoutUser as a GET method ?'); + }); + + + +$app->GET('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing getUserByName as a GET method ?'); + }); + + + +$app->PUT('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing updateUser as a PUT method ?'); + }); + + + +$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing deleteUser as a DELETE method ?'); + }); + + + + + + + +$app->PUT('/pet', function(Application $app, Request $request) { + + + return new Response('How about implementing updatePet as a PUT method ?'); + }); + + + +$app->POST('/pet', function(Application $app, Request $request) { + + + return new Response('How about implementing addPet as a POST method ?'); + }); + + + +$app->GET('/pet/findByStatus', function(Application $app, Request $request) { + $status = $request->get('status'); + + return new Response('How about implementing findPetsByStatus as a GET method ?'); + }); + + + +$app->GET('/pet/findByTags', function(Application $app, Request $request) { + $tags = $request->get('tags'); + + return new Response('How about implementing findPetsByTags as a GET method ?'); + }); + + + +$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + + return new Response('How about implementing getPetById as a GET method ?'); + }); + + + +$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + $name = $request->get('name'); $status = $request->get('status'); + return new Response('How about implementing updatePetWithForm as a POST method ?'); + }); + + + +$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + + return new Response('How about implementing deletePet as a DELETE method ?'); + }); + + + +$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) { + + $additional_metadata = $request->get('additional_metadata'); $file = $request->get('file'); + return new Response('How about implementing uploadFile as a POST method ?'); + }); + + + + + + + +$app->GET('/store/inventory', function(Application $app, Request $request) { + + + return new Response('How about implementing getInventory as a GET method ?'); + }); + + + +$app->POST('/store/order', function(Application $app, Request $request) { + + + return new Response('How about implementing placeOrder as a POST method ?'); + }); + + + +$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { + + + return new Response('How about implementing getOrderById as a GET method ?'); + }); + + + +$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { + + + return new Response('How about implementing deleteOrder as a DELETE method ?'); + }); + + + + + +$app->run(); diff --git a/samples/client/petstore/silex/silex/.htaccess b/samples/client/petstore/silex/silex/.htaccess new file mode 100644 index 00000000000..e47b5fb8a0c --- /dev/null +++ b/samples/client/petstore/silex/silex/.htaccess @@ -0,0 +1,5 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] + \ No newline at end of file diff --git a/samples/client/petstore/silex/silex/README.md b/samples/client/petstore/silex/silex/README.md new file mode 100644 index 00000000000..9f35636b3f8 --- /dev/null +++ b/samples/client/petstore/silex/silex/README.md @@ -0,0 +1,10 @@ +# Swagger generated server + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This +is an example of building a PHP server. + +This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: + +[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/) diff --git a/samples/client/petstore/silex/silex/composer.json b/samples/client/petstore/silex/silex/composer.json new file mode 100644 index 00000000000..466cd3fbc77 --- /dev/null +++ b/samples/client/petstore/silex/silex/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "silex/silex": "~1.2" + } +} \ No newline at end of file diff --git a/samples/client/petstore/silex/silex/index.php b/samples/client/petstore/silex/silex/index.php new file mode 100644 index 00000000000..1526f3cb8f3 --- /dev/null +++ b/samples/client/petstore/silex/silex/index.php @@ -0,0 +1,184 @@ +POST('/user', function(Application $app, Request $request) { + + + return new Response('How about implementing createUser as a POST method ?'); + }); + + + +$app->POST('/user/createWithArray', function(Application $app, Request $request) { + + + return new Response('How about implementing createUsersWithArrayInput as a POST method ?'); + }); + + + +$app->POST('/user/createWithList', function(Application $app, Request $request) { + + + return new Response('How about implementing createUsersWithListInput as a POST method ?'); + }); + + + +$app->GET('/user/login', function(Application $app, Request $request) { + $username = $request->get('username'); $password = $request->get('password'); + + return new Response('How about implementing loginUser as a GET method ?'); + }); + + + +$app->GET('/user/logout', function(Application $app, Request $request) { + + + return new Response('How about implementing logoutUser as a GET method ?'); + }); + + + +$app->GET('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing getUserByName as a GET method ?'); + }); + + + +$app->PUT('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing updateUser as a PUT method ?'); + }); + + + +$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing deleteUser as a DELETE method ?'); + }); + + + + + + + +$app->PUT('/pet', function(Application $app, Request $request) { + + + return new Response('How about implementing updatePet as a PUT method ?'); + }); + + + +$app->POST('/pet', function(Application $app, Request $request) { + + + return new Response('How about implementing addPet as a POST method ?'); + }); + + + +$app->GET('/pet/findByStatus', function(Application $app, Request $request) { + $status = $request->get('status'); + + return new Response('How about implementing findPetsByStatus as a GET method ?'); + }); + + + +$app->GET('/pet/findByTags', function(Application $app, Request $request) { + $tags = $request->get('tags'); + + return new Response('How about implementing findPetsByTags as a GET method ?'); + }); + + + +$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + + return new Response('How about implementing getPetById as a GET method ?'); + }); + + + +$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + $name = $request->get('name'); $status = $request->get('status'); + return new Response('How about implementing updatePetWithForm as a POST method ?'); + }); + + + +$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + + return new Response('How about implementing deletePet as a DELETE method ?'); + }); + + + +$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) { + + $additional_metadata = $request->get('additional_metadata'); $file = $request->get('file'); + return new Response('How about implementing uploadFile as a POST method ?'); + }); + + + + + + + +$app->GET('/store/inventory', function(Application $app, Request $request) { + + + return new Response('How about implementing getInventory as a GET method ?'); + }); + + + +$app->POST('/store/order', function(Application $app, Request $request) { + + + return new Response('How about implementing placeOrder as a POST method ?'); + }); + + + +$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { + + + return new Response('How about implementing getOrderById as a GET method ?'); + }); + + + +$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { + + + return new Response('How about implementing deleteOrder as a DELETE method ?'); + }); + + + + + +$app->run(); From 9c4e5ed5965e65815bca7d835591cec26a6d4ca9 Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 17 Jun 2015 16:15:37 +0800 Subject: [PATCH 034/499] Rebuild Petstare sample for Java, Android, PHP, etc. --- .../scala/io/swagger/client/api/PetApi.scala | 4 ++-- .../java/io/swagger/client/api/PetApi.java | 4 ++-- .../java/io/swagger/client/model/Pet.java | 2 +- .../io/swagger/petstore/test/PetApiTest.java | 2 +- .../java/io/swagger/client/api/PetApi.java | 6 ++--- .../java/io/swagger/client/model/Pet.java | 2 +- .../io/swagger/petstore/test/PetApiTest.java | 2 +- .../php/SwaggerClient-php/lib/PetApi.php | 22 +++++++++---------- .../php/SwaggerClient-php/lib/StoreApi.php | 2 +- .../php/SwaggerClient-php/lib/UserApi.php | 12 +++++----- .../petstore/ruby/lib/swagger_client.rb | 2 +- .../ruby/lib/swagger_client/api/pet_api.rb | 2 +- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/samples/client/petstore/akka-scala/src/main/scala/io/swagger/client/api/PetApi.scala b/samples/client/petstore/akka-scala/src/main/scala/io/swagger/client/api/PetApi.scala index d5ae6fd65f0..591d055dad6 100644 --- a/samples/client/petstore/akka-scala/src/main/scala/io/swagger/client/api/PetApi.scala +++ b/samples/client/petstore/akka-scala/src/main/scala/io/swagger/client/api/PetApi.scala @@ -108,10 +108,10 @@ object PetApi { * Expected answers: * code 400 : (Invalid pet value) * - * @param apiKey * @param petId Pet id to delete + * @param apiKey */ - def deletePet(apiKey: Option[String] = None, petId: Long): ApiRequest[Unit] = + def deletePet(petId: Long, apiKey: Option[String] = None): ApiRequest[Unit] = ApiRequest[Unit](ApiMethods.DELETE, "http://petstore.swagger.io/v2", "/pet/{petId}", "application/json") .withPathParam("petId", petId) .withHeaderParam("api_key", apiKey) diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java index ebf600d787e..68121b9376a 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java @@ -391,11 +391,11 @@ public class PetApi { /** * Deletes a pet * - * @param apiKey * @param petId Pet id to delete + * @param apiKey * @return void */ - public void deletePet (String apiKey, Long petId) throws ApiException { + public void deletePet (Long petId, String apiKey) throws ApiException { Object postBody = null; // verify the required parameter 'petId' is set diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java index 26219b16a45..90a840e6e42 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import java.util.*; import io.swagger.client.model.Tag; +import java.util.*; import io.swagger.annotations.*; import com.google.gson.annotations.SerializedName; diff --git a/samples/client/petstore/android-java/src/test/java/io/swagger/petstore/test/PetApiTest.java b/samples/client/petstore/android-java/src/test/java/io/swagger/petstore/test/PetApiTest.java index a4900a92b9b..ca868d2ea22 100644 --- a/samples/client/petstore/android-java/src/test/java/io/swagger/petstore/test/PetApiTest.java +++ b/samples/client/petstore/android-java/src/test/java/io/swagger/petstore/test/PetApiTest.java @@ -118,7 +118,7 @@ public class PetApiTest { api.addPet(pet); Pet fetched = api.getPetById(pet.getId()); - api.deletePet(null, fetched.getId()); + api.deletePet(fetched.getId(), null); try { fetched = api.getPetById(fetched.getId()); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index c102cf00b51..28608fd0d38 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -322,7 +322,7 @@ public class PetApi { } try { - String[] authNames = new String[] { "petstore_auth", "api_key" }; + String[] authNames = new String[] { "api_key", "petstore_auth" }; String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); if(response != null){ return (Pet) apiClient.deserialize(response, "", Pet.class); @@ -417,11 +417,11 @@ public class PetApi { /** * Deletes a pet * - * @param apiKey * @param petId Pet id to delete + * @param apiKey * @return void */ - public void deletePet (String apiKey, Long petId) throws ApiException { + public void deletePet (Long petId, String apiKey) throws ApiException { Object postBody = null; // verify the required parameter 'petId' is set diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java index ddd0e1038c0..cf7ace02309 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import java.util.*; import io.swagger.client.model.Tag; +import java.util.*; import io.swagger.annotations.*; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java b/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java index 7178049d644..b6ad5fb0527 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java @@ -151,7 +151,7 @@ public class PetApiTest { api.addPet(pet); Pet fetched = api.getPetById(pet.getId()); - api.deletePet(null, fetched.getId()); + api.deletePet(fetched.getId(), null); try { fetched = api.getPetById(fetched.getId()); diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php index 2e1b2aa262e..03883d01bfd 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php @@ -59,7 +59,7 @@ class PetApi { * * Update an existing pet * - * @param Pet $body Pet object that needs to be added to the store (required) + * @param Pet $body Pet object that needs to be added to the store * @return void */ public function updatePet($body) { @@ -113,7 +113,7 @@ class PetApi { * * Add a new pet to the store * - * @param Pet $body Pet object that needs to be added to the store (required) + * @param Pet $body Pet object that needs to be added to the store * @return void */ public function addPet($body) { @@ -167,7 +167,7 @@ class PetApi { * * Finds Pets by status * - * @param array[string] $status Status values that need to be considered for filter (required) + * @param array[string] $status Status values that need to be considered for filter * @return array[Pet] */ public function findPetsByStatus($status) { @@ -225,7 +225,7 @@ class PetApi { * * Finds Pets by tags * - * @param array[string] $tags Tags to filter by (required) + * @param array[string] $tags Tags to filter by * @return array[Pet] */ public function findPetsByTags($tags) { @@ -327,7 +327,7 @@ class PetApi { } // authentication setting, if any - $authSettings = array('petstore_auth', 'api_key'); + $authSettings = array('api_key', 'petstore_auth'); // make the API Call $response = $this->apiClient->callAPI($resourcePath, $method, @@ -348,8 +348,8 @@ class PetApi { * Updates a pet in the store with form data * * @param string $pet_id ID of pet that needs to be updated (required) - * @param string $name Updated name of the pet (required) - * @param string $status Updated status of the pet (required) + * @param string $name Updated name of the pet + * @param string $status Updated status of the pet * @return void */ public function updatePetWithForm($pet_id, $name, $status) { @@ -414,11 +414,11 @@ class PetApi { * * Deletes a pet * - * @param string $api_key (required) * @param int $pet_id Pet id to delete (required) + * @param string $api_key * @return void */ - public function deletePet($api_key, $pet_id) { + public function deletePet($pet_id, $api_key) { // verify the required parameter 'pet_id' is set if ($pet_id === null) { @@ -478,8 +478,8 @@ class PetApi { * uploads an image * * @param int $pet_id ID of pet to update (required) - * @param string $additional_metadata Additional data to pass to server (required) - * @param string $file file to upload (required) + * @param string $additional_metadata Additional data to pass to server + * @param string $file file to upload * @return void */ public function uploadFile($pet_id, $additional_metadata, $file) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php index 87937a60283..eb15f2d97cd 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php @@ -113,7 +113,7 @@ class StoreApi { * * Place an order for a pet * - * @param Order $body order placed for purchasing the pet (required) + * @param Order $body order placed for purchasing the pet * @return Order */ public function placeOrder($body) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php index 2e16022f25a..387c093dcea 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php @@ -59,7 +59,7 @@ class UserApi { * * Create user * - * @param User $body Created user object (required) + * @param User $body Created user object * @return void */ public function createUser($body) { @@ -113,7 +113,7 @@ class UserApi { * * Creates list of users with given input array * - * @param array[User] $body List of user object (required) + * @param array[User] $body List of user object * @return void */ public function createUsersWithArrayInput($body) { @@ -167,7 +167,7 @@ class UserApi { * * Creates list of users with given input array * - * @param array[User] $body List of user object (required) + * @param array[User] $body List of user object * @return void */ public function createUsersWithListInput($body) { @@ -221,8 +221,8 @@ class UserApi { * * Logs user into the system * - * @param string $username The user name for login (required) - * @param string $password The password for login in clear text (required) + * @param string $username The user name for login + * @param string $password The password for login in clear text * @return string */ public function loginUser($username, $password) { @@ -397,7 +397,7 @@ class UserApi { * Updated user * * @param string $username name that need to be deleted (required) - * @param User $body Updated user object (required) + * @param User $body Updated user object * @return void */ public function updateUser($username, $body) { diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 998658c8b6e..6d239185005 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -16,8 +16,8 @@ require 'swagger_client/models/order' # APIs require 'swagger_client/api/user_api' -require 'swagger_client/api/store_api' require 'swagger_client/api/pet_api' +require 'swagger_client/api/store_api' module SwaggerClient # Initialize the default configuration diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 2ce4fb04ecd..7bed9b47780 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -190,7 +190,7 @@ module SwaggerClient post_body = nil - auth_names = ['petstore_auth', 'api_key'] + auth_names = ['api_key', 'petstore_auth'] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Pet.new() and obj.build_from_hash(response) end From b39d44db0356c020be24cd5676af65cf3d7e275e Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 17 Jun 2015 16:16:44 +0800 Subject: [PATCH 035/499] Add missing petstore scripts to bin/all-petstore.sh --- bin/all-petstore.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bin/all-petstore.sh b/bin/all-petstore.sh index 8937200c77f..1ae311848a0 100755 --- a/bin/all-petstore.sh +++ b/bin/all-petstore.sh @@ -18,19 +18,25 @@ if [ ! -d "${APP_DIR}" ]; then fi cd $APP_DIR +./bin/akka-scala-petstore.sh ./bin/android-java-petstore.sh ./bin/csharp-petstore.sh ./bin/dynamic-html.sh ./bin/html-petstore.sh -./bin/jaxrs-petstore-server.sh ./bin/java-petstore.sh -./bin/qt5-petstore.sh +./bin/jaxrs-petstore-server.sh +./bin/nodejs-petstore-server.sh +./bin/objc-petstore.sh ./bin/perl-petstore.sh ./bin/php-petstore.sh ./bin/python-petstore.sh +./bin/python3-petstore.sh +./bin/qt5-petstore.sh ./bin/retrofit-petstore.sh ./bin/ruby-petstore.sh -./bin/objc-petstore.sh +./bin/scala-async-petstore.sh ./bin/scala-petstore.sh +./bin/scalatra-petstore-server.sh ./bin/spring-mvc-petstore-server.sh +./bin/swift-petstore.sh ./bin/tizen-petstore.sh From ba4b88ef86d512e8827e5cdd9c2ad433752e36b5 Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Wed, 17 Jun 2015 12:22:15 +0200 Subject: [PATCH 036/499] Fixed TypeScript mustache --- .../TypeScript-Angular/model.mustache | 25 +++++++++++----- .../resources/TypeScript-node/model.mustache | 29 ++++++++++++------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache index bbda64b37da..b425d14d5e4 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache @@ -2,16 +2,22 @@ module {{package}} { 'use strict'; + {{#models}} {{#model}} - {{#description}}/** - * {{{description}}} - */{{/description}} +{{#description}} + /** + * {{{description}}} + */ +{{/description}} export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ {{#vars}} - {{#description}}/** - * {{{description}}} - */{{/description}} + +{{#description}} + /** + * {{{description}}} + */ +{{/description}} {{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}}; {{/vars}} } @@ -19,9 +25,12 @@ module {{package}} { {{#hasEnums}} export module {{classname}} { {{#vars}} - {{#isEnum}}export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}} +{{#isEnum}} + + export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}} {{.}} = '{{.}}',{{/values}}{{/allowableValues}} - }{{/isEnum}} + } +{{/isEnum}} {{/vars}} } {{/hasEnums}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache index f187ac3e40f..55c8997e1bc 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache @@ -1,22 +1,31 @@ {{#models}} {{#model}} -{{#description}}/** -* {{{description}}} -*/{{/description}} +{{#description}} +/** + * {{{description}}} + */ +{{/description}} export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ - {{#vars}}{{#description}}/** - * {{{description}}} - */ - {{/description}} - {{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};{{/vars}} +{{#vars}} + +{{#description}} + /** + * {{{description}}} + */ +{{/description}} + {{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}}; +{{/vars}} } {{#hasEnums}} export module {{classname}} { {{#vars}} - {{#isEnum}}export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}} +{{#isEnum}} + + export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}} {{.}} = '{{.}}',{{/values}}{{/allowableValues}} - }{{/isEnum}} + } +{{/isEnum}} {{/vars}} } {{/hasEnums}} From 436db1f8e78c9fd8136c2f687b93b7aa5b3accee Mon Sep 17 00:00:00 2001 From: William Cheng Date: Wed, 17 Jun 2015 19:00:29 +0800 Subject: [PATCH 037/499] add __toString and update php sample --- .../swagger-codegen/src/main/resources/php/model.mustache | 8 ++++++++ .../lib/{APIClient.php => ApiClient.php} | 0 .../php/SwaggerClient-php/lib/models/Category.php | 8 ++++++++ .../petstore/php/SwaggerClient-php/lib/models/Order.php | 8 ++++++++ .../petstore/php/SwaggerClient-php/lib/models/Pet.php | 8 ++++++++ .../petstore/php/SwaggerClient-php/lib/models/Tag.php | 8 ++++++++ .../petstore/php/SwaggerClient-php/lib/models/User.php | 8 ++++++++ .../petstore/php/SwaggerClient-php/tests/PetApiTest.php | 3 +++ samples/client/petstore/php/test.php | 3 ++- 9 files changed, 53 insertions(+), 1 deletion(-) rename samples/client/petstore/php/SwaggerClient-php/lib/{APIClient.php => ApiClient.php} (100%) diff --git a/modules/swagger-codegen/src/main/resources/php/model.mustache b/modules/swagger-codegen/src/main/resources/php/model.mustache index 9ce348ad131..e2b98aa23ce 100644 --- a/modules/swagger-codegen/src/main/resources/php/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php/model.mustache @@ -65,6 +65,14 @@ class {{classname}} implements ArrayAccess { public function offsetUnset($offset) { unset($this->$offset); } + + public function __toString() { + if (defined('JSON_PRETTY_PRINT')) { + return json_encode($this, JSON_PRETTY_PRINT); + } else { + return json_encode($this); + } + } } {{/model}} {{/models}} diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php similarity index 100% rename from samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php rename to samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php b/samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php index 7512921b898..c49c711fa8e 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php @@ -61,4 +61,12 @@ class Category implements ArrayAccess { public function offsetUnset($offset) { unset($this->$offset); } + + public function __toString() { + if (defined('JSON_PRETTY_PRINT')) { + return json_encode($this, JSON_PRETTY_PRINT); + } else { + return json_encode($this); + } + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php b/samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php index 4314d0df6f3..bf8a0178e4c 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php @@ -80,4 +80,12 @@ class Order implements ArrayAccess { public function offsetUnset($offset) { unset($this->$offset); } + + public function __toString() { + if (defined('JSON_PRETTY_PRINT')) { + return json_encode($this, JSON_PRETTY_PRINT); + } else { + return json_encode($this); + } + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php b/samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php index f74c9a88315..2009cc373cf 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php @@ -80,4 +80,12 @@ class Pet implements ArrayAccess { public function offsetUnset($offset) { unset($this->$offset); } + + public function __toString() { + if (defined('JSON_PRETTY_PRINT')) { + return json_encode($this, JSON_PRETTY_PRINT); + } else { + return json_encode($this); + } + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php b/samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php index 309d4087088..37729c68d9e 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php @@ -61,4 +61,12 @@ class Tag implements ArrayAccess { public function offsetUnset($offset) { unset($this->$offset); } + + public function __toString() { + if (defined('JSON_PRETTY_PRINT')) { + return json_encode($this, JSON_PRETTY_PRINT); + } else { + return json_encode($this); + } + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/User.php b/samples/client/petstore/php/SwaggerClient-php/lib/models/User.php index bbdaa1082b4..0ec53c409e6 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/User.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/models/User.php @@ -88,4 +88,12 @@ class User implements ArrayAccess { public function offsetUnset($offset) { unset($this->$offset); } + + public function __toString() { + if (defined('JSON_PRETTY_PRINT')) { + return json_encode($this, JSON_PRETTY_PRINT); + } else { + return json_encode($this); + } + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index 69536879d7d..5131fb7649c 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -10,6 +10,9 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // for error reporting (need to run with php5.3 to get no warning) //ini_set('display_errors', 1); //error_reporting(~0); + ini_set('display_startup_errors',1); + ini_set('display_errors',1); + error_reporting(-1); // enable debugging //SwaggerClient\Configuration::$debug = true; diff --git a/samples/client/petstore/php/test.php b/samples/client/petstore/php/test.php index efb6ccaf8f5..0c52f0fdb8a 100644 --- a/samples/client/petstore/php/test.php +++ b/samples/client/petstore/php/test.php @@ -23,7 +23,8 @@ try { $pet_api->getApiClient()->addDefaultHeader("TEST_API_KEY", "09182sdkanafndsl903"); // return Pet (model) $response = $pet_api->getPetById($petId); - var_dump($response); + // to test __toString() + print ($response); // add pet (post json) $new_pet_id = 10005; From 9e8631b75f4a1fae6bd20106841092257b21a99d Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Wed, 17 Jun 2015 17:56:37 +0200 Subject: [PATCH 038/499] Added shell scripts for sample generation of TypeScript --- bin/all-petstore.sh | 2 + bin/typescript-angular-petstore.sh | 31 ++ bin/typescript-node-petstore.sh | 31 ++ .../typescript-angular/api/Category.ts | 13 + .../petstore/typescript-angular/api/Order.ts | 32 ++ .../petstore/typescript-angular/api/Pet.ts | 32 ++ .../petstore/typescript-angular/api/PetApi.ts | 262 +++++++++++++ .../typescript-angular/api/StoreApi.ts | 141 +++++++ .../petstore/typescript-angular/api/Tag.ts | 13 + .../petstore/typescript-angular/api/User.ts | 28 ++ .../typescript-angular/api/UserApi.ts | 262 +++++++++++++ .../petstore/typescript-angular/api/api.d.ts | 9 + .../petstore/typescript-node/api/PetApi.ts | 358 ++++++++++++++++++ .../petstore/typescript-node/api/StoreApi.ts | 182 +++++++++ .../petstore/typescript-node/api/UserApi.ts | 357 +++++++++++++++++ .../typescript-node/model/Category.ts | 7 + .../petstore/typescript-node/model/Order.ts | 26 ++ .../petstore/typescript-node/model/Pet.ts | 26 ++ .../petstore/typescript-node/model/Tag.ts | 7 + .../petstore/typescript-node/model/User.ts | 22 ++ 20 files changed, 1841 insertions(+) create mode 100755 bin/typescript-angular-petstore.sh create mode 100755 bin/typescript-node-petstore.sh create mode 100644 samples/client/petstore/typescript-angular/api/Category.ts create mode 100644 samples/client/petstore/typescript-angular/api/Order.ts create mode 100644 samples/client/petstore/typescript-angular/api/Pet.ts create mode 100644 samples/client/petstore/typescript-angular/api/PetApi.ts create mode 100644 samples/client/petstore/typescript-angular/api/StoreApi.ts create mode 100644 samples/client/petstore/typescript-angular/api/Tag.ts create mode 100644 samples/client/petstore/typescript-angular/api/User.ts create mode 100644 samples/client/petstore/typescript-angular/api/UserApi.ts create mode 100644 samples/client/petstore/typescript-angular/api/api.d.ts create mode 100644 samples/client/petstore/typescript-node/api/PetApi.ts create mode 100644 samples/client/petstore/typescript-node/api/StoreApi.ts create mode 100644 samples/client/petstore/typescript-node/api/UserApi.ts create mode 100644 samples/client/petstore/typescript-node/model/Category.ts create mode 100644 samples/client/petstore/typescript-node/model/Order.ts create mode 100644 samples/client/petstore/typescript-node/model/Pet.ts create mode 100644 samples/client/petstore/typescript-node/model/Tag.ts create mode 100644 samples/client/petstore/typescript-node/model/User.ts diff --git a/bin/all-petstore.sh b/bin/all-petstore.sh index 8937200c77f..2f72165f1e5 100755 --- a/bin/all-petstore.sh +++ b/bin/all-petstore.sh @@ -34,3 +34,5 @@ cd $APP_DIR ./bin/scala-petstore.sh ./bin/spring-mvc-petstore-server.sh ./bin/tizen-petstore.sh +./bin/typescript-angular-petstore.sh +./bin/typescript-node-petstore.sh diff --git a/bin/typescript-angular-petstore.sh b/bin/typescript-angular-petstore.sh new file mode 100755 index 00000000000..60c10790c90 --- /dev/null +++ b/bin/typescript-angular-petstore.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-angular -o samples/client/petstore/typescript-angular" + +java $JAVA_OPTS -jar $executable $ags diff --git a/bin/typescript-node-petstore.sh b/bin/typescript-node-petstore.sh new file mode 100755 index 00000000000..53c5a6f8d82 --- /dev/null +++ b/bin/typescript-node-petstore.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-node -o samples/client/petstore/typescript-node" + +java $JAVA_OPTS -jar $executable $ags diff --git a/samples/client/petstore/typescript-angular/api/Category.ts b/samples/client/petstore/typescript-angular/api/Category.ts new file mode 100644 index 00000000000..e4a3caa208e --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/Category.ts @@ -0,0 +1,13 @@ +/// + +module api { + 'use strict'; + + export class Category { + + id: number; + + name: string; + } + +} \ No newline at end of file diff --git a/samples/client/petstore/typescript-angular/api/Order.ts b/samples/client/petstore/typescript-angular/api/Order.ts new file mode 100644 index 00000000000..3f37c608758 --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/Order.ts @@ -0,0 +1,32 @@ +/// + +module api { + 'use strict'; + + export class Order { + + id: number; + + petId: number; + + quantity: number; + + shipDate: DateTime; + + /** + * Order Status + */ + status: Order.StatusEnum; + + complete: boolean; + } + + export module Order { + + export enum StatusEnum { + placed = 'placed', + approved = 'approved', + delivered = 'delivered', + } + } +} \ No newline at end of file diff --git a/samples/client/petstore/typescript-angular/api/Pet.ts b/samples/client/petstore/typescript-angular/api/Pet.ts new file mode 100644 index 00000000000..c34be9c3dbc --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/Pet.ts @@ -0,0 +1,32 @@ +/// + +module api { + 'use strict'; + + export class Pet { + + id: number; + + category: Category; + + name: string; + + photoUrls: Array; + + tags: Array; + + /** + * pet status in the store + */ + status: Pet.StatusEnum; + } + + export module Pet { + + export enum StatusEnum { + available = 'available', + pending = 'pending', + sold = 'sold', + } + } +} \ No newline at end of file diff --git a/samples/client/petstore/typescript-angular/api/PetApi.ts b/samples/client/petstore/typescript-angular/api/PetApi.ts new file mode 100644 index 00000000000..2c5f2a25b6d --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/PetApi.ts @@ -0,0 +1,262 @@ +/// + +/* tslint:disable:no-unused-variable member-ordering */ + +module api { + 'use strict'; + + + export class PetApi { + private basePath = 'http://petstore.swagger.io/v2'; + + static $inject: string[] = ['$http']; + + constructor(private $http: ng.IHttpService, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + public updatePet (body: Pet, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/pet'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'PUT', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public addPet (body: Pet, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/pet'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public findPetsByStatus (status: Array, extraHttpRequestParams?: any ) : ng.IHttpPromise> { + var path = this.basePath + '/pet/findByStatus'; + + var queryParameters: any = {}; + var headers: any = {}; + + if (status !== undefined) { + queryParameters['status'] = status; + } + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public findPetsByTags (tags: Array, extraHttpRequestParams?: any ) : ng.IHttpPromise> { + var path = this.basePath + '/pet/findByTags'; + + var queryParameters: any = {}; + var headers: any = {}; + + if (tags !== undefined) { + queryParameters['tags'] = tags; + } + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public getPetById (petId: number, extraHttpRequestParams?: any ) : ng.IHttpPromise { + var path = this.basePath + '/pet/{petId}'; + + path = path.replace('{' + 'petId' + '}', String(petId)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public updatePetWithForm (petId: string, name: string, status: string, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/pet/{petId}'; + + path = path.replace('{' + 'petId' + '}', String(petId)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public deletePet (apiKey: string, petId: number, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/pet/{petId}'; + + path = path.replace('{' + 'petId' + '}', String(petId)); + + var queryParameters: any = {}; + var headers: any = {}; + + + headerParams['apiKey'] = apiKey; + var httpRequestParams: any = { + method: 'DELETE', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public uploadFile (petId: number, additionalMetadata: string, file: file, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/pet/{petId}/uploadImage'; + + path = path.replace('{' + 'petId' + '}', String(petId)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + } + + angular.module('api_PetApi', ['$http']) + .service('PetApi', PetApi); +} diff --git a/samples/client/petstore/typescript-angular/api/StoreApi.ts b/samples/client/petstore/typescript-angular/api/StoreApi.ts new file mode 100644 index 00000000000..e4c9e48e0e9 --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/StoreApi.ts @@ -0,0 +1,141 @@ +/// + +/* tslint:disable:no-unused-variable member-ordering */ + +module api { + 'use strict'; + + + export class StoreApi { + private basePath = 'http://petstore.swagger.io/v2'; + + static $inject: string[] = ['$http']; + + constructor(private $http: ng.IHttpService, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + public getInventory ( extraHttpRequestParams?: any ) : ng.IHttpPromise> { + var path = this.basePath + '/store/inventory'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public placeOrder (body: Order, extraHttpRequestParams?: any ) : ng.IHttpPromise { + var path = this.basePath + '/store/order'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public getOrderById (orderId: string, extraHttpRequestParams?: any ) : ng.IHttpPromise { + var path = this.basePath + '/store/order/{orderId}'; + + path = path.replace('{' + 'orderId' + '}', String(orderId)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public deleteOrder (orderId: string, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/store/order/{orderId}'; + + path = path.replace('{' + 'orderId' + '}', String(orderId)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'DELETE', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + } + + angular.module('api_StoreApi', ['$http']) + .service('StoreApi', StoreApi); +} diff --git a/samples/client/petstore/typescript-angular/api/Tag.ts b/samples/client/petstore/typescript-angular/api/Tag.ts new file mode 100644 index 00000000000..33f0ffaa1e2 --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/Tag.ts @@ -0,0 +1,13 @@ +/// + +module api { + 'use strict'; + + export class Tag { + + id: number; + + name: string; + } + +} \ No newline at end of file diff --git a/samples/client/petstore/typescript-angular/api/User.ts b/samples/client/petstore/typescript-angular/api/User.ts new file mode 100644 index 00000000000..57385044943 --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/User.ts @@ -0,0 +1,28 @@ +/// + +module api { + 'use strict'; + + export class User { + + id: number; + + username: string; + + firstName: string; + + lastName: string; + + email: string; + + password: string; + + phone: string; + + /** + * User Status + */ + userStatus: number; + } + +} \ No newline at end of file diff --git a/samples/client/petstore/typescript-angular/api/UserApi.ts b/samples/client/petstore/typescript-angular/api/UserApi.ts new file mode 100644 index 00000000000..dfbe9032dba --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/UserApi.ts @@ -0,0 +1,262 @@ +/// + +/* tslint:disable:no-unused-variable member-ordering */ + +module api { + 'use strict'; + + + export class UserApi { + private basePath = 'http://petstore.swagger.io/v2'; + + static $inject: string[] = ['$http']; + + constructor(private $http: ng.IHttpService, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + public createUser (body: User, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/user'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public createUsersWithArrayInput (body: Array, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/user/createWithArray'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public createUsersWithListInput (body: Array, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/user/createWithList'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'POST', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public loginUser (username: string, password: string, extraHttpRequestParams?: any ) : ng.IHttpPromise { + var path = this.basePath + '/user/login'; + + var queryParameters: any = {}; + var headers: any = {}; + + if (username !== undefined) { + queryParameters['username'] = username; + }if (password !== undefined) { + queryParameters['password'] = password; + } + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public logoutUser ( extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/user/logout'; + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public getUserByName (username: string, extraHttpRequestParams?: any ) : ng.IHttpPromise { + var path = this.basePath + '/user/{username}'; + + path = path.replace('{' + 'username' + '}', String(username)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'GET', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public updateUser (username: string, body: User, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/user/{username}'; + + path = path.replace('{' + 'username' + '}', String(username)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'PUT', + url: path, + json: true, + data: body, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + public deleteUser (username: string, extraHttpRequestParams?: any ) : ng.IHttpPromise<{}> { + var path = this.basePath + '/user/{username}'; + + path = path.replace('{' + 'username' + '}', String(username)); + + var queryParameters: any = {}; + var headers: any = {}; + + + + var httpRequestParams: any = { + method: 'DELETE', + url: path, + json: true, + + params: queryParameters, + headers: headers + }; + + if (extraHttpRequestParams) { + for (var k in extraHttpRequestParams){ + if (extraHttpRequestParams.hasOwnProperty(k)) { + httpRequestParams[k] = extraHttpRequestParams[k]; + } + } + } + + return this.$http(httpRequestParams); + } + + } + + angular.module('api_UserApi', ['$http']) + .service('UserApi', UserApi); +} diff --git a/samples/client/petstore/typescript-angular/api/api.d.ts b/samples/client/petstore/typescript-angular/api/api.d.ts new file mode 100644 index 00000000000..19c60623dc9 --- /dev/null +++ b/samples/client/petstore/typescript-angular/api/api.d.ts @@ -0,0 +1,9 @@ +/// +/// +/// +/// +/// + +/// +/// +/// diff --git a/samples/client/petstore/typescript-node/api/PetApi.ts b/samples/client/petstore/typescript-node/api/PetApi.ts new file mode 100644 index 00000000000..c948f8036e6 --- /dev/null +++ b/samples/client/petstore/typescript-node/api/PetApi.ts @@ -0,0 +1,358 @@ +/* tslint:disable:no-unused-variable */ + +export class PetApi { + private basePath = 'http://petstore.swagger.io/v2'; + + constructor(private url: string, private username: string, private password: string, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + + public updatePet (body: Pet ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/pet'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'PUT', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public addPet (body: Pet ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/pet'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public findPetsByStatus (status: Array ) : Promise<{ response: http.ClientResponse; body: Array; }> { + var path = this.url + this.basePath + '/pet/findByStatus'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + if (status !== undefined) { + queryParameters['status'] = status; + } + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: Array; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public findPetsByTags (tags: Array ) : Promise<{ response: http.ClientResponse; body: Array; }> { + var path = this.url + this.basePath + '/pet/findByTags'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + if (tags !== undefined) { + queryParameters['tags'] = tags; + } + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: Array; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public getPetById (petId: number ) : Promise<{ response: http.ClientResponse; body: Pet; }> { + var path = this.url + this.basePath + '/pet/{petId}'; + + + path = path.replace('{' + 'petId' + '}', String(petId)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: Pet; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public updatePetWithForm (petId: string, name: string, status: string ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/pet/{petId}'; + + + path = path.replace('{' + 'petId' + '}', String(petId)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public deletePet (apiKey: string, petId: number ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/pet/{petId}'; + + + path = path.replace('{' + 'petId' + '}', String(petId)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + headerParams['apiKey'] = apiKey; + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'DELETE', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public uploadFile (petId: number, additionalMetadata: string, file: file ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/pet/{petId}/uploadImage'; + + + path = path.replace('{' + 'petId' + '}', String(petId)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + +} diff --git a/samples/client/petstore/typescript-node/api/StoreApi.ts b/samples/client/petstore/typescript-node/api/StoreApi.ts new file mode 100644 index 00000000000..1c2c6623523 --- /dev/null +++ b/samples/client/petstore/typescript-node/api/StoreApi.ts @@ -0,0 +1,182 @@ +/* tslint:disable:no-unused-variable */ + +export class StoreApi { + private basePath = 'http://petstore.swagger.io/v2'; + + constructor(private url: string, private username: string, private password: string, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + + public getInventory ( ) : Promise<{ response: http.ClientResponse; body: map; }> { + var path = this.url + this.basePath + '/store/inventory'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: map; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public placeOrder (body: Order ) : Promise<{ response: http.ClientResponse; body: Order; }> { + var path = this.url + this.basePath + '/store/order'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: Order; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public getOrderById (orderId: string ) : Promise<{ response: http.ClientResponse; body: Order; }> { + var path = this.url + this.basePath + '/store/order/{orderId}'; + + + path = path.replace('{' + 'orderId' + '}', String(orderId)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: Order; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public deleteOrder (orderId: string ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/store/order/{orderId}'; + + + path = path.replace('{' + 'orderId' + '}', String(orderId)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'DELETE', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + +} diff --git a/samples/client/petstore/typescript-node/api/UserApi.ts b/samples/client/petstore/typescript-node/api/UserApi.ts new file mode 100644 index 00000000000..fa4365f8edc --- /dev/null +++ b/samples/client/petstore/typescript-node/api/UserApi.ts @@ -0,0 +1,357 @@ +/* tslint:disable:no-unused-variable */ + +export class UserApi { + private basePath = 'http://petstore.swagger.io/v2'; + + constructor(private url: string, private username: string, private password: string, basePath?: string) { + if (basePath) { + this.basePath = basePath; + } + } + + + public createUser (body: User ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/user'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public createUsersWithArrayInput (body: Array ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/user/createWithArray'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public createUsersWithListInput (body: Array ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/user/createWithList'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'POST', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public loginUser (username: string, password: string ) : Promise<{ response: http.ClientResponse; body: string; }> { + var path = this.url + this.basePath + '/user/login'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + if (username !== undefined) { + queryParameters['username'] = username; + } + if (password !== undefined) { + queryParameters['password'] = password; + } + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: string; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public logoutUser ( ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/user/logout'; + + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public getUserByName (username: string ) : Promise<{ response: http.ClientResponse; body: User; }> { + var path = this.url + this.basePath + '/user/{username}'; + + + path = path.replace('{' + 'username' + '}', String(username)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; body: User; }>(); + + request({ + method: 'GET', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public updateUser (username: string, body: User ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/user/{username}'; + + + path = path.replace('{' + 'username' + '}', String(username)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'PUT', + qs: queryParameters, + uri: path, + json: true, + body: body, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + + public deleteUser (username: string ) : Promise<{ response: http.ClientResponse; }> { + var path = this.url + this.basePath + '/user/{username}'; + + + path = path.replace('{' + 'username' + '}', String(username)); + + + var queryParameters: any = {}; + var headers: any = {}; + + + + + + + + var deferred = promise.defer<{ response: http.ClientResponse; }>(); + + request({ + method: 'DELETE', + qs: queryParameters, + uri: path, + json: true, + + auth: { + username: this.username, password: this.password + } + }, (error, response, body) => { + if (error) { + deferred.reject(error); + } else { + if (response.statusCode >= 200 && response.statusCode <= 299) { + deferred.resolve({ response: response, body: body }); + } else { + deferred.reject({ response: response, body: body }); + } + } + }); + + return deferred.promise; + } + + +} diff --git a/samples/client/petstore/typescript-node/model/Category.ts b/samples/client/petstore/typescript-node/model/Category.ts new file mode 100644 index 00000000000..fc4b2874e93 --- /dev/null +++ b/samples/client/petstore/typescript-node/model/Category.ts @@ -0,0 +1,7 @@ +export class Category { + + id: number; + + name: string; +} + diff --git a/samples/client/petstore/typescript-node/model/Order.ts b/samples/client/petstore/typescript-node/model/Order.ts new file mode 100644 index 00000000000..b46ad4570a0 --- /dev/null +++ b/samples/client/petstore/typescript-node/model/Order.ts @@ -0,0 +1,26 @@ +export class Order { + + id: number; + + petId: number; + + quantity: number; + + shipDate: DateTime; + + /** + * Order Status + */ + status: Order.StatusEnum; + + complete: boolean; +} + +export module Order { + + export enum StatusEnum { + placed = 'placed', + approved = 'approved', + delivered = 'delivered', + } +} diff --git a/samples/client/petstore/typescript-node/model/Pet.ts b/samples/client/petstore/typescript-node/model/Pet.ts new file mode 100644 index 00000000000..4a3faa129ed --- /dev/null +++ b/samples/client/petstore/typescript-node/model/Pet.ts @@ -0,0 +1,26 @@ +export class Pet { + + id: number; + + category: Category; + + name: string; + + photoUrls: Array; + + tags: Array; + + /** + * pet status in the store + */ + status: Pet.StatusEnum; +} + +export module Pet { + + export enum StatusEnum { + available = 'available', + pending = 'pending', + sold = 'sold', + } +} diff --git a/samples/client/petstore/typescript-node/model/Tag.ts b/samples/client/petstore/typescript-node/model/Tag.ts new file mode 100644 index 00000000000..6ae0d4ef576 --- /dev/null +++ b/samples/client/petstore/typescript-node/model/Tag.ts @@ -0,0 +1,7 @@ +export class Tag { + + id: number; + + name: string; +} + diff --git a/samples/client/petstore/typescript-node/model/User.ts b/samples/client/petstore/typescript-node/model/User.ts new file mode 100644 index 00000000000..fee31563d13 --- /dev/null +++ b/samples/client/petstore/typescript-node/model/User.ts @@ -0,0 +1,22 @@ +export class User { + + id: number; + + username: string; + + firstName: string; + + lastName: string; + + email: string; + + password: string; + + phone: string; + + /** + * User Status + */ + userStatus: number; +} + From e7d4a438ddea8a9c5ba43c2526c4859a7622b013 Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Wed, 17 Jun 2015 17:58:52 +0200 Subject: [PATCH 039/499] Added tests for TypeScript Angular and Node.js --- .../TypeScriptAngularModelTest.scala | 170 ++++++++++++++++++ .../TypeScriptNodeModelTest.scala | 170 ++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 modules/swagger-codegen/src/test/scala/typescriptangular/TypeScriptAngularModelTest.scala create mode 100644 modules/swagger-codegen/src/test/scala/typescriptnode/TypeScriptNodeModelTest.scala diff --git a/modules/swagger-codegen/src/test/scala/typescriptangular/TypeScriptAngularModelTest.scala b/modules/swagger-codegen/src/test/scala/typescriptangular/TypeScriptAngularModelTest.scala new file mode 100644 index 00000000000..5e28e3e8dc7 --- /dev/null +++ b/modules/swagger-codegen/src/test/scala/typescriptangular/TypeScriptAngularModelTest.scala @@ -0,0 +1,170 @@ +package typescriptangular + +import io.swagger.codegen.languages.TypeScriptAngularClientCodegen +import io.swagger.models._ +import io.swagger.models.properties._ +import org.junit.runner.RunWith +import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.junit.JUnitRunner + +import scala.collection.JavaConverters._ + +@RunWith(classOf[JUnitRunner]) +class TypeScriptAngularModelTest extends FlatSpec with Matchers { + + it should "convert a simple TypeScript Angular model" in { + val model = new ModelImpl() + .description("a sample model") + .property("id", new LongProperty()) + .property("name", new StringProperty()) + .property("createdAt", new DateTimeProperty()) + .required("id") + .required("name") + + val codegen = new TypeScriptAngularClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(3) + + val vars = cm.vars + vars.get(0).baseName should be("id") + vars.get(0).datatype should be("number") + vars.get(0).name should be("id") + vars.get(0).defaultValue should be("null") + vars.get(0).baseType should be("number") + vars.get(0).hasMore should equal(true) + vars.get(0).required should equal(true) + vars.get(0).isNotContainer should equal(true) + + vars.get(1).baseName should be("name") + vars.get(1).datatype should be("string") + vars.get(1).name should be("name") + vars.get(1).defaultValue should be("null") + vars.get(1).baseType should be("string") + vars.get(1).hasMore should equal(true) + vars.get(1).required should equal(true) + vars.get(1).isNotContainer should equal(true) + + vars.get(2).baseName should be("createdAt") + vars.get(2).complexType should be("DateTime") + vars.get(2).datatype should be("DateTime") + vars.get(2).name should be("createdAt") + vars.get(2).defaultValue should be("null") + vars.get(2).hasMore should equal(null) + vars.get(2).required should equal(null) + vars.get(2).isNotContainer should equal(true) + } + + it should "convert a model with list property" in { + val model = new ModelImpl() + .description("a sample model") + .property("id", new LongProperty()) + .property("urls", new ArrayProperty() + .items(new StringProperty())) + .required("id") + + val codegen = new TypeScriptAngularClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(2) + + val vars = cm.vars + vars.get(0).baseName should be("id") + vars.get(0).datatype should be("number") + vars.get(0).name should be("id") + vars.get(0).defaultValue should be("null") + vars.get(0).baseType should be("number") + vars.get(0).hasMore should equal(true) + vars.get(0).required should equal(true) + vars.get(0).isNotContainer should equal(true) + + vars.get(1).baseName should be("urls") + vars.get(1).datatype should be("Array") + vars.get(1).name should be("urls") + vars.get(1).baseType should be("Array") + vars.get(1).hasMore should be(null) + vars.get(1).required should equal(null) + vars.get(1).isContainer should equal(true) + } + + it should "convert a model with complex property" in { + val model = new ModelImpl() + .description("a sample model") + .property("children", new RefProperty("#/definitions/Children")) + + val codegen = new TypeScriptAngularClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(1) + + val vars = cm.vars + vars.get(0).baseName should be("children") + vars.get(0).datatype should be("Children") + vars.get(0).name should be("children") + vars.get(0).baseType should be("Children") + vars.get(0).required should equal(null) + vars.get(0).isNotContainer should equal(true) + } + + it should "convert a model with complex list property" in { + val model = new ModelImpl() + .description("a sample model") + .property("children", new ArrayProperty() + .items(new RefProperty("#/definitions/Children"))) + + val codegen = new TypeScriptAngularClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(1) + + val vars = cm.vars + vars.get(0).baseName should be("children") + vars.get(0).complexType should be("Children") + vars.get(0).datatype should be("Array") + vars.get(0).name should be("children") + vars.get(0).baseType should be("Array") + vars.get(0).required should equal(null) + vars.get(0).isContainer should equal(true) + } + + it should "convert an array model" in { + val model = new ArrayModel() + .description("an array model") + .items(new RefProperty("#/definitions/Children")) + val codegen = new TypeScriptAngularClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("an array model") + cm.vars.size should be(0) + } + + it should "convert an map model" in { + val model = new ModelImpl() + .description("an map model") + .additionalProperties(new RefProperty("#/definitions/Children")) + + val codegen = new TypeScriptAngularClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("an map model") + cm.vars.size should be(0) + cm.imports.size should be(1) + (cm.imports.asScala.toSet & Set("Children")).size should be(1) + } +} diff --git a/modules/swagger-codegen/src/test/scala/typescriptnode/TypeScriptNodeModelTest.scala b/modules/swagger-codegen/src/test/scala/typescriptnode/TypeScriptNodeModelTest.scala new file mode 100644 index 00000000000..0b91d717bf6 --- /dev/null +++ b/modules/swagger-codegen/src/test/scala/typescriptnode/TypeScriptNodeModelTest.scala @@ -0,0 +1,170 @@ +package typescriptnode + +import io.swagger.codegen.languages.TypeScriptNodeClientCodegen +import io.swagger.models._ +import io.swagger.models.properties._ +import org.junit.runner.RunWith +import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.junit.JUnitRunner + +import scala.collection.JavaConverters._ + +@RunWith(classOf[JUnitRunner]) +class TypeScriptNodeModelTest extends FlatSpec with Matchers { + + it should "convert a simple TypeScript Node model" in { + val model = new ModelImpl() + .description("a sample model") + .property("id", new LongProperty()) + .property("name", new StringProperty()) + .property("createdAt", new DateTimeProperty()) + .required("id") + .required("name") + + val codegen = new TypeScriptNodeClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(3) + + val vars = cm.vars + vars.get(0).baseName should be("id") + vars.get(0).datatype should be("number") + vars.get(0).name should be("id") + vars.get(0).defaultValue should be("null") + vars.get(0).baseType should be("number") + vars.get(0).hasMore should equal(true) + vars.get(0).required should equal(true) + vars.get(0).isNotContainer should equal(true) + + vars.get(1).baseName should be("name") + vars.get(1).datatype should be("string") + vars.get(1).name should be("name") + vars.get(1).defaultValue should be("null") + vars.get(1).baseType should be("string") + vars.get(1).hasMore should equal(true) + vars.get(1).required should equal(true) + vars.get(1).isNotContainer should equal(true) + + vars.get(2).baseName should be("createdAt") + vars.get(2).complexType should be("DateTime") + vars.get(2).datatype should be("DateTime") + vars.get(2).name should be("createdAt") + vars.get(2).defaultValue should be("null") + vars.get(2).hasMore should equal(null) + vars.get(2).required should equal(null) + vars.get(2).isNotContainer should equal(true) + } + + it should "convert a model with list property" in { + val model = new ModelImpl() + .description("a sample model") + .property("id", new LongProperty()) + .property("urls", new ArrayProperty() + .items(new StringProperty())) + .required("id") + + val codegen = new TypeScriptNodeClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(2) + + val vars = cm.vars + vars.get(0).baseName should be("id") + vars.get(0).datatype should be("number") + vars.get(0).name should be("id") + vars.get(0).defaultValue should be("null") + vars.get(0).baseType should be("number") + vars.get(0).hasMore should equal(true) + vars.get(0).required should equal(true) + vars.get(0).isNotContainer should equal(true) + + vars.get(1).baseName should be("urls") + vars.get(1).datatype should be("Array") + vars.get(1).name should be("urls") + vars.get(1).baseType should be("Array") + vars.get(1).hasMore should be(null) + vars.get(1).required should equal(null) + vars.get(1).isContainer should equal(true) + } + + it should "convert a model with complex property" in { + val model = new ModelImpl() + .description("a sample model") + .property("children", new RefProperty("#/definitions/Children")) + + val codegen = new TypeScriptNodeClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(1) + + val vars = cm.vars + vars.get(0).baseName should be("children") + vars.get(0).datatype should be("Children") + vars.get(0).name should be("children") + vars.get(0).baseType should be("Children") + vars.get(0).required should equal(null) + vars.get(0).isNotContainer should equal(true) + } + + it should "convert a model with complex list property" in { + val model = new ModelImpl() + .description("a sample model") + .property("children", new ArrayProperty() + .items(new RefProperty("#/definitions/Children"))) + + val codegen = new TypeScriptNodeClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("a sample model") + cm.vars.size should be(1) + + val vars = cm.vars + vars.get(0).baseName should be("children") + vars.get(0).complexType should be("Children") + vars.get(0).datatype should be("Array") + vars.get(0).name should be("children") + vars.get(0).baseType should be("Array") + vars.get(0).required should equal(null) + vars.get(0).isContainer should equal(true) + } + + it should "convert an array model" in { + val model = new ArrayModel() + .description("an array model") + .items(new RefProperty("#/definitions/Children")) + val codegen = new TypeScriptNodeClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("an array model") + cm.vars.size should be(0) + } + + it should "convert an map model" in { + val model = new ModelImpl() + .description("an map model") + .additionalProperties(new RefProperty("#/definitions/Children")) + + val codegen = new TypeScriptNodeClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.description should be("an map model") + cm.vars.size should be(0) + cm.imports.size should be(1) + (cm.imports.asScala.toSet & Set("Children")).size should be(1) + } +} From 10e07eaf743dc6891163bd4014c4b7f2169fc295 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 15 Jun 2015 15:44:23 +0800 Subject: [PATCH 040/499] add support for cli (perl) --- .../codegen/languages/PerlClientCodegen.java | 49 +++++++++----- .../main/resources/perl/ApiClient.mustache | 18 +++--- .../main/resources/perl/BaseObject.mustache | 4 +- .../resources/perl/Configuration.mustache | 4 +- .../src/main/resources/perl/api.mustache | 8 +-- .../src/main/resources/perl/object.mustache | 4 +- .../csharp/io/swagger/Model/ApiResponse.cs | 61 ++++++++++++++++++ .../io/swagger/client/model/ApiResponse.java | 64 +++++++++++++++++++ .../petstore/objc/client/SWGApiResponse.h | 17 +++++ .../petstore/objc/client/SWGApiResponse.m | 22 +++++++ .../lib/WWW/SwaggerClient/Configuration.pm | 2 + 11 files changed, 219 insertions(+), 34 deletions(-) create mode 100644 samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs create mode 100644 samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java create mode 100644 samples/client/petstore/objc/client/SWGApiResponse.h create mode 100644 samples/client/petstore/objc/client/SWGApiResponse.m diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java index 1b0da2698e2..39218e9d8dc 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java @@ -7,16 +7,16 @@ import io.swagger.codegen.SupportingFile; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import io.swagger.codegen.CliOption; + import java.io.File; import java.util.Arrays; import java.util.HashSet; public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { - protected String invokerPackage = "SwaggerClient"; - protected String groupId = "io.swagger"; - protected String artifactId = "swagger-client"; - protected String artifactVersion = "1.0.0"; + protected String moduleName = "SwaggerClient"; + protected String moduleVersion = "1.0.0"; public PerlClientCodegen() { super(); @@ -26,8 +26,6 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { apiTemplateFiles.put("api.mustache", ".pm"); templateDir = "perl"; - typeMapping.clear(); - languageSpecificPrimitives.clear(); reservedWords = new HashSet( Arrays.asList( @@ -44,11 +42,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { ) ); - additionalProperties.put("invokerPackage", invokerPackage); - additionalProperties.put("groupId", groupId); - additionalProperties.put("artifactId", artifactId); - additionalProperties.put("artifactVersion", artifactVersion); - + languageSpecificPrimitives.clear(); languageSpecificPrimitives.add("int"); languageSpecificPrimitives.add("double"); languageSpecificPrimitives.add("string"); @@ -58,6 +52,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { languageSpecificPrimitives.add("HASH"); languageSpecificPrimitives.add("object"); + typeMapping.clear(); typeMapping.put("integer", "int"); typeMapping.put("long", "int"); typeMapping.put("float", "double"); @@ -71,9 +66,31 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("map", "HASH"); typeMapping.put("object", "object"); - 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")); + cliOptions.clear(); + cliOptions.add(new CliOption("moduleName", "perl module name, default: SwaggerClient")); + cliOptions.add(new CliOption("moduleVersion", "perl module version, default: 1.0.0")); + } + + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey("moduleVersion")) { + moduleVersion = (String) additionalProperties.get("moduleVersion"); + } else { + additionalProperties.put("moduleVersion", moduleVersion); + } + + if (additionalProperties.containsKey("moduleName")) { + moduleName = (String) additionalProperties.get("moduleName"); + } else { + additionalProperties.put("moduleName", moduleName); + } + + supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiClient.pm")); + supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Configuration.pm")); + supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm")); } public CodegenType getTag() { @@ -95,11 +112,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/" + moduleName + apiPackage()).replace('/', File.separatorChar); } public String modelFileFolder() { - return (outputFolder + "/lib/WWW/" + invokerPackage + modelPackage()).replace('/', File.separatorChar); + return (outputFolder + "/lib/WWW/" + moduleName + modelPackage()).replace('/', File.separatorChar); } @Override diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index f57642ff293..7124424baa6 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -1,4 +1,4 @@ -package WWW::{{invokerPackage}}::ApiClient; +package WWW::{{moduleName}}::ApiClient; use strict; use warnings; @@ -18,7 +18,7 @@ use Log::Any qw($log); use Carp; use Module::Runtime qw(use_module); -use WWW::{{invokerPackage}}::Configuration; +use WWW::{{moduleName}}::Configuration; sub new { @@ -115,8 +115,8 @@ sub call_api { else { } - $self->{ua}->timeout($self->{http_timeout} || $WWW::{{invokerPackage}}::Configuration::http_timeout); - $self->{ua}->agent($self->{http_user_agent} || $WWW::{{invokerPackage}}::Configuration::http_user_agent); + $self->{ua}->timeout($self->{http_timeout} || $WWW::{{moduleName}}::Configuration::http_timeout); + $self->{ua}->agent($self->{http_user_agent} || $WWW::{{moduleName}}::Configuration::http_user_agent); my $_response = $self->{ua}->request($_request); @@ -237,7 +237,7 @@ sub deserialize } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { return $data; } else { # model - my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; + my $_instance = use_module("WWW::{{moduleName}}::Object::$class")->new; if (ref $data eq "HASH") { return $_instance->from_hash($data); } else { # string, need to json decode first @@ -287,10 +287,10 @@ sub select_header_content_type 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}; + if ($WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}) { + return $WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{moduleName}}::Configuration::api_key->{$api_key}; } else { - return $WWW::{{invokerPackage}}::Configuration::api_key->{$api_key}; + return $WWW::{{moduleName}}::Configuration::api_key->{$api_key}; } } @@ -310,7 +310,7 @@ sub update_params_for_auth { 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}} + {{#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::{{moduleName}}::Configuration::username.":".$WWW::{{moduleName}}::Configuration::password);{{/isBasic}} {{#isOAuth}}# TODO support oauth{{/isOAuth}} } {{/authMethods}} diff --git a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache index b4a7885a798..4be9f8408d6 100644 --- a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache @@ -1,4 +1,4 @@ -package WWW::{{invokerPackage}}::Object::BaseObject; +package WWW::{{moduleName}}::Object::BaseObject; require 5.6.0; use strict; @@ -68,7 +68,7 @@ sub _deserialize { } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { return $data; } else { # hash(model) - my $_instance = eval "WWW::{{invokerPackage}}::Object::$type->new()"; + my $_instance = eval "WWW::{{moduleName}}::Object::$type->new()"; return $_instance->from_hash($data); } } diff --git a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache index 38eb2ad8dae..0a097dda7bd 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache @@ -1,4 +1,4 @@ -package WWW::{{invokerPackage}}::Configuration; +package WWW::{{moduleName}}::Configuration; use strict; use warnings; @@ -7,6 +7,8 @@ use utf8; use Log::Any qw($log); use Carp; +use constant VERSION => '{{moduleVersion}}'; + # class/static variables our $api_client; our $http_timeout = 180; diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index c67139ee33d..6fb3227a6e5 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -17,7 +17,7 @@ # NOTE: This class is auto generated by the swagger code generator program. # Do not edit the class manually. # -package WWW::{{invokerPackage}}::{{classname}}; +package WWW::{{moduleName}}::{{classname}}; require 5.6.0; use strict; @@ -27,8 +27,8 @@ use Exporter; use Carp qw( croak ); use Log::Any qw($log); -use WWW::{{invokerPackage}}::ApiClient; -use WWW::{{invokerPackage}}::Configuration; +use WWW::{{moduleName}}::ApiClient; +use WWW::{{moduleName}}::Configuration; {{#operations}} our @EXPORT_OK = qw( @@ -38,7 +38,7 @@ our @EXPORT_OK = qw( sub new { my $class = shift; - my $default_api_client = $WWW::{{invokerPackage}}::Configuration::api_client ? $WWW::{{invokerPackage}}::Configuration::api_client : WWW::{{invokerPackage}}::ApiClient->new; + my $default_api_client = $WWW::{{moduleName}}::Configuration::api_client ? $WWW::{{moduleName}}::Configuration::api_client : WWW::{{moduleName}}::ApiClient->new; my (%self) = ( 'api_client' => $default_api_client, @_ diff --git a/modules/swagger-codegen/src/main/resources/perl/object.mustache b/modules/swagger-codegen/src/main/resources/perl/object.mustache index c527957a9b1..c3a15b012bb 100644 --- a/modules/swagger-codegen/src/main/resources/perl/object.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/object.mustache @@ -1,6 +1,6 @@ {{#models}} {{#model}} -package WWW::{{invokerPackage}}::Object::{{classname}}; +package WWW::{{moduleName}}::Object::{{classname}}; require 5.6.0; use strict; @@ -13,7 +13,7 @@ use Log::Any qw($log); use Date::Parse; use DateTime; -use base "WWW::{{invokerPackage}}::Object::BaseObject"; +use base "WWW::{{moduleName}}::Object::BaseObject"; # #{{description}} diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs new file mode 100644 index 00000000000..7b23e25cb55 --- /dev/null +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs @@ -0,0 +1,61 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using Newtonsoft.Json; + +namespace IO.Swagger.Model { + + /// + /// + /// + [DataContract] + public class ApiResponse { + + + [DataMember(Name="code", EmitDefaultValue=false)] + public int? Code { get; set; } + + + + [DataMember(Name="type", EmitDefaultValue=false)] + public string Type { get; set; } + + + + [DataMember(Name="message", EmitDefaultValue=false)] + public string Message { get; set; } + + + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class ApiResponse {\n"); + + sb.Append(" Code: ").Append(Code).Append("\n"); + + sb.Append(" Type: ").Append(Type).Append("\n"); + + sb.Append(" Message: ").Append(Message).Append("\n"); + + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} + + +} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java new file mode 100644 index 00000000000..802fa4743f7 --- /dev/null +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java @@ -0,0 +1,64 @@ +package io.swagger.client.model; + + +import io.swagger.annotations.*; +import com.fasterxml.jackson.annotation.JsonProperty; + + +@ApiModel(description = "") +public class ApiResponse { + + private Integer code = null; + private String type = null; + private String message = null; + + + /** + **/ + @ApiModelProperty(value = "") + @JsonProperty("code") + public Integer getCode() { + return code; + } + public void setCode(Integer code) { + this.code = code; + } + + + /** + **/ + @ApiModelProperty(value = "") + @JsonProperty("type") + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + + + /** + **/ + @ApiModelProperty(value = "") + @JsonProperty("message") + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiResponse {\n"); + + sb.append(" code: ").append(code).append("\n"); + sb.append(" type: ").append(type).append("\n"); + sb.append(" message: ").append(message).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/objc/client/SWGApiResponse.h b/samples/client/petstore/objc/client/SWGApiResponse.h new file mode 100644 index 00000000000..38525ad185d --- /dev/null +++ b/samples/client/petstore/objc/client/SWGApiResponse.h @@ -0,0 +1,17 @@ +#import +#import "SWGObject.h" + + +@protocol SWGApiResponse +@end + +@interface SWGApiResponse : SWGObject + + +@property(nonatomic) NSNumber* code; + +@property(nonatomic) NSString* type; + +@property(nonatomic) NSString* message; + +@end diff --git a/samples/client/petstore/objc/client/SWGApiResponse.m b/samples/client/petstore/objc/client/SWGApiResponse.m new file mode 100644 index 00000000000..08d8f7dae18 --- /dev/null +++ b/samples/client/petstore/objc/client/SWGApiResponse.m @@ -0,0 +1,22 @@ +#import "SWGApiResponse.h" + +@implementation SWGApiResponse + ++ (JSONKeyMapper *)keyMapper +{ + return [[JSONKeyMapper alloc] initWithDictionary:@{ @"code": @"code", @"type": @"type", @"message": @"message" }]; +} + ++ (BOOL)propertyIsOptional:(NSString *)propertyName +{ + NSArray *optionalProperties = @[@"code", @"type", @"message"]; + + if ([optionalProperties containsObject:propertyName]) { + return YES; + } + else { + return NO; + } +} + +@end diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm index bbce9d74759..aaa387236d9 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm @@ -7,6 +7,8 @@ use utf8; use Log::Any qw($log); use Carp; +use constant VERSION => '1.0.0'; + # class/static variables our $api_client; our $http_timeout = 180; From d7315b56dc720e26153eaa3b7b0641510ace2f34 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 15 Jun 2015 16:26:34 +0800 Subject: [PATCH 041/499] removed non-perl update --- .../csharp/io/swagger/Model/ApiResponse.cs | 61 ------------------ .../io/swagger/client/model/ApiResponse.java | 64 ------------------- .../petstore/objc/client/SWGApiResponse.h | 17 ----- .../petstore/objc/client/SWGApiResponse.m | 22 ------- 4 files changed, 164 deletions(-) delete mode 100644 samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs delete mode 100644 samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java delete mode 100644 samples/client/petstore/objc/client/SWGApiResponse.h delete mode 100644 samples/client/petstore/objc/client/SWGApiResponse.m diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs deleted file mode 100644 index 7b23e25cb55..00000000000 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/ApiResponse.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.Serialization; -using Newtonsoft.Json; - -namespace IO.Swagger.Model { - - /// - /// - /// - [DataContract] - public class ApiResponse { - - - [DataMember(Name="code", EmitDefaultValue=false)] - public int? Code { get; set; } - - - - [DataMember(Name="type", EmitDefaultValue=false)] - public string Type { get; set; } - - - - [DataMember(Name="message", EmitDefaultValue=false)] - public string Message { get; set; } - - - - /// - /// Get the string presentation of the object - /// - /// String presentation of the object - public override string ToString() { - var sb = new StringBuilder(); - sb.Append("class ApiResponse {\n"); - - sb.Append(" Code: ").Append(Code).Append("\n"); - - sb.Append(" Type: ").Append(Type).Append("\n"); - - sb.Append(" Message: ").Append(Message).Append("\n"); - - sb.Append("}\n"); - return sb.ToString(); - } - - /// - /// Get the JSON string presentation of the object - /// - /// JSON string presentation of the object - public string ToJson() { - return JsonConvert.SerializeObject(this, Formatting.Indented); - } - -} - - -} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java deleted file mode 100644 index 802fa4743f7..00000000000 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.swagger.client.model; - - -import io.swagger.annotations.*; -import com.fasterxml.jackson.annotation.JsonProperty; - - -@ApiModel(description = "") -public class ApiResponse { - - private Integer code = null; - private String type = null; - private String message = null; - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("code") - public Integer getCode() { - return code; - } - public void setCode(Integer code) { - this.code = code; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("type") - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - - - /** - **/ - @ApiModelProperty(value = "") - @JsonProperty("message") - public String getMessage() { - return message; - } - public void setMessage(String message) { - this.message = message; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponse {\n"); - - sb.append(" code: ").append(code).append("\n"); - sb.append(" type: ").append(type).append("\n"); - sb.append(" message: ").append(message).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/samples/client/petstore/objc/client/SWGApiResponse.h b/samples/client/petstore/objc/client/SWGApiResponse.h deleted file mode 100644 index 38525ad185d..00000000000 --- a/samples/client/petstore/objc/client/SWGApiResponse.h +++ /dev/null @@ -1,17 +0,0 @@ -#import -#import "SWGObject.h" - - -@protocol SWGApiResponse -@end - -@interface SWGApiResponse : SWGObject - - -@property(nonatomic) NSNumber* code; - -@property(nonatomic) NSString* type; - -@property(nonatomic) NSString* message; - -@end diff --git a/samples/client/petstore/objc/client/SWGApiResponse.m b/samples/client/petstore/objc/client/SWGApiResponse.m deleted file mode 100644 index 08d8f7dae18..00000000000 --- a/samples/client/petstore/objc/client/SWGApiResponse.m +++ /dev/null @@ -1,22 +0,0 @@ -#import "SWGApiResponse.h" - -@implementation SWGApiResponse - -+ (JSONKeyMapper *)keyMapper -{ - return [[JSONKeyMapper alloc] initWithDictionary:@{ @"code": @"code", @"type": @"type", @"message": @"message" }]; -} - -+ (BOOL)propertyIsOptional:(NSString *)propertyName -{ - NSArray *optionalProperties = @[@"code", @"type", @"message"]; - - if ([optionalProperties containsObject:propertyName]) { - return YES; - } - else { - return NO; - } -} - -@end From 82baa7ce4b39cb9a41513c6548460fcc0ce99876 Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 16 Jun 2015 11:25:23 +0800 Subject: [PATCH 042/499] update help text --- .../java/io/swagger/codegen/languages/PerlClientCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java index 39218e9d8dc..8c079973a1b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java @@ -67,7 +67,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("object", "object"); cliOptions.clear(); - cliOptions.add(new CliOption("moduleName", "perl module name, default: SwaggerClient")); + cliOptions.add(new CliOption("moduleName", "perl module name (convention: CamelCase), default: SwaggerClient")); cliOptions.add(new CliOption("moduleVersion", "perl module version, default: 1.0.0")); } From 64b46c2e15e0b1dd1d92afd2cc204dca48148b06 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 18 Jun 2015 02:40:15 +0800 Subject: [PATCH 043/499] update indentation, remove export --- .../main/resources/perl/ApiClient.mustache | 342 +++++++++--------- .../main/resources/perl/BaseObject.mustache | 72 ++-- .../src/main/resources/perl/api.mustache | 131 ++++--- .../src/main/resources/perl/object.mustache | 12 +- 4 files changed, 276 insertions(+), 281 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index 7124424baa6..fa88dbd0333 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -22,14 +22,14 @@ use WWW::{{moduleName}}::Configuration; sub new { - my $class = shift; - my (%args) = ( - 'ua' => LWP::UserAgent->new, - 'base_url' => '{{basePath}}', - @_ - ); - - return bless \%args, $class; + my $class = shift; + my (%args) = ( + 'ua' => LWP::UserAgent->new, + 'base_url' => '{{basePath}}', + @_ + ); + + return bless \%args, $class; } # Set the user agent of the API client @@ -37,8 +37,8 @@ sub new # @param string $user_agent The user agent of the API client # sub set_user_agent { - my ($self, $user_agent) = @_; - $self->{http_user_agent}= $user_agent; + my ($self, $user_agent) = @_; + $self->{http_user_agent}= $user_agent; } # Set timeout @@ -46,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 ($self, $seconds) = @_; - if (!looks_like_number($seconds)) { - croak('Timeout variable must be numeric.'); - } - $self->{http_timeout} = $seconds; + my ($self, $seconds) = @_; + if (!looks_like_number($seconds)) { + croak('Timeout variable must be numeric.'); + } + $self->{http_timeout} = $seconds; } # make the HTTP request @@ -61,71 +61,71 @@ sub set_timeout { # @param array $headerParams parameters to be place in request header # @return mixed sub call_api { - my $self = shift; - my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; - - # update parameters based on authentication settings - $self->update_params_for_auth($header_params, $query_params, $auth_settings); - - - 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; - if ($method eq 'POST') { - # multipart - $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? - 'form-data' : $header_params->{'Content-Type'}; - - $_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 { - } - - $self->{ua}->timeout($self->{http_timeout} || $WWW::{{moduleName}}::Configuration::http_timeout); - $self->{ua}->agent($self->{http_user_agent} || $WWW::{{moduleName}}::Configuration::http_user_agent); + my $self = shift; + my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; + + # update parameters based on authentication settings + $self->update_params_for_auth($header_params, $query_params, $auth_settings); + + + 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; + if ($method eq 'POST') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_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 { + } + + $self->{ua}->timeout($self->{http_timeout} || $WWW::{{moduleName}}::Configuration::http_timeout); + $self->{ua}->agent($self->{http_user_agent} || $WWW::{{moduleName}}::Configuration::http_user_agent); + + my $_response = $self->{ua}->request($_request); + + unless ($_response->is_success) { + croak("API Exception(".$_response->code."): ".$_response->message); + } + + return $_response->content; - my $_response = $self->{ua}->request($_request); - - unless ($_response->is_success) { - croak("API Exception(".$_response->code."): ".$_response->message); - } - - return $_response->content; - } # Take value and turn it into a string suitable for inclusion in @@ -180,13 +180,13 @@ sub to_form_value { # @param string $value the value of the parameter # @return string the header string sub to_string { - my ($self, $value) = @_; - if (ref($value) eq "DateTime") { # datetime in ISO8601 format - return $value->datetime(); - } - else { - return $value; - } + my ($self, $value) = @_; + if (ref($value) eq "DateTime") { # datetime in ISO8601 format + return $value->datetime(); + } + else { + return $value; + } } # Deserialize a JSON string into an object @@ -196,55 +196,55 @@ sub to_string { # @return object an instance of $class sub deserialize { - my ($self, $class, $data) = @_; - $log->debugf("deserializing %s for %s", $data, $class); - - if (not defined $data) { - return undef; - } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash - if ($class =~ /^HASH\[(.*),(.*)\]$/) { - my ($key_type, $type) = ($1, $2); - my %hash; - my $decoded_data = decode_json $data; - foreach my $key (keys %$decoded_data) { - if (ref $decoded_data->{$key} eq 'HASH') { - $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + my ($self, $class, $data) = @_; + $log->debugf("deserializing %s for %s", $data, $class); + + if (not defined $data) { + return undef; + } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash + if ($class =~ /^HASH\[(.*),(.*)\]$/) { + my ($key_type, $type) = ($1, $2); + my %hash; + my $decoded_data = decode_json $data; + foreach my $key (keys %$decoded_data) { + if (ref $decoded_data->{$key} eq 'HASH') { + $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + } else { + $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + } + } + return \%hash; } else { - $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + #TODO log error + } + + } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data + return $data if $data eq '[]'; # return if empty array + + my $_sub_class = substr($class, 6, -1); + my $_json_data = decode_json $data; + my @_values = (); + foreach my $_value (@$_json_data) { + if (ref $_value eq 'ARRAY') { + push @_values, $self->deserialize($_sub_class, encode_json $_value); + } else { + push @_values, $self->deserialize($_sub_class, $_value); + } + } + return \@_values; + } elsif ($class eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { + return $data; + } else { # model + my $_instance = use_module("WWW::{{moduleName}}::Object::$class")->new; + if (ref $data eq "HASH") { + return $_instance->from_hash($data); + } else { # string, need to json decode first + return $_instance->from_hash(decode_json $data); } - } - return \%hash; - } else { - #TODO log error } - - } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data - return $data if $data eq '[]'; # return if empty array - - my $_sub_class = substr($class, 6, -1); - my $_json_data = decode_json $data; - my @_values = (); - foreach my $_value (@$_json_data) { - if (ref $_value eq 'ARRAY') { - push @_values, $self->deserialize($_sub_class, encode_json $_value); - } else { - push @_values, $self->deserialize($_sub_class, $_value); - } - } - return \@_values; - } elsif ($class eq 'DateTime') { - return DateTime->from_epoch(epoch => str2time($data)); - } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { - return $data; - } else { # model - my $_instance = use_module("WWW::{{moduleName}}::Object::$class")->new; - if (ref $data eq "HASH") { - return $_instance->from_hash($data); - } else { # string, need to json decode first - return $_instance->from_hash(decode_json $data); - } - } - + } # return 'Accept' based on an array of accept provided @@ -252,16 +252,16 @@ sub deserialize # @return String Accept (e.g. application/json) sub select_header_accept { - my ($self, @header) = @_; - - if (@header == 0 || (@header == 1 && $header[0] eq '')) { - return undef; - } elsif (grep(/^application\/json$/i, @header)) { - return 'application/json'; - } else { - return join(',', @header); - } - + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return undef; + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + } # return the content type based on an array of content-type provided @@ -269,16 +269,16 @@ sub select_header_accept # @return String Content-Type (e.g. application/json) sub select_header_content_type { - my ($self, @header) = @_; - - if (@header == 0 || (@header == 1 && $header[0] eq '')) { - return 'application/json'; # default to application/json - } elsif (grep(/^application\/json$/i, @header)) { - return 'application/json'; - } else { - return join(',', @header); - } - + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return 'application/json'; # default to application/json + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + } # Get API key (with prefix if set) @@ -288,9 +288,9 @@ sub get_api_key_with_prefix { my ($self, $api_key) = @_; if ($WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}) { - return $WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{moduleName}}::Configuration::api_key->{$api_key}; + return $WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{moduleName}}::Configuration::api_key->{$api_key}; } else { - return $WWW::{{moduleName}}::Configuration::api_key->{$api_key}; + return $WWW::{{moduleName}}::Configuration::api_key->{$api_key}; } } @@ -300,24 +300,24 @@ sub get_api_key_with_prefix # @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)) { + 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::{{moduleName}}::Configuration::username.":".$WWW::{{moduleName}}::Configuration::password);{{/isBasic}} + {{#isOAuth}}# TODO support oauth{{/isOAuth}} + } + {{/authMethods}} + else { + # TODO show warning about security definition not found + } } - {{#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::{{moduleName}}::Configuration::username.":".$WWW::{{moduleName}}::Configuration::password);{{/isBasic}} - {{#isOAuth}}# TODO support oauth{{/isOAuth}} - } - {{/authMethods}} - else { - # TODO show warning about security definition not found - } - } } diff --git a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache index 4be9f8408d6..f3fca3f41a7 100644 --- a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache @@ -21,56 +21,56 @@ use DateTime; # return json string sub to_hash { - return decode_json(JSON->new->convert_blessed->encode( shift )); + return decode_json(JSON->new->convert_blessed->encode( shift )); } # used by JSON for serialization sub TO_JSON { - my $self = shift; - my $_data = {}; - foreach my $_key (keys $self->get_attribute_map) { - if (defined $self->{$_key}) { - $_data->{$self->get_attribute_map->{$_key}} = $self->{$_key}; + my $self = shift; + my $_data = {}; + foreach my $_key (keys $self->get_attribute_map) { + if (defined $self->{$_key}) { + $_data->{$self->get_attribute_map->{$_key}} = $self->{$_key}; + } } - } - return $_data; + return $_data; } # from json string sub from_hash { - my ($self, $hash) = @_; - # loop through attributes and use swagger_types to deserialize the data - while ( my ($_key, $_type) = each $self->get_swagger_types ) { - if ($_type =~ /^array\[/i) { # array - my $_subclass = substr($_type, 6, -1); - my @_array = (); - foreach my $_element (@{$hash->{$self->get_attribute_map->{$_key}}}) { - push @_array, $self->_deserialize($_subclass, $_element); - } - $self->{$_key} = \@_array; - } elsif (defined $hash->{$_key}) { #hash(model), primitive, datetime - $self->{$_key} = $self->_deserialize($_type, $hash->{$_key}); - } else { - $log->debugf("warning: %s not defined\n", $_key); + my ($self, $hash) = @_; + # loop through attributes and use swagger_types to deserialize the data + while ( my ($_key, $_type) = each $self->get_swagger_types ) { + if ($_type =~ /^array\[/i) { # array + my $_subclass = substr($_type, 6, -1); + my @_array = (); + foreach my $_element (@{$hash->{$self->get_attribute_map->{$_key}}}) { + push @_array, $self->_deserialize($_subclass, $_element); + } + $self->{$_key} = \@_array; + } elsif (defined $hash->{$_key}) { #hash(model), primitive, datetime + $self->{$_key} = $self->_deserialize($_type, $hash->{$_key}); + } else { + $log->debugf("warning: %s not defined\n", $_key); + } } - } - - return $self; + + return $self; } # deserialize non-array data sub _deserialize { - my ($self, $type, $data) = @_; - $log->debugf("deserializing %s with %s",Dumper($data), $type); - - if ($type eq 'DateTime') { - return DateTime->from_epoch(epoch => str2time($data)); - } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { - return $data; - } else { # hash(model) - my $_instance = eval "WWW::{{moduleName}}::Object::$type->new()"; - return $_instance->from_hash($data); - } + my ($self, $type, $data) = @_; + $log->debugf("deserializing %s with %s",Dumper($data), $type); + + if ($type eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { + return $data; + } else { # hash(model) + my $_instance = eval "WWW::{{moduleName}}::Object::$type->new()"; + return $_instance->from_hash($data); + } } 1; diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index 6fb3227a6e5..93848cf5af8 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -30,12 +30,6 @@ use Log::Any qw($log); use WWW::{{moduleName}}::ApiClient; use WWW::{{moduleName}}::Configuration; -{{#operations}} -our @EXPORT_OK = qw( - {{#operation}}{{{nickname}}} - {{/operation}} -); - sub new { my $class = shift; my $default_api_client = $WWW::{{moduleName}}::Configuration::api_client ? $WWW::{{moduleName}}::Configuration::api_client : WWW::{{moduleName}}::ApiClient->new; @@ -52,89 +46,90 @@ sub new { bless \%self, $class; } +{{#operations}} - {{#operation}} - # - # {{{nickname}}} - # - # {{{summary}}} - # - {{#allParams}} # @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} - {{/allParams}} # @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} - # - sub {{nickname}} { - my ($self, %args) = @_; +{{#operation}} +# +# {{{nickname}}} +# +# {{{summary}}} +# +{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} +{{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} +# +sub {{nickname}} { + my ($self, %args) = @_; - {{#allParams}}{{#required}} - # verify the required parameter '{{paramName}}' is set - unless (exists $args{'{{paramName}}'}) { - croak("Missing the required parameter '{{paramName}}' when calling {{nickname}}"); - } - {{/required}}{{/allParams}} + {{#allParams}}{{#required}} + # verify the required parameter '{{paramName}}' is set + unless (exists $args{'{{paramName}}'}) { + croak("Missing the required parameter '{{paramName}}' when calling {{nickname}}"); + } + {{/required}}{{/allParams}} - # parse inputs - my $_resource_path = '{{path}}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '{{path}}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = '{{httpMethod}}'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = '{{httpMethod}}'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->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}}); - {{#queryParams}}# query params - if ( exists $args{'{{paramName}}'}) { + {{#queryParams}}# query params + if ( exists $args{'{{paramName}}'}) { $query_params->{'{{baseName}}'} = $self->{api_client}->to_query_value($args{'{{paramName}}'}); - }{{/queryParams}} - {{#headerParams}}# header params - if ( exists $args{'{{paramName}}'}) { + }{{/queryParams}} + {{#headerParams}}# header params + if ( exists $args{'{{paramName}}'}) { $header_params->{'{{baseName}}'} = $self->{api_client}->to_header_value($args{'{{paramName}}'}); - }{{/headerParams}} - {{#pathParams}}# path params - if ( exists $args{'{{paramName}}'}) { + }{{/headerParams}} + {{#pathParams}}# path params + if ( exists $args{'{{paramName}}'}) { my $_base_variable = "{" . "{{baseName}}" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'{{paramName}}'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - }{{/pathParams}} - {{#formParams}}# form params - if ( exists $args{'{{paramName}}'} ) { + }{{/pathParams}} + {{#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}}'} = $self->{api_client}->to_form_value($args{'{{paramName}}'}); {{/isFile}} - }{{/formParams}} - my $_body_data; - {{#bodyParams}}# body params - if ( exists $args{'{{paramName}}'}) { + }{{/formParams}} + my $_body_data; + {{#bodyParams}}# body params + if ( exists $args{'{{paramName}}'}) { $_body_data = $args{'{{paramName}}'}; - }{{/bodyParams}} + }{{/bodyParams}} - # authentication setting, if any - my $auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]; + # 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, $auth_settings); - if (!$response) { + # make the API Call + {{#returnType}}my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - 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, $auth_settings); - return; - {{/returnType}} - } - {{/operation}} + } + 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, $auth_settings); + return; + {{/returnType}} +} +{{/operation}} {{newline}} {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/perl/object.mustache b/modules/swagger-codegen/src/main/resources/perl/object.mustache index c3a15b012bb..d4d6961c646 100644 --- a/modules/swagger-codegen/src/main/resources/perl/object.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/object.mustache @@ -22,13 +22,13 @@ use base "WWW::{{moduleName}}::Object::BaseObject"; # my $swagger_types = { - {{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}}, - {{/hasMore}}{{/vars}} + {{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} }; my $attribute_map = { - {{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}}, - {{/hasMore}}{{/vars}} + {{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} }; # new object @@ -45,12 +45,12 @@ sub new { # get swagger type of the attribute sub get_swagger_types { - return $swagger_types; + return $swagger_types; } # get attribute mappping sub get_attribute_map { - return $attribute_map; + return $attribute_map; } 1; From 8858e7d7e3ea9ac72f9e31e587398bb120f04935 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 18 Jun 2015 02:44:40 +0800 Subject: [PATCH 044/499] update perl sample --- .../perl/lib/WWW/SwaggerClient/ApiClient.pm | 348 ++++---- .../WWW/SwaggerClient/Object/BaseObject.pm | 72 +- .../lib/WWW/SwaggerClient/Object/Category.pm | 12 +- .../lib/WWW/SwaggerClient/Object/Order.pm | 28 +- .../perl/lib/WWW/SwaggerClient/Object/Pet.pm | 28 +- .../perl/lib/WWW/SwaggerClient/Object/Tag.pm | 12 +- .../perl/lib/WWW/SwaggerClient/Object/User.pm | 36 +- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 759 +++++++++--------- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 367 ++++----- .../perl/lib/WWW/SwaggerClient/UserApi.pm | 721 ++++++++--------- 10 files changed, 1164 insertions(+), 1219 deletions(-) diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm index 3a69adbad4d..9987a46ef76 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm @@ -22,14 +22,14 @@ use WWW::SwaggerClient::Configuration; sub new { - my $class = shift; - my (%args) = ( - 'ua' => LWP::UserAgent->new, - 'base_url' => 'http://petstore.swagger.io/v2', - @_ - ); - - return bless \%args, $class; + my $class = shift; + my (%args) = ( + 'ua' => LWP::UserAgent->new, + 'base_url' => 'http://petstore.swagger.io/v2', + @_ + ); + + return bless \%args, $class; } # Set the user agent of the API client @@ -37,8 +37,8 @@ sub new # @param string $user_agent The user agent of the API client # sub set_user_agent { - my ($self, $user_agent) = @_; - $self->{http_user_agent}= $user_agent; + my ($self, $user_agent) = @_; + $self->{http_user_agent}= $user_agent; } # Set timeout @@ -46,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 ($self, $seconds) = @_; - if (!looks_like_number($seconds)) { - croak('Timeout variable must be numeric.'); - } - $self->{http_timeout} = $seconds; + my ($self, $seconds) = @_; + if (!looks_like_number($seconds)) { + croak('Timeout variable must be numeric.'); + } + $self->{http_timeout} = $seconds; } # make the HTTP request @@ -61,71 +61,71 @@ sub set_timeout { # @param array $headerParams parameters to be place in request header # @return mixed sub call_api { - my $self = shift; - my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; - - # update parameters based on authentication settings - $self->update_params_for_auth($header_params, $query_params, $auth_settings); - - - 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; - if ($method eq 'POST') { - # multipart - $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? - 'form-data' : $header_params->{'Content-Type'}; - - $_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 { - } - - $self->{ua}->timeout($self->{http_timeout} || $WWW::SwaggerClient::Configuration::http_timeout); - $self->{ua}->agent($self->{http_user_agent} || $WWW::SwaggerClient::Configuration::http_user_agent); + my $self = shift; + my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; + + # update parameters based on authentication settings + $self->update_params_for_auth($header_params, $query_params, $auth_settings); + + + 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; + if ($method eq 'POST') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_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 { + } + + $self->{ua}->timeout($self->{http_timeout} || $WWW::SwaggerClient::Configuration::http_timeout); + $self->{ua}->agent($self->{http_user_agent} || $WWW::SwaggerClient::Configuration::http_user_agent); + + my $_response = $self->{ua}->request($_request); + + unless ($_response->is_success) { + croak("API Exception(".$_response->code."): ".$_response->message); + } + + return $_response->content; - my $_response = $self->{ua}->request($_request); - - unless ($_response->is_success) { - croak("API Exception(".$_response->code."): ".$_response->message); - } - - return $_response->content; - } # Take value and turn it into a string suitable for inclusion in @@ -180,13 +180,13 @@ sub to_form_value { # @param string $value the value of the parameter # @return string the header string sub to_string { - my ($self, $value) = @_; - if (ref($value) eq "DateTime") { # datetime in ISO8601 format - return $value->datetime(); - } - else { - return $value; - } + my ($self, $value) = @_; + if (ref($value) eq "DateTime") { # datetime in ISO8601 format + return $value->datetime(); + } + else { + return $value; + } } # Deserialize a JSON string into an object @@ -196,55 +196,55 @@ sub to_string { # @return object an instance of $class sub deserialize { - my ($self, $class, $data) = @_; - $log->debugf("deserializing %s for %s", $data, $class); - - if (not defined $data) { - return undef; - } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash - if ($class =~ /^HASH\[(.*),(.*)\]$/) { - my ($key_type, $type) = ($1, $2); - my %hash; - my $decoded_data = decode_json $data; - foreach my $key (keys %$decoded_data) { - if (ref $decoded_data->{$key} eq 'HASH') { - $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + my ($self, $class, $data) = @_; + $log->debugf("deserializing %s for %s", $data, $class); + + if (not defined $data) { + return undef; + } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash + if ($class =~ /^HASH\[(.*),(.*)\]$/) { + my ($key_type, $type) = ($1, $2); + my %hash; + my $decoded_data = decode_json $data; + foreach my $key (keys %$decoded_data) { + if (ref $decoded_data->{$key} eq 'HASH') { + $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + } else { + $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + } + } + return \%hash; } else { - $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + #TODO log error + } + + } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data + return $data if $data eq '[]'; # return if empty array + + my $_sub_class = substr($class, 6, -1); + my $_json_data = decode_json $data; + my @_values = (); + foreach my $_value (@$_json_data) { + if (ref $_value eq 'ARRAY') { + push @_values, $self->deserialize($_sub_class, encode_json $_value); + } else { + push @_values, $self->deserialize($_sub_class, $_value); + } + } + return \@_values; + } elsif ($class eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { + return $data; + } else { # model + my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; + if (ref $data eq "HASH") { + return $_instance->from_hash($data); + } else { # string, need to json decode first + return $_instance->from_hash(decode_json $data); } - } - return \%hash; - } else { - #TODO log error } - - } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data - return $data if $data eq '[]'; # return if empty array - - my $_sub_class = substr($class, 6, -1); - my $_json_data = decode_json $data; - my @_values = (); - foreach my $_value (@$_json_data) { - if (ref $_value eq 'ARRAY') { - push @_values, $self->deserialize($_sub_class, encode_json $_value); - } else { - push @_values, $self->deserialize($_sub_class, $_value); - } - } - return \@_values; - } elsif ($class eq 'DateTime') { - return DateTime->from_epoch(epoch => str2time($data)); - } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { - return $data; - } else { # model - my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; - if (ref $data eq "HASH") { - return $_instance->from_hash($data); - } else { # string, need to json decode first - return $_instance->from_hash(decode_json $data); - } - } - + } # return 'Accept' based on an array of accept provided @@ -252,16 +252,16 @@ sub deserialize # @return String Accept (e.g. application/json) sub select_header_accept { - my ($self, @header) = @_; - - if (@header == 0 || (@header == 1 && $header[0] eq '')) { - return undef; - } elsif (grep(/^application\/json$/i, @header)) { - return 'application/json'; - } else { - return join(',', @header); - } - + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return undef; + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + } # return the content type based on an array of content-type provided @@ -269,16 +269,16 @@ sub select_header_accept # @return String Content-Type (e.g. application/json) sub select_header_content_type { - my ($self, @header) = @_; - - if (@header == 0 || (@header == 1 && $header[0] eq '')) { - return 'application/json'; # default to application/json - } elsif (grep(/^application\/json$/i, @header)) { - return 'application/json'; - } else { - return join(',', @header); - } - + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return 'application/json'; # default to application/json + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + } # Get API key (with prefix if set) @@ -288,9 +288,9 @@ sub get_api_key_with_prefix { my ($self, $api_key) = @_; if ($WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}) { - return $WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}." ".$WWW::SwaggerClient::Configuration::api_key->{$api_key}; + return $WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}." ".$WWW::SwaggerClient::Configuration::api_key->{$api_key}; } else { - return $WWW::SwaggerClient::Configuration::api_key->{$api_key}; + return $WWW::SwaggerClient::Configuration::api_key->{$api_key}; } } @@ -300,28 +300,28 @@ sub get_api_key_with_prefix # @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)) { - } - elsif ($auth eq 'api_key') { - $header_params->{'api_key'} = $self->get_api_key_with_prefix('api_key'); + 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)) { + } + elsif ($auth eq 'api_key') { + $header_params->{'api_key'} = $self->get_api_key_with_prefix('api_key'); + + } + elsif ($auth eq 'petstore_auth') { + + # TODO support oauth + } + else { + # TODO show warning about security definition not found + } } - elsif ($auth eq 'petstore_auth') { - - # TODO support oauth - } - - else { - # TODO show warning about security definition not found - } - } } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm index c4fd4e6aece..12088eb56cd 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm @@ -21,56 +21,56 @@ use DateTime; # return json string sub to_hash { - return decode_json(JSON->new->convert_blessed->encode( shift )); + return decode_json(JSON->new->convert_blessed->encode( shift )); } # used by JSON for serialization sub TO_JSON { - my $self = shift; - my $_data = {}; - foreach my $_key (keys $self->get_attribute_map) { - if (defined $self->{$_key}) { - $_data->{$self->get_attribute_map->{$_key}} = $self->{$_key}; + my $self = shift; + my $_data = {}; + foreach my $_key (keys $self->get_attribute_map) { + if (defined $self->{$_key}) { + $_data->{$self->get_attribute_map->{$_key}} = $self->{$_key}; + } } - } - return $_data; + return $_data; } # from json string sub from_hash { - my ($self, $hash) = @_; - # loop through attributes and use swagger_types to deserialize the data - while ( my ($_key, $_type) = each $self->get_swagger_types ) { - if ($_type =~ /^array\[/i) { # array - my $_subclass = substr($_type, 6, -1); - my @_array = (); - foreach my $_element (@{$hash->{$self->get_attribute_map->{$_key}}}) { - push @_array, $self->_deserialize($_subclass, $_element); - } - $self->{$_key} = \@_array; - } elsif (defined $hash->{$_key}) { #hash(model), primitive, datetime - $self->{$_key} = $self->_deserialize($_type, $hash->{$_key}); - } else { - $log->debugf("warning: %s not defined\n", $_key); + my ($self, $hash) = @_; + # loop through attributes and use swagger_types to deserialize the data + while ( my ($_key, $_type) = each $self->get_swagger_types ) { + if ($_type =~ /^array\[/i) { # array + my $_subclass = substr($_type, 6, -1); + my @_array = (); + foreach my $_element (@{$hash->{$self->get_attribute_map->{$_key}}}) { + push @_array, $self->_deserialize($_subclass, $_element); + } + $self->{$_key} = \@_array; + } elsif (defined $hash->{$_key}) { #hash(model), primitive, datetime + $self->{$_key} = $self->_deserialize($_type, $hash->{$_key}); + } else { + $log->debugf("warning: %s not defined\n", $_key); + } } - } - - return $self; + + return $self; } # deserialize non-array data sub _deserialize { - my ($self, $type, $data) = @_; - $log->debugf("deserializing %s with %s",Dumper($data), $type); - - if ($type eq 'DateTime') { - return DateTime->from_epoch(epoch => str2time($data)); - } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { - return $data; - } else { # hash(model) - my $_instance = eval "WWW::SwaggerClient::Object::$type->new()"; - return $_instance->from_hash($data); - } + my ($self, $type, $data) = @_; + $log->debugf("deserializing %s with %s",Dumper($data), $type); + + if ($type eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { + return $data; + } else { # hash(model) + my $_instance = eval "WWW::SwaggerClient::Object::$type->new()"; + return $_instance->from_hash($data); + } } 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm index 857dccdce5a..2b2c0beceac 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm @@ -20,13 +20,13 @@ use base "WWW::SwaggerClient::Object::BaseObject"; # my $swagger_types = { - 'id' => 'int', - 'name' => 'string' + 'id' => 'int', + 'name' => 'string' }; my $attribute_map = { - 'id' => 'id', - 'name' => 'name' + 'id' => 'id', + 'name' => 'name' }; # new object @@ -44,12 +44,12 @@ sub new { # get swagger type of the attribute sub get_swagger_types { - return $swagger_types; + return $swagger_types; } # get attribute mappping sub get_attribute_map { - return $attribute_map; + return $attribute_map; } 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm index 35449647e13..14da4a5f3af 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm @@ -20,21 +20,21 @@ use base "WWW::SwaggerClient::Object::BaseObject"; # my $swagger_types = { - 'id' => 'int', - 'pet_id' => 'int', - 'quantity' => 'int', - 'ship_date' => 'DateTime', - 'status' => 'string', - 'complete' => 'boolean' + 'id' => 'int', + 'pet_id' => 'int', + 'quantity' => 'int', + 'ship_date' => 'DateTime', + 'status' => 'string', + 'complete' => 'boolean' }; my $attribute_map = { - 'id' => 'id', - 'pet_id' => 'petId', - 'quantity' => 'quantity', - 'ship_date' => 'shipDate', - 'status' => 'status', - 'complete' => 'complete' + 'id' => 'id', + 'pet_id' => 'petId', + 'quantity' => 'quantity', + 'ship_date' => 'shipDate', + 'status' => 'status', + 'complete' => 'complete' }; # new object @@ -60,12 +60,12 @@ sub new { # get swagger type of the attribute sub get_swagger_types { - return $swagger_types; + return $swagger_types; } # get attribute mappping sub get_attribute_map { - return $attribute_map; + return $attribute_map; } 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm index df32665e826..eb74ad3f368 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm @@ -20,21 +20,21 @@ use base "WWW::SwaggerClient::Object::BaseObject"; # my $swagger_types = { - 'id' => 'int', - 'category' => 'Category', - 'name' => 'string', - 'photo_urls' => 'ARRAY[string]', - 'tags' => 'ARRAY[Tag]', - 'status' => 'string' + 'id' => 'int', + 'category' => 'Category', + 'name' => 'string', + 'photo_urls' => 'ARRAY[string]', + 'tags' => 'ARRAY[Tag]', + 'status' => 'string' }; my $attribute_map = { - 'id' => 'id', - 'category' => 'category', - 'name' => 'name', - 'photo_urls' => 'photoUrls', - 'tags' => 'tags', - 'status' => 'status' + 'id' => 'id', + 'category' => 'category', + 'name' => 'name', + 'photo_urls' => 'photoUrls', + 'tags' => 'tags', + 'status' => 'status' }; # new object @@ -60,12 +60,12 @@ sub new { # get swagger type of the attribute sub get_swagger_types { - return $swagger_types; + return $swagger_types; } # get attribute mappping sub get_attribute_map { - return $attribute_map; + return $attribute_map; } 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm index 35850032d5c..1b136d5fbfc 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm @@ -20,13 +20,13 @@ use base "WWW::SwaggerClient::Object::BaseObject"; # my $swagger_types = { - 'id' => 'int', - 'name' => 'string' + 'id' => 'int', + 'name' => 'string' }; my $attribute_map = { - 'id' => 'id', - 'name' => 'name' + 'id' => 'id', + 'name' => 'name' }; # new object @@ -44,12 +44,12 @@ sub new { # get swagger type of the attribute sub get_swagger_types { - return $swagger_types; + return $swagger_types; } # get attribute mappping sub get_attribute_map { - return $attribute_map; + return $attribute_map; } 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm index 88a396ece3a..1beb8f0b201 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm @@ -20,25 +20,25 @@ use base "WWW::SwaggerClient::Object::BaseObject"; # my $swagger_types = { - 'id' => 'int', - 'username' => 'string', - 'first_name' => 'string', - 'last_name' => 'string', - 'email' => 'string', - 'password' => 'string', - 'phone' => 'string', - 'user_status' => 'int' + 'id' => 'int', + 'username' => 'string', + 'first_name' => 'string', + 'last_name' => 'string', + 'email' => 'string', + 'password' => 'string', + 'phone' => 'string', + 'user_status' => 'int' }; my $attribute_map = { - 'id' => 'id', - 'username' => 'username', - 'first_name' => 'firstName', - 'last_name' => 'lastName', - 'email' => 'email', - 'password' => 'password', - 'phone' => 'phone', - 'user_status' => 'userStatus' + 'id' => 'id', + 'username' => 'username', + 'first_name' => 'firstName', + 'last_name' => 'lastName', + 'email' => 'email', + 'password' => 'password', + 'phone' => 'phone', + 'user_status' => 'userStatus' }; # new object @@ -68,12 +68,12 @@ sub new { # get swagger type of the attribute sub get_swagger_types { - return $swagger_types; + return $swagger_types; } # get attribute mappping sub get_attribute_map { - return $attribute_map; + return $attribute_map; } 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 0a926625b74..7fe640aaea4 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -30,18 +30,6 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; -our @EXPORT_OK = qw( - update_pet - add_pet - find_pets_by_status - find_pets_by_tags - get_pet_by_id - update_pet_with_form - delete_pet - upload_file - -); - sub new { my $class = shift; my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; @@ -59,481 +47,472 @@ sub new { } +# +# update_pet +# +# Update an existing pet +# +# @param Pet $body Pet object that needs to be added to the store (required) +# @return void +# +sub update_pet { + my ($self, %args) = @_; + - # - # update_pet - # - # Update an existing pet - # - # @param Pet $body Pet object that needs to be added to the store (required) - # @return void - # - sub update_pet { - my ($self, %args) = @_; - + # parse inputs + my $_resource_path = '/pet'; + $_resource_path =~ s/{format}/json/; # default format to json - # parse inputs - my $_resource_path = '/pet'; - $_resource_path =~ s/{format}/json/; # default format to json + my $_method = 'PUT'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - my $_method = 'PUT'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; - - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml'); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml'); - - - - - my $_body_data; - # body params - if ( exists $args{'body'}) { + + + + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # add_pet - # - # Add a new pet to the store - # - # @param Pet $body Pet object that needs to be added to the store (required) - # @return void - # - sub add_pet { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# add_pet +# +# Add a new pet to the store +# +# @param Pet $body Pet object that needs to be added to the store (required) +# @return void +# +sub add_pet { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/pet'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml'); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml'); - - - - - my $_body_data; - # body params - if ( exists $args{'body'}) { + + + + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # find_pets_by_status - # - # Finds Pets by status - # - # @param ARRAY[string] $status Status values that need to be considered for filter (required) - # @return ARRAY[Pet] - # - sub find_pets_by_status { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# find_pets_by_status +# +# Finds Pets by status +# +# @param ARRAY[string] $status Status values that need to be considered for filter (required) +# @return ARRAY[Pet] +# +sub find_pets_by_status { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/pet/findByStatus'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet/findByStatus'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # query params - if ( exists $args{'status'}) { + # query params + if ( exists $args{'status'}) { $query_params->{'status'} = $self->{api_client}->to_query_value($args{'status'}); - } - - - - my $_body_data; - + } + + + + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); - return $_response_object; - - } - - # - # find_pets_by_tags - # - # Finds Pets by tags - # - # @param ARRAY[string] $tags Tags to filter by (required) - # @return ARRAY[Pet] - # - sub find_pets_by_tags { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); + return $_response_object; + +} +# +# find_pets_by_tags +# +# Finds Pets by tags +# +# @param ARRAY[string] $tags Tags to filter by (required) +# @return ARRAY[Pet] +# +sub find_pets_by_tags { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/pet/findByTags'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet/findByTags'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # query params - if ( exists $args{'tags'}) { + # query params + if ( exists $args{'tags'}) { $query_params->{'tags'} = $self->{api_client}->to_query_value($args{'tags'}); - } - - - - my $_body_data; - + } + + + + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); - return $_response_object; - - } - - # - # get_pet_by_id - # - # Find pet by ID - # - # @param int $pet_id ID of pet that needs to be fetched (required) - # @return Pet - # - sub get_pet_by_id { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); + return $_response_object; + +} +# +# get_pet_by_id +# +# Find pet by ID +# +# @param int $pet_id ID of pet that needs to be fetched (required) +# @return Pet +# +sub get_pet_by_id { + my ($self, %args) = @_; - - # verify the required parameter 'pet_id' is set - unless (exists $args{'pet_id'}) { - croak("Missing the required parameter 'pet_id' when calling get_pet_by_id"); - } - + + # verify the required parameter 'pet_id' is set + unless (exists $args{'pet_id'}) { + croak("Missing the required parameter 'pet_id' when calling get_pet_by_id"); + } + - # parse inputs - my $_resource_path = '/pet/{petId}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet/{petId}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - # path params - if ( exists $args{'pet_id'}) { + + + # path params + if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - + } + + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['api_key', 'petstore_auth']; + # authentication setting, if any + my $auth_settings = ['api_key', 'petstore_auth']; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('Pet', $response); - return $_response_object; - - } - - # - # update_pet_with_form - # - # Updates a pet in the store with form data - # - # @param string $pet_id ID of pet that needs to be updated (required) - # @param string $name Updated name of the pet (required) - # @param string $status Updated status of the pet (required) - # @return void - # - sub update_pet_with_form { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('Pet', $response); + return $_response_object; + +} +# +# update_pet_with_form +# +# Updates a pet in the store with form data +# +# @param string $pet_id ID of pet that needs to be updated (required) +# @param string $name Updated name of the pet (required) +# @param string $status Updated status of the pet (required) +# @return void +# +sub update_pet_with_form { + my ($self, %args) = @_; - - # verify the required parameter 'pet_id' is set - unless (exists $args{'pet_id'}) { - croak("Missing the required parameter 'pet_id' when calling update_pet_with_form"); - } - + + # verify the required parameter 'pet_id' is set + unless (exists $args{'pet_id'}) { + croak("Missing the required parameter 'pet_id' when calling update_pet_with_form"); + } + - # parse inputs - my $_resource_path = '/pet/{petId}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet/{petId}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/x-www-form-urlencoded'); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/x-www-form-urlencoded'); - - - # path params - if ( exists $args{'pet_id'}) { + + + # path params + if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - # form params - if ( exists $args{'name'} ) { + } + # form params + if ( exists $args{'name'} ) { $form_params->{'name'} = $self->{api_client}->to_form_value($args{'name'}); - }# form params - if ( exists $args{'status'} ) { + }# form params + if ( exists $args{'status'} ) { $form_params->{'status'} = $self->{api_client}->to_form_value($args{'status'}); - } - my $_body_data; - + } + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # delete_pet - # - # Deletes a pet - # - # @param string $api_key (required) - # @param int $pet_id Pet id to delete (required) - # @return void - # - sub delete_pet { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# delete_pet +# +# Deletes a pet +# +# @param string $api_key (required) +# @param int $pet_id Pet id to delete (required) +# @return void +# +sub delete_pet { + my ($self, %args) = @_; - - # verify the required parameter 'pet_id' is set - unless (exists $args{'pet_id'}) { - croak("Missing the required parameter 'pet_id' when calling delete_pet"); - } - + + # verify the required parameter 'pet_id' is set + unless (exists $args{'pet_id'}) { + croak("Missing the required parameter 'pet_id' when calling delete_pet"); + } + - # parse inputs - my $_resource_path = '/pet/{petId}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet/{petId}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'DELETE'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'DELETE'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - # header params - if ( exists $args{'api_key'}) { + + # header params + if ( exists $args{'api_key'}) { $header_params->{'api_key'} = $self->{api_client}->to_header_value($args{'api_key'}); - } - # path params - if ( exists $args{'pet_id'}) { + } + # path params + if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - + } + + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # upload_file - # - # uploads an image - # - # @param int $pet_id ID of pet to update (required) - # @param string $additional_metadata Additional data to pass to server (required) - # @param file $file file to upload (required) - # @return void - # - sub upload_file { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# upload_file +# +# uploads an image +# +# @param int $pet_id ID of pet to update (required) +# @param string $additional_metadata Additional data to pass to server (required) +# @param file $file file to upload (required) +# @return void +# +sub upload_file { + my ($self, %args) = @_; - - # verify the required parameter 'pet_id' is set - unless (exists $args{'pet_id'}) { - croak("Missing the required parameter 'pet_id' when calling upload_file"); - } - + + # verify the required parameter 'pet_id' is set + unless (exists $args{'pet_id'}) { + croak("Missing the required parameter 'pet_id' when calling upload_file"); + } + - # parse inputs - my $_resource_path = '/pet/{petId}/uploadImage'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/pet/{petId}/uploadImage'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('multipart/form-data'); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('multipart/form-data'); - - - # path params - if ( exists $args{'pet_id'}) { + + + # path params + if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - # form params - if ( exists $args{'additional_metadata'} ) { + } + # form params + if ( exists $args{'additional_metadata'} ) { $form_params->{'additionalMetadata'} = $self->{api_client}->to_form_value($args{'additional_metadata'}); - }# form params - if ( exists $args{'file'} ) { + }# form params + if ( exists $args{'file'} ) { $form_params->{'file'} = [] unless defined $form_params->{'file'}; push $form_params->{'file'}, $args{'file'}; - } - my $_body_data; - + } + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['petstore_auth']; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index c27d241cb76..6072f61518c 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -30,14 +30,6 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; -our @EXPORT_OK = qw( - get_inventory - place_order - get_order_by_id - delete_order - -); - sub new { my $class = shift; my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; @@ -55,230 +47,225 @@ sub new { } +# +# get_inventory +# +# Returns pet inventories by status +# +# @return HASH[string,int] +# +sub get_inventory { + my ($self, %args) = @_; + - # - # get_inventory - # - # Returns pet inventories by status - # - # @return HASH[string,int] - # - sub get_inventory { - my ($self, %args) = @_; - + # parse inputs + my $_resource_path = '/store/inventory'; + $_resource_path =~ s/{format}/json/; # default format to json - # parse inputs - my $_resource_path = '/store/inventory'; - $_resource_path =~ s/{format}/json/; # default format to json + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; - - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - - - my $_body_data; - + + + + + my $_body_data; + - # authentication setting, if any - my $auth_settings = ['api_key']; + # authentication setting, if any + my $auth_settings = ['api_key']; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('HASH[string,int]', $response); - return $_response_object; - - } - - # - # place_order - # - # Place an order for a pet - # - # @param Order $body order placed for purchasing the pet (required) - # @return Order - # - sub place_order { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('HASH[string,int]', $response); + return $_response_object; + +} +# +# place_order +# +# Place an order for a pet +# +# @param Order $body order placed for purchasing the pet (required) +# @return Order +# +sub place_order { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/store/order'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/store/order'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - - - my $_body_data; - # body params - if ( exists $args{'body'}) { + + + + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('Order', $response); - return $_response_object; - - } - - # - # get_order_by_id - # - # Find purchase order by ID - # - # @param string $order_id ID of pet that needs to be fetched (required) - # @return Order - # - sub get_order_by_id { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('Order', $response); + return $_response_object; + +} +# +# get_order_by_id +# +# Find purchase order by ID +# +# @param string $order_id ID of pet that needs to be fetched (required) +# @return Order +# +sub get_order_by_id { + my ($self, %args) = @_; - - # verify the required parameter 'order_id' is set - unless (exists $args{'order_id'}) { - croak("Missing the required parameter 'order_id' when calling get_order_by_id"); - } - + + # verify the required parameter 'order_id' is set + unless (exists $args{'order_id'}) { + croak("Missing the required parameter 'order_id' when calling get_order_by_id"); + } + - # parse inputs - my $_resource_path = '/store/order/{orderId}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/store/order/{orderId}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - # path params - if ( exists $args{'order_id'}) { + + + # path params + if ( exists $args{'order_id'}) { my $_base_variable = "{" . "orderId" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'order_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - + } + + my $_body_data; + - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('Order', $response); - return $_response_object; - - } - - # - # delete_order - # - # Delete purchase order by ID - # - # @param string $order_id ID of the order that needs to be deleted (required) - # @return void - # - sub delete_order { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('Order', $response); + return $_response_object; + +} +# +# delete_order +# +# Delete purchase order by ID +# +# @param string $order_id ID of the order that needs to be deleted (required) +# @return void +# +sub delete_order { + my ($self, %args) = @_; - - # verify the required parameter 'order_id' is set - unless (exists $args{'order_id'}) { - croak("Missing the required parameter 'order_id' when calling delete_order"); - } - + + # verify the required parameter 'order_id' is set + unless (exists $args{'order_id'}) { + croak("Missing the required parameter 'order_id' when calling delete_order"); + } + - # parse inputs - my $_resource_path = '/store/order/{orderId}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/store/order/{orderId}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'DELETE'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'DELETE'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - # path params - if ( exists $args{'order_id'}) { + + + # path params + if ( exists $args{'order_id'}) { my $_base_variable = "{" . "orderId" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'order_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - + } + + my $_body_data; + - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index ffb9d4b732b..f588f1bb410 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -30,18 +30,6 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; -our @EXPORT_OK = qw( - create_user - create_users_with_array_input - create_users_with_list_input - login_user - logout_user - get_user_by_name - update_user - delete_user - -); - sub new { my $class = shift; my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; @@ -59,446 +47,437 @@ sub new { } +# +# create_user +# +# Create user +# +# @param User $body Created user object (required) +# @return void +# +sub create_user { + my ($self, %args) = @_; + - # - # create_user - # - # Create user - # - # @param User $body Created user object (required) - # @return void - # - sub create_user { - my ($self, %args) = @_; - + # parse inputs + my $_resource_path = '/user'; + $_resource_path =~ s/{format}/json/; # default format to json - # parse inputs - my $_resource_path = '/user'; - $_resource_path =~ s/{format}/json/; # default format to json + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; - - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - - - my $_body_data; - # body params - if ( exists $args{'body'}) { + + + + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # create_users_with_array_input - # - # Creates list of users with given input array - # - # @param ARRAY[User] $body List of user object (required) - # @return void - # - sub create_users_with_array_input { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# create_users_with_array_input +# +# Creates list of users with given input array +# +# @param ARRAY[User] $body List of user object (required) +# @return void +# +sub create_users_with_array_input { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/user/createWithArray'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/createWithArray'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - - - my $_body_data; - # body params - if ( exists $args{'body'}) { + + + + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # create_users_with_list_input - # - # Creates list of users with given input array - # - # @param ARRAY[User] $body List of user object (required) - # @return void - # - sub create_users_with_list_input { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# create_users_with_list_input +# +# Creates list of users with given input array +# +# @param ARRAY[User] $body List of user object (required) +# @return void +# +sub create_users_with_list_input { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/user/createWithList'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/createWithList'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'POST'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'POST'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - - - my $_body_data; - # body params - if ( exists $args{'body'}) { + + + + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # login_user - # - # Logs user into the system - # - # @param string $username The user name for login (required) - # @param string $password The password for login in clear text (required) - # @return string - # - sub login_user { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# login_user +# +# Logs user into the system +# +# @param string $username The user name for login (required) +# @param string $password The password for login in clear text (required) +# @return string +# +sub login_user { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/user/login'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/login'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # query params - if ( exists $args{'username'}) { + # query params + if ( exists $args{'username'}) { $query_params->{'username'} = $self->{api_client}->to_query_value($args{'username'}); - }# query params - if ( exists $args{'password'}) { + }# query params + if ( exists $args{'password'}) { $query_params->{'password'} = $self->{api_client}->to_query_value($args{'password'}); - } - - - - my $_body_data; - + } + + + + my $_body_data; + - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('string', $response); - return $_response_object; - - } - - # - # logout_user - # - # Logs out current logged in user session - # - # @return void - # - sub logout_user { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('string', $response); + return $_response_object; + +} +# +# logout_user +# +# Logs out current logged in user session +# +# @return void +# +sub logout_user { + my ($self, %args) = @_; - + - # parse inputs - my $_resource_path = '/user/logout'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/logout'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - - - my $_body_data; - + + + + + my $_body_data; + - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # get_user_by_name - # - # Get user by user name - # - # @param string $username The name that needs to be fetched. Use user1 for testing. (required) - # @return User - # - sub get_user_by_name { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# get_user_by_name +# +# Get user by user name +# +# @param string $username The name that needs to be fetched. Use user1 for testing. (required) +# @return User +# +sub get_user_by_name { + my ($self, %args) = @_; - - # verify the required parameter 'username' is set - unless (exists $args{'username'}) { - croak("Missing the required parameter 'username' when calling get_user_by_name"); - } - + + # verify the required parameter 'username' is set + unless (exists $args{'username'}) { + croak("Missing the required parameter 'username' when calling get_user_by_name"); + } + - # parse inputs - my $_resource_path = '/user/{username}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/{username}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'GET'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'GET'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - # path params - if ( exists $args{'username'}) { + + + # path params + if ( exists $args{'username'}) { my $_base_variable = "{" . "username" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'username'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - + } + + my $_body_data; + - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - my $response = $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - if (!$response) { + # make the API Call + my $response = $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + if (!$response) { return; - } - my $_response_object = $self->{api_client}->deserialize('User', $response); - return $_response_object; - - } - - # - # update_user - # - # Updated user - # - # @param string $username name that need to be deleted (required) - # @param User $body Updated user object (required) - # @return void - # - sub update_user { - my ($self, %args) = @_; + } + my $_response_object = $self->{api_client}->deserialize('User', $response); + return $_response_object; + +} +# +# update_user +# +# Updated user +# +# @param string $username name that need to be deleted (required) +# @param User $body Updated user object (required) +# @return void +# +sub update_user { + my ($self, %args) = @_; - - # verify the required parameter 'username' is set - unless (exists $args{'username'}) { - croak("Missing the required parameter 'username' when calling update_user"); - } - + + # verify the required parameter 'username' is set + unless (exists $args{'username'}) { + croak("Missing the required parameter 'username' when calling update_user"); + } + - # parse inputs - my $_resource_path = '/user/{username}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/{username}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'PUT'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'PUT'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - # path params - if ( exists $args{'username'}) { + + + # path params + if ( exists $args{'username'}) { my $_base_variable = "{" . "username" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'username'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - # body params - if ( exists $args{'body'}) { + } + + my $_body_data; + # body params + if ( exists $args{'body'}) { $_body_data = $args{'body'}; - } + } - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - - # - # delete_user - # - # Delete user - # - # @param string $username The name that needs to be deleted (required) - # @return void - # - sub delete_user { - my ($self, %args) = @_; + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} +# +# delete_user +# +# Delete user +# +# @param string $username The name that needs to be deleted (required) +# @return void +# +sub delete_user { + my ($self, %args) = @_; - - # verify the required parameter 'username' is set - unless (exists $args{'username'}) { - croak("Missing the required parameter 'username' when calling delete_user"); - } - + + # verify the required parameter 'username' is set + unless (exists $args{'username'}) { + croak("Missing the required parameter 'username' when calling delete_user"); + } + - # parse inputs - my $_resource_path = '/user/{username}'; - $_resource_path =~ s/{format}/json/; # default format to json + # parse inputs + my $_resource_path = '/user/{username}'; + $_resource_path =~ s/{format}/json/; # default format to json - my $_method = 'DELETE'; - my $query_params = {}; - my $header_params = {}; - my $form_params = {}; + my $_method = 'DELETE'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; - # 'Accept' and 'Content-Type' header - my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); - if ($_header_accept) { + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept('application/json', 'application/xml'); + if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; - } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - - - # path params - if ( exists $args{'username'}) { + + + # path params + if ( exists $args{'username'}) { my $_base_variable = "{" . "username" . "}"; my $_base_value = $self->{api_client}->to_path_value($args{'username'}); $_resource_path =~ s/$_base_variable/$_base_value/g; - } - - my $_body_data; - + } + + my $_body_data; + - # authentication setting, if any - my $auth_settings = []; + # authentication setting, if any + my $auth_settings = []; - # make the API Call - - $self->{api_client}->call_api($_resource_path, $_method, - $query_params, $form_params, - $header_params, $_body_data, $auth_settings); - return; - - } - + # make the API Call + + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; + +} 1; From 0da3e58fffb324e5821978c85d6a6d3b962f71dd Mon Sep 17 00:00:00 2001 From: geekerzp Date: Fri, 12 Jun 2015 14:48:02 +0800 Subject: [PATCH 045/499] Support map response for objc client. not completed --- .../codegen/languages/ObjcClientCodegen.java | 16 +- ...ApiClient.m => SWGApiClient-body.mustache} | 260 +++++--------- ...iClient.h => SWGApiClient-header.mustache} | 54 ++- .../src/main/resources/objc/api-body.mustache | 34 +- .../apiBodyResponseWithContainer.mustache | 7 + .../src/test/scala/Objc/ObjcModelTest.scala | 4 +- .../petstore/objc/client/SWGApiClient.h | 58 ++- .../petstore/objc/client/SWGApiClient.m | 260 +++++--------- .../client/petstore/objc/client/SWGPetApi.m | 338 ++++++------------ .../client/petstore/objc/client/SWGStoreApi.h | 4 +- .../client/petstore/objc/client/SWGStoreApi.m | 187 +++------- .../client/petstore/objc/client/SWGUserApi.m | 323 ++++++----------- 12 files changed, 539 insertions(+), 1006 deletions(-) rename modules/swagger-codegen/src/main/resources/objc/{SWGApiClient.m => SWGApiClient-body.mustache} (70%) rename modules/swagger-codegen/src/main/resources/objc/{SWGApiClient.h => SWGApiClient-header.mustache} (72%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java index 01f72040bf5..ce3ec065012 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java @@ -143,15 +143,15 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m")); supportingFiles.add(new SupportingFile("SWGQueryParamCollection.h", sourceFolder, "SWGQueryParamCollection.h")); supportingFiles.add(new SupportingFile("SWGQueryParamCollection.m", sourceFolder, "SWGQueryParamCollection.m")); - supportingFiles.add(new SupportingFile("SWGApiClient.h", sourceFolder, "SWGApiClient.h")); - supportingFiles.add(new SupportingFile("SWGApiClient.m", sourceFolder, "SWGApiClient.m")); + supportingFiles.add(new SupportingFile("SWGApiClient-header.mustache", sourceFolder, "SWGApiClient.h")); + supportingFiles.add(new SupportingFile("SWGApiClient-body.mustache", sourceFolder, "SWGApiClient.m")); supportingFiles.add(new SupportingFile("SWGFile.h", sourceFolder, "SWGFile.h")); supportingFiles.add(new SupportingFile("SWGFile.m", sourceFolder, "SWGFile.m")); supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", sourceFolder, "JSONValueTransformer+ISO8601.m")); supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", sourceFolder, "JSONValueTransformer+ISO8601.h")); supportingFiles.add(new SupportingFile("SWGConfiguration-body.mustache", sourceFolder, "SWGConfiguration.m")); supportingFiles.add(new SupportingFile("SWGConfiguration-header.mustache", sourceFolder, "SWGConfiguration.h")); - supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile")); + // supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile")); } @Override @@ -215,6 +215,16 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { } return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + + String innerTypeDeclaration = getTypeDeclaration(inner); + + if (innerTypeDeclaration.endsWith("*")) { + innerTypeDeclaration = innerTypeDeclaration.substring(0, innerTypeDeclaration.length() - 1); + } + return getSwaggerType(p) + "* /* NSString, " + innerTypeDeclaration + " */"; } else { String swaggerType = getSwaggerType(p); diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache similarity index 70% rename from modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m rename to modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache index 5e2985bbe79..ee8be40e2ab 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache @@ -351,179 +351,114 @@ static bool loggingEnabled = true; *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; } -#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 { - // setting request serializer - if ([requestContentType isEqualToString:@"application/json"]) { - self.requestSerializer = [AFJSONRequestSerializer serializer]; - } - else if ([requestContentType isEqualToString:@"application/x-www-form-urlencoded"]) { - self.requestSerializer = [AFHTTPRequestSerializer serializer]; - } - else if ([requestContentType isEqualToString:@"multipart/form-data"]) { - self.requestSerializer = [AFHTTPRequestSerializer serializer]; - } - else { - NSAssert(false, @"unsupport request type %@", requestContentType); +- (id) deserialize:(id) data class:(NSString *) class { + NSRegularExpression *regexp = nil; + NSTextCheckingResult *match = nil; + NSMutableArray *resultArray = nil; + NSMutableDictionary *resultDict = nil; + + // list of models + NSString *arrayOfModelsPat = @"NSArray<(.+)>"; + regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat + options:NSRegularExpressionCaseInsensitive + error:nil]; + + match = [regexp firstMatchInString:class + options:0 + range:NSMakeRange(0, [class length])]; + + if (match) { + NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]]; + + resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [resultArray addObject:[self deserialize:obj class:innerType]]; + } + ]; + + return resultArray; } - // setting response serializer - if ([responseContentType isEqualToString:@"application/json"]) { - self.responseSerializer = [AFJSONResponseSerializer serializer]; + // list of primitives + NSString *arrayOfPrimitivesPet = @"NSArray"; + regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPet + options:NSRegularExpressionCaseInsensitive + error:nil]; + match = [regexp firstMatchInString:class + options:0 + range:NSMakeRange(0, [class length])]; + + if (match) { + resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [resultArray addObject:[self deserialize:obj class:NSStringFromClass([obj class])]]; + }]; + + return resultArray; } - else { - self.responseSerializer = [AFHTTPResponseSerializer serializer]; + + // map + NSString *dictPat = @"NSDictionary /\\* (.+), (.+) \\*/"; + regexp = [NSRegularExpression regularExpressionWithPattern:dictPat + options:NSRegularExpressionCaseInsensitive + error:nil]; + match = [regexp firstMatchInString:class + options:0 + range:NSMakeRange(0, [class length])]; + + if (match) { + NSString *valueType = [class substringWithRange:[match rangeAtIndex:2]]; + + resultDict = [NSMutableDictionary dictionaryWithCapacity:[data count]]; + [data enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [resultDict setValue:[self deserialize:obj class:valueType] forKey:key]; + }]; + + return resultDict; } - // auth setting - [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; + // primitives + NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"BOOL", @"NSNumber"]; - NSMutableURLRequest * request = nil; - if (body != nil && [body isKindOfClass:[NSArray class]]){ - SWGFile * file; - NSMutableDictionary * params = [[NSMutableDictionary alloc] init]; - for(id obj in body) { - if([obj isKindOfClass:[SWGFile class]]) { - file = (SWGFile*) obj; - requestContentType = @"multipart/form-data"; - } - else if([obj isKindOfClass:[NSDictionary class]]) { - for(NSString * key in obj) { - params[key] = obj[key]; - } - } + if ([primitiveTypes containsObject:class]) { + if ([class isEqualToString:@"NSString"]) { + return [NSString stringWithString:data]; } - NSString * urlString = [[NSURL URLWithString:path relativeToURL:self.baseURL] absoluteString]; - - // request with multipart form - if([requestContentType isEqualToString:@"multipart/form-data"]) { - request = [self.requestSerializer multipartFormRequestWithMethod: @"POST" - URLString: urlString - parameters: nil - constructingBodyWithBlock: ^(id formData) { - - for(NSString * key in params) { - NSData* data = [params[key] dataUsingEncoding:NSUTF8StringEncoding]; - [formData appendPartWithFormData: data name: key]; - } - - if (file) { - [formData appendPartWithFileData: [file data] - name: [file paramName] - fileName: [file name] - mimeType: [file mimeType]]; - } - - } - error:nil]; + else if ([class isEqualToString:@"NSDate"]) { + return [NSDate dateWithISO8601String:data]; } - // request with form parameters or json - else { - NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams]; - NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString]; - - request = [self.requestSerializer requestWithMethod:method - URLString:urlString - parameters:params - error:nil]; + else if ([class isEqualToString:@"BOOL"]) { + // Returns YES on encountering one of "Y", "y", "T", "t", or a + // digit 1-9—the method ignores any trailing characters + // NSString => BOOL => NSNumber + return [NSNumber numberWithBool:[data boolValue]]; + } + else if ([class isEqualToString:@"NSNumber"]) { + return [data numberFromString:data]; } } - else { - NSString * pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams]; - NSString * urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString]; - - request = [self.requestSerializer requestWithMethod:method - URLString:urlString - parameters:body - error:nil]; - } - BOOL hasHeaderParams = false; - if(headerParams != nil && [headerParams count] > 0) - hasHeaderParams = true; - if(offlineState) { - NSLog(@"%@ cache forced", path); - [request setCachePolicy:NSURLRequestReturnCacheDataDontLoad]; - } - else if(!hasHeaderParams && [method isEqualToString:@"GET"] && cacheEnabled) { - NSLog(@"%@ cache enabled", path); - [request setCachePolicy:NSURLRequestUseProtocolCachePolicy]; - } - else { - NSLog(@"%@ cache disabled", path); - [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; + + // model + Class ModelClass = NSClassFromString(class); + if ([ModelClass instancesRespondToSelector:@selector(initWithDictionary:error:)]) { + return [[ModelClass alloc] initWithDictionary:data error:nil]; } - if(body != nil) { - if([body isKindOfClass:[NSDictionary class]] || [body isKindOfClass:[NSArray class]]){ - [self.requestSerializer setValue:requestContentType forHTTPHeaderField:@"Content-Type"]; - } - else if ([body isKindOfClass:[SWGFile class]]) {} - else { - NSAssert(false, @"unsupported post type!"); - } - } - if(headerParams != nil){ - for(NSString * key in [headerParams keyEnumerator]){ - [request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key]; - } - } - [self.requestSerializer setValue:responseContentType forHTTPHeaderField:@"Accept"]; - - // Always disable cookies! - [request setHTTPShouldHandleCookies:NO]; - - - if (self.logRequests) { - [self logRequest:request]; - } - - NSNumber* requestId = [SWGApiClient queueRequest]; - AFHTTPRequestOperation *op = - [self HTTPRequestOperationWithRequest:request - success:^(AFHTTPRequestOperation *operation, id JSON) { - if([self executeRequestWithId:requestId]) { - if(self.logServerResponses) - [self logResponse:JSON forRequest:request error:nil]; - completionBlock(JSON, nil); - } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - if([self executeRequestWithId:requestId]) { - NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; - if(operation.responseObject) { - // Add in the (parsed) response body. - userInfo[SWGResponseObjectErrorKey] = operation.responseObject; - } - NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo]; - - if(self.logServerResponses) - [self logResponse:nil forRequest:request error:augmentedError]; - completionBlock(nil, augmentedError); - } - } - ]; - - [self.operationQueue addOperation:op]; - return requestId; + return nil; } --(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 { +#pragma mark - Perform Request Methods + +-(NSNumber*) requestWithCompletionBlock: (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 (^)(id, NSError *))completionBlock { // setting request serializer if ([requestContentType isEqualToString:@"application/json"]) { self.requestSerializer = [AFJSONRequestSerializer serializer]; @@ -648,11 +583,11 @@ static bool loggingEnabled = true; NSNumber* requestId = [SWGApiClient queueRequest]; AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request - success:^(AFHTTPRequestOperation *operation, id responseObject) { - NSString *response = [operation responseString]; + success:^(AFHTTPRequestOperation *operation, id response) { if([self executeRequestWithId:requestId]) { - if(self.logServerResponses) - [self logResponse:responseObject forRequest:request error:nil]; + if(self.logServerResponses) { + [self logResponse:response forRequest:request error:nil]; + } completionBlock(response, nil); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { @@ -683,3 +618,4 @@ static bool loggingEnabled = true; + diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache similarity index 72% rename from modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h rename to modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache index 250811c4016..09cb6fe57bd 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache @@ -1,6 +1,10 @@ #import +#import #import "AFHTTPRequestOperationManager.h" +{{#models}}{{#model}}#import "{{classname}}.h" +{{/model}}{{/models}} + /** * A key for `NSError` user info dictionaries. * @@ -159,37 +163,16 @@ extern NSString *const SWGResponseObjectErrorKey; WithAuthSettings:(NSArray *)authSettings; /** - * Perform request + * Deserialize the given data to Objective-C object. * - * 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. + * @param data The data will be deserialized. + * @param class The type of objective-c object. */ --(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; +- (id) deserialize:(id) data class:(NSString *) class; /** * Perform request * - * Request with empty response - * * @param path Request url. * @param method Request method. * @param queryParams Request query parameters. @@ -202,15 +185,18 @@ extern NSString *const SWGResponseObjectErrorKey; * * @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; +-(NSNumber*) requestWithCompletionBlock:(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 (^)(id, NSError *))completionBlock; + + @end + diff --git a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache index 40d75bd806b..ba61a8b2c7c 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache @@ -195,27 +195,19 @@ static NSString * basePath = @"{{basePath}}"; } {{/requiredParams}} {{/requiredParamCount}} - - {{#returnContainer}} - // response is in a container - {{>apiBodyResponseWithContainer}}{{/returnContainer}} - - {{#returnSimpleType}} - // non container response - - {{#returnTypeIsPrimitive}} - // primitive response - {{>apiPrimitiveResponse}}{{/returnTypeIsPrimitive}} - - {{#returnBaseType}} - // complex response - {{>apiNonPrimitiveResponse}}{{/returnBaseType}} - {{/returnSimpleType}} - - {{^returnSimpleType}}{{^returnContainer}} - // it's void - {{>voidResponse}} - {{/returnContainer}}{{/returnSimpleType}} + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"{{httpMethod}}" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + {{^returnType}}completionBlock(error);{{/returnType}} + {{#returnType}}completionBlock([self.apiClient deserialize: data class:@"{{{returnType}}}"], error);{{/returnType}} + } + ]; } {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache b/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache index acaeaf2ddf5..7d178353d52 100644 --- a/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache @@ -36,3 +36,10 @@ {{/isListContainer}} }]; + + + + + + + diff --git a/modules/swagger-codegen/src/test/scala/Objc/ObjcModelTest.scala b/modules/swagger-codegen/src/test/scala/Objc/ObjcModelTest.scala index 6cfac9a0eff..6747b94d4f8 100644 --- a/modules/swagger-codegen/src/test/scala/Objc/ObjcModelTest.scala +++ b/modules/swagger-codegen/src/test/scala/Objc/ObjcModelTest.scala @@ -118,7 +118,7 @@ class ObjcModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("translations") - vars.get(0).datatype should be("NSDictionary*") + vars.get(0).datatype should be("NSDictionary* /* NSString, NSString */") vars.get(0).name should be("translations") vars.get(0).baseType should be("NSDictionary") vars.get(0).containerType should be("map") @@ -192,7 +192,7 @@ class ObjcModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") vars.get(0).complexType should be("SWGChildren") - vars.get(0).datatype should be("NSDictionary*") + vars.get(0).datatype should be("NSDictionary* /* NSString, SWGChildren */") vars.get(0).name should be("children") vars.get(0).baseType should be("NSDictionary") vars.get(0).containerType should be("map") diff --git a/samples/client/petstore/objc/client/SWGApiClient.h b/samples/client/petstore/objc/client/SWGApiClient.h index 250811c4016..829aec58b96 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.h +++ b/samples/client/petstore/objc/client/SWGApiClient.h @@ -1,6 +1,14 @@ #import +#import #import "AFHTTPRequestOperationManager.h" +#import "SWGUser.h" +#import "SWGCategory.h" +#import "SWGPet.h" +#import "SWGTag.h" +#import "SWGOrder.h" + + /** * A key for `NSError` user info dictionaries. * @@ -159,37 +167,16 @@ extern NSString *const SWGResponseObjectErrorKey; WithAuthSettings:(NSArray *)authSettings; /** - * Perform request + * Deserialize the given data to Objective-C object. * - * 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. + * @param data The data will be deserialized. + * @param class The type of objective-c object. */ --(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; +- (id) deserialize:(id) data class:(NSString *) class; /** * Perform request * - * Request with empty response - * * @param path Request url. * @param method Request method. * @param queryParams Request query parameters. @@ -202,15 +189,18 @@ extern NSString *const SWGResponseObjectErrorKey; * * @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; +-(NSNumber*) requestWithCompletionBlock:(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 (^)(id, NSError *))completionBlock; + + @end + diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index 5e2985bbe79..ee8be40e2ab 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -351,179 +351,114 @@ static bool loggingEnabled = true; *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; } -#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 { - // setting request serializer - if ([requestContentType isEqualToString:@"application/json"]) { - self.requestSerializer = [AFJSONRequestSerializer serializer]; - } - else if ([requestContentType isEqualToString:@"application/x-www-form-urlencoded"]) { - self.requestSerializer = [AFHTTPRequestSerializer serializer]; - } - else if ([requestContentType isEqualToString:@"multipart/form-data"]) { - self.requestSerializer = [AFHTTPRequestSerializer serializer]; - } - else { - NSAssert(false, @"unsupport request type %@", requestContentType); +- (id) deserialize:(id) data class:(NSString *) class { + NSRegularExpression *regexp = nil; + NSTextCheckingResult *match = nil; + NSMutableArray *resultArray = nil; + NSMutableDictionary *resultDict = nil; + + // list of models + NSString *arrayOfModelsPat = @"NSArray<(.+)>"; + regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat + options:NSRegularExpressionCaseInsensitive + error:nil]; + + match = [regexp firstMatchInString:class + options:0 + range:NSMakeRange(0, [class length])]; + + if (match) { + NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]]; + + resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [resultArray addObject:[self deserialize:obj class:innerType]]; + } + ]; + + return resultArray; } - // setting response serializer - if ([responseContentType isEqualToString:@"application/json"]) { - self.responseSerializer = [AFJSONResponseSerializer serializer]; + // list of primitives + NSString *arrayOfPrimitivesPet = @"NSArray"; + regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPet + options:NSRegularExpressionCaseInsensitive + error:nil]; + match = [regexp firstMatchInString:class + options:0 + range:NSMakeRange(0, [class length])]; + + if (match) { + resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [resultArray addObject:[self deserialize:obj class:NSStringFromClass([obj class])]]; + }]; + + return resultArray; } - else { - self.responseSerializer = [AFHTTPResponseSerializer serializer]; + + // map + NSString *dictPat = @"NSDictionary /\\* (.+), (.+) \\*/"; + regexp = [NSRegularExpression regularExpressionWithPattern:dictPat + options:NSRegularExpressionCaseInsensitive + error:nil]; + match = [regexp firstMatchInString:class + options:0 + range:NSMakeRange(0, [class length])]; + + if (match) { + NSString *valueType = [class substringWithRange:[match rangeAtIndex:2]]; + + resultDict = [NSMutableDictionary dictionaryWithCapacity:[data count]]; + [data enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [resultDict setValue:[self deserialize:obj class:valueType] forKey:key]; + }]; + + return resultDict; } - // auth setting - [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; + // primitives + NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"BOOL", @"NSNumber"]; - NSMutableURLRequest * request = nil; - if (body != nil && [body isKindOfClass:[NSArray class]]){ - SWGFile * file; - NSMutableDictionary * params = [[NSMutableDictionary alloc] init]; - for(id obj in body) { - if([obj isKindOfClass:[SWGFile class]]) { - file = (SWGFile*) obj; - requestContentType = @"multipart/form-data"; - } - else if([obj isKindOfClass:[NSDictionary class]]) { - for(NSString * key in obj) { - params[key] = obj[key]; - } - } + if ([primitiveTypes containsObject:class]) { + if ([class isEqualToString:@"NSString"]) { + return [NSString stringWithString:data]; } - NSString * urlString = [[NSURL URLWithString:path relativeToURL:self.baseURL] absoluteString]; - - // request with multipart form - if([requestContentType isEqualToString:@"multipart/form-data"]) { - request = [self.requestSerializer multipartFormRequestWithMethod: @"POST" - URLString: urlString - parameters: nil - constructingBodyWithBlock: ^(id formData) { - - for(NSString * key in params) { - NSData* data = [params[key] dataUsingEncoding:NSUTF8StringEncoding]; - [formData appendPartWithFormData: data name: key]; - } - - if (file) { - [formData appendPartWithFileData: [file data] - name: [file paramName] - fileName: [file name] - mimeType: [file mimeType]]; - } - - } - error:nil]; + else if ([class isEqualToString:@"NSDate"]) { + return [NSDate dateWithISO8601String:data]; } - // request with form parameters or json - else { - NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams]; - NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString]; - - request = [self.requestSerializer requestWithMethod:method - URLString:urlString - parameters:params - error:nil]; + else if ([class isEqualToString:@"BOOL"]) { + // Returns YES on encountering one of "Y", "y", "T", "t", or a + // digit 1-9—the method ignores any trailing characters + // NSString => BOOL => NSNumber + return [NSNumber numberWithBool:[data boolValue]]; + } + else if ([class isEqualToString:@"NSNumber"]) { + return [data numberFromString:data]; } } - else { - NSString * pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams]; - NSString * urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString]; - - request = [self.requestSerializer requestWithMethod:method - URLString:urlString - parameters:body - error:nil]; - } - BOOL hasHeaderParams = false; - if(headerParams != nil && [headerParams count] > 0) - hasHeaderParams = true; - if(offlineState) { - NSLog(@"%@ cache forced", path); - [request setCachePolicy:NSURLRequestReturnCacheDataDontLoad]; - } - else if(!hasHeaderParams && [method isEqualToString:@"GET"] && cacheEnabled) { - NSLog(@"%@ cache enabled", path); - [request setCachePolicy:NSURLRequestUseProtocolCachePolicy]; - } - else { - NSLog(@"%@ cache disabled", path); - [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; + + // model + Class ModelClass = NSClassFromString(class); + if ([ModelClass instancesRespondToSelector:@selector(initWithDictionary:error:)]) { + return [[ModelClass alloc] initWithDictionary:data error:nil]; } - if(body != nil) { - if([body isKindOfClass:[NSDictionary class]] || [body isKindOfClass:[NSArray class]]){ - [self.requestSerializer setValue:requestContentType forHTTPHeaderField:@"Content-Type"]; - } - else if ([body isKindOfClass:[SWGFile class]]) {} - else { - NSAssert(false, @"unsupported post type!"); - } - } - if(headerParams != nil){ - for(NSString * key in [headerParams keyEnumerator]){ - [request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key]; - } - } - [self.requestSerializer setValue:responseContentType forHTTPHeaderField:@"Accept"]; - - // Always disable cookies! - [request setHTTPShouldHandleCookies:NO]; - - - if (self.logRequests) { - [self logRequest:request]; - } - - NSNumber* requestId = [SWGApiClient queueRequest]; - AFHTTPRequestOperation *op = - [self HTTPRequestOperationWithRequest:request - success:^(AFHTTPRequestOperation *operation, id JSON) { - if([self executeRequestWithId:requestId]) { - if(self.logServerResponses) - [self logResponse:JSON forRequest:request error:nil]; - completionBlock(JSON, nil); - } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - if([self executeRequestWithId:requestId]) { - NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; - if(operation.responseObject) { - // Add in the (parsed) response body. - userInfo[SWGResponseObjectErrorKey] = operation.responseObject; - } - NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo]; - - if(self.logServerResponses) - [self logResponse:nil forRequest:request error:augmentedError]; - completionBlock(nil, augmentedError); - } - } - ]; - - [self.operationQueue addOperation:op]; - return requestId; + return nil; } --(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 { +#pragma mark - Perform Request Methods + +-(NSNumber*) requestWithCompletionBlock: (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 (^)(id, NSError *))completionBlock { // setting request serializer if ([requestContentType isEqualToString:@"application/json"]) { self.requestSerializer = [AFJSONRequestSerializer serializer]; @@ -648,11 +583,11 @@ static bool loggingEnabled = true; NSNumber* requestId = [SWGApiClient queueRequest]; AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request - success:^(AFHTTPRequestOperation *operation, id responseObject) { - NSString *response = [operation responseString]; + success:^(AFHTTPRequestOperation *operation, id response) { if([self executeRequestWithId:requestId]) { - if(self.logServerResponses) - [self logResponse:responseObject forRequest:request error:nil]; + if(self.logServerResponses) { + [self logResponse:response forRequest:request error:nil]; + } completionBlock(response, nil); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { @@ -683,3 +618,4 @@ static bool loggingEnabled = true; + diff --git a/samples/client/petstore/objc/client/SWGPetApi.m b/samples/client/petstore/objc/client/SWGPetApi.m index c14da125af5..8a03932001c 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.m +++ b/samples/client/petstore/objc/client/SWGPetApi.m @@ -153,30 +153,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"PUT" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"PUT" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -260,30 +249,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -350,44 +328,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - // response is in a container - // array container response type - return [self.apiClient dictionary: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - return; - } - - if([data isKindOfClass:[NSArray class]]){ - NSMutableArray * objs = [[NSMutableArray alloc] initWithCapacity:[data count]]; - for (NSDictionary* dict in (NSArray*)data) { - - - SWGPet* d = [[SWGPet alloc] initWithDictionary:dict error:nil]; - - [objs addObject:d]; - } - completionBlock((NSArray*)objs, nil); - } - - - }]; - - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"NSArray*"], error); + } + ]; } /*! @@ -454,44 +407,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - // response is in a container - // array container response type - return [self.apiClient dictionary: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - return; - } - - if([data isKindOfClass:[NSArray class]]){ - NSMutableArray * objs = [[NSMutableArray alloc] initWithCapacity:[data count]]; - for (NSDictionary* dict in (NSArray*)data) { - - - SWGPet* d = [[SWGPet alloc] initWithDictionary:dict error:nil]; - - [objs addObject:d]; - } - completionBlock((NSArray*)objs, nil); - } - - - }]; - - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"NSArray*"], error); + } + ]; } /*! @@ -556,44 +484,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - // non container response - - - - - // complex response - - // comples response type - return [self.apiClient dictionary: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - - return; - } - SWGPet* result = nil; - if (data) { - result = [[SWGPet alloc] initWithDictionary:data error:nil]; - } - completionBlock(result , nil); - - }]; - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"SWGPet*"], error); + } + ]; } /*! @@ -678,30 +581,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -770,30 +662,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"DELETE" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"DELETE" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -885,30 +766,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } diff --git a/samples/client/petstore/objc/client/SWGStoreApi.h b/samples/client/petstore/objc/client/SWGStoreApi.h index 49d8db806c8..b7d64469532 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.h +++ b/samples/client/petstore/objc/client/SWGStoreApi.h @@ -21,10 +21,10 @@ - return type: NSDictionary* + return type: NSDictionary* /* NSString, NSNumber */ */ -(NSNumber*) getInventoryWithCompletionBlock : - (void (^)(NSDictionary* output, NSError* error))completionBlock; + (void (^)(NSDictionary* /* NSString, NSNumber */ output, NSError* error))completionBlock; diff --git a/samples/client/petstore/objc/client/SWGStoreApi.m b/samples/client/petstore/objc/client/SWGStoreApi.m index a112db6d639..0af0ebaad78 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.m +++ b/samples/client/petstore/objc/client/SWGStoreApi.m @@ -74,10 +74,10 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; /*! * Returns pet inventories by status * Returns a map of status codes to quantities - * \returns NSDictionary* + * \returns NSDictionary* /* NSString, NSNumber */ */ -(NSNumber*) getInventoryWithCompletionBlock: - (void (^)(NSDictionary* output, NSError* error))completionBlock + (void (^)(NSDictionary* /* NSString, NSNumber */ output, NSError* error))completionBlock { @@ -127,37 +127,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - // response is in a container - // map container response type - return [self.apiClient dictionary: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - return; - } - - NSDictionary *result = nil; - if (data) { - result = [[NSDictionary alloc]initWithDictionary: data]; - } - completionBlock(data, nil); - - }]; - - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"NSDictionary* /* NSString, NSNumber */"], error); + } + ]; } /*! @@ -241,44 +223,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - // non container response - - - - - // complex response - - // comples response type - return [self.apiClient dictionary: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - - return; - } - SWGOrder* result = nil; - if (data) { - result = [[SWGOrder alloc] initWithDictionary:data error:nil]; - } - completionBlock(result , nil); - - }]; - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"SWGOrder*"], error); + } + ]; } /*! @@ -343,44 +300,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - // non container response - - - - - // complex response - - // comples response type - return [self.apiClient dictionary: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - - return; - } - SWGOrder* result = nil; - if (data) { - result = [[SWGOrder alloc] initWithDictionary:data error:nil]; - } - completionBlock(result , nil); - - }]; - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"SWGOrder*"], error); + } + ]; } /*! @@ -445,30 +377,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"DELETE" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"DELETE" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } diff --git a/samples/client/petstore/objc/client/SWGUserApi.m b/samples/client/petstore/objc/client/SWGUserApi.m index e2fe69aca8d..401df17e396 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.m +++ b/samples/client/petstore/objc/client/SWGUserApi.m @@ -152,30 +152,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -259,30 +248,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -366,30 +344,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"POST" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"POST" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -460,43 +427,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - // non container response - - - // primitive response - // primitive response type - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(nil, error); - return; - } - NSString *result = data ? [[NSString alloc]initWithString: data] : nil; - completionBlock(result, nil); - }]; - - - - - - - // complex response - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"NSString*"], error); + } + ]; } /*! @@ -555,30 +498,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -643,44 +575,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - // non container response - - - - - // complex response - - // comples response type - return [self.apiClient dictionary: requestUrl - method: @"GET" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - completionBlock(nil, error); - - return; - } - SWGUser* result = nil; - if (data) { - result = [[SWGUser alloc] initWithDictionary:data error:nil]; - } - completionBlock(result , nil); - - }]; - - - - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"GET" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + + completionBlock([self.apiClient deserialize: data class:@"SWGUser*"], error); + } + ]; } /*! @@ -770,30 +677,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"PUT" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"PUT" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } /*! @@ -858,30 +754,19 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - - - - - - - // it's void - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"DELETE" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - - + return [self.apiClient requestWithCompletionBlock: requestUrl + method: @"DELETE" + queryParams: queryParams + body: bodyDictionary + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + completionBlock: ^(id data, NSError *error) { + completionBlock(error); + + } + ]; } From c50c8b724d65186b4c548f0a76495871832f709e Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 09:32:53 +0800 Subject: [PATCH 046/499] Support map response for objc client. completed. --- .../resources/objc/SWGApiClient-body.mustache | 23 ++- .../src/main/resources/objc/api-body.mustache | 12 +- .../main/resources/objc/api-header.mustache | 19 +- .../apiBodyResponseWithContainer.mustache | 45 ----- .../objc/apiNonPrimitiveResponse.mustache | 24 --- .../objc/apiPrimitiveResponse.mustache | 36 ---- .../main/resources/objc/voidResponse.mustache | 15 -- .../PetstoreClientTests/StoreApiTest.m | 47 +++++ .../SwaggerClient.xcodeproj/project.pbxproj | 4 + .../SwaggerClient/ViewController.m | 9 +- .../SwaggerClientTests/SWGApiClientTest.m | 62 +++++++ .../petstore/objc/client/SWGApiClient.m | 23 ++- .../client/petstore/objc/client/SWGPetApi.h | 162 +++++++++--------- .../client/petstore/objc/client/SWGPetApi.m | 106 ++++++------ .../client/petstore/objc/client/SWGStoreApi.h | 74 ++++---- .../client/petstore/objc/client/SWGStoreApi.m | 47 +++-- .../client/petstore/objc/client/SWGUserApi.h | 154 ++++++++--------- .../client/petstore/objc/client/SWGUserApi.m | 98 +++++------ 18 files changed, 477 insertions(+), 483 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache create mode 100644 samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache index ee8be40e2ab..45c6fc6d305 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache @@ -351,6 +351,7 @@ static bool loggingEnabled = true; *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; } +#pragma mark - Deserialize methods - (id) deserialize:(id) data class:(NSString *) class { NSRegularExpression *regexp = nil; @@ -358,6 +359,11 @@ static bool loggingEnabled = true; NSMutableArray *resultArray = nil; NSMutableDictionary *resultDict = nil; + // remove "*" from class, if ends with "*" + if ([class hasSuffix:@"*"]) { + class = [class substringToIndex:[class length] - 1]; + } + // list of models NSString *arrayOfModelsPat = @"NSArray<(.+)>"; regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat @@ -371,7 +377,7 @@ static bool loggingEnabled = true; if (match) { NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]]; - resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + resultArray = [NSMutableArray arrayWithCapacity:[data count]]; [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [resultArray addObject:[self deserialize:obj class:innerType]]; } @@ -390,7 +396,7 @@ static bool loggingEnabled = true; range:NSMakeRange(0, [class length])]; if (match) { - resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + resultArray = [NSMutableArray arrayWithCapacity:[data count]]; [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [resultArray addObject:[self deserialize:obj class:NSStringFromClass([obj class])]]; }]; @@ -399,7 +405,7 @@ static bool loggingEnabled = true; } // map - NSString *dictPat = @"NSDictionary /\\* (.+), (.+) \\*/"; + NSString *dictPat = @"NSDictionary\\* /\\* (.+), (.+) \\*/"; regexp = [NSRegularExpression regularExpressionWithPattern:dictPat options:NSRegularExpressionCaseInsensitive error:nil]; @@ -435,7 +441,16 @@ static bool loggingEnabled = true; return [NSNumber numberWithBool:[data boolValue]]; } else if ([class isEqualToString:@"NSNumber"]) { - return [data numberFromString:data]; + // NSNumber from NSNumber + if ([data isKindOfClass:[NSNumber class]]) { + return data; + } + // NSNumber from NSString + else { + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + formatter.numberStyle = NSNumberFormatterDecimalStyle; + return [formatter numberFromString:data]; + } } } diff --git a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache index ba61a8b2c7c..1f3c6ca299e 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache @@ -74,12 +74,12 @@ static NSString * basePath = @"{{basePath}}"; {{#operation}} -/*! - * {{{summary}}} - * {{{notes}}} -{{#allParams}} * \param {{paramName}} {{{description}}} -{{/allParams}} * \returns {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} - */ +// +// {{{summary}}} +// {{{notes}}} +// {{#allParams}} @param {{paramName}} {{{description}}} +// {{/allParams}} @returns {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} +// -(NSNumber*) {{nickname}}WithCompletionBlock{{^allParams}}: {{/allParams}}{{#allParams}}{{#secondaryParam}} {{paramName}}{{/secondaryParam}}: ({{{dataType}}}) {{paramName}} {{/allParams}} {{#returnBaseType}}{{#hasParams}}completionHandler: {{/hasParams}}(void (^)({{{returnType}}} output, NSError* error))completionBlock{{/returnBaseType}} diff --git a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache index 65f4c39e0b3..cc9ad03616e 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache @@ -17,16 +17,15 @@ +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; {{#operation}} -/** - - {{{summary}}} - {{#notes}}{{{notes}}}{{/notes}} - - {{#allParams}}@param {{paramName}} {{description}} - {{/allParams}} - - return type: {{{returnType}}} - */ +// +// +// {{{summary}}} +// {{#notes}}{{{notes}}}{{/notes}} +// +// {{#allParams}}@param {{paramName}} {{description}} +// {{/allParams}} +// +// @return {{{returnType}}} -(NSNumber*) {{nickname}}WithCompletionBlock {{^allParams}}:{{/allParams}}{{#allParams}}{{#secondaryParam}} {{paramName}}{{/secondaryParam}}:({{{dataType}}}) {{paramName}} {{#hasMore}} {{/hasMore}}{{/allParams}} {{#returnBaseType}}{{#hasParams}} diff --git a/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache b/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache deleted file mode 100644 index 7d178353d52..00000000000 --- a/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache +++ /dev/null @@ -1,45 +0,0 @@ - // {{returnContainer}} container response type - return [self.apiClient dictionary: requestUrl - method: @"{{httpMethod}}" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - {{#returnBaseType}}completionBlock(nil, error);{{/returnBaseType}}{{^returnBaseType}}completionBlock(error);{{/returnBaseType}} - return; - } - {{#isMapContainer}} - NSDictionary *result = nil; - if (data) { - result = [[NSDictionary alloc]initWithDictionary: data]; - } - completionBlock(data, nil); - {{/isMapContainer}}{{#isListContainer}} - {{#returnBaseType}}if([data isKindOfClass:[NSArray class]]){ - NSMutableArray * objs = [[NSMutableArray alloc] initWithCapacity:[data count]]; - for (NSDictionary* dict in (NSArray*)data) { - {{#returnTypeIsPrimitive}} - {{returnBaseType}}* d = [[{{{returnBaseType}}} alloc]initWithString: dict]; - {{/returnTypeIsPrimitive}} - {{^returnTypeIsPrimitive}} - {{{returnBaseType}}}* d = [[{{{returnBaseType}}} alloc] initWithDictionary:dict error:nil]; - {{/returnTypeIsPrimitive}} - [objs addObject:d]; - } - completionBlock(({{{returnType}}})objs, nil); - } - {{/returnBaseType}} - {{/isListContainer}} - }]; - - - - - - - - diff --git a/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache b/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache deleted file mode 100644 index da8ea063bfb..00000000000 --- a/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache +++ /dev/null @@ -1,24 +0,0 @@ - {{^returnTypeIsPrimitive}} - // comples response type - return [self.apiClient dictionary: requestUrl - method: @"{{httpMethod}}" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSDictionary *data, NSError *error) { - if (error) { - {{#returnBaseType}}completionBlock(nil, error);{{/returnBaseType}} - {{^returnBaseType}}completionBlock(error);{{/returnBaseType}} - return; - } - {{#returnType}}{{returnType}} result = nil; - if (data) { - result = [[{{#instantiationType}}NSClassFromString(@"{{{instantiationType}}}") {{/instantiationType}}{{^instantiationType}}{{{returnBaseType}}} {{/instantiationType}} alloc] {{#returnContainer}}{{#isMapContainer}}initWithDictionary{{/isMapContainer}}{{#isListContainer}} initWithDictionary{{/isListContainer}}{{/returnContainer}}{{^returnContainer}} initWithDictionary{{/returnContainer}}:data error:nil]; - } - {{#returnType}}completionBlock(result , nil);{{/returnType}} - {{/returnType}} - }]; - {{/returnTypeIsPrimitive}} diff --git a/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache b/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache deleted file mode 100644 index d44d356526d..00000000000 --- a/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache +++ /dev/null @@ -1,36 +0,0 @@ - // primitive response type - {{#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) { - if (error) { - completionBlock(nil, error); - return; - } - {{returnBaseType}} *result = data ? [[{{#instantiationType}}NSClassFromString(@"{{{instantiationType}}}") {{/instantiationType}}{{^instantiationType}}{{{returnBaseType}}} {{/instantiationType}} alloc]initWithString: data] : nil; - completionBlock(result, nil); - }]; - {{/returnBaseType}} - {{^returnBaseType}} - // no return base type - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"{{httpMethod}}" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; - {{/returnBaseType}} - diff --git a/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache b/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache deleted file mode 100644 index 7bbbc14c066..00000000000 --- a/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache +++ /dev/null @@ -1,15 +0,0 @@ - return [self.apiClient stringWithCompletionBlock: requestUrl - method: @"{{httpMethod}}" - queryParams: queryParams - body: bodyDictionary - headerParams: headerParams - authSettings: authSettings - requestContentType: requestContentType - responseContentType: responseContentType - completionBlock: ^(NSString *data, NSError *error) { - if (error) { - completionBlock(error); - return; - } - completionBlock(nil); - }]; diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m new file mode 100644 index 00000000000..5440935be1b --- /dev/null +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m @@ -0,0 +1,47 @@ +#import +#import +#import "SWGStoreApi.h" + +@interface StoreApiTest : XCTestCase + +@property (nonatomic) SWGStoreApi *api; + +@end + +@implementation StoreApiTest + +- (void)setUp { + [super setUp]; + self.api = [[SWGStoreApi alloc] init]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testGetInventory { + XCTestExpectation *expectation = [self expectationWithDescription:@"testGetPetByStatus"]; + + [self.api getInventoryWithCompletionBlock:^(NSDictionary *output, NSError *error) { + + if (error) { + XCTFail(@"got error %@", error); + } + + if (!output) { + XCTFail(@"failed to fetch inventory"); + } + + NSSet *expectKeys = [NSSet setWithArray:@[@"confused", @"string", @"pending", @"available", @"sold"]]; + NSSet *keys = [NSSet setWithArray:[output allKeys]]; + + XCTAssertEqualObjects(expectKeys, keys); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10.0 handler:nil]; +} + + +@end diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj index ae903f27499..ffb61953051 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ BA525648922D4C0E9F44D4F1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 73DA4F1067C343C3962F1542 /* libPods.a */; }; CF0560EB1B1855CF00C0D4EC /* SWGConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */; }; CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF31D0981B105E4B00509935 /* SWGApiClientTest.m */; }; + CFB37D061B2B11DD00D2E5F1 /* StoreApiTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */; }; CFD1B6701B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; EA66999A1811D2FA00A70D03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA6699991811D2FA00A70D03 /* Foundation.framework */; }; @@ -60,6 +61,7 @@ CF0560E91B1855CF00C0D4EC /* SWGConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWGConfiguration.h; sourceTree = ""; }; CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGConfiguration.m; sourceTree = ""; }; CF31D0981B105E4B00509935 /* SWGApiClientTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGApiClientTest.m; sourceTree = ""; }; + CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StoreApiTest.m; sourceTree = ""; }; CFD1B66E1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JSONValueTransformer+ISO8601.h"; sourceTree = ""; }; CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "JSONValueTransformer+ISO8601.m"; sourceTree = ""; }; E2B6DA00BE52336E23783686 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "../Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -212,6 +214,7 @@ isa = PBXGroup; children = ( EA8CD3EB1AC274BE00C47D0B /* PetApiTest.h */, + CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */, CF31D0981B105E4B00509935 /* SWGApiClientTest.m */, EA6699C71811D2FB00A70D03 /* PetApiTest.m */, EA6699C21811D2FB00A70D03 /* Supporting Files */, @@ -426,6 +429,7 @@ EAB26B0C1AC8DF78002F5C7A /* PetApiTest.h in Sources */, CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */, EAB26B0D1AC8DF78002F5C7A /* PetApiTest.m in Sources */, + CFB37D061B2B11DD00D2E5F1 /* StoreApiTest.m in Sources */, CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m index fd15f391f49..56d0a8f621f 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m @@ -8,6 +8,7 @@ #import "ViewController.h" #import "SWGPetApi.h" +#import "SWGStoreApi.h" #import "SWGConfiguration.h" @interface ViewController () @@ -54,14 +55,6 @@ // } ]; */ - SWGConfiguration *config = [SWGConfiguration sharedConfig]; - config.username = @"foo"; - config.password = @"bar"; - SWGPetApi *api = [[SWGPetApi alloc] init]; - [api addPetWithCompletionBlock:nil - completionHandler:^(NSError *error) { - - }]; } - (void)didReceiveMemoryWarning diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m index 61925b16960..1bd0c0eb1c3 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m @@ -98,4 +98,66 @@ XCTAssertEqualObjects(basicAuthCredentials, [config getBasicAuthToken]); } +- (void)testDeserialize { + id data; + id result; + + // list of models + data = + @[ + @{ + @"id": @119, + @"category": @{ + @"id": @0, + @"name": @"string" + }, + @"name": @"doggie", + @"photoUrls": @[ + @"string" + ], + @"tags": @[ + @{ + @"id": @0, + @"name": @"string" + } + ], + @"status": @"available" + + }]; + result = [self.apiClient deserialize:data class:@"NSArray*"]; + + XCTAssertTrue([result isKindOfClass:[NSArray class]]); + XCTAssertTrue([[result firstObject] isKindOfClass:[SWGPet class]]); + XCTAssertEqualObjects([[result firstObject] _id], @119); + + // map of models + data = + @{ + @"pet": @{ + @"id": @119, + @"category": @{ + @"id": @0, + @"name": @"string" + }, + @"name": @"doggie", + @"photoUrls": @[ + @"string" + ], + @"tags": @[ + @{ + @"id": @0, + @"name": @"string" + } + ], + @"status": @"available" + + } + }; + result = [self.apiClient deserialize:data class:@"NSDictionary* /* NSString, SWGPet */"]; + + XCTAssertTrue([result isKindOfClass:[NSDictionary class]]); + XCTAssertTrue([result[@"pet"] isKindOfClass:[SWGPet class]]); + XCTAssertEqualObjects([result[@"pet"] _id], @119); +} + @end diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index ee8be40e2ab..45c6fc6d305 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -351,6 +351,7 @@ static bool loggingEnabled = true; *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; } +#pragma mark - Deserialize methods - (id) deserialize:(id) data class:(NSString *) class { NSRegularExpression *regexp = nil; @@ -358,6 +359,11 @@ static bool loggingEnabled = true; NSMutableArray *resultArray = nil; NSMutableDictionary *resultDict = nil; + // remove "*" from class, if ends with "*" + if ([class hasSuffix:@"*"]) { + class = [class substringToIndex:[class length] - 1]; + } + // list of models NSString *arrayOfModelsPat = @"NSArray<(.+)>"; regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat @@ -371,7 +377,7 @@ static bool loggingEnabled = true; if (match) { NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]]; - resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + resultArray = [NSMutableArray arrayWithCapacity:[data count]]; [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [resultArray addObject:[self deserialize:obj class:innerType]]; } @@ -390,7 +396,7 @@ static bool loggingEnabled = true; range:NSMakeRange(0, [class length])]; if (match) { - resultArray = [NSMutableArray arrayWithCapacity:[data length]]; + resultArray = [NSMutableArray arrayWithCapacity:[data count]]; [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [resultArray addObject:[self deserialize:obj class:NSStringFromClass([obj class])]]; }]; @@ -399,7 +405,7 @@ static bool loggingEnabled = true; } // map - NSString *dictPat = @"NSDictionary /\\* (.+), (.+) \\*/"; + NSString *dictPat = @"NSDictionary\\* /\\* (.+), (.+) \\*/"; regexp = [NSRegularExpression regularExpressionWithPattern:dictPat options:NSRegularExpressionCaseInsensitive error:nil]; @@ -435,7 +441,16 @@ static bool loggingEnabled = true; return [NSNumber numberWithBool:[data boolValue]]; } else if ([class isEqualToString:@"NSNumber"]) { - return [data numberFromString:data]; + // NSNumber from NSNumber + if ([data isKindOfClass:[NSNumber class]]) { + return data; + } + // NSNumber from NSString + else { + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + formatter.numberStyle = NSNumberFormatterDecimalStyle; + return [formatter numberFromString:data]; + } } } diff --git a/samples/client/petstore/objc/client/SWGPetApi.h b/samples/client/petstore/objc/client/SWGPetApi.h index aa255cd144e..ce17f2c30ab 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.h +++ b/samples/client/petstore/objc/client/SWGPetApi.h @@ -15,98 +15,92 @@ +(SWGPetApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; -/** - - Update an existing pet - - - @param body Pet object that needs to be added to the store - - - return type: - */ +// +// +// Update an existing pet +// +// +// @param body Pet object that needs to be added to the store +// +// +// @return -(NSNumber*) updatePetWithCompletionBlock :(SWGPet*) body completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Add a new pet to the store - - - @param body Pet object that needs to be added to the store - - - return type: - */ +// +// +// Add a new pet to the store +// +// +// @param body Pet object that needs to be added to the store +// +// +// @return -(NSNumber*) addPetWithCompletionBlock :(SWGPet*) body completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Finds Pets by status - Multiple status values can be provided with comma seperated strings - - @param status Status values that need to be considered for filter - - - return type: NSArray* - */ +// +// +// Finds Pets by status +// Multiple status values can be provided with comma seperated strings +// +// @param status Status values that need to be considered for filter +// +// +// @return NSArray* -(NSNumber*) findPetsByStatusWithCompletionBlock :(NSArray*) status completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock; -/** - - Finds Pets by tags - Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - - @param tags Tags to filter by - - - return type: NSArray* - */ +// +// +// Finds Pets by tags +// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. +// +// @param tags Tags to filter by +// +// +// @return NSArray* -(NSNumber*) findPetsByTagsWithCompletionBlock :(NSArray*) tags completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock; -/** - - Find pet by ID - Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - - @param petId ID of pet that needs to be fetched - - - return type: SWGPet* - */ +// +// +// Find pet by ID +// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions +// +// @param petId ID of pet that needs to be fetched +// +// +// @return SWGPet* -(NSNumber*) getPetByIdWithCompletionBlock :(NSNumber*) petId completionHandler: (void (^)(SWGPet* output, NSError* error))completionBlock; -/** - - Updates a pet in the store with form data - - - @param petId ID of pet that needs to be updated - @param name Updated name of the pet - @param status Updated status of the pet - - - return type: - */ +// +// +// Updates a pet in the store with form data +// +// +// @param petId ID of pet that needs to be updated +// @param name Updated name of the pet +// @param status Updated status of the pet +// +// +// @return -(NSNumber*) updatePetWithFormWithCompletionBlock :(NSString*) petId name:(NSString*) name status:(NSString*) status @@ -115,17 +109,16 @@ completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Deletes a pet - - - @param apiKey - @param petId Pet id to delete - - - return type: - */ +// +// +// Deletes a pet +// +// +// @param apiKey +// @param petId Pet id to delete +// +// +// @return -(NSNumber*) deletePetWithCompletionBlock :(NSString*) apiKey petId:(NSNumber*) petId @@ -133,18 +126,17 @@ completionHandler: (void (^)(NSError* error))completionBlock; -/** - - uploads an image - - - @param petId ID of pet to update - @param additionalMetadata Additional data to pass to server - @param file file to upload - - - return type: - */ +// +// +// uploads an image +// +// +// @param petId ID of pet to update +// @param additionalMetadata Additional data to pass to server +// @param file file to upload +// +// +// @return -(NSNumber*) uploadFileWithCompletionBlock :(NSNumber*) petId additionalMetadata:(NSString*) additionalMetadata file:(SWGFile*) file diff --git a/samples/client/petstore/objc/client/SWGPetApi.m b/samples/client/petstore/objc/client/SWGPetApi.m index 8a03932001c..d23a2ce9979 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.m +++ b/samples/client/petstore/objc/client/SWGPetApi.m @@ -72,12 +72,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; } -/*! - * Update an existing pet - * - * \param body Pet object that needs to be added to the store - * \returns void - */ +// +// Update an existing pet +// +// @param body Pet object that needs to be added to the store +// @returns void +// -(NSNumber*) updatePetWithCompletionBlock: (SWGPet*) body @@ -168,12 +168,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Add a new pet to the store - * - * \param body Pet object that needs to be added to the store - * \returns void - */ +// +// Add a new pet to the store +// +// @param body Pet object that needs to be added to the store +// @returns void +// -(NSNumber*) addPetWithCompletionBlock: (SWGPet*) body @@ -264,12 +264,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Finds Pets by status - * Multiple status values can be provided with comma seperated strings - * \param status Status values that need to be considered for filter - * \returns NSArray* - */ +// +// Finds Pets by status +// Multiple status values can be provided with comma seperated strings +// @param status Status values that need to be considered for filter +// @returns NSArray* +// -(NSNumber*) findPetsByStatusWithCompletionBlock: (NSArray*) status completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock @@ -343,12 +343,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Finds Pets by tags - * Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - * \param tags Tags to filter by - * \returns NSArray* - */ +// +// Finds Pets by tags +// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. +// @param tags Tags to filter by +// @returns NSArray* +// -(NSNumber*) findPetsByTagsWithCompletionBlock: (NSArray*) tags completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock @@ -422,12 +422,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Find pet by ID - * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - * \param petId ID of pet that needs to be fetched - * \returns SWGPet* - */ +// +// Find pet by ID +// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions +// @param petId ID of pet that needs to be fetched +// @returns SWGPet* +// -(NSNumber*) getPetByIdWithCompletionBlock: (NSNumber*) petId completionHandler: (void (^)(SWGPet* output, NSError* error))completionBlock @@ -499,14 +499,14 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Updates a pet in the store with form data - * - * \param petId ID of pet that needs to be updated - * \param name Updated name of the pet - * \param status Updated status of the pet - * \returns void - */ +// +// Updates a pet in the store with form data +// +// @param petId ID of pet that needs to be updated +// @param name Updated name of the pet +// @param status Updated status of the pet +// @returns void +// -(NSNumber*) updatePetWithFormWithCompletionBlock: (NSString*) petId name: (NSString*) name status: (NSString*) status @@ -596,13 +596,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Deletes a pet - * - * \param apiKey - * \param petId Pet id to delete - * \returns void - */ +// +// Deletes a pet +// +// @param apiKey +// @param petId Pet id to delete +// @returns void +// -(NSNumber*) deletePetWithCompletionBlock: (NSString*) apiKey petId: (NSNumber*) petId @@ -677,14 +677,14 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * uploads an image - * - * \param petId ID of pet to update - * \param additionalMetadata Additional data to pass to server - * \param file file to upload - * \returns void - */ +// +// uploads an image +// +// @param petId ID of pet to update +// @param additionalMetadata Additional data to pass to server +// @param file file to upload +// @returns void +// -(NSNumber*) uploadFileWithCompletionBlock: (NSNumber*) petId additionalMetadata: (NSString*) additionalMetadata file: (SWGFile*) file diff --git a/samples/client/petstore/objc/client/SWGStoreApi.h b/samples/client/petstore/objc/client/SWGStoreApi.h index b7d64469532..a59d861bbb8 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.h +++ b/samples/client/petstore/objc/client/SWGStoreApi.h @@ -14,62 +14,58 @@ +(SWGStoreApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; -/** - - Returns pet inventories by status - Returns a map of status codes to quantities - - - - return type: NSDictionary* /* NSString, NSNumber */ - */ +// +// +// Returns pet inventories by status +// Returns a map of status codes to quantities +// +// +// +// @return NSDictionary* /* NSString, NSNumber */ -(NSNumber*) getInventoryWithCompletionBlock : (void (^)(NSDictionary* /* NSString, NSNumber */ output, NSError* error))completionBlock; -/** - - Place an order for a pet - - - @param body order placed for purchasing the pet - - - return type: SWGOrder* - */ +// +// +// Place an order for a pet +// +// +// @param body order placed for purchasing the pet +// +// +// @return SWGOrder* -(NSNumber*) placeOrderWithCompletionBlock :(SWGOrder*) body completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock; -/** - - Find purchase order by ID - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - @param orderId ID of pet that needs to be fetched - - - return type: SWGOrder* - */ +// +// +// Find purchase order by ID +// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions +// +// @param orderId ID of pet that needs to be fetched +// +// +// @return SWGOrder* -(NSNumber*) getOrderByIdWithCompletionBlock :(NSString*) orderId completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock; -/** - - Delete purchase order by ID - For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors - - @param orderId ID of the order that needs to be deleted - - - return type: - */ +// +// +// Delete purchase order by ID +// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors +// +// @param orderId ID of the order that needs to be deleted +// +// +// @return -(NSNumber*) deleteOrderWithCompletionBlock :(NSString*) orderId diff --git a/samples/client/petstore/objc/client/SWGStoreApi.m b/samples/client/petstore/objc/client/SWGStoreApi.m index 0af0ebaad78..ce3a63c9483 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.m +++ b/samples/client/petstore/objc/client/SWGStoreApi.m @@ -71,17 +71,16 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; } -/*! - * Returns pet inventories by status - * Returns a map of status codes to quantities - * \returns NSDictionary* /* NSString, NSNumber */ - */ +// +// Returns pet inventories by status +// Returns a map of status codes to quantities +// @returns NSDictionary* /* NSString, NSNumber */ +// -(NSNumber*) getInventoryWithCompletionBlock: (void (^)(NSDictionary* /* NSString, NSNumber */ output, NSError* error))completionBlock { - NSMutableString* requestUrl = [NSMutableString stringWithFormat:@"%@/store/inventory", basePath]; // remove format in URL if needed @@ -142,12 +141,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Place an order for a pet - * - * \param body order placed for purchasing the pet - * \returns SWGOrder* - */ +// +// Place an order for a pet +// +// @param body order placed for purchasing the pet +// @returns SWGOrder* +// -(NSNumber*) placeOrderWithCompletionBlock: (SWGOrder*) body completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock @@ -238,12 +237,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Find purchase order by ID - * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - * \param orderId ID of pet that needs to be fetched - * \returns SWGOrder* - */ +// +// Find purchase order by ID +// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions +// @param orderId ID of pet that needs to be fetched +// @returns SWGOrder* +// -(NSNumber*) getOrderByIdWithCompletionBlock: (NSString*) orderId completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock @@ -315,12 +314,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Delete purchase order by ID - * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors - * \param orderId ID of the order that needs to be deleted - * \returns void - */ +// +// Delete purchase order by ID +// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors +// @param orderId ID of the order that needs to be deleted +// @returns void +// -(NSNumber*) deleteOrderWithCompletionBlock: (NSString*) orderId diff --git a/samples/client/petstore/objc/client/SWGUserApi.h b/samples/client/petstore/objc/client/SWGUserApi.h index e6e73ddfba6..c26046a17c6 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.h +++ b/samples/client/petstore/objc/client/SWGUserApi.h @@ -14,65 +14,61 @@ +(SWGUserApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; -/** - - Create user - This can only be done by the logged in user. - - @param body Created user object - - - return type: - */ +// +// +// Create user +// This can only be done by the logged in user. +// +// @param body Created user object +// +// +// @return -(NSNumber*) createUserWithCompletionBlock :(SWGUser*) body completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Creates list of users with given input array - - - @param body List of user object - - - return type: - */ +// +// +// Creates list of users with given input array +// +// +// @param body List of user object +// +// +// @return -(NSNumber*) createUsersWithArrayInputWithCompletionBlock :(NSArray*) body completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Creates list of users with given input array - - - @param body List of user object - - - return type: - */ +// +// +// Creates list of users with given input array +// +// +// @param body List of user object +// +// +// @return -(NSNumber*) createUsersWithListInputWithCompletionBlock :(NSArray*) body completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Logs user into the system - - - @param username The user name for login - @param password The password for login in clear text - - - return type: NSString* - */ +// +// +// Logs user into the system +// +// +// @param username The user name for login +// @param password The password for login in clear text +// +// +// @return NSString* -(NSNumber*) loginUserWithCompletionBlock :(NSString*) username password:(NSString*) password @@ -80,47 +76,44 @@ -/** - - Logs out current logged in user session - - - - - return type: - */ +// +// +// Logs out current logged in user session +// +// +// +// +// @return -(NSNumber*) logoutUserWithCompletionBlock : (void (^)(NSError* error))completionBlock; -/** - - Get user by user name - - - @param username The name that needs to be fetched. Use user1 for testing. - - - return type: SWGUser* - */ +// +// +// Get user by user name +// +// +// @param username The name that needs to be fetched. Use user1 for testing. +// +// +// @return SWGUser* -(NSNumber*) getUserByNameWithCompletionBlock :(NSString*) username completionHandler: (void (^)(SWGUser* output, NSError* error))completionBlock; -/** - - Updated user - This can only be done by the logged in user. - - @param username name that need to be deleted - @param body Updated user object - - - return type: - */ +// +// +// Updated user +// This can only be done by the logged in user. +// +// @param username name that need to be deleted +// @param body Updated user object +// +// +// @return -(NSNumber*) updateUserWithCompletionBlock :(NSString*) username body:(SWGUser*) body @@ -128,16 +121,15 @@ completionHandler: (void (^)(NSError* error))completionBlock; -/** - - Delete user - This can only be done by the logged in user. - - @param username The name that needs to be deleted - - - return type: - */ +// +// +// Delete user +// This can only be done by the logged in user. +// +// @param username The name that needs to be deleted +// +// +// @return -(NSNumber*) deleteUserWithCompletionBlock :(NSString*) username diff --git a/samples/client/petstore/objc/client/SWGUserApi.m b/samples/client/petstore/objc/client/SWGUserApi.m index 401df17e396..3ef45ea1e77 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.m +++ b/samples/client/petstore/objc/client/SWGUserApi.m @@ -71,12 +71,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; } -/*! - * Create user - * This can only be done by the logged in user. - * \param body Created user object - * \returns void - */ +// +// Create user +// This can only be done by the logged in user. +// @param body Created user object +// @returns void +// -(NSNumber*) createUserWithCompletionBlock: (SWGUser*) body @@ -167,12 +167,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Creates list of users with given input array - * - * \param body List of user object - * \returns void - */ +// +// Creates list of users with given input array +// +// @param body List of user object +// @returns void +// -(NSNumber*) createUsersWithArrayInputWithCompletionBlock: (NSArray*) body @@ -263,12 +263,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Creates list of users with given input array - * - * \param body List of user object - * \returns void - */ +// +// Creates list of users with given input array +// +// @param body List of user object +// @returns void +// -(NSNumber*) createUsersWithListInputWithCompletionBlock: (NSArray*) body @@ -359,13 +359,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Logs user into the system - * - * \param username The user name for login - * \param password The password for login in clear text - * \returns NSString* - */ +// +// Logs user into the system +// +// @param username The user name for login +// @param password The password for login in clear text +// @returns NSString* +// -(NSNumber*) loginUserWithCompletionBlock: (NSString*) username password: (NSString*) password @@ -442,11 +442,11 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Logs out current logged in user session - * - * \returns void - */ +// +// Logs out current logged in user session +// +// @returns void +// -(NSNumber*) logoutUserWithCompletionBlock: (void (^)(NSError* error))completionBlock { @@ -513,12 +513,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Get user by user name - * - * \param username The name that needs to be fetched. Use user1 for testing. - * \returns SWGUser* - */ +// +// Get user by user name +// +// @param username The name that needs to be fetched. Use user1 for testing. +// @returns SWGUser* +// -(NSNumber*) getUserByNameWithCompletionBlock: (NSString*) username completionHandler: (void (^)(SWGUser* output, NSError* error))completionBlock @@ -590,13 +590,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Updated user - * This can only be done by the logged in user. - * \param username name that need to be deleted - * \param body Updated user object - * \returns void - */ +// +// Updated user +// This can only be done by the logged in user. +// @param username name that need to be deleted +// @param body Updated user object +// @returns void +// -(NSNumber*) updateUserWithCompletionBlock: (NSString*) username body: (SWGUser*) body @@ -692,12 +692,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -/*! - * Delete user - * This can only be done by the logged in user. - * \param username The name that needs to be deleted - * \returns void - */ +// +// Delete user +// This can only be done by the logged in user. +// @param username The name that needs to be deleted +// @returns void +// -(NSNumber*) deleteUserWithCompletionBlock: (NSString*) username From a6bdc35d59b0692352f6465a4f483c0f182cc0e8 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 10:17:08 +0800 Subject: [PATCH 047/499] Support pure object response for objc client --- .../src/main/resources/objc/SWGApiClient-body.mustache | 5 +++++ .../objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m | 2 +- .../objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m | 5 +++++ samples/client/petstore/objc/client/SWGApiClient.m | 5 +++++ samples/client/petstore/objc/client/SWGStoreApi.m | 1 + 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache index 45c6fc6d305..a0c9c63d27c 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache @@ -364,6 +364,11 @@ static bool loggingEnabled = true; class = [class substringToIndex:[class length] - 1]; } + // pure object + if ([class isEqualToString:@"NSObject"]) { + return [[NSObject alloc] init]; + } + // list of models NSString *arrayOfModelsPat = @"NSArray<(.+)>"; regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m index 5440935be1b..8ea2e7ee0fc 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m @@ -32,7 +32,7 @@ XCTFail(@"failed to fetch inventory"); } - NSSet *expectKeys = [NSSet setWithArray:@[@"confused", @"string", @"pending", @"available", @"sold"]]; + NSSet *expectKeys = [NSSet setWithArray:@[@"confused", @"string", @"available"]]; NSSet *keys = [NSSet setWithArray:[output allKeys]]; XCTAssertEqualObjects(expectKeys, keys); diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m index 1bd0c0eb1c3..597cf2fb714 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m @@ -158,6 +158,11 @@ XCTAssertTrue([result isKindOfClass:[NSDictionary class]]); XCTAssertTrue([result[@"pet"] isKindOfClass:[SWGPet class]]); XCTAssertEqualObjects([result[@"pet"] _id], @119); + + // pure object + result = [self.apiClient deserialize:nil class:@"NSObject*"]; + + XCTAssertTrue([result isKindOfClass:[NSObject class]]); } @end diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index 45c6fc6d305..a0c9c63d27c 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -364,6 +364,11 @@ static bool loggingEnabled = true; class = [class substringToIndex:[class length] - 1]; } + // pure object + if ([class isEqualToString:@"NSObject"]) { + return [[NSObject alloc] init]; + } + // list of models NSString *arrayOfModelsPat = @"NSArray<(.+)>"; regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat diff --git a/samples/client/petstore/objc/client/SWGStoreApi.m b/samples/client/petstore/objc/client/SWGStoreApi.m index ce3a63c9483..2613f8b6caf 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.m +++ b/samples/client/petstore/objc/client/SWGStoreApi.m @@ -81,6 +81,7 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; { + NSMutableString* requestUrl = [NSMutableString stringWithFormat:@"%@/store/inventory", basePath]; // remove format in URL if needed From bc92465bf7596d488b9e3cb73325b773033a2482 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 10:48:45 +0800 Subject: [PATCH 048/499] Update Objective-C method description (doc comments) style --- .../src/main/resources/objc/api-body.mustache | 14 +- .../main/resources/objc/api-header.mustache | 18 +- .../client/petstore/objc/client/SWGPetApi.h | 154 +++++++++--------- .../client/petstore/objc/client/SWGPetApi.m | 120 ++++++++------ .../client/petstore/objc/client/SWGStoreApi.h | 70 ++++---- .../client/petstore/objc/client/SWGStoreApi.m | 50 +++--- .../client/petstore/objc/client/SWGUserApi.h | 146 ++++++++--------- .../client/petstore/objc/client/SWGUserApi.m | 108 ++++++------ 8 files changed, 355 insertions(+), 325 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache index 1f3c6ca299e..29dca1f4a7a 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache @@ -72,14 +72,16 @@ static NSString * basePath = @"{{basePath}}"; return [SWGApiClient requestQueueSize]; } +#pragma mark - Api Methods {{#operation}} -// -// {{{summary}}} -// {{{notes}}} -// {{#allParams}} @param {{paramName}} {{{description}}} -// {{/allParams}} @returns {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} -// +/// +/// {{{summary}}} +/// {{{notes}}} +/// {{#allParams}} @param {{paramName}} {{{description}}} +/// +/// {{/allParams}} @returns {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} +/// -(NSNumber*) {{nickname}}WithCompletionBlock{{^allParams}}: {{/allParams}}{{#allParams}}{{#secondaryParam}} {{paramName}}{{/secondaryParam}}: ({{{dataType}}}) {{paramName}} {{/allParams}} {{#returnBaseType}}{{#hasParams}}completionHandler: {{/hasParams}}(void (^)({{{returnType}}} output, NSError* error))completionBlock{{/returnBaseType}} diff --git a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache index cc9ad03616e..7f14262d116 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache @@ -17,15 +17,15 @@ +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; {{#operation}} -// -// -// {{{summary}}} -// {{#notes}}{{{notes}}}{{/notes}} -// -// {{#allParams}}@param {{paramName}} {{description}} -// {{/allParams}} -// -// @return {{{returnType}}} +/// +/// +/// {{{summary}}} +/// {{#notes}}{{{notes}}}{{/notes}} +/// +/// {{#allParams}}@param {{paramName}} {{description}} +/// {{/allParams}} +/// +/// @return {{{returnType}}} -(NSNumber*) {{nickname}}WithCompletionBlock {{^allParams}}:{{/allParams}}{{#allParams}}{{#secondaryParam}} {{paramName}}{{/secondaryParam}}:({{{dataType}}}) {{paramName}} {{#hasMore}} {{/hasMore}}{{/allParams}} {{#returnBaseType}}{{#hasParams}} diff --git a/samples/client/petstore/objc/client/SWGPetApi.h b/samples/client/petstore/objc/client/SWGPetApi.h index ce17f2c30ab..257a7d1453e 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.h +++ b/samples/client/petstore/objc/client/SWGPetApi.h @@ -15,92 +15,92 @@ +(SWGPetApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; -// -// -// Update an existing pet -// -// -// @param body Pet object that needs to be added to the store -// -// -// @return +/// +/// +/// Update an existing pet +/// +/// +/// @param body Pet object that needs to be added to the store +/// +/// +/// @return -(NSNumber*) updatePetWithCompletionBlock :(SWGPet*) body completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Add a new pet to the store -// -// -// @param body Pet object that needs to be added to the store -// -// -// @return +/// +/// +/// Add a new pet to the store +/// +/// +/// @param body Pet object that needs to be added to the store +/// +/// +/// @return -(NSNumber*) addPetWithCompletionBlock :(SWGPet*) body completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Finds Pets by status -// Multiple status values can be provided with comma seperated strings -// -// @param status Status values that need to be considered for filter -// -// -// @return NSArray* +/// +/// +/// Finds Pets by status +/// Multiple status values can be provided with comma seperated strings +/// +/// @param status Status values that need to be considered for filter +/// +/// +/// @return NSArray* -(NSNumber*) findPetsByStatusWithCompletionBlock :(NSArray*) status completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock; -// -// -// Finds Pets by tags -// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. -// -// @param tags Tags to filter by -// -// -// @return NSArray* +/// +/// +/// Finds Pets by tags +/// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. +/// +/// @param tags Tags to filter by +/// +/// +/// @return NSArray* -(NSNumber*) findPetsByTagsWithCompletionBlock :(NSArray*) tags completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock; -// -// -// Find pet by ID -// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions -// -// @param petId ID of pet that needs to be fetched -// -// -// @return SWGPet* +/// +/// +/// Find pet by ID +/// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions +/// +/// @param petId ID of pet that needs to be fetched +/// +/// +/// @return SWGPet* -(NSNumber*) getPetByIdWithCompletionBlock :(NSNumber*) petId completionHandler: (void (^)(SWGPet* output, NSError* error))completionBlock; -// -// -// Updates a pet in the store with form data -// -// -// @param petId ID of pet that needs to be updated -// @param name Updated name of the pet -// @param status Updated status of the pet -// -// -// @return +/// +/// +/// Updates a pet in the store with form data +/// +/// +/// @param petId ID of pet that needs to be updated +/// @param name Updated name of the pet +/// @param status Updated status of the pet +/// +/// +/// @return -(NSNumber*) updatePetWithFormWithCompletionBlock :(NSString*) petId name:(NSString*) name status:(NSString*) status @@ -109,16 +109,16 @@ completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Deletes a pet -// -// -// @param apiKey -// @param petId Pet id to delete -// -// -// @return +/// +/// +/// Deletes a pet +/// +/// +/// @param apiKey +/// @param petId Pet id to delete +/// +/// +/// @return -(NSNumber*) deletePetWithCompletionBlock :(NSString*) apiKey petId:(NSNumber*) petId @@ -126,17 +126,17 @@ completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// uploads an image -// -// -// @param petId ID of pet to update -// @param additionalMetadata Additional data to pass to server -// @param file file to upload -// -// -// @return +/// +/// +/// uploads an image +/// +/// +/// @param petId ID of pet to update +/// @param additionalMetadata Additional data to pass to server +/// @param file file to upload +/// +/// +/// @return -(NSNumber*) uploadFileWithCompletionBlock :(NSNumber*) petId additionalMetadata:(NSString*) additionalMetadata file:(SWGFile*) file diff --git a/samples/client/petstore/objc/client/SWGPetApi.m b/samples/client/petstore/objc/client/SWGPetApi.m index d23a2ce9979..e4306f1b235 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.m +++ b/samples/client/petstore/objc/client/SWGPetApi.m @@ -71,13 +71,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; return [SWGApiClient requestQueueSize]; } +#pragma mark - Api Methods -// -// Update an existing pet -// -// @param body Pet object that needs to be added to the store -// @returns void -// +/// +/// Update an existing pet +/// +/// @param body Pet object that needs to be added to the store +/// +/// @returns void +/// -(NSNumber*) updatePetWithCompletionBlock: (SWGPet*) body @@ -168,12 +170,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Add a new pet to the store -// -// @param body Pet object that needs to be added to the store -// @returns void -// +/// +/// Add a new pet to the store +/// +/// @param body Pet object that needs to be added to the store +/// +/// @returns void +/// -(NSNumber*) addPetWithCompletionBlock: (SWGPet*) body @@ -264,12 +267,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Finds Pets by status -// Multiple status values can be provided with comma seperated strings -// @param status Status values that need to be considered for filter -// @returns NSArray* -// +/// +/// Finds Pets by status +/// Multiple status values can be provided with comma seperated strings +/// @param status Status values that need to be considered for filter +/// +/// @returns NSArray* +/// -(NSNumber*) findPetsByStatusWithCompletionBlock: (NSArray*) status completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock @@ -343,12 +347,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Finds Pets by tags -// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. -// @param tags Tags to filter by -// @returns NSArray* -// +/// +/// Finds Pets by tags +/// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. +/// @param tags Tags to filter by +/// +/// @returns NSArray* +/// -(NSNumber*) findPetsByTagsWithCompletionBlock: (NSArray*) tags completionHandler: (void (^)(NSArray* output, NSError* error))completionBlock @@ -422,12 +427,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Find pet by ID -// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions -// @param petId ID of pet that needs to be fetched -// @returns SWGPet* -// +/// +/// Find pet by ID +/// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions +/// @param petId ID of pet that needs to be fetched +/// +/// @returns SWGPet* +/// -(NSNumber*) getPetByIdWithCompletionBlock: (NSNumber*) petId completionHandler: (void (^)(SWGPet* output, NSError* error))completionBlock @@ -499,14 +505,17 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Updates a pet in the store with form data -// -// @param petId ID of pet that needs to be updated -// @param name Updated name of the pet -// @param status Updated status of the pet -// @returns void -// +/// +/// Updates a pet in the store with form data +/// +/// @param petId ID of pet that needs to be updated +/// +/// @param name Updated name of the pet +/// +/// @param status Updated status of the pet +/// +/// @returns void +/// -(NSNumber*) updatePetWithFormWithCompletionBlock: (NSString*) petId name: (NSString*) name status: (NSString*) status @@ -596,13 +605,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Deletes a pet -// -// @param apiKey -// @param petId Pet id to delete -// @returns void -// +/// +/// Deletes a pet +/// +/// @param apiKey +/// +/// @param petId Pet id to delete +/// +/// @returns void +/// -(NSNumber*) deletePetWithCompletionBlock: (NSString*) apiKey petId: (NSNumber*) petId @@ -677,14 +688,17 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// uploads an image -// -// @param petId ID of pet to update -// @param additionalMetadata Additional data to pass to server -// @param file file to upload -// @returns void -// +/// +/// uploads an image +/// +/// @param petId ID of pet to update +/// +/// @param additionalMetadata Additional data to pass to server +/// +/// @param file file to upload +/// +/// @returns void +/// -(NSNumber*) uploadFileWithCompletionBlock: (NSNumber*) petId additionalMetadata: (NSString*) additionalMetadata file: (SWGFile*) file diff --git a/samples/client/petstore/objc/client/SWGStoreApi.h b/samples/client/petstore/objc/client/SWGStoreApi.h index a59d861bbb8..7488c1baa70 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.h +++ b/samples/client/petstore/objc/client/SWGStoreApi.h @@ -14,58 +14,58 @@ +(SWGStoreApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; -// -// -// Returns pet inventories by status -// Returns a map of status codes to quantities -// -// -// -// @return NSDictionary* /* NSString, NSNumber */ +/// +/// +/// Returns pet inventories by status +/// Returns a map of status codes to quantities +/// +/// +/// +/// @return NSDictionary* /* NSString, NSNumber */ -(NSNumber*) getInventoryWithCompletionBlock : (void (^)(NSDictionary* /* NSString, NSNumber */ output, NSError* error))completionBlock; -// -// -// Place an order for a pet -// -// -// @param body order placed for purchasing the pet -// -// -// @return SWGOrder* +/// +/// +/// Place an order for a pet +/// +/// +/// @param body order placed for purchasing the pet +/// +/// +/// @return SWGOrder* -(NSNumber*) placeOrderWithCompletionBlock :(SWGOrder*) body completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock; -// -// -// Find purchase order by ID -// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions -// -// @param orderId ID of pet that needs to be fetched -// -// -// @return SWGOrder* +/// +/// +/// Find purchase order by ID +/// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions +/// +/// @param orderId ID of pet that needs to be fetched +/// +/// +/// @return SWGOrder* -(NSNumber*) getOrderByIdWithCompletionBlock :(NSString*) orderId completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock; -// -// -// Delete purchase order by ID -// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors -// -// @param orderId ID of the order that needs to be deleted -// -// -// @return +/// +/// +/// Delete purchase order by ID +/// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors +/// +/// @param orderId ID of the order that needs to be deleted +/// +/// +/// @return -(NSNumber*) deleteOrderWithCompletionBlock :(NSString*) orderId diff --git a/samples/client/petstore/objc/client/SWGStoreApi.m b/samples/client/petstore/objc/client/SWGStoreApi.m index 2613f8b6caf..98582602027 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.m +++ b/samples/client/petstore/objc/client/SWGStoreApi.m @@ -70,12 +70,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; return [SWGApiClient requestQueueSize]; } +#pragma mark - Api Methods -// -// Returns pet inventories by status -// Returns a map of status codes to quantities -// @returns NSDictionary* /* NSString, NSNumber */ -// +/// +/// Returns pet inventories by status +/// Returns a map of status codes to quantities +/// @returns NSDictionary* /* NSString, NSNumber */ +/// -(NSNumber*) getInventoryWithCompletionBlock: (void (^)(NSDictionary* /* NSString, NSNumber */ output, NSError* error))completionBlock { @@ -142,12 +143,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Place an order for a pet -// -// @param body order placed for purchasing the pet -// @returns SWGOrder* -// +/// +/// Place an order for a pet +/// +/// @param body order placed for purchasing the pet +/// +/// @returns SWGOrder* +/// -(NSNumber*) placeOrderWithCompletionBlock: (SWGOrder*) body completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock @@ -238,12 +240,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Find purchase order by ID -// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions -// @param orderId ID of pet that needs to be fetched -// @returns SWGOrder* -// +/// +/// Find purchase order by ID +/// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions +/// @param orderId ID of pet that needs to be fetched +/// +/// @returns SWGOrder* +/// -(NSNumber*) getOrderByIdWithCompletionBlock: (NSString*) orderId completionHandler: (void (^)(SWGOrder* output, NSError* error))completionBlock @@ -315,12 +318,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Delete purchase order by ID -// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors -// @param orderId ID of the order that needs to be deleted -// @returns void -// +/// +/// Delete purchase order by ID +/// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors +/// @param orderId ID of the order that needs to be deleted +/// +/// @returns void +/// -(NSNumber*) deleteOrderWithCompletionBlock: (NSString*) orderId diff --git a/samples/client/petstore/objc/client/SWGUserApi.h b/samples/client/petstore/objc/client/SWGUserApi.h index c26046a17c6..6fda87cca70 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.h +++ b/samples/client/petstore/objc/client/SWGUserApi.h @@ -14,61 +14,61 @@ +(SWGUserApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +(void) setBasePath:(NSString*)basePath; +(NSString*) getBasePath; -// -// -// Create user -// This can only be done by the logged in user. -// -// @param body Created user object -// -// -// @return +/// +/// +/// Create user +/// This can only be done by the logged in user. +/// +/// @param body Created user object +/// +/// +/// @return -(NSNumber*) createUserWithCompletionBlock :(SWGUser*) body completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Creates list of users with given input array -// -// -// @param body List of user object -// -// -// @return +/// +/// +/// Creates list of users with given input array +/// +/// +/// @param body List of user object +/// +/// +/// @return -(NSNumber*) createUsersWithArrayInputWithCompletionBlock :(NSArray*) body completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Creates list of users with given input array -// -// -// @param body List of user object -// -// -// @return +/// +/// +/// Creates list of users with given input array +/// +/// +/// @param body List of user object +/// +/// +/// @return -(NSNumber*) createUsersWithListInputWithCompletionBlock :(NSArray*) body completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Logs user into the system -// -// -// @param username The user name for login -// @param password The password for login in clear text -// -// -// @return NSString* +/// +/// +/// Logs user into the system +/// +/// +/// @param username The user name for login +/// @param password The password for login in clear text +/// +/// +/// @return NSString* -(NSNumber*) loginUserWithCompletionBlock :(NSString*) username password:(NSString*) password @@ -76,44 +76,44 @@ -// -// -// Logs out current logged in user session -// -// -// -// -// @return +/// +/// +/// Logs out current logged in user session +/// +/// +/// +/// +/// @return -(NSNumber*) logoutUserWithCompletionBlock : (void (^)(NSError* error))completionBlock; -// -// -// Get user by user name -// -// -// @param username The name that needs to be fetched. Use user1 for testing. -// -// -// @return SWGUser* +/// +/// +/// Get user by user name +/// +/// +/// @param username The name that needs to be fetched. Use user1 for testing. +/// +/// +/// @return SWGUser* -(NSNumber*) getUserByNameWithCompletionBlock :(NSString*) username completionHandler: (void (^)(SWGUser* output, NSError* error))completionBlock; -// -// -// Updated user -// This can only be done by the logged in user. -// -// @param username name that need to be deleted -// @param body Updated user object -// -// -// @return +/// +/// +/// Updated user +/// This can only be done by the logged in user. +/// +/// @param username name that need to be deleted +/// @param body Updated user object +/// +/// +/// @return -(NSNumber*) updateUserWithCompletionBlock :(NSString*) username body:(SWGUser*) body @@ -121,15 +121,15 @@ completionHandler: (void (^)(NSError* error))completionBlock; -// -// -// Delete user -// This can only be done by the logged in user. -// -// @param username The name that needs to be deleted -// -// -// @return +/// +/// +/// Delete user +/// This can only be done by the logged in user. +/// +/// @param username The name that needs to be deleted +/// +/// +/// @return -(NSNumber*) deleteUserWithCompletionBlock :(NSString*) username diff --git a/samples/client/petstore/objc/client/SWGUserApi.m b/samples/client/petstore/objc/client/SWGUserApi.m index 3ef45ea1e77..2e8ce66b74e 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.m +++ b/samples/client/petstore/objc/client/SWGUserApi.m @@ -70,13 +70,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; return [SWGApiClient requestQueueSize]; } +#pragma mark - Api Methods -// -// Create user -// This can only be done by the logged in user. -// @param body Created user object -// @returns void -// +/// +/// Create user +/// This can only be done by the logged in user. +/// @param body Created user object +/// +/// @returns void +/// -(NSNumber*) createUserWithCompletionBlock: (SWGUser*) body @@ -167,12 +169,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Creates list of users with given input array -// -// @param body List of user object -// @returns void -// +/// +/// Creates list of users with given input array +/// +/// @param body List of user object +/// +/// @returns void +/// -(NSNumber*) createUsersWithArrayInputWithCompletionBlock: (NSArray*) body @@ -263,12 +266,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Creates list of users with given input array -// -// @param body List of user object -// @returns void -// +/// +/// Creates list of users with given input array +/// +/// @param body List of user object +/// +/// @returns void +/// -(NSNumber*) createUsersWithListInputWithCompletionBlock: (NSArray*) body @@ -359,13 +363,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Logs user into the system -// -// @param username The user name for login -// @param password The password for login in clear text -// @returns NSString* -// +/// +/// Logs user into the system +/// +/// @param username The user name for login +/// +/// @param password The password for login in clear text +/// +/// @returns NSString* +/// -(NSNumber*) loginUserWithCompletionBlock: (NSString*) username password: (NSString*) password @@ -442,11 +448,11 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Logs out current logged in user session -// -// @returns void -// +/// +/// Logs out current logged in user session +/// +/// @returns void +/// -(NSNumber*) logoutUserWithCompletionBlock: (void (^)(NSError* error))completionBlock { @@ -513,12 +519,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Get user by user name -// -// @param username The name that needs to be fetched. Use user1 for testing. -// @returns SWGUser* -// +/// +/// Get user by user name +/// +/// @param username The name that needs to be fetched. Use user1 for testing. +/// +/// @returns SWGUser* +/// -(NSNumber*) getUserByNameWithCompletionBlock: (NSString*) username completionHandler: (void (^)(SWGUser* output, NSError* error))completionBlock @@ -590,13 +597,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Updated user -// This can only be done by the logged in user. -// @param username name that need to be deleted -// @param body Updated user object -// @returns void -// +/// +/// Updated user +/// This can only be done by the logged in user. +/// @param username name that need to be deleted +/// +/// @param body Updated user object +/// +/// @returns void +/// -(NSNumber*) updateUserWithCompletionBlock: (NSString*) username body: (SWGUser*) body @@ -692,12 +701,13 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; ]; } -// -// Delete user -// This can only be done by the logged in user. -// @param username The name that needs to be deleted -// @returns void -// +/// +/// Delete user +/// This can only be done by the logged in user. +/// @param username The name that needs to be deleted +/// +/// @returns void +/// -(NSNumber*) deleteUserWithCompletionBlock: (NSString*) username From 8b15416be5eb405174d6d147723f7a0ce9d11005 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 17:31:48 +0800 Subject: [PATCH 049/499] Add SWGJSONResponseSerializer for objective-c client. If the response data is valid json, return the deserialized json. If the response data is invalid json, return the string of response data. --- .../codegen/languages/ObjcClientCodegen.java | 2 + .../resources/objc/SWGApiClient-body.mustache | 5 ++ .../SWGJSONResponseSerializer-body.mustache | 28 +++++++++++ .../SWGJSONResponseSerializer-header.mustache | 6 +++ .../PetstoreClientTests/StoreApiTest.m | 5 +- .../PetstoreClientTests/UserApiTest.m | 47 +++++++++++++++++++ .../SwaggerClient.xcodeproj/project.pbxproj | 10 ++++ .../SwaggerClient/ViewController.m | 6 +++ .../SwaggerClientTests/SWGApiClientTest.m | 8 +++- .../petstore/objc/client/SWGApiClient.m | 5 ++ .../objc/client/SWGJSONResponseSerializer.h | 6 +++ .../objc/client/SWGJSONResponseSerializer.m | 28 +++++++++++ 12 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache create mode 100644 modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache create mode 100644 samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m create mode 100644 samples/client/petstore/objc/client/SWGJSONResponseSerializer.h create mode 100644 samples/client/petstore/objc/client/SWGJSONResponseSerializer.m diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java index ce3ec065012..ddd4d0c53ff 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java @@ -145,6 +145,8 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("SWGQueryParamCollection.m", sourceFolder, "SWGQueryParamCollection.m")); supportingFiles.add(new SupportingFile("SWGApiClient-header.mustache", sourceFolder, "SWGApiClient.h")); supportingFiles.add(new SupportingFile("SWGApiClient-body.mustache", sourceFolder, "SWGApiClient.m")); + supportingFiles.add(new SupportingFile("SWGJSONResponseSerializer-header.mustache", sourceFolder, "SWGJSONResponseSerializer.h")); + supportingFiles.add(new SupportingFile("SWGJSONResponseSerializer-body.mustache", sourceFolder, "SWGJSONResponseSerializer.m")); supportingFiles.add(new SupportingFile("SWGFile.h", sourceFolder, "SWGFile.h")); supportingFiles.add(new SupportingFile("SWGFile.m", sourceFolder, "SWGFile.m")); supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", sourceFolder, "JSONValueTransformer+ISO8601.m")); diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache index a0c9c63d27c..39ad87c76bb 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache @@ -359,6 +359,11 @@ static bool loggingEnabled = true; NSMutableArray *resultArray = nil; NSMutableDictionary *resultDict = nil; + // return nil if data is nil + if (!data) { + return nil; + } + // remove "*" from class, if ends with "*" if ([class hasSuffix:@"*"]) { class = [class substringToIndex:[class length] - 1]; diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache new file mode 100644 index 00000000000..80fd09f6954 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache @@ -0,0 +1,28 @@ +#import "SWGJSONResponseSerializer.h" + +static BOOL JSONParseError(NSError *error) { + if ([error.domain isEqualToString:NSCocoaErrorDomain] && error.code == 3840) { + return YES; + } + + return NO; +} + +@implementation SWGJSONResponseSerializer + +- (id) responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error { + NSDictionary *responseJson = [super responseObjectForResponse:response data:data error:error]; + + // if response data is not a valid json, return string of data. + if (JSONParseError(*error)) { + *error = nil; + NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + return responseString; + } + + return responseJson; +} + +@end diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache new file mode 100644 index 00000000000..16cda122217 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache @@ -0,0 +1,6 @@ +#import +#import + +@interface SWGJSONResponseSerializer : AFJSONResponseSerializer + +@end diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m index 8ea2e7ee0fc..d2864afe51d 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m @@ -32,10 +32,7 @@ XCTFail(@"failed to fetch inventory"); } - NSSet *expectKeys = [NSSet setWithArray:@[@"confused", @"string", @"available"]]; - NSSet *keys = [NSSet setWithArray:[output allKeys]]; - - XCTAssertEqualObjects(expectKeys, keys); + XCTAssertNotNil(output.allKeys); [expectation fulfill]; }]; diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m new file mode 100644 index 00000000000..b703797a280 --- /dev/null +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m @@ -0,0 +1,47 @@ +#import +#import +#import "SWGUserApi.h" + +@interface UserApiTest : XCTestCase + +@property (nonatomic) SWGUserApi *api; + +@end + +@implementation UserApiTest + +- (void)setUp { + [super setUp]; + self.api = [[SWGUserApi alloc] init]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testLoginUser { + XCTestExpectation *expectation = [self expectationWithDescription:@"test login user"]; + + [self.api loginUserWithCompletionBlock:@"test username" password:@"test password" completionHandler:^(NSString *output, NSError *error) { + if (error) { + XCTFail(@"got error %@", error); + } + + if (!output) { + XCTFail(@"response can't be nil"); + } + + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"logged in user" + options:0 + error:nil]; + NSTextCheckingResult *match = [regex firstMatchInString:output + options:0 + range:NSMakeRange(0, [output length])]; + XCTAssertNotNil(match); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10.0 handler:nil]; +} + +@end diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj index ffb61953051..ac15f78e357 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj @@ -10,7 +10,9 @@ BA525648922D4C0E9F44D4F1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 73DA4F1067C343C3962F1542 /* libPods.a */; }; CF0560EB1B1855CF00C0D4EC /* SWGConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */; }; CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF31D0981B105E4B00509935 /* SWGApiClientTest.m */; }; + CF5B6E2D1B2BD70800862A1C /* UserApiTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF5B6E2C1B2BD70800862A1C /* UserApiTest.m */; }; CFB37D061B2B11DD00D2E5F1 /* StoreApiTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */; }; + CFCEFE511B2C1330006313BE /* SWGJSONResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = CFCEFE501B2C1330006313BE /* SWGJSONResponseSerializer.m */; }; CFD1B6701B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; EA66999A1811D2FA00A70D03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA6699991811D2FA00A70D03 /* Foundation.framework */; }; @@ -61,7 +63,10 @@ CF0560E91B1855CF00C0D4EC /* SWGConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWGConfiguration.h; sourceTree = ""; }; CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGConfiguration.m; sourceTree = ""; }; CF31D0981B105E4B00509935 /* SWGApiClientTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGApiClientTest.m; sourceTree = ""; }; + CF5B6E2C1B2BD70800862A1C /* UserApiTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserApiTest.m; sourceTree = ""; }; CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StoreApiTest.m; sourceTree = ""; }; + CFCEFE4F1B2C1330006313BE /* SWGJSONResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWGJSONResponseSerializer.h; sourceTree = ""; }; + CFCEFE501B2C1330006313BE /* SWGJSONResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGJSONResponseSerializer.m; sourceTree = ""; }; CFD1B66E1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JSONValueTransformer+ISO8601.h"; sourceTree = ""; }; CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "JSONValueTransformer+ISO8601.m"; sourceTree = ""; }; E2B6DA00BE52336E23783686 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "../Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -214,6 +219,7 @@ isa = PBXGroup; children = ( EA8CD3EB1AC274BE00C47D0B /* PetApiTest.h */, + CF5B6E2C1B2BD70800862A1C /* UserApiTest.m */, CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */, CF31D0981B105E4B00509935 /* SWGApiClientTest.m */, EA6699C71811D2FB00A70D03 /* PetApiTest.m */, @@ -251,6 +257,8 @@ EAEA85D61811D3AE00F06E69 /* SWGOrder.h */, EAEA85D71811D3AE00F06E69 /* SWGOrder.m */, EAB26B0E1AC8E692002F5C7A /* SWGPet.h */, + CFCEFE4F1B2C1330006313BE /* SWGJSONResponseSerializer.h */, + CFCEFE501B2C1330006313BE /* SWGJSONResponseSerializer.m */, EAEA85D91811D3AE00F06E69 /* SWGPet.m */, EAEA85DA1811D3AE00F06E69 /* SWGPetApi.h */, EAEA85DB1811D3AE00F06E69 /* SWGPetApi.m */, @@ -418,6 +426,7 @@ EAEA85E91811D3AE00F06E69 /* SWGOrder.m in Sources */, EAEA85E81811D3AE00F06E69 /* SWGObject.m in Sources */, EA8B8AA41AC6683700638FBB /* SWGQueryParamCollection.m in Sources */, + CFCEFE511B2C1330006313BE /* SWGJSONResponseSerializer.m in Sources */, EAEA85E71811D3AE00F06E69 /* SWGFile.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -429,6 +438,7 @@ EAB26B0C1AC8DF78002F5C7A /* PetApiTest.h in Sources */, CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */, EAB26B0D1AC8DF78002F5C7A /* PetApiTest.m in Sources */, + CF5B6E2D1B2BD70800862A1C /* UserApiTest.m in Sources */, CFB37D061B2B11DD00D2E5F1 /* StoreApiTest.m in Sources */, CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */, ); diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m index 56d0a8f621f..5ba0fe18382 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m @@ -9,6 +9,7 @@ #import "ViewController.h" #import "SWGPetApi.h" #import "SWGStoreApi.h" +#import "SWGUserApi.h" #import "SWGConfiguration.h" @interface ViewController () @@ -55,6 +56,11 @@ // } ]; */ + SWGUserApi *api = [[SWGUserApi alloc] init]; + [api loginUserWithCompletionBlock:@"username" password:@"password" completionHandler:^(NSString *output, NSError *error) { + NSLog(@"output => %@", output); + NSLog(@"error => %@", error); + }]; } - (void)didReceiveMemoryWarning diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m index 597cf2fb714..c68b3e2a42e 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m @@ -160,9 +160,15 @@ XCTAssertEqualObjects([result[@"pet"] _id], @119); // pure object - result = [self.apiClient deserialize:nil class:@"NSObject*"]; + result = [self.apiClient deserialize:@"" class:@"NSObject*"]; XCTAssertTrue([result isKindOfClass:[NSObject class]]); + + // NSString + data = @"test string"; + result = [self.apiClient deserialize:data class:@"NSString*"]; + + XCTAssertTrue([result isKindOfClass:[NSString class]]); } @end diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index a0c9c63d27c..39ad87c76bb 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -359,6 +359,11 @@ static bool loggingEnabled = true; NSMutableArray *resultArray = nil; NSMutableDictionary *resultDict = nil; + // return nil if data is nil + if (!data) { + return nil; + } + // remove "*" from class, if ends with "*" if ([class hasSuffix:@"*"]) { class = [class substringToIndex:[class length] - 1]; diff --git a/samples/client/petstore/objc/client/SWGJSONResponseSerializer.h b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.h new file mode 100644 index 00000000000..16cda122217 --- /dev/null +++ b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.h @@ -0,0 +1,6 @@ +#import +#import + +@interface SWGJSONResponseSerializer : AFJSONResponseSerializer + +@end diff --git a/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m new file mode 100644 index 00000000000..80fd09f6954 --- /dev/null +++ b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m @@ -0,0 +1,28 @@ +#import "SWGJSONResponseSerializer.h" + +static BOOL JSONParseError(NSError *error) { + if ([error.domain isEqualToString:NSCocoaErrorDomain] && error.code == 3840) { + return YES; + } + + return NO; +} + +@implementation SWGJSONResponseSerializer + +- (id) responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error { + NSDictionary *responseJson = [super responseObjectForResponse:response data:data error:error]; + + // if response data is not a valid json, return string of data. + if (JSONParseError(*error)) { + *error = nil; + NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + return responseString; + } + + return responseJson; +} + +@end From a4df33d04083a54b6ea7650089a24a0e556fccc4 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Sat, 13 Jun 2015 17:49:39 +0800 Subject: [PATCH 050/499] Add comments for SWGJSONResponseSerializer#responseObjectForResponse method of objective-c client. --- .../objc/SWGJSONResponseSerializer-body.mustache | 11 +++++++++++ .../petstore/objc/client/SWGJSONResponseSerializer.m | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache index 80fd09f6954..a2dd21bcf5d 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache @@ -10,6 +10,17 @@ static BOOL JSONParseError(NSError *error) { @implementation SWGJSONResponseSerializer +/// +/// When customize a response serializer, +/// the serializer must conform the protocol `AFURLResponseSerialization` +/// and implements the protocol method `responseObjectForResponse:error:` +/// +/// @param response The response to be processed. +/// @param data The response data to be decoded. +/// @param error The error that occurred while attempting to decode the respnse data. +/// +/// @return The object decoded from the specified response data. +/// - (id) responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { diff --git a/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m index 80fd09f6954..a2dd21bcf5d 100644 --- a/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m +++ b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m @@ -10,6 +10,17 @@ static BOOL JSONParseError(NSError *error) { @implementation SWGJSONResponseSerializer +/// +/// When customize a response serializer, +/// the serializer must conform the protocol `AFURLResponseSerialization` +/// and implements the protocol method `responseObjectForResponse:error:` +/// +/// @param response The response to be processed. +/// @param data The response data to be decoded. +/// @param error The error that occurred while attempting to decode the respnse data. +/// +/// @return The object decoded from the specified response data. +/// - (id) responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { From 6b6480a026604c8ed1bc6441270eea54a82b1080 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Thu, 18 Jun 2015 10:38:19 +0800 Subject: [PATCH 051/499] Updated xcode project of objc client --- .../codegen/languages/ObjcClientCodegen.java | 2 +- .../resources/objc/SWGApiClient-body.mustache | 2 +- .../objc/SWGApiClient-header.mustache | 1 + .../xcshareddata/SwaggerClient.xccheckout | 41 ++++++++++++++++++ .../UserInterfaceState.xcuserstate | Bin 7666 -> 16336 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 17 ++++++++ .../SwaggerClient/ViewController.m | 13 +++--- .../SwaggerClientTests}/StoreApiTest.m | 0 .../SwaggerClientTests}/UserApiTest.m | 0 .../petstore/objc/client/SWGApiClient.h | 1 + .../petstore/objc/client/SWGApiClient.m | 2 +- 11 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 samples/client/petstore/objc/SwaggerClient.xcworkspace/xcshareddata/SwaggerClient.xccheckout create mode 100644 samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests => SwaggerClient/SwaggerClientTests}/StoreApiTest.m (100%) rename samples/client/petstore/objc/{PetstoreClient/PetstoreClientTests => SwaggerClient/SwaggerClientTests}/UserApiTest.m (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java index ddd4d0c53ff..03905cbdfaf 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java @@ -153,7 +153,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { 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")); + supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile")); } @Override diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache index 39ad87c76bb..1b479d039e6 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache @@ -500,7 +500,7 @@ static bool loggingEnabled = true; // setting response serializer if ([responseContentType isEqualToString:@"application/json"]) { - self.responseSerializer = [AFJSONResponseSerializer serializer]; + self.responseSerializer = [SWGJSONResponseSerializer serializer]; } else { self.responseSerializer = [AFHTTPResponseSerializer serializer]; diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache index 09cb6fe57bd..691c92cc625 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-header.mustache @@ -1,6 +1,7 @@ #import #import #import "AFHTTPRequestOperationManager.h" +#import "SWGJSONResponseSerializer.h" {{#models}}{{#model}}#import "{{classname}}.h" {{/model}}{{/models}} diff --git a/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcshareddata/SwaggerClient.xccheckout b/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcshareddata/SwaggerClient.xccheckout new file mode 100644 index 00000000000..325cb92c1b8 --- /dev/null +++ b/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcshareddata/SwaggerClient.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 15AAFA18-9D61-437F-988D-A691BA4C08B1 + IDESourceControlProjectName + SwaggerClient + IDESourceControlProjectOriginsDictionary + + E5BBF0AA85077C865C95437976D06D819733A208 + https://github.com/geekerzp/swagger-codegen.git + + IDESourceControlProjectPath + samples/client/petstore/objc/SwaggerClient.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + E5BBF0AA85077C865C95437976D06D819733A208 + ../../../../.. + + IDESourceControlProjectURL + https://github.com/geekerzp/swagger-codegen.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + E5BBF0AA85077C865C95437976D06D819733A208 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + E5BBF0AA85077C865C95437976D06D819733A208 + IDESourceControlWCCName + swagger-codegen + + + + diff --git a/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/UserInterfaceState.xcuserstate b/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/UserInterfaceState.xcuserstate index 79012184db63a3743953f712c7514d98f2b40464..d8a48b72bc2eb6cb0a734c22a88f15e99e0edb35 100644 GIT binary patch literal 16336 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סvZ4#T@rnG5n$u_es$ChWa+lp+Zw$Zk8 zY>l=xw!OBawvTLI+J3N|wqtvYU20d_%j~1=6YUq+YwdORS$3!0Z||}9+Lzf^+E>|E z+b^}RwO?glXWwYwWbe0cDTpYL7bF&_3bX|q3bqt%E7(!6t1zn&s%;8O3r83JqwvYX g1BK5NK3|kwbWTx4(ZnG?m=WGZ1z~P5Dw_QN0GEDeL;wH) delta 4592 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 diff --git a/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 00000000000..e2573a5943c --- /dev/null +++ b/samples/client/petstore/objc/SwaggerClient.xcworkspace/xcuserdata/geekerzp.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m index 5ba0fe18382..388cacbb157 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m @@ -56,11 +56,14 @@ // } ]; */ - SWGUserApi *api = [[SWGUserApi alloc] init]; - [api loginUserWithCompletionBlock:@"username" password:@"password" completionHandler:^(NSString *output, NSError *error) { - NSLog(@"output => %@", output); - NSLog(@"error => %@", error); - }]; + SWGPetApi *api = [[SWGPetApi alloc] init]; + [api deletePetWithCompletionBlock:@"hello" + petId:@1434529787992 + completionHandler:^(NSError *error) { + if (error) { + NSLog(@"%@", error); + } + }]; } - (void)didReceiveMemoryWarning diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/StoreApiTest.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/StoreApiTest.m diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/UserApiTest.m similarity index 100% rename from samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m rename to samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/UserApiTest.m diff --git a/samples/client/petstore/objc/client/SWGApiClient.h b/samples/client/petstore/objc/client/SWGApiClient.h index 829aec58b96..6ede775cb02 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.h +++ b/samples/client/petstore/objc/client/SWGApiClient.h @@ -1,6 +1,7 @@ #import #import #import "AFHTTPRequestOperationManager.h" +#import "SWGJSONResponseSerializer.h" #import "SWGUser.h" #import "SWGCategory.h" diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index 39ad87c76bb..1b479d039e6 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -500,7 +500,7 @@ static bool loggingEnabled = true; // setting response serializer if ([responseContentType isEqualToString:@"application/json"]) { - self.responseSerializer = [AFJSONResponseSerializer serializer]; + self.responseSerializer = [SWGJSONResponseSerializer serializer]; } else { self.responseSerializer = [AFHTTPResponseSerializer serializer]; From a32335dfbcb09bce83aeb4b214b2159e8e8724de Mon Sep 17 00:00:00 2001 From: geekerzp Date: Fri, 12 Jun 2015 17:51:05 +0800 Subject: [PATCH 052/499] Enable cli config options for python generator --- .../languages/PythonClientCodegen.java | 79 ++++++++++++++---- .../src/main/resources/python/setup.mustache | 7 +- .../Makefile | 0 .../README.md | 0 .../dev-requirements.txt | 0 .../pom.xml | 0 .../setup.cfg | 0 .../setup.py | 7 +- .../swagger_client}/__init__.py | 0 .../swagger_client}/api_client.py | 0 .../swagger_client}/apis/__init__.py | 0 .../swagger_client}/apis/pet_api.py | 0 .../swagger_client}/apis/store_api.py | 0 .../swagger_client}/apis/user_api.py | 0 .../swagger_client}/configuration.py | 0 .../swagger_client}/models/__init__.py | 0 .../swagger_client}/models/category.py | 0 .../swagger_client}/models/order.py | 0 .../swagger_client}/models/pet.py | 0 .../swagger_client}/models/tag.py | 0 .../swagger_client}/models/user.py | 0 .../swagger_client}/rest.py | 0 .../testfiles/foo.png | Bin .../tests/__init__.py | 0 .../tests/test_api_client.py | 20 ++--- .../tests/test_api_exception.py | 16 ++-- .../tests/test_pet_api.py | 30 +++---- .../tox.ini | 0 28 files changed, 105 insertions(+), 54 deletions(-) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/Makefile (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/README.md (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/dev-requirements.txt (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/pom.xml (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/setup.cfg (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/setup.py (92%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/__init__.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/api_client.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/apis/__init__.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/apis/pet_api.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/apis/store_api.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/apis/user_api.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/configuration.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/models/__init__.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/models/category.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/models/order.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/models/pet.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/models/tag.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/models/user.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python/SwaggerPetstore => swagger_client_python/swagger_client}/rest.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/testfiles/foo.png (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/tests/__init__.py (100%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/tests/test_api_client.py (85%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/tests/test_api_exception.py (85%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/tests/test_pet_api.py (84%) rename samples/client/petstore/python/{SwaggerPetstore-python => swagger_client_python}/tox.ini (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index a14fa71f425..e5a3b0810b2 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -1,5 +1,6 @@ package io.swagger.codegen.languages; +import io.swagger.codegen.CliOption; import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenType; import io.swagger.codegen.DefaultCodegen; @@ -13,25 +14,19 @@ import java.util.Arrays; import java.util.HashSet; public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig { - protected String module = "SwaggerPetstore"; - protected String invokerPackage; - protected String eggPackage; + protected String packageName = null; + protected String packageVersion = null; public PythonClientCodegen() { super(); - eggPackage = module + "-python"; - - invokerPackage = eggPackage + File.separatorChar + module; - + modelPackage = "models"; + apiPackage = "api"; outputFolder = "generated-code" + File.separatorChar + "python"; modelTemplateFiles.put("model.mustache", ".py"); apiTemplateFiles.put("api.mustache", ".py"); templateDir = "python"; - apiPackage = invokerPackage + File.separatorChar + "apis"; - modelPackage = invokerPackage + File.separatorChar + "models"; - languageSpecificPrimitives.clear(); languageSpecificPrimitives.add("int"); languageSpecificPrimitives.add("float"); @@ -60,14 +55,45 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig "print", "class", "exec", "in", "raise", "continue", "finally", "is", "return", "def", "for", "lambda", "try")); - additionalProperties.put("module", module); + cliOptions.clear(); + cliOptions.add(new CliOption("packageName", "python package name, default: SwaggerClient")); + cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0")); + } - supportingFiles.add(new SupportingFile("README.mustache", eggPackage, "README.md")); - supportingFiles.add(new SupportingFile("setup.mustache", eggPackage, "setup.py")); - supportingFiles.add(new SupportingFile("api_client.mustache", invokerPackage, "api_client.py")); - supportingFiles.add(new SupportingFile("rest.mustache", invokerPackage, "rest.py")); - supportingFiles.add(new SupportingFile("configuration.mustache", invokerPackage, "configuration.py")); - supportingFiles.add(new SupportingFile("__init__package.mustache", invokerPackage, "__init__.py")); + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey("packageName")) { + setPackageName((String) additionalProperties.get("packageName")); + } + else { + setPackageName("SwaggerClient"); + } + setPackageName(generatePackageName(packageName)); + + if (additionalProperties.containsKey("packageVersion")) { + setPackageVersion((String) additionalProperties.get("packageVersion")); + } + else { + setPackageVersion("1.0.0"); + } + + additionalProperties.put("packageName", packageName); + additionalProperties.put("packageVersion", packageVersion); + + String baseFolder = packageName + "_python"; + String swaggerFoler = baseFolder + File.separatorChar + packageName; + + modelPackage = swaggerFoler + File.separatorChar + "models"; + apiPackage = swaggerFoler + File.separatorChar + "apis"; + + supportingFiles.add(new SupportingFile("README.mustache", baseFolder, "README.md")); + supportingFiles.add(new SupportingFile("setup.mustache", baseFolder, "setup.py")); + supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFoler, "api_client.py")); + supportingFiles.add(new SupportingFile("rest.mustache", swaggerFoler, "rest.py")); + supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFoler, "configuration.py")); + supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFoler, "__init__.py")); supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py")); supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py")); } @@ -225,4 +251,23 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig return underscore(operationId); } + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public void setPackageVersion(String packageVersion) { + this.packageVersion = packageVersion; + } + + /** + * Generate Python package name from String `packageName` + * + * (PEP 0008) Python packages should also have short, all-lowercase names, + * although the use of underscores is discouraged. + */ + public String generatePackageName(String packageName) { + return underscore(packageName.replaceAll("[^\\w]+", "")); + } } + + diff --git a/modules/swagger-codegen/src/main/resources/python/setup.mustache b/modules/swagger-codegen/src/main/resources/python/setup.mustache index f1ba52d2930..af4fa69baf3 100644 --- a/modules/swagger-codegen/src/main/resources/python/setup.mustache +++ b/modules/swagger-codegen/src/main/resources/python/setup.mustache @@ -1,6 +1,9 @@ import sys from setuptools import setup, find_packages +NAME = "{{packageName}}" +VERSION = "{{packageVersion}}" + {{#apiInfo}}{{#apis}}{{^hasMore}} # To install the library, open a Terminal shell, then run this @@ -15,8 +18,8 @@ from setuptools import setup, find_packages REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"] setup( - name="{{module}}", - version="{{version}}", + name=NAME, + version=VERSION, description="{{appName}}", author_email="{{infoEmail}}", url="{{infoUrl}}", diff --git a/samples/client/petstore/python/SwaggerPetstore-python/Makefile b/samples/client/petstore/python/swagger_client_python/Makefile similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/Makefile rename to samples/client/petstore/python/swagger_client_python/Makefile diff --git a/samples/client/petstore/python/SwaggerPetstore-python/README.md b/samples/client/petstore/python/swagger_client_python/README.md similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/README.md rename to samples/client/petstore/python/swagger_client_python/README.md diff --git a/samples/client/petstore/python/SwaggerPetstore-python/dev-requirements.txt b/samples/client/petstore/python/swagger_client_python/dev-requirements.txt similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/dev-requirements.txt rename to samples/client/petstore/python/swagger_client_python/dev-requirements.txt diff --git a/samples/client/petstore/python/SwaggerPetstore-python/pom.xml b/samples/client/petstore/python/swagger_client_python/pom.xml similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/pom.xml rename to samples/client/petstore/python/swagger_client_python/pom.xml diff --git a/samples/client/petstore/python/SwaggerPetstore-python/setup.cfg b/samples/client/petstore/python/swagger_client_python/setup.cfg similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/setup.cfg rename to samples/client/petstore/python/swagger_client_python/setup.cfg diff --git a/samples/client/petstore/python/SwaggerPetstore-python/setup.py b/samples/client/petstore/python/swagger_client_python/setup.py similarity index 92% rename from samples/client/petstore/python/SwaggerPetstore-python/setup.py rename to samples/client/petstore/python/swagger_client_python/setup.py index fbd738be680..4232c3992b9 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/setup.py +++ b/samples/client/petstore/python/swagger_client_python/setup.py @@ -1,6 +1,9 @@ import sys from setuptools import setup, find_packages +NAME = "swagger_client" +VERSION = "1.0.0" + # To install the library, open a Terminal shell, then run this @@ -15,8 +18,8 @@ from setuptools import setup, find_packages REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"] setup( - name="SwaggerPetstore", - version="1.0.0", + name=NAME, + version=VERSION, description="Swagger Petstore", author_email="apiteam@swagger.io", url="", diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py b/samples/client/petstore/python/swagger_client_python/swagger_client/__init__.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/__init__.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/__init__.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py b/samples/client/petstore/python/swagger_client_python/swagger_client/api_client.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/api_client.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/api_client.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py b/samples/client/petstore/python/swagger_client_python/swagger_client/apis/__init__.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/__init__.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/apis/__init__.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py b/samples/client/petstore/python/swagger_client_python/swagger_client/apis/pet_api.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/apis/pet_api.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py b/samples/client/petstore/python/swagger_client_python/swagger_client/apis/store_api.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/apis/store_api.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py b/samples/client/petstore/python/swagger_client_python/swagger_client/apis/user_api.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/apis/user_api.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/configuration.py b/samples/client/petstore/python/swagger_client_python/swagger_client/configuration.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/configuration.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/configuration.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/__init__.py b/samples/client/petstore/python/swagger_client_python/swagger_client/models/__init__.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/__init__.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/models/__init__.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/category.py b/samples/client/petstore/python/swagger_client_python/swagger_client/models/category.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/category.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/models/category.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/order.py b/samples/client/petstore/python/swagger_client_python/swagger_client/models/order.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/order.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/models/order.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/pet.py b/samples/client/petstore/python/swagger_client_python/swagger_client/models/pet.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/pet.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/models/pet.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/tag.py b/samples/client/petstore/python/swagger_client_python/swagger_client/models/tag.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/tag.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/models/tag.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/user.py b/samples/client/petstore/python/swagger_client_python/swagger_client/models/user.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/models/user.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/models/user.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py b/samples/client/petstore/python/swagger_client_python/swagger_client/rest.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py rename to samples/client/petstore/python/swagger_client_python/swagger_client/rest.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/testfiles/foo.png b/samples/client/petstore/python/swagger_client_python/testfiles/foo.png similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/testfiles/foo.png rename to samples/client/petstore/python/swagger_client_python/testfiles/foo.png diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/__init__.py b/samples/client/petstore/python/swagger_client_python/tests/__init__.py similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/tests/__init__.py rename to samples/client/petstore/python/swagger_client_python/tests/__init__.py diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py b/samples/client/petstore/python/swagger_client_python/tests/test_api_client.py similarity index 85% rename from samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py rename to samples/client/petstore/python/swagger_client_python/tests/test_api_client.py index 42d838417fd..d18008f5575 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py +++ b/samples/client/petstore/python/swagger_client_python/tests/test_api_client.py @@ -11,8 +11,8 @@ import os import time import unittest -import SwaggerPetstore -import SwaggerPetstore.configuration +import swagger_client +import swagger_client.configuration HOST = 'http://petstore.swagger.io/v2' @@ -20,20 +20,20 @@ HOST = 'http://petstore.swagger.io/v2' class ApiClientTests(unittest.TestCase): def setUp(self): - self.api_client = SwaggerPetstore.ApiClient(HOST) + self.api_client = swagger_client.ApiClient(HOST) def test_configuration(self): - SwaggerPetstore.configuration.api_key['api_key'] = '123456' - SwaggerPetstore.configuration.api_key_prefix['api_key'] = 'PREFIX' - SwaggerPetstore.configuration.username = 'test_username' - SwaggerPetstore.configuration.password = 'test_password' + swagger_client.configuration.api_key['api_key'] = '123456' + swagger_client.configuration.api_key_prefix['api_key'] = 'PREFIX' + swagger_client.configuration.username = 'test_username' + swagger_client.configuration.password = 'test_password' header_params = {'test1': 'value1'} query_params = {'test2': 'value2'} auth_settings = ['api_key', 'unknown'] # test prefix - self.assertEqual('PREFIX', SwaggerPetstore.configuration.api_key_prefix['api_key']) + self.assertEqual('PREFIX', swagger_client.configuration.api_key_prefix['api_key']) # update parameters based on auth setting self.api_client.update_params_for_auth(header_params, query_params, auth_settings) @@ -44,8 +44,8 @@ class ApiClientTests(unittest.TestCase): self.assertEqual(query_params['test2'], 'value2') # test basic auth - self.assertEqual('test_username', SwaggerPetstore.configuration.username) - self.assertEqual('test_password', SwaggerPetstore.configuration.password) + self.assertEqual('test_username', swagger_client.configuration.username) + self.assertEqual('test_password', swagger_client.configuration.password) def test_select_header_accept(self): accepts = ['APPLICATION/JSON', 'APPLICATION/XML'] diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_exception.py b/samples/client/petstore/python/swagger_client_python/tests/test_api_exception.py similarity index 85% rename from samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_exception.py rename to samples/client/petstore/python/swagger_client_python/tests/test_api_exception.py index d1b786241e8..f3d00cb10dc 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_exception.py +++ b/samples/client/petstore/python/swagger_client_python/tests/test_api_exception.py @@ -3,7 +3,7 @@ """ Run the tests. $ pip install nose (optional) -$ cd SwaggerPetstore-python +$ cd swagger_client-python $ nosetests -v """ @@ -11,25 +11,25 @@ import os import time import unittest -import SwaggerPetstore -from SwaggerPetstore.rest import ApiException +import swagger_client +from swagger_client.rest import ApiException class ApiExceptionTests(unittest.TestCase): def setUp(self): - self.api_client = SwaggerPetstore.ApiClient() - self.pet_api = SwaggerPetstore.PetApi(self.api_client) + self.api_client = swagger_client.ApiClient() + self.pet_api = swagger_client.PetApi(self.api_client) self.setUpModels() def setUpModels(self): - self.category = SwaggerPetstore.Category() + self.category = swagger_client.Category() self.category.id = int(time.time()) self.category.name = "dog" - self.tag = SwaggerPetstore.Tag() + self.tag = swagger_client.Tag() self.tag.id = int(time.time()) self.tag.name = "blank" - self.pet = SwaggerPetstore.Pet() + self.pet = swagger_client.Pet() self.pet.id = int(time.time()) self.pet.name = "hello kity" self.pet.photo_urls = ["http://foo.bar.com/1", "http://foo.bar.com/2"] diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py b/samples/client/petstore/python/swagger_client_python/tests/test_pet_api.py similarity index 84% rename from samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py rename to samples/client/petstore/python/swagger_client_python/tests/test_pet_api.py index 3bf18607729..5397c0b50ef 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py +++ b/samples/client/petstore/python/swagger_client_python/tests/test_pet_api.py @@ -3,7 +3,7 @@ """ Run the tests. $ pip install nose (optional) -$ cd SwaggerPetstore-python +$ cd swagger_client-python $ nosetests -v """ @@ -11,8 +11,8 @@ import os import time import unittest -import SwaggerPetstore -from SwaggerPetstore.rest import ApiException +import swagger_client +from swagger_client.rest import ApiException HOST = 'http://petstore.swagger.io/v2' @@ -20,8 +20,8 @@ HOST = 'http://petstore.swagger.io/v2' class PetApiTests(unittest.TestCase): def setUp(self): - self.api_client = SwaggerPetstore.ApiClient(HOST) - self.pet_api = SwaggerPetstore.PetApi(self.api_client) + self.api_client = swagger_client.ApiClient(HOST) + self.pet_api = swagger_client.PetApi(self.api_client) self.setUpModels() self.setUpFiles() @@ -30,13 +30,13 @@ class PetApiTests(unittest.TestCase): time.sleep(1) def setUpModels(self): - self.category = SwaggerPetstore.Category() + self.category = swagger_client.Category() self.category.id = int(time.time()) self.category.name = "dog" - self.tag = SwaggerPetstore.Tag() + self.tag = swagger_client.Tag() self.tag.id = int(time.time()) self.tag.name = "blank" - self.pet = SwaggerPetstore.Pet() + self.pet = swagger_client.Pet() self.pet.id = int(time.time()) self.pet.name = "hello kity" self.pet.photo_urls = ["http://foo.bar.com/1", "http://foo.bar.com/2"] @@ -50,22 +50,22 @@ class PetApiTests(unittest.TestCase): self.foo = os.path.join(self.test_file_dir, "foo.png") def test_create_api_instance(self): - pet_api = SwaggerPetstore.PetApi() - pet_api2 = SwaggerPetstore.PetApi() - api_client3 = SwaggerPetstore.ApiClient() + pet_api = swagger_client.PetApi() + pet_api2 = swagger_client.PetApi() + api_client3 = swagger_client.ApiClient() api_client3.user_agent = 'api client 3' - api_client4 = SwaggerPetstore.ApiClient() + api_client4 = swagger_client.ApiClient() api_client4.user_agent = 'api client 4' - pet_api3 = SwaggerPetstore.PetApi(api_client3) + pet_api3 = swagger_client.PetApi(api_client3) # same default api client self.assertEqual(pet_api.api_client, pet_api2.api_client) # confirm using the default api client in the config module - self.assertEqual(pet_api.api_client, SwaggerPetstore.configuration.api_client) + self.assertEqual(pet_api.api_client, swagger_client.configuration.api_client) # 2 different api clients are not the same self.assertNotEqual(api_client3, api_client4) # customized pet api not using the default api client - self.assertNotEqual(pet_api3.api_client, SwaggerPetstore.configuration.api_client) + self.assertNotEqual(pet_api3.api_client, swagger_client.configuration.api_client) # customized pet api not using the old pet api's api client self.assertNotEqual(pet_api3.api_client, pet_api2.api_client) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tox.ini b/samples/client/petstore/python/swagger_client_python/tox.ini similarity index 100% rename from samples/client/petstore/python/SwaggerPetstore-python/tox.ini rename to samples/client/petstore/python/swagger_client_python/tox.ini From 5d19ef6146ff926cd4fe94078ceb5bbfd771fa46 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Fri, 12 Jun 2015 18:22:24 +0800 Subject: [PATCH 053/499] Generate the python into `python/` folder directly --- .../codegen/languages/PythonClientCodegen.java | 7 +++---- .../python/{swagger_client_python => }/Makefile | 0 .../python/{swagger_client_python => }/README.md | 0 .../dev-requirements.txt | 0 .../python/{swagger_client_python => }/pom.xml | 0 .../python/{swagger_client_python => }/setup.cfg | 0 .../python/{swagger_client_python => }/setup.py | 0 .../swagger_client/__init__.py | 0 .../swagger_client/api_client.py | 0 .../swagger_client/apis/__init__.py | 0 .../swagger_client/apis/pet_api.py | 0 .../swagger_client/apis/store_api.py | 0 .../swagger_client/apis/user_api.py | 0 .../swagger_client/configuration.py | 0 .../swagger_client/models/__init__.py | 0 .../swagger_client/models/category.py | 0 .../swagger_client/models/order.py | 0 .../swagger_client/models/pet.py | 0 .../swagger_client/models/tag.py | 0 .../swagger_client/models/user.py | 0 .../swagger_client/rest.py | 0 .../{swagger_client_python => }/testfiles/foo.png | Bin .../{swagger_client_python => }/tests/__init__.py | 0 .../tests/test_api_client.py | 0 .../tests/test_api_exception.py | 0 .../tests/test_pet_api.py | 0 .../python/{swagger_client_python => }/tox.ini | 0 27 files changed, 3 insertions(+), 4 deletions(-) rename samples/client/petstore/python/{swagger_client_python => }/Makefile (100%) rename samples/client/petstore/python/{swagger_client_python => }/README.md (100%) rename samples/client/petstore/python/{swagger_client_python => }/dev-requirements.txt (100%) rename samples/client/petstore/python/{swagger_client_python => }/pom.xml (100%) rename samples/client/petstore/python/{swagger_client_python => }/setup.cfg (100%) rename samples/client/petstore/python/{swagger_client_python => }/setup.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/__init__.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/api_client.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/apis/__init__.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/apis/pet_api.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/apis/store_api.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/apis/user_api.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/configuration.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/models/__init__.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/models/category.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/models/order.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/models/pet.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/models/tag.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/models/user.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/swagger_client/rest.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/testfiles/foo.png (100%) rename samples/client/petstore/python/{swagger_client_python => }/tests/__init__.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/tests/test_api_client.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/tests/test_api_exception.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/tests/test_pet_api.py (100%) rename samples/client/petstore/python/{swagger_client_python => }/tox.ini (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index e5a3b0810b2..030e19c1a31 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -82,14 +82,13 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig additionalProperties.put("packageName", packageName); additionalProperties.put("packageVersion", packageVersion); - String baseFolder = packageName + "_python"; - String swaggerFoler = baseFolder + File.separatorChar + packageName; + String swaggerFoler = packageName; modelPackage = swaggerFoler + File.separatorChar + "models"; apiPackage = swaggerFoler + File.separatorChar + "apis"; - supportingFiles.add(new SupportingFile("README.mustache", baseFolder, "README.md")); - supportingFiles.add(new SupportingFile("setup.mustache", baseFolder, "setup.py")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py")); supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFoler, "api_client.py")); supportingFiles.add(new SupportingFile("rest.mustache", swaggerFoler, "rest.py")); supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFoler, "configuration.py")); diff --git a/samples/client/petstore/python/swagger_client_python/Makefile b/samples/client/petstore/python/Makefile similarity index 100% rename from samples/client/petstore/python/swagger_client_python/Makefile rename to samples/client/petstore/python/Makefile diff --git a/samples/client/petstore/python/swagger_client_python/README.md b/samples/client/petstore/python/README.md similarity index 100% rename from samples/client/petstore/python/swagger_client_python/README.md rename to samples/client/petstore/python/README.md diff --git a/samples/client/petstore/python/swagger_client_python/dev-requirements.txt b/samples/client/petstore/python/dev-requirements.txt similarity index 100% rename from samples/client/petstore/python/swagger_client_python/dev-requirements.txt rename to samples/client/petstore/python/dev-requirements.txt diff --git a/samples/client/petstore/python/swagger_client_python/pom.xml b/samples/client/petstore/python/pom.xml similarity index 100% rename from samples/client/petstore/python/swagger_client_python/pom.xml rename to samples/client/petstore/python/pom.xml diff --git a/samples/client/petstore/python/swagger_client_python/setup.cfg b/samples/client/petstore/python/setup.cfg similarity index 100% rename from samples/client/petstore/python/swagger_client_python/setup.cfg rename to samples/client/petstore/python/setup.cfg diff --git a/samples/client/petstore/python/swagger_client_python/setup.py b/samples/client/petstore/python/setup.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/setup.py rename to samples/client/petstore/python/setup.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/__init__.py b/samples/client/petstore/python/swagger_client/__init__.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/__init__.py rename to samples/client/petstore/python/swagger_client/__init__.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/api_client.py b/samples/client/petstore/python/swagger_client/api_client.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/api_client.py rename to samples/client/petstore/python/swagger_client/api_client.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/apis/__init__.py b/samples/client/petstore/python/swagger_client/apis/__init__.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/apis/__init__.py rename to samples/client/petstore/python/swagger_client/apis/__init__.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/apis/pet_api.py b/samples/client/petstore/python/swagger_client/apis/pet_api.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/apis/pet_api.py rename to samples/client/petstore/python/swagger_client/apis/pet_api.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/apis/store_api.py b/samples/client/petstore/python/swagger_client/apis/store_api.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/apis/store_api.py rename to samples/client/petstore/python/swagger_client/apis/store_api.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/apis/user_api.py b/samples/client/petstore/python/swagger_client/apis/user_api.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/apis/user_api.py rename to samples/client/petstore/python/swagger_client/apis/user_api.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/configuration.py b/samples/client/petstore/python/swagger_client/configuration.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/configuration.py rename to samples/client/petstore/python/swagger_client/configuration.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/models/__init__.py b/samples/client/petstore/python/swagger_client/models/__init__.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/models/__init__.py rename to samples/client/petstore/python/swagger_client/models/__init__.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/models/category.py b/samples/client/petstore/python/swagger_client/models/category.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/models/category.py rename to samples/client/petstore/python/swagger_client/models/category.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/models/order.py b/samples/client/petstore/python/swagger_client/models/order.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/models/order.py rename to samples/client/petstore/python/swagger_client/models/order.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/models/pet.py b/samples/client/petstore/python/swagger_client/models/pet.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/models/pet.py rename to samples/client/petstore/python/swagger_client/models/pet.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/models/tag.py b/samples/client/petstore/python/swagger_client/models/tag.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/models/tag.py rename to samples/client/petstore/python/swagger_client/models/tag.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/models/user.py b/samples/client/petstore/python/swagger_client/models/user.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/models/user.py rename to samples/client/petstore/python/swagger_client/models/user.py diff --git a/samples/client/petstore/python/swagger_client_python/swagger_client/rest.py b/samples/client/petstore/python/swagger_client/rest.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/swagger_client/rest.py rename to samples/client/petstore/python/swagger_client/rest.py diff --git a/samples/client/petstore/python/swagger_client_python/testfiles/foo.png b/samples/client/petstore/python/testfiles/foo.png similarity index 100% rename from samples/client/petstore/python/swagger_client_python/testfiles/foo.png rename to samples/client/petstore/python/testfiles/foo.png diff --git a/samples/client/petstore/python/swagger_client_python/tests/__init__.py b/samples/client/petstore/python/tests/__init__.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/tests/__init__.py rename to samples/client/petstore/python/tests/__init__.py diff --git a/samples/client/petstore/python/swagger_client_python/tests/test_api_client.py b/samples/client/petstore/python/tests/test_api_client.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/tests/test_api_client.py rename to samples/client/petstore/python/tests/test_api_client.py diff --git a/samples/client/petstore/python/swagger_client_python/tests/test_api_exception.py b/samples/client/petstore/python/tests/test_api_exception.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/tests/test_api_exception.py rename to samples/client/petstore/python/tests/test_api_exception.py diff --git a/samples/client/petstore/python/swagger_client_python/tests/test_pet_api.py b/samples/client/petstore/python/tests/test_pet_api.py similarity index 100% rename from samples/client/petstore/python/swagger_client_python/tests/test_pet_api.py rename to samples/client/petstore/python/tests/test_pet_api.py diff --git a/samples/client/petstore/python/swagger_client_python/tox.ini b/samples/client/petstore/python/tox.ini similarity index 100% rename from samples/client/petstore/python/swagger_client_python/tox.ini rename to samples/client/petstore/python/tox.ini From 62f4c252f2eb01c58350f27d70c35aaeaf17ec8c Mon Sep 17 00:00:00 2001 From: geekerzp Date: Tue, 16 Jun 2015 09:44:18 +0800 Subject: [PATCH 054/499] Update python codegen. * Update config-help message. * Do not sanitize packageName to underscore format. --- .../io/swagger/codegen/languages/PythonClientCodegen.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index 030e19c1a31..c901462ca48 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -56,7 +56,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig "return", "def", "for", "lambda", "try")); cliOptions.clear(); - cliOptions.add(new CliOption("packageName", "python package name, default: SwaggerClient")); + cliOptions.add(new CliOption("packageName", "python package name, default: swagger_client")); cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0")); } @@ -68,9 +68,8 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig setPackageName((String) additionalProperties.get("packageName")); } else { - setPackageName("SwaggerClient"); + setPackageName("swagger_client"); } - setPackageName(generatePackageName(packageName)); if (additionalProperties.containsKey("packageVersion")) { setPackageVersion((String) additionalProperties.get("packageVersion")); From 194c8ff71deb1382c1e5547b877f6f99f0191e07 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Tue, 16 Jun 2015 15:29:10 +0800 Subject: [PATCH 055/499] Update config-help message of python client --- .../java/io/swagger/codegen/languages/PythonClientCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index c901462ca48..cdafa337c21 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -56,7 +56,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig "return", "def", "for", "lambda", "try")); cliOptions.clear(); - cliOptions.add(new CliOption("packageName", "python package name, default: swagger_client")); + cliOptions.add(new CliOption("packageName", "python package name (convension: under_score), default: swagger_client")); cliOptions.add(new CliOption("packageVersion", "python package version, default: 1.0.0")); } From 449ba4f64470592e0c08035a877919a5f47f0a0b Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Thu, 18 Jun 2015 12:42:04 +0200 Subject: [PATCH 056/499] Fixed required parameters for APIs in TypeScript --- .../resources/TypeScript-Angular/api.mustache | 10 +++++----- .../resources/TypeScript-node/api.mustache | 10 +++++----- .../petstore/typescript-angular/api/PetApi.ts | 20 +++++++++++++++++++ .../typescript-angular/api/StoreApi.ts | 10 ++++++++++ .../typescript-angular/api/UserApi.ts | 15 ++++++++++++++ .../petstore/typescript-node/api/PetApi.ts | 20 +++++++++++++++++++ .../petstore/typescript-node/api/StoreApi.ts | 10 ++++++++++ .../petstore/typescript-node/api/UserApi.ts | 15 ++++++++++++++ 8 files changed, 100 insertions(+), 10 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache index 3b53e816891..1095667b245 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache @@ -29,12 +29,12 @@ module {{package}} { {{/pathParams}} var queryParameters: any = {}; var headers: any = {}; - {{#requiredParamCount}} - // verify required params are set - if ({{/requiredParamCount}}{{#requiredParams}} !{{paramName}} {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) { - throw new Error('Missing required parameter: {{¶mName}}'); + {{#allParams}}{{#required}} + // verify required parameter '{{paramName}}' is set + if (!{{paramName}}) { + throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}'); } - {{/requiredParamCount}} + {{/required}}{{/allParams}} {{#queryParams}}if ({{paramName}} !== undefined) { queryParameters['{{paramName}}'] = {{paramName}}; }{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache index 4b329799ad5..156ad63f72d 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache @@ -26,12 +26,12 @@ export class {{classname}} { var queryParameters: any = {}; var headers: any = {}; - {{#requiredParamCount}} - // verify required params are set - if ({{/requiredParamCount}}{{#requiredParams}} !{{paramName}} {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) { - throw new Error('Missing required parameter: {{¶mName}}'); + {{#allParams}}{{#required}} + // verify required parameter '{{paramName}}' is set + if (!{{paramName}}) { + throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}'); } - {{/requiredParamCount}} + {{/required}}{{/allParams}} {{#queryParams}}if ({{paramName}} !== undefined) { queryParameters['{{paramName}}'] = {{paramName}}; diff --git a/samples/client/petstore/typescript-angular/api/PetApi.ts b/samples/client/petstore/typescript-angular/api/PetApi.ts index 2c5f2a25b6d..d294cfbebbc 100644 --- a/samples/client/petstore/typescript-angular/api/PetApi.ts +++ b/samples/client/petstore/typescript-angular/api/PetApi.ts @@ -143,6 +143,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling getPetById'); + } + var httpRequestParams: any = { @@ -173,6 +178,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling updatePetWithForm'); + } + var httpRequestParams: any = { @@ -203,6 +213,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling deletePet'); + } + headerParams['apiKey'] = apiKey; var httpRequestParams: any = { @@ -233,6 +248,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling uploadFile'); + } + var httpRequestParams: any = { diff --git a/samples/client/petstore/typescript-angular/api/StoreApi.ts b/samples/client/petstore/typescript-angular/api/StoreApi.ts index e4c9e48e0e9..e8c85b00c45 100644 --- a/samples/client/petstore/typescript-angular/api/StoreApi.ts +++ b/samples/client/petstore/typescript-angular/api/StoreApi.ts @@ -82,6 +82,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'orderId' is set + if (!orderId) { + throw new Error('Missing required parameter orderId when calling getOrderById'); + } + var httpRequestParams: any = { @@ -112,6 +117,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'orderId' is set + if (!orderId) { + throw new Error('Missing required parameter orderId when calling deleteOrder'); + } + var httpRequestParams: any = { diff --git a/samples/client/petstore/typescript-angular/api/UserApi.ts b/samples/client/petstore/typescript-angular/api/UserApi.ts index dfbe9032dba..40d82f73852 100644 --- a/samples/client/petstore/typescript-angular/api/UserApi.ts +++ b/samples/client/petstore/typescript-angular/api/UserApi.ts @@ -172,6 +172,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'username' is set + if (!username) { + throw new Error('Missing required parameter username when calling getUserByName'); + } + var httpRequestParams: any = { @@ -202,6 +207,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'username' is set + if (!username) { + throw new Error('Missing required parameter username when calling updateUser'); + } + var httpRequestParams: any = { @@ -233,6 +243,11 @@ module api { var queryParameters: any = {}; var headers: any = {}; + // verify required parameter 'username' is set + if (!username) { + throw new Error('Missing required parameter username when calling deleteUser'); + } + var httpRequestParams: any = { diff --git a/samples/client/petstore/typescript-node/api/PetApi.ts b/samples/client/petstore/typescript-node/api/PetApi.ts index c948f8036e6..02605f2c8a8 100644 --- a/samples/client/petstore/typescript-node/api/PetApi.ts +++ b/samples/client/petstore/typescript-node/api/PetApi.ts @@ -193,6 +193,11 @@ export class PetApi { var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling getPetById'); + } + @@ -236,6 +241,11 @@ export class PetApi { var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling updatePetWithForm'); + } + @@ -279,6 +289,11 @@ export class PetApi { var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling deletePet'); + } + @@ -323,6 +338,11 @@ export class PetApi { var headers: any = {}; + // verify required parameter 'petId' is set + if (!petId) { + throw new Error('Missing required parameter petId when calling uploadFile'); + } + diff --git a/samples/client/petstore/typescript-node/api/StoreApi.ts b/samples/client/petstore/typescript-node/api/StoreApi.ts index 1c2c6623523..71cfe106fca 100644 --- a/samples/client/petstore/typescript-node/api/StoreApi.ts +++ b/samples/client/petstore/typescript-node/api/StoreApi.ts @@ -104,6 +104,11 @@ export class StoreApi { var headers: any = {}; + // verify required parameter 'orderId' is set + if (!orderId) { + throw new Error('Missing required parameter orderId when calling getOrderById'); + } + @@ -147,6 +152,11 @@ export class StoreApi { var headers: any = {}; + // verify required parameter 'orderId' is set + if (!orderId) { + throw new Error('Missing required parameter orderId when calling deleteOrder'); + } + diff --git a/samples/client/petstore/typescript-node/api/UserApi.ts b/samples/client/petstore/typescript-node/api/UserApi.ts index fa4365f8edc..ca6fd41c593 100644 --- a/samples/client/petstore/typescript-node/api/UserApi.ts +++ b/samples/client/petstore/typescript-node/api/UserApi.ts @@ -235,6 +235,11 @@ export class UserApi { var headers: any = {}; + // verify required parameter 'username' is set + if (!username) { + throw new Error('Missing required parameter username when calling getUserByName'); + } + @@ -278,6 +283,11 @@ export class UserApi { var headers: any = {}; + // verify required parameter 'username' is set + if (!username) { + throw new Error('Missing required parameter username when calling updateUser'); + } + @@ -322,6 +332,11 @@ export class UserApi { var headers: any = {}; + // verify required parameter 'username' is set + if (!username) { + throw new Error('Missing required parameter username when calling deleteUser'); + } + From 8d18aee2f2222e17f4bd7d4dbba1e4918b5b2e3b Mon Sep 17 00:00:00 2001 From: geekerzp Date: Thu, 18 Jun 2015 22:02:54 +0800 Subject: [PATCH 057/499] Update test case `test_deserialize_to_dict` of python client --- samples/client/petstore/python/tests/test_api_client.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/samples/client/petstore/python/tests/test_api_client.py b/samples/client/petstore/python/tests/test_api_client.py index d18008f5575..d932006c052 100644 --- a/samples/client/petstore/python/tests/test_api_client.py +++ b/samples/client/petstore/python/tests/test_api_client.py @@ -114,7 +114,7 @@ class ApiClientTests(unittest.TestCase): data = self.api_client.deserialize(json, 'dict(str, Pet)') self.assertTrue(isinstance(data, dict)) - self.assertTrue(isinstance(data['pet'], SwaggerPetstore.Pet)) + self.assertTrue(isinstance(data['pet'], swagger_client.Pet)) # dict(str, int) json = { @@ -128,6 +128,3 @@ class ApiClientTests(unittest.TestCase): def test_deserialize_to_object(self): data = self.api_client.deserialize("", "object") self.assertTrue(type(data) == object) - - - From df72188bc0c7e4db21d87b288fb6ae97ab5ccfd5 Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 18 Jun 2015 22:06:59 +0800 Subject: [PATCH 058/499] add cli support to csharp --- .../languages/CSharpClientCodegen.java | 64 +++++++++++++------ .../main/resources/csharp/ApiClient.mustache | 2 +- .../resources/csharp/ApiException.mustache | 2 +- .../resources/csharp/Configuration.mustache | 3 +- .../src/main/resources/csharp/api.mustache | 6 +- .../src/main/resources/csharp/model.mustache | 2 +- samples/client/petstore/csharp/compile.bat | 2 +- .../csharp/io/swagger/client/Configuration.cs | 1 - 8 files changed, 53 insertions(+), 29 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index a564ec5f883..33ea13b5e31 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -7,6 +7,7 @@ import io.swagger.codegen.SupportingFile; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import io.swagger.codegen.CliOption; import java.io.File; import java.util.Arrays; @@ -14,15 +15,14 @@ import java.util.HashMap; import java.util.HashSet; public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig { - protected String invokerPackage = "IO.Swagger.Client"; - protected String groupId = "io.swagger"; - protected String artifactId = "swagger-csharp-client"; - protected String artifactVersion = "1.0.0"; - protected String sourceFolder = "src/main/csharp"; + protected String packageName = "IO.Swagger"; + protected String packageVersion = "1.0.0"; + protected String clientPackage = "IO.Swagger.Client"; + protected String sourceFolder = "src" + File.separator + "main" + File.separator + "csharp"; public CSharpClientCodegen() { super(); - outputFolder = "generated-code/csharp"; + outputFolder = "generated-code" + File.separator + "csharp"; modelTemplateFiles.put("model.mustache", ".cs"); apiTemplateFiles.put("api.mustache", ".cs"); templateDir = "csharp"; @@ -34,17 +34,6 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while") ); - additionalProperties.put("invokerPackage", invokerPackage); - - supportingFiles.add(new SupportingFile("Configuration.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.cs")); - supportingFiles.add(new SupportingFile("ApiClient.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.cs")); - supportingFiles.add(new SupportingFile("ApiException.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.cs")); - supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll")); - supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll")); - supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat")); languageSpecificPrimitives = new HashSet( Arrays.asList( @@ -85,6 +74,43 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.put("map", "Dictionary"); typeMapping.put("object", "Object"); + cliOptions.clear(); + cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger")); + cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0")); + + } + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey("packageVersion")) { + packageVersion = (String) additionalProperties.get("packageVersion"); + } else { + additionalProperties.put("packageVersion", packageVersion); + } + + if (additionalProperties.containsKey("packageName")) { + packageName = (String) additionalProperties.get("packageName"); + apiPackage = packageName + ".Api"; + modelPackage = packageName + ".Model"; + clientPackage = packageName + ".Client"; + } else { + additionalProperties.put("packageName", packageName); + } + + additionalProperties.put("clientPackage", clientPackage); + + supportingFiles.add(new SupportingFile("Configuration.mustache", + (sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "Configuration.cs")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", + (sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiClient.cs")); + supportingFiles.add(new SupportingFile("ApiException.mustache", + (sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiException.cs")); + supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll")); + supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll")); + supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat")); + } public CodegenType getTag() { @@ -106,11 +132,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig @Override public String apiFileFolder() { - return (outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/')).replace('.', File.separatorChar); + return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar); } public String modelFileFolder() { - return (outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/')).replace('.', File.separatorChar); + return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar); } @Override diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index ad57cffdf34..c6f57bd4a37 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -8,7 +8,7 @@ using System.Threading.Tasks; using Newtonsoft.Json; using RestSharp; -namespace {{invokerPackage}} { +namespace {{packageName}}.Client { /// /// API client is mainly responible for making the HTTP call to the API backend /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache index 38a340be249..65c6193b84f 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache @@ -1,6 +1,6 @@ using System; -namespace {{invokerPackage}} { +namespace {{packageName}}.Client { /// /// API Exception /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index 1f5c00a356d..86e35441493 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -4,9 +4,8 @@ using System.IO; using System.Linq; using System.Net; using System.Text; -using {{invokerPackage}}; -namespace {{invokerPackage}} { +namespace {{packageName}}.Client { /// /// Represents a set of configuration settings /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index e22d5517ab5..652d15a30b3 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -2,12 +2,12 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using RestSharp; -using {{invokerPackage}}; -using {{modelPackage}}; +using {{packageName}}.Client; +using {{packageName}}.Model; {{#imports}} {{/imports}} -namespace {{package}} { +namespace {{packageName}}.Api { {{#operations}} public interface I{{classname}} { diff --git a/modules/swagger-codegen/src/main/resources/csharp/model.mustache b/modules/swagger-codegen/src/main/resources/csharp/model.mustache index ce0e62de192..0d86e0e2b99 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/model.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/model.mustache @@ -7,7 +7,7 @@ using Newtonsoft.Json; {{#models}} {{#model}} -namespace {{package}} { +namespace {{packageName}}.Model { /// /// {{description}} diff --git a/samples/client/petstore/csharp/compile.bat b/samples/client/petstore/csharp/compile.bat index 63b79e03eed..bb6ae8097ea 100644 --- a/samples/client/petstore/csharp/compile.bat +++ b/samples/client/petstore/csharp/compile.bat @@ -1,3 +1,3 @@ SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319 -%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll;bin/RestSharp.dll /target:library /out:bin/IO.Swagger.Client.dll /recurse:src\*.cs /doc:bin/IO.Swagger.Client.xml +%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll;bin/RestSharp.dll /target:library /out:bin/.dll /recurse:src\*.cs /doc:bin/.xml diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs index 4e7975e3ad0..cf5162b62ea 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Net; using System.Text; -using IO.Swagger.Client; namespace IO.Swagger.Client { /// From 6ab7be405834c17c3ac9a11ab06c5c43b6f7c9be Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 18 Jun 2015 22:20:52 +0800 Subject: [PATCH 059/499] add package version --- .../src/main/resources/csharp/Configuration.mustache | 5 +++++ .../src/main/csharp/io/swagger/client/Configuration.cs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index 86e35441493..485d97058ce 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -11,6 +11,11 @@ namespace {{packageName}}.Client { /// public class Configuration{ + /// + /// Version of the package + /// + public const string Version = "{{packageVersion}}"; + /// /// Gets or sets the API client. This is the default API client for making HTTP calls. /// diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs index cf5162b62ea..ab24fc1252c 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs @@ -11,6 +11,11 @@ namespace IO.Swagger.Client { /// public class Configuration{ + /// + /// Version of the package + /// + public const string Version = "1.0.0"; + /// /// Gets or sets the API client. This is the default API client for making HTTP calls. /// From 4ef34680cd53cb2b047bc2126a72f977001651fc Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Thu, 18 Jun 2015 10:30:53 -0700 Subject: [PATCH 060/499] renaming to ApiClient.mustache --- .../main/resources/php/{APIClient.mustache => ApiClient.mustache} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/swagger-codegen/src/main/resources/php/{APIClient.mustache => ApiClient.mustache} (100%) diff --git a/modules/swagger-codegen/src/main/resources/php/APIClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache similarity index 100% rename from modules/swagger-codegen/src/main/resources/php/APIClient.mustache rename to modules/swagger-codegen/src/main/resources/php/ApiClient.mustache From d178d5e7d86a3c3d5e2c71e071a6adbf23e3e93b Mon Sep 17 00:00:00 2001 From: William Cheng Date: Fri, 19 Jun 2015 02:11:08 +0800 Subject: [PATCH 061/499] add sinatra template --- bin/silex-petstore-server.sh | 2 +- bin/sinatra-petstore-server.sh | 31 +++ .../languages/SinatraServerCodegen.java | 215 ++++++++++++++++ .../services/io.swagger.codegen.CodegenConfig | 1 + .../src/main/resources/sinatra/Gemfile | 4 + .../src/main/resources/sinatra/README.md | 29 +++ .../src/main/resources/sinatra/Swaggering.rb | 154 ++++++++++++ .../src/main/resources/sinatra/api.mustache | 57 +++++ .../src/main/resources/sinatra/config.ru | 2 + .../main/resources/sinatra/my_app.mustache | 12 + .../petstore/silex/SwaggerServer/.htaccess | 5 - .../petstore/silex/SwaggerServer/README.md | 10 - .../silex/SwaggerServer/composer.json | 5 - .../petstore/silex/SwaggerServer/index.php | 184 -------------- samples/client/petstore/silex/silex/.htaccess | 5 - samples/client/petstore/silex/silex/README.md | 10 - .../client/petstore/silex/silex/composer.json | 5 - samples/client/petstore/silex/silex/index.php | 184 -------------- samples/server/petstore/sinatra/Gemfile | 4 + samples/server/petstore/sinatra/README.md | 29 +++ .../server/petstore/sinatra/api/pet_api.rb | 231 ++++++++++++++++++ .../server/petstore/sinatra/api/store_api.rb | 103 ++++++++ .../server/petstore/sinatra/api/user_api.rb | 231 ++++++++++++++++++ samples/server/petstore/sinatra/config.rb | 2 + .../server/petstore/sinatra/lib/Swaggering.rb | 154 ++++++++++++ samples/server/petstore/sinatra/my_app.rb | 9 + 26 files changed, 1269 insertions(+), 409 deletions(-) create mode 100755 bin/sinatra-petstore-server.sh create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java create mode 100644 modules/swagger-codegen/src/main/resources/sinatra/Gemfile create mode 100644 modules/swagger-codegen/src/main/resources/sinatra/README.md create mode 100644 modules/swagger-codegen/src/main/resources/sinatra/Swaggering.rb create mode 100644 modules/swagger-codegen/src/main/resources/sinatra/api.mustache create mode 100644 modules/swagger-codegen/src/main/resources/sinatra/config.ru create mode 100644 modules/swagger-codegen/src/main/resources/sinatra/my_app.mustache delete mode 100644 samples/client/petstore/silex/SwaggerServer/.htaccess delete mode 100644 samples/client/petstore/silex/SwaggerServer/README.md delete mode 100644 samples/client/petstore/silex/SwaggerServer/composer.json delete mode 100644 samples/client/petstore/silex/SwaggerServer/index.php delete mode 100644 samples/client/petstore/silex/silex/.htaccess delete mode 100644 samples/client/petstore/silex/silex/README.md delete mode 100644 samples/client/petstore/silex/silex/composer.json delete mode 100644 samples/client/petstore/silex/silex/index.php create mode 100644 samples/server/petstore/sinatra/Gemfile create mode 100644 samples/server/petstore/sinatra/README.md create mode 100644 samples/server/petstore/sinatra/api/pet_api.rb create mode 100644 samples/server/petstore/sinatra/api/store_api.rb create mode 100644 samples/server/petstore/sinatra/api/user_api.rb create mode 100644 samples/server/petstore/sinatra/config.rb create mode 100644 samples/server/petstore/sinatra/lib/Swaggering.rb create mode 100644 samples/server/petstore/sinatra/my_app.rb diff --git a/bin/silex-petstore-server.sh b/bin/silex-petstore-server.sh index 5ead9db0002..ffa030b88c3 100755 --- a/bin/silex-petstore-server.sh +++ b/bin/silex-petstore-server.sh @@ -26,6 +26,6 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/client/petstore/silex" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/server/petstore/silex" java $JAVA_OPTS -jar $executable $ags diff --git a/bin/sinatra-petstore-server.sh b/bin/sinatra-petstore-server.sh new file mode 100755 index 00000000000..4f7e19cee39 --- /dev/null +++ b/bin/sinatra-petstore-server.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/sinatra -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l sinatra -o samples/server/petstore/sinatra" + +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java new file mode 100644 index 00000000000..318bf03130d --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java @@ -0,0 +1,215 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.CliOption; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.CodegenType; +import io.swagger.codegen.DefaultCodegen; +import io.swagger.codegen.SupportingFile; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.Property; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; + +public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig { + protected String gemName = null; + protected String moduleName = null; + protected String gemVersion = "1.0.0"; + protected String libFolder = "lib"; + + public SinatraServerCodegen() { + super(); + apiPackage = "lib"; + outputFolder = "generated-code" + File.separator + "sinatra"; + + // no model + modelTemplateFiles.clear(); + apiTemplateFiles.put("api.mustache", ".rb"); + templateDir = "sinatra"; + + typeMapping.clear(); + languageSpecificPrimitives.clear(); + + reservedWords = new HashSet( + Arrays.asList( + "__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__", + "begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN", + "break", "do", "false", "next", "rescue", "then", "when", "END", "case", + "else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif", + "if", "not", "return", "undef", "yield") + ); + + languageSpecificPrimitives.add("int"); + languageSpecificPrimitives.add("array"); + languageSpecificPrimitives.add("map"); + languageSpecificPrimitives.add("string"); + languageSpecificPrimitives.add("DateTime"); + + typeMapping.put("long", "int"); + typeMapping.put("integer", "int"); + typeMapping.put("Array", "array"); + typeMapping.put("String", "string"); + typeMapping.put("List", "array"); + typeMapping.put("map", "map"); + + // remove modelPackage and apiPackage added by default + cliOptions.clear(); + } + + @Override + public void processOpts() { + super.processOpts(); + + // use constant model/api package (folder path) + //setModelPackage("models"); + setApiPackage("api"); + + supportingFiles.add(new SupportingFile("my_app.mustache", "", "my_app.rb")); + supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "Swaggering.rb")); + supportingFiles.add(new SupportingFile("config.ru", "", "config.rb")); + supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile")); + supportingFiles.add(new SupportingFile("README.md", "", "README.md")); + } + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "sinatra"; + } + + public String getHelp() { + return "Generates a Sinatra server library."; + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return outputFolder + File.separator + apiPackage.replace("/", File.separator); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) { + return type; + } + } else { + type = swaggerType; + } + if (type == null) { + return null; + } + return type; + } + + public String toDefaultValue(Property p) { + return "null"; + } + + @Override + public String toVarName(String name) { + // replace - with _ e.g. created-at => created_at + name = name.replaceAll("-", "_"); + + // if it's all uppper case, convert to lower case + if (name.matches("^[A-Z_]*$")) { + name = name.toLowerCase(); + } + + // camelize (lower first character) the variable name + // petId => pet_id + name = underscore(name); + + // for reserved word or word starting with number, append _ + if (reservedWords.contains(name) || name.matches("^\\d.*")) { + name = escapeReservedWord(name); + } + + return name; + } + + @Override + public String toParamName(String name) { + // should be the same as variable name + return toVarName(name); + } + + @Override + public String toModelName(String name) { + // model name cannot use reserved keyword, e.g. return + if (reservedWords.contains(name)) { + throw new RuntimeException(name + " (reserved word) cannot be used as a model name"); + } + + // camelize the model name + // phone_number => PhoneNumber + return camelize(name); + } + + @Override + public String toModelFilename(String name) { + // model name cannot use reserved keyword, e.g. return + if (reservedWords.contains(name)) { + throw new RuntimeException(name + " (reserved word) cannot be used as a model name"); + } + + // underscore the model file name + // PhoneNumber.rb => phone_number.rb + return underscore(name); + } + + @Override + public String toApiFilename(String name) { + // replace - with _ e.g. created-at => created_at + name = name.replaceAll("-", "_"); + + // e.g. PhoneNumberApi.rb => phone_number_api.rb + return underscore(name) + "_api"; + } + + @Override + public String toApiName(String name) { + if (name.length() == 0) { + return "DefaultApi"; + } + // e.g. phone_number_api => PhoneNumberApi + return camelize(name) + "Api"; + } + + @Override + public String toOperationId(String operationId) { + // method name cannot use reserved keyword, e.g. return + if (reservedWords.contains(operationId)) { + throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); + } + + return underscore(operationId); + } + + +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index ce3edfd1359..86cf9ef6013 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -15,6 +15,7 @@ io.swagger.codegen.languages.RubyClientCodegen io.swagger.codegen.languages.ScalaClientCodegen io.swagger.codegen.languages.ScalatraServerCodegen io.swagger.codegen.languages.SilexServerCodegen +io.swagger.codegen.languages.SinatraServerCodegen io.swagger.codegen.languages.SpringMVCServerCodegen io.swagger.codegen.languages.StaticDocCodegen io.swagger.codegen.languages.StaticHtmlGenerator diff --git a/modules/swagger-codegen/src/main/resources/sinatra/Gemfile b/modules/swagger-codegen/src/main/resources/sinatra/Gemfile new file mode 100644 index 00000000000..be9c3168ea6 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/sinatra/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem "sinatra" +gem "sinatra-cross_origin" \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/sinatra/README.md b/modules/swagger-codegen/src/main/resources/sinatra/README.md new file mode 100644 index 00000000000..23c501353da --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/sinatra/README.md @@ -0,0 +1,29 @@ +# Swagger for Sinatra + +## Overview +This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find +out more about both the spec and the framework at http://swagger.wordnik.com. For more information about +Wordnik's APIs, please visit http://developer.wordnik.com. + +## Prerequisites +You need to install ruby 1.9.3 and the following gems: + +``` +sinatra +sinatra-cross_origin +``` + +## Getting started +This sample was generated with the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project. + +``` +rackup -p 4567 config.ru +``` + +In your [swagger ui](https://github.com/wordnik/swagger-ui), put in the following URL: + +``` +http://localhost:4567/resources.json +``` + +Voila! diff --git a/modules/swagger-codegen/src/main/resources/sinatra/Swaggering.rb b/modules/swagger-codegen/src/main/resources/sinatra/Swaggering.rb new file mode 100644 index 00000000000..79aca1da2c9 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/sinatra/Swaggering.rb @@ -0,0 +1,154 @@ +require 'json' +require 'sinatra/base' +require 'sinatra/cross_origin' + +class Configuration + attr_accessor :base_path, :api_version, :swagger_version, :format_specifier + + def initialize + @api_version = '1.0' + @base_path = 'http://localhost:4567' + @swagger_version = '1.1' + @format_specifier = ".json" + end +end + +class Swaggering < Sinatra::Base + register Sinatra::CrossOrigin + + @@routes = {} + @@configuration = Configuration.new + + attr_accessor :configuration + + def self.configure + get("/resources" + @@configuration.format_specifier) { + cross_origin + Swaggering.to_resource_listing + } + @@configuration ||= Configuration.new + yield(@@configuration) if block_given? + end + + def self.add_route(method, path, swag={}, opts={}, &block) + fullPath = swag["resourcePath"].to_s + @@configuration.format_specifier + path + + accepted = case method + when 'get' + get(fullPath, opts, &block) + true + when 'post' + post(fullPath, opts, &block) + true + when 'delete' + delete(fullPath, opts, &block) + true + when 'put' + put(fullPath, opts, &block) + true + else + false + end + + if accepted then + resourcePath = swag["resourcePath"].to_s + ops = @@routes[resourcePath] + if ops.nil? + ops = Array.new + @@routes.merge!(resourcePath => ops) + + get(resourcePath + @@configuration.format_specifier) do + cross_origin + Swaggering.to_api(resourcePath) + end + end + + swag.merge!("httpMethod" => method.to_s.upcase) + ops.push(swag) + end + end + + def self.to_resource_listing + apis = Array.new + (@@routes.keys).each do |key| + api = { + "path" => (key + ".{format}"), + "description" => "no description" + } + apis.push api + end + + resource = { + "apiVersion" => @@configuration.api_version, + "swaggerVersion" => @@configuration.swagger_version, + "apis" => apis + } + + resource.to_json + end + + def self.to_api(resourcePath) + apis = {} + models = [] + + @@routes[resourcePath].each do |route| + endpoint = route["endpoint"].gsub(/:(\w+)(\/?)/,'{\1}\2') + path = (resourcePath + ".{format}" + endpoint) + api = apis[path] + if api.nil? + api = {"path" => path, "description" => "description", "operations" => []} + apis.merge!(path => api) + end + + parameters = route["parameters"] + + unless parameters.nil? then + parameters.each do |param| + av_string = param["allowableValues"] + unless av_string.nil? + if av_string.count('[') > 0 + pattern = /^([A-Z]*)\[(.*)\]/ + match = pattern.match av_string + case match.to_a[1] + when "LIST" + allowables = match.to_a[2].split(',') + param["allowableValues"] = { + "valueType" => "LIST", + "values" => allowables + } + when "RANGE" + allowables = match.to_a[2].split(',') + param["allowableValues"] = { + "valueType" => "RANGE", + "min" => allowables[0], + "max" => allowables[1] + } + end + end + end + end + end + + op = { + "httpMethod" => route["httpMethod"], + "description" => route["summary"], + "responseClass" => route["responseClass"], + "notes" => route["notes"], + "nickname" => route["nickname"], + "summary" => route["summary"], + "parameters" => route["parameters"] + } + api["operations"].push(op) + end + + api_listing = { + "apiVersion" => @@configuration.api_version, + "swaggerVersion" => @@configuration.swagger_version, + "basePath" => @@configuration.base_path, + "resourcePath" => resourcePath, + "apis" => apis.values, + "models" => models + } + api_listing.to_json + end +end diff --git a/modules/swagger-codegen/src/main/resources/sinatra/api.mustache b/modules/swagger-codegen/src/main/resources/sinatra/api.mustache new file mode 100644 index 00000000000..cfeae19de7a --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/sinatra/api.mustache @@ -0,0 +1,57 @@ +require 'json' + +{{#operations}} +{{#operation}} + +MyApp.add_route('{{httpMethod}}', '{{path}}', { + "resourcePath" => "/{{baseName}}", + "summary" => "{{{summary}}}", + "nickname" => "{{nickname}}", + "responseClass" => "{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}", + "endpoint" => "{{path}}", + "notes" => "{{{notes}}}", + "parameters" => [ + {{#queryParams}} + { + "name" => "{{paramName}}", + "description" => "{{description}}", + "dataType" => "{{swaggerDataType}}", + "paramType" => "query", + "allowMultiple" => {{allowMultiple}}, + "allowableValues" => "{{allowableValues}}", + {{#defaultValue}}"defaultValue" => {{{defaultValue}}}{{/defaultValue}} + }, + {{/queryParams}} + {{#pathParams}} + { + "name" => "{{paramName}}", + "description" => "{{description}}", + "dataType" => "{{swaggerDataType}}", + "paramType" => "path", + }, + {{/pathParams}} + {{#headerParams}} + { + "name" => "{{paramName}}", + "description" => "{{description}}", + "dataType" => "{{swaggerDataType}}", + "paramType" => "header", + }, + {{/headerParams}} + {{#bodyParams}} + { + "name" => "body", + "description" => "{{description}}", + "dataType" => "{{swaggerDataType}}", + "paramType" => "body", + } + {{/bodyParams}} + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + +{{/operation}} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/sinatra/config.ru b/modules/swagger-codegen/src/main/resources/sinatra/config.ru new file mode 100644 index 00000000000..395d0587123 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/sinatra/config.ru @@ -0,0 +1,2 @@ +require './my_app' +run MyApp diff --git a/modules/swagger-codegen/src/main/resources/sinatra/my_app.mustache b/modules/swagger-codegen/src/main/resources/sinatra/my_app.mustache new file mode 100644 index 00000000000..72b5267a140 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/sinatra/my_app.mustache @@ -0,0 +1,12 @@ +require './lib/swaggering' + +# only need to extend if you want special configuration! +class MyApp < Swaggering + self.configure do |config| + config.api_version = '0.2' + end +end + +{{#apis}} +require './lib/{{className}}.rb' +{{/apis}} \ No newline at end of file diff --git a/samples/client/petstore/silex/SwaggerServer/.htaccess b/samples/client/petstore/silex/SwaggerServer/.htaccess deleted file mode 100644 index e47b5fb8a0c..00000000000 --- a/samples/client/petstore/silex/SwaggerServer/.htaccess +++ /dev/null @@ -1,5 +0,0 @@ - - RewriteEngine On - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] - \ No newline at end of file diff --git a/samples/client/petstore/silex/SwaggerServer/README.md b/samples/client/petstore/silex/SwaggerServer/README.md deleted file mode 100644 index 9f35636b3f8..00000000000 --- a/samples/client/petstore/silex/SwaggerServer/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Swagger generated server - -## Overview -This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the -[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This -is an example of building a PHP server. - -This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: - -[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/) diff --git a/samples/client/petstore/silex/SwaggerServer/composer.json b/samples/client/petstore/silex/SwaggerServer/composer.json deleted file mode 100644 index 466cd3fbc77..00000000000 --- a/samples/client/petstore/silex/SwaggerServer/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "silex/silex": "~1.2" - } -} \ No newline at end of file diff --git a/samples/client/petstore/silex/SwaggerServer/index.php b/samples/client/petstore/silex/SwaggerServer/index.php deleted file mode 100644 index 1526f3cb8f3..00000000000 --- a/samples/client/petstore/silex/SwaggerServer/index.php +++ /dev/null @@ -1,184 +0,0 @@ -POST('/user', function(Application $app, Request $request) { - - - return new Response('How about implementing createUser as a POST method ?'); - }); - - - -$app->POST('/user/createWithArray', function(Application $app, Request $request) { - - - return new Response('How about implementing createUsersWithArrayInput as a POST method ?'); - }); - - - -$app->POST('/user/createWithList', function(Application $app, Request $request) { - - - return new Response('How about implementing createUsersWithListInput as a POST method ?'); - }); - - - -$app->GET('/user/login', function(Application $app, Request $request) { - $username = $request->get('username'); $password = $request->get('password'); - - return new Response('How about implementing loginUser as a GET method ?'); - }); - - - -$app->GET('/user/logout', function(Application $app, Request $request) { - - - return new Response('How about implementing logoutUser as a GET method ?'); - }); - - - -$app->GET('/user/{username}', function(Application $app, Request $request, $username) { - - - return new Response('How about implementing getUserByName as a GET method ?'); - }); - - - -$app->PUT('/user/{username}', function(Application $app, Request $request, $username) { - - - return new Response('How about implementing updateUser as a PUT method ?'); - }); - - - -$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) { - - - return new Response('How about implementing deleteUser as a DELETE method ?'); - }); - - - - - - - -$app->PUT('/pet', function(Application $app, Request $request) { - - - return new Response('How about implementing updatePet as a PUT method ?'); - }); - - - -$app->POST('/pet', function(Application $app, Request $request) { - - - return new Response('How about implementing addPet as a POST method ?'); - }); - - - -$app->GET('/pet/findByStatus', function(Application $app, Request $request) { - $status = $request->get('status'); - - return new Response('How about implementing findPetsByStatus as a GET method ?'); - }); - - - -$app->GET('/pet/findByTags', function(Application $app, Request $request) { - $tags = $request->get('tags'); - - return new Response('How about implementing findPetsByTags as a GET method ?'); - }); - - - -$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) { - - - return new Response('How about implementing getPetById as a GET method ?'); - }); - - - -$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) { - - $name = $request->get('name'); $status = $request->get('status'); - return new Response('How about implementing updatePetWithForm as a POST method ?'); - }); - - - -$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) { - - - return new Response('How about implementing deletePet as a DELETE method ?'); - }); - - - -$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) { - - $additional_metadata = $request->get('additional_metadata'); $file = $request->get('file'); - return new Response('How about implementing uploadFile as a POST method ?'); - }); - - - - - - - -$app->GET('/store/inventory', function(Application $app, Request $request) { - - - return new Response('How about implementing getInventory as a GET method ?'); - }); - - - -$app->POST('/store/order', function(Application $app, Request $request) { - - - return new Response('How about implementing placeOrder as a POST method ?'); - }); - - - -$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { - - - return new Response('How about implementing getOrderById as a GET method ?'); - }); - - - -$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { - - - return new Response('How about implementing deleteOrder as a DELETE method ?'); - }); - - - - - -$app->run(); diff --git a/samples/client/petstore/silex/silex/.htaccess b/samples/client/petstore/silex/silex/.htaccess deleted file mode 100644 index e47b5fb8a0c..00000000000 --- a/samples/client/petstore/silex/silex/.htaccess +++ /dev/null @@ -1,5 +0,0 @@ - - RewriteEngine On - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] - \ No newline at end of file diff --git a/samples/client/petstore/silex/silex/README.md b/samples/client/petstore/silex/silex/README.md deleted file mode 100644 index 9f35636b3f8..00000000000 --- a/samples/client/petstore/silex/silex/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Swagger generated server - -## Overview -This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the -[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This -is an example of building a PHP server. - -This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: - -[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/) diff --git a/samples/client/petstore/silex/silex/composer.json b/samples/client/petstore/silex/silex/composer.json deleted file mode 100644 index 466cd3fbc77..00000000000 --- a/samples/client/petstore/silex/silex/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "silex/silex": "~1.2" - } -} \ No newline at end of file diff --git a/samples/client/petstore/silex/silex/index.php b/samples/client/petstore/silex/silex/index.php deleted file mode 100644 index 1526f3cb8f3..00000000000 --- a/samples/client/petstore/silex/silex/index.php +++ /dev/null @@ -1,184 +0,0 @@ -POST('/user', function(Application $app, Request $request) { - - - return new Response('How about implementing createUser as a POST method ?'); - }); - - - -$app->POST('/user/createWithArray', function(Application $app, Request $request) { - - - return new Response('How about implementing createUsersWithArrayInput as a POST method ?'); - }); - - - -$app->POST('/user/createWithList', function(Application $app, Request $request) { - - - return new Response('How about implementing createUsersWithListInput as a POST method ?'); - }); - - - -$app->GET('/user/login', function(Application $app, Request $request) { - $username = $request->get('username'); $password = $request->get('password'); - - return new Response('How about implementing loginUser as a GET method ?'); - }); - - - -$app->GET('/user/logout', function(Application $app, Request $request) { - - - return new Response('How about implementing logoutUser as a GET method ?'); - }); - - - -$app->GET('/user/{username}', function(Application $app, Request $request, $username) { - - - return new Response('How about implementing getUserByName as a GET method ?'); - }); - - - -$app->PUT('/user/{username}', function(Application $app, Request $request, $username) { - - - return new Response('How about implementing updateUser as a PUT method ?'); - }); - - - -$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) { - - - return new Response('How about implementing deleteUser as a DELETE method ?'); - }); - - - - - - - -$app->PUT('/pet', function(Application $app, Request $request) { - - - return new Response('How about implementing updatePet as a PUT method ?'); - }); - - - -$app->POST('/pet', function(Application $app, Request $request) { - - - return new Response('How about implementing addPet as a POST method ?'); - }); - - - -$app->GET('/pet/findByStatus', function(Application $app, Request $request) { - $status = $request->get('status'); - - return new Response('How about implementing findPetsByStatus as a GET method ?'); - }); - - - -$app->GET('/pet/findByTags', function(Application $app, Request $request) { - $tags = $request->get('tags'); - - return new Response('How about implementing findPetsByTags as a GET method ?'); - }); - - - -$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) { - - - return new Response('How about implementing getPetById as a GET method ?'); - }); - - - -$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) { - - $name = $request->get('name'); $status = $request->get('status'); - return new Response('How about implementing updatePetWithForm as a POST method ?'); - }); - - - -$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) { - - - return new Response('How about implementing deletePet as a DELETE method ?'); - }); - - - -$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) { - - $additional_metadata = $request->get('additional_metadata'); $file = $request->get('file'); - return new Response('How about implementing uploadFile as a POST method ?'); - }); - - - - - - - -$app->GET('/store/inventory', function(Application $app, Request $request) { - - - return new Response('How about implementing getInventory as a GET method ?'); - }); - - - -$app->POST('/store/order', function(Application $app, Request $request) { - - - return new Response('How about implementing placeOrder as a POST method ?'); - }); - - - -$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { - - - return new Response('How about implementing getOrderById as a GET method ?'); - }); - - - -$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { - - - return new Response('How about implementing deleteOrder as a DELETE method ?'); - }); - - - - - -$app->run(); diff --git a/samples/server/petstore/sinatra/Gemfile b/samples/server/petstore/sinatra/Gemfile new file mode 100644 index 00000000000..be9c3168ea6 --- /dev/null +++ b/samples/server/petstore/sinatra/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem "sinatra" +gem "sinatra-cross_origin" \ No newline at end of file diff --git a/samples/server/petstore/sinatra/README.md b/samples/server/petstore/sinatra/README.md new file mode 100644 index 00000000000..23c501353da --- /dev/null +++ b/samples/server/petstore/sinatra/README.md @@ -0,0 +1,29 @@ +# Swagger for Sinatra + +## Overview +This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find +out more about both the spec and the framework at http://swagger.wordnik.com. For more information about +Wordnik's APIs, please visit http://developer.wordnik.com. + +## Prerequisites +You need to install ruby 1.9.3 and the following gems: + +``` +sinatra +sinatra-cross_origin +``` + +## Getting started +This sample was generated with the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project. + +``` +rackup -p 4567 config.ru +``` + +In your [swagger ui](https://github.com/wordnik/swagger-ui), put in the following URL: + +``` +http://localhost:4567/resources.json +``` + +Voila! diff --git a/samples/server/petstore/sinatra/api/pet_api.rb b/samples/server/petstore/sinatra/api/pet_api.rb new file mode 100644 index 00000000000..2fdc1f2a6e6 --- /dev/null +++ b/samples/server/petstore/sinatra/api/pet_api.rb @@ -0,0 +1,231 @@ +require 'json' + + +MyApp.add_route('PUT', '/pet', { + "resourcePath" => "/Pet", + "summary" => "Update an existing pet", + "nickname" => "update_pet", + "responseClass" => "void", + "endpoint" => "/pet", + "notes" => "", + "parameters" => [ + + + + + { + "name" => "body", + "description" => "Pet object that needs to be added to the store", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('POST', '/pet', { + "resourcePath" => "/Pet", + "summary" => "Add a new pet to the store", + "nickname" => "add_pet", + "responseClass" => "void", + "endpoint" => "/pet", + "notes" => "", + "parameters" => [ + + + + + { + "name" => "body", + "description" => "Pet object that needs to be added to the store", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/pet/findByStatus', { + "resourcePath" => "/Pet", + "summary" => "Finds Pets by status", + "nickname" => "find_pets_by_status", + "responseClass" => "array[Pet]", + "endpoint" => "/pet/findByStatus", + "notes" => "Multiple status values can be provided with comma seperated strings", + "parameters" => [ + + { + "name" => "status", + "description" => "Status values that need to be considered for filter", + "dataType" => "", + "paramType" => "query", + "allowMultiple" => , + "allowableValues" => "", + "defaultValue" => available + }, + + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/pet/findByTags', { + "resourcePath" => "/Pet", + "summary" => "Finds Pets by tags", + "nickname" => "find_pets_by_tags", + "responseClass" => "array[Pet]", + "endpoint" => "/pet/findByTags", + "notes" => "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", + "parameters" => [ + + { + "name" => "tags", + "description" => "Tags to filter by", + "dataType" => "", + "paramType" => "query", + "allowMultiple" => , + "allowableValues" => "", + + }, + + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/pet/{petId}', { + "resourcePath" => "/Pet", + "summary" => "Find pet by ID", + "nickname" => "get_pet_by_id", + "responseClass" => "Pet", + "endpoint" => "/pet/{petId}", + "notes" => "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions", + "parameters" => [ + + + { + "name" => "pet_id", + "description" => "ID of pet that needs to be fetched", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('POST', '/pet/{petId}', { + "resourcePath" => "/Pet", + "summary" => "Updates a pet in the store with form data", + "nickname" => "update_pet_with_form", + "responseClass" => "void", + "endpoint" => "/pet/{petId}", + "notes" => "", + "parameters" => [ + + + { + "name" => "pet_id", + "description" => "ID of pet that needs to be updated", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('DELETE', '/pet/{petId}', { + "resourcePath" => "/Pet", + "summary" => "Deletes a pet", + "nickname" => "delete_pet", + "responseClass" => "void", + "endpoint" => "/pet/{petId}", + "notes" => "", + "parameters" => [ + + + { + "name" => "pet_id", + "description" => "Pet id to delete", + "dataType" => "", + "paramType" => "path", + }, + + + { + "name" => "api_key", + "description" => "", + "dataType" => "", + "paramType" => "header", + }, + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('POST', '/pet/{petId}/uploadImage', { + "resourcePath" => "/Pet", + "summary" => "uploads an image", + "nickname" => "upload_file", + "responseClass" => "void", + "endpoint" => "/pet/{petId}/uploadImage", + "notes" => "", + "parameters" => [ + + + { + "name" => "pet_id", + "description" => "ID of pet to update", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + diff --git a/samples/server/petstore/sinatra/api/store_api.rb b/samples/server/petstore/sinatra/api/store_api.rb new file mode 100644 index 00000000000..245ae23bff7 --- /dev/null +++ b/samples/server/petstore/sinatra/api/store_api.rb @@ -0,0 +1,103 @@ +require 'json' + + +MyApp.add_route('GET', '/store/inventory', { + "resourcePath" => "/Store", + "summary" => "Returns pet inventories by status", + "nickname" => "get_inventory", + "responseClass" => "map[string,int]", + "endpoint" => "/store/inventory", + "notes" => "Returns a map of status codes to quantities", + "parameters" => [ + + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('POST', '/store/order', { + "resourcePath" => "/Store", + "summary" => "Place an order for a pet", + "nickname" => "place_order", + "responseClass" => "Order", + "endpoint" => "/store/order", + "notes" => "", + "parameters" => [ + + + + + { + "name" => "body", + "description" => "order placed for purchasing the pet", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/store/order/{orderId}', { + "resourcePath" => "/Store", + "summary" => "Find purchase order by ID", + "nickname" => "get_order_by_id", + "responseClass" => "Order", + "endpoint" => "/store/order/{orderId}", + "notes" => "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", + "parameters" => [ + + + { + "name" => "order_id", + "description" => "ID of pet that needs to be fetched", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('DELETE', '/store/order/{orderId}', { + "resourcePath" => "/Store", + "summary" => "Delete purchase order by ID", + "nickname" => "delete_order", + "responseClass" => "void", + "endpoint" => "/store/order/{orderId}", + "notes" => "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", + "parameters" => [ + + + { + "name" => "order_id", + "description" => "ID of the order that needs to be deleted", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + diff --git a/samples/server/petstore/sinatra/api/user_api.rb b/samples/server/petstore/sinatra/api/user_api.rb new file mode 100644 index 00000000000..8cbd49d72a0 --- /dev/null +++ b/samples/server/petstore/sinatra/api/user_api.rb @@ -0,0 +1,231 @@ +require 'json' + + +MyApp.add_route('POST', '/user', { + "resourcePath" => "/User", + "summary" => "Create user", + "nickname" => "create_user", + "responseClass" => "void", + "endpoint" => "/user", + "notes" => "This can only be done by the logged in user.", + "parameters" => [ + + + + + { + "name" => "body", + "description" => "Created user object", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('POST', '/user/createWithArray', { + "resourcePath" => "/User", + "summary" => "Creates list of users with given input array", + "nickname" => "create_users_with_array_input", + "responseClass" => "void", + "endpoint" => "/user/createWithArray", + "notes" => "", + "parameters" => [ + + + + + { + "name" => "body", + "description" => "List of user object", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('POST', '/user/createWithList', { + "resourcePath" => "/User", + "summary" => "Creates list of users with given input array", + "nickname" => "create_users_with_list_input", + "responseClass" => "void", + "endpoint" => "/user/createWithList", + "notes" => "", + "parameters" => [ + + + + + { + "name" => "body", + "description" => "List of user object", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/user/login', { + "resourcePath" => "/User", + "summary" => "Logs user into the system", + "nickname" => "login_user", + "responseClass" => "string", + "endpoint" => "/user/login", + "notes" => "", + "parameters" => [ + + { + "name" => "username", + "description" => "The user name for login", + "dataType" => "", + "paramType" => "query", + "allowMultiple" => , + "allowableValues" => "", + + }, + + { + "name" => "password", + "description" => "The password for login in clear text", + "dataType" => "", + "paramType" => "query", + "allowMultiple" => , + "allowableValues" => "", + + }, + + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/user/logout', { + "resourcePath" => "/User", + "summary" => "Logs out current logged in user session", + "nickname" => "logout_user", + "responseClass" => "void", + "endpoint" => "/user/logout", + "notes" => "", + "parameters" => [ + + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('GET', '/user/{username}', { + "resourcePath" => "/User", + "summary" => "Get user by user name", + "nickname" => "get_user_by_name", + "responseClass" => "User", + "endpoint" => "/user/{username}", + "notes" => "", + "parameters" => [ + + + { + "name" => "username", + "description" => "The name that needs to be fetched. Use user1 for testing. ", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('PUT', '/user/{username}', { + "resourcePath" => "/User", + "summary" => "Updated user", + "nickname" => "update_user", + "responseClass" => "void", + "endpoint" => "/user/{username}", + "notes" => "This can only be done by the logged in user.", + "parameters" => [ + + + { + "name" => "username", + "description" => "name that need to be deleted", + "dataType" => "", + "paramType" => "path", + }, + + + + { + "name" => "body", + "description" => "Updated user object", + "dataType" => "", + "paramType" => "body", + } + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + + +MyApp.add_route('DELETE', '/user/{username}', { + "resourcePath" => "/User", + "summary" => "Delete user", + "nickname" => "delete_user", + "responseClass" => "void", + "endpoint" => "/user/{username}", + "notes" => "This can only be done by the logged in user.", + "parameters" => [ + + + { + "name" => "username", + "description" => "The name that needs to be deleted", + "dataType" => "", + "paramType" => "path", + }, + + + + ]}) do + cross_origin + # the guts live here + + {"message" => "yes, it worked"}.to_json +end + diff --git a/samples/server/petstore/sinatra/config.rb b/samples/server/petstore/sinatra/config.rb new file mode 100644 index 00000000000..395d0587123 --- /dev/null +++ b/samples/server/petstore/sinatra/config.rb @@ -0,0 +1,2 @@ +require './my_app' +run MyApp diff --git a/samples/server/petstore/sinatra/lib/Swaggering.rb b/samples/server/petstore/sinatra/lib/Swaggering.rb new file mode 100644 index 00000000000..79aca1da2c9 --- /dev/null +++ b/samples/server/petstore/sinatra/lib/Swaggering.rb @@ -0,0 +1,154 @@ +require 'json' +require 'sinatra/base' +require 'sinatra/cross_origin' + +class Configuration + attr_accessor :base_path, :api_version, :swagger_version, :format_specifier + + def initialize + @api_version = '1.0' + @base_path = 'http://localhost:4567' + @swagger_version = '1.1' + @format_specifier = ".json" + end +end + +class Swaggering < Sinatra::Base + register Sinatra::CrossOrigin + + @@routes = {} + @@configuration = Configuration.new + + attr_accessor :configuration + + def self.configure + get("/resources" + @@configuration.format_specifier) { + cross_origin + Swaggering.to_resource_listing + } + @@configuration ||= Configuration.new + yield(@@configuration) if block_given? + end + + def self.add_route(method, path, swag={}, opts={}, &block) + fullPath = swag["resourcePath"].to_s + @@configuration.format_specifier + path + + accepted = case method + when 'get' + get(fullPath, opts, &block) + true + when 'post' + post(fullPath, opts, &block) + true + when 'delete' + delete(fullPath, opts, &block) + true + when 'put' + put(fullPath, opts, &block) + true + else + false + end + + if accepted then + resourcePath = swag["resourcePath"].to_s + ops = @@routes[resourcePath] + if ops.nil? + ops = Array.new + @@routes.merge!(resourcePath => ops) + + get(resourcePath + @@configuration.format_specifier) do + cross_origin + Swaggering.to_api(resourcePath) + end + end + + swag.merge!("httpMethod" => method.to_s.upcase) + ops.push(swag) + end + end + + def self.to_resource_listing + apis = Array.new + (@@routes.keys).each do |key| + api = { + "path" => (key + ".{format}"), + "description" => "no description" + } + apis.push api + end + + resource = { + "apiVersion" => @@configuration.api_version, + "swaggerVersion" => @@configuration.swagger_version, + "apis" => apis + } + + resource.to_json + end + + def self.to_api(resourcePath) + apis = {} + models = [] + + @@routes[resourcePath].each do |route| + endpoint = route["endpoint"].gsub(/:(\w+)(\/?)/,'{\1}\2') + path = (resourcePath + ".{format}" + endpoint) + api = apis[path] + if api.nil? + api = {"path" => path, "description" => "description", "operations" => []} + apis.merge!(path => api) + end + + parameters = route["parameters"] + + unless parameters.nil? then + parameters.each do |param| + av_string = param["allowableValues"] + unless av_string.nil? + if av_string.count('[') > 0 + pattern = /^([A-Z]*)\[(.*)\]/ + match = pattern.match av_string + case match.to_a[1] + when "LIST" + allowables = match.to_a[2].split(',') + param["allowableValues"] = { + "valueType" => "LIST", + "values" => allowables + } + when "RANGE" + allowables = match.to_a[2].split(',') + param["allowableValues"] = { + "valueType" => "RANGE", + "min" => allowables[0], + "max" => allowables[1] + } + end + end + end + end + end + + op = { + "httpMethod" => route["httpMethod"], + "description" => route["summary"], + "responseClass" => route["responseClass"], + "notes" => route["notes"], + "nickname" => route["nickname"], + "summary" => route["summary"], + "parameters" => route["parameters"] + } + api["operations"].push(op) + end + + api_listing = { + "apiVersion" => @@configuration.api_version, + "swaggerVersion" => @@configuration.swagger_version, + "basePath" => @@configuration.base_path, + "resourcePath" => resourcePath, + "apis" => apis.values, + "models" => models + } + api_listing.to_json + end +end diff --git a/samples/server/petstore/sinatra/my_app.rb b/samples/server/petstore/sinatra/my_app.rb new file mode 100644 index 00000000000..4e692eb53bc --- /dev/null +++ b/samples/server/petstore/sinatra/my_app.rb @@ -0,0 +1,9 @@ +require './lib/swaggering' + +# only need to extend if you want special configuration! +class MyApp < Swaggering + self.configure do |config| + config.api_version = '0.2' + end +end + From 0b0325b8afd49d29594da6c6a5384153c71fe9e8 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Fri, 19 Jun 2015 02:32:50 +0800 Subject: [PATCH 062/499] update readme, fix swaggering name --- .../languages/SinatraServerCodegen.java | 4 ++-- .../src/main/resources/sinatra/README.md | 6 +++--- samples/server/petstore/sinatra/Gemfile.lock | 19 +++++++++++++++++++ samples/server/petstore/sinatra/README.md | 6 +++--- .../petstore/sinatra/{config.rb => config.ru} | 0 .../lib/{Swaggering.rb => swaggering.rb} | 0 6 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 samples/server/petstore/sinatra/Gemfile.lock rename samples/server/petstore/sinatra/{config.rb => config.ru} (100%) rename samples/server/petstore/sinatra/lib/{Swaggering.rb => swaggering.rb} (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java index 318bf03130d..44cf978eb1d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SinatraServerCodegen.java @@ -67,8 +67,8 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi setApiPackage("api"); supportingFiles.add(new SupportingFile("my_app.mustache", "", "my_app.rb")); - supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "Swaggering.rb")); - supportingFiles.add(new SupportingFile("config.ru", "", "config.rb")); + supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "swaggering.rb")); + supportingFiles.add(new SupportingFile("config.ru", "", "config.ru")); supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile")); supportingFiles.add(new SupportingFile("README.md", "", "README.md")); } diff --git a/modules/swagger-codegen/src/main/resources/sinatra/README.md b/modules/swagger-codegen/src/main/resources/sinatra/README.md index 23c501353da..c5b8cfffe77 100644 --- a/modules/swagger-codegen/src/main/resources/sinatra/README.md +++ b/modules/swagger-codegen/src/main/resources/sinatra/README.md @@ -2,7 +2,7 @@ ## Overview This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find -out more about both the spec and the framework at http://swagger.wordnik.com. For more information about +out more about both the spec and the framework at http://swagger.io. For more information about Wordnik's APIs, please visit http://developer.wordnik.com. ## Prerequisites @@ -14,13 +14,13 @@ sinatra-cross_origin ``` ## Getting started -This sample was generated with the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project. +This sample was generated with the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. ``` rackup -p 4567 config.ru ``` -In your [swagger ui](https://github.com/wordnik/swagger-ui), put in the following URL: +In your [swagger ui](https://github.com/swagger-api/swagger-ui), put in the following URL: ``` http://localhost:4567/resources.json diff --git a/samples/server/petstore/sinatra/Gemfile.lock b/samples/server/petstore/sinatra/Gemfile.lock new file mode 100644 index 00000000000..3b7c05b4083 --- /dev/null +++ b/samples/server/petstore/sinatra/Gemfile.lock @@ -0,0 +1,19 @@ +GEM + remote: https://rubygems.org/ + specs: + rack (1.6.4) + rack-protection (1.5.3) + rack + sinatra (1.4.6) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (>= 1.3, < 3) + sinatra-cross_origin (0.3.2) + tilt (2.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + sinatra + sinatra-cross_origin diff --git a/samples/server/petstore/sinatra/README.md b/samples/server/petstore/sinatra/README.md index 23c501353da..c5b8cfffe77 100644 --- a/samples/server/petstore/sinatra/README.md +++ b/samples/server/petstore/sinatra/README.md @@ -2,7 +2,7 @@ ## Overview This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find -out more about both the spec and the framework at http://swagger.wordnik.com. For more information about +out more about both the spec and the framework at http://swagger.io. For more information about Wordnik's APIs, please visit http://developer.wordnik.com. ## Prerequisites @@ -14,13 +14,13 @@ sinatra-cross_origin ``` ## Getting started -This sample was generated with the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project. +This sample was generated with the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. ``` rackup -p 4567 config.ru ``` -In your [swagger ui](https://github.com/wordnik/swagger-ui), put in the following URL: +In your [swagger ui](https://github.com/swagger-api/swagger-ui), put in the following URL: ``` http://localhost:4567/resources.json diff --git a/samples/server/petstore/sinatra/config.rb b/samples/server/petstore/sinatra/config.ru similarity index 100% rename from samples/server/petstore/sinatra/config.rb rename to samples/server/petstore/sinatra/config.ru diff --git a/samples/server/petstore/sinatra/lib/Swaggering.rb b/samples/server/petstore/sinatra/lib/swaggering.rb similarity index 100% rename from samples/server/petstore/sinatra/lib/Swaggering.rb rename to samples/server/petstore/sinatra/lib/swaggering.rb From f9574715096b741d79f13b161e5a5d7b15d86b5b Mon Sep 17 00:00:00 2001 From: William Cheng Date: Fri, 19 Jun 2015 02:37:08 +0800 Subject: [PATCH 063/499] update silex sample code location --- .../petstore/silex/SwaggerServer/.htaccess | 5 + .../petstore/silex/SwaggerServer/README.md | 10 + .../silex/SwaggerServer/composer.json | 5 + .../petstore/silex/SwaggerServer/index.php | 184 ++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 samples/server/petstore/silex/SwaggerServer/.htaccess create mode 100644 samples/server/petstore/silex/SwaggerServer/README.md create mode 100644 samples/server/petstore/silex/SwaggerServer/composer.json create mode 100644 samples/server/petstore/silex/SwaggerServer/index.php diff --git a/samples/server/petstore/silex/SwaggerServer/.htaccess b/samples/server/petstore/silex/SwaggerServer/.htaccess new file mode 100644 index 00000000000..e47b5fb8a0c --- /dev/null +++ b/samples/server/petstore/silex/SwaggerServer/.htaccess @@ -0,0 +1,5 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] + \ No newline at end of file diff --git a/samples/server/petstore/silex/SwaggerServer/README.md b/samples/server/petstore/silex/SwaggerServer/README.md new file mode 100644 index 00000000000..9f35636b3f8 --- /dev/null +++ b/samples/server/petstore/silex/SwaggerServer/README.md @@ -0,0 +1,10 @@ +# Swagger generated server + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This +is an example of building a PHP server. + +This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: + +[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/) diff --git a/samples/server/petstore/silex/SwaggerServer/composer.json b/samples/server/petstore/silex/SwaggerServer/composer.json new file mode 100644 index 00000000000..466cd3fbc77 --- /dev/null +++ b/samples/server/petstore/silex/SwaggerServer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "silex/silex": "~1.2" + } +} \ No newline at end of file diff --git a/samples/server/petstore/silex/SwaggerServer/index.php b/samples/server/petstore/silex/SwaggerServer/index.php new file mode 100644 index 00000000000..1526f3cb8f3 --- /dev/null +++ b/samples/server/petstore/silex/SwaggerServer/index.php @@ -0,0 +1,184 @@ +POST('/user', function(Application $app, Request $request) { + + + return new Response('How about implementing createUser as a POST method ?'); + }); + + + +$app->POST('/user/createWithArray', function(Application $app, Request $request) { + + + return new Response('How about implementing createUsersWithArrayInput as a POST method ?'); + }); + + + +$app->POST('/user/createWithList', function(Application $app, Request $request) { + + + return new Response('How about implementing createUsersWithListInput as a POST method ?'); + }); + + + +$app->GET('/user/login', function(Application $app, Request $request) { + $username = $request->get('username'); $password = $request->get('password'); + + return new Response('How about implementing loginUser as a GET method ?'); + }); + + + +$app->GET('/user/logout', function(Application $app, Request $request) { + + + return new Response('How about implementing logoutUser as a GET method ?'); + }); + + + +$app->GET('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing getUserByName as a GET method ?'); + }); + + + +$app->PUT('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing updateUser as a PUT method ?'); + }); + + + +$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) { + + + return new Response('How about implementing deleteUser as a DELETE method ?'); + }); + + + + + + + +$app->PUT('/pet', function(Application $app, Request $request) { + + + return new Response('How about implementing updatePet as a PUT method ?'); + }); + + + +$app->POST('/pet', function(Application $app, Request $request) { + + + return new Response('How about implementing addPet as a POST method ?'); + }); + + + +$app->GET('/pet/findByStatus', function(Application $app, Request $request) { + $status = $request->get('status'); + + return new Response('How about implementing findPetsByStatus as a GET method ?'); + }); + + + +$app->GET('/pet/findByTags', function(Application $app, Request $request) { + $tags = $request->get('tags'); + + return new Response('How about implementing findPetsByTags as a GET method ?'); + }); + + + +$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + + return new Response('How about implementing getPetById as a GET method ?'); + }); + + + +$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + $name = $request->get('name'); $status = $request->get('status'); + return new Response('How about implementing updatePetWithForm as a POST method ?'); + }); + + + +$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) { + + + return new Response('How about implementing deletePet as a DELETE method ?'); + }); + + + +$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) { + + $additional_metadata = $request->get('additional_metadata'); $file = $request->get('file'); + return new Response('How about implementing uploadFile as a POST method ?'); + }); + + + + + + + +$app->GET('/store/inventory', function(Application $app, Request $request) { + + + return new Response('How about implementing getInventory as a GET method ?'); + }); + + + +$app->POST('/store/order', function(Application $app, Request $request) { + + + return new Response('How about implementing placeOrder as a POST method ?'); + }); + + + +$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { + + + return new Response('How about implementing getOrderById as a GET method ?'); + }); + + + +$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) { + + + return new Response('How about implementing deleteOrder as a DELETE method ?'); + }); + + + + + +$app->run(); From 8ed690cad0cc2f88d88727caf5dd881c5b4c6640 Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Fri, 12 Jun 2015 15:01:10 -0700 Subject: [PATCH 064/499] Better namespace support, so that your not limited to only having a single vendor space, you can have \Vendor\Package\Model as a namespace. Also updates with proper phpdoc comments so that IDE code hinting can function properly. --- .../codegen/languages/PhpClientCodegen.java | 78 ++++++++++++++----- .../src/main/resources/php/ApiClient.mustache | 16 ++-- .../main/resources/php/ApiException.mustache | 8 +- .../src/main/resources/php/api.mustache | 15 ++-- .../src/main/resources/php/autoload.mustache | 41 ++++++++++ .../src/main/resources/php/composer.mustache | 5 +- .../main/resources/php/configuration.mustache | 31 +++----- .../src/main/resources/php/model.mustache | 18 +++-- .../src/main/resources/php/require.mustache | 13 ---- 9 files changed, 138 insertions(+), 87 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/php/autoload.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/php/require.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 10c03fe4381..2134bfe75dc 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -7,6 +7,7 @@ import io.swagger.codegen.SupportingFile; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import io.swagger.models.properties.RefProperty; import java.io.File; import java.util.Arrays; @@ -14,24 +15,20 @@ import java.util.HashMap; import java.util.HashSet; public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { - protected String invokerPackage = "io.swagger.client"; - protected String groupId = "io.swagger"; + protected String invokerPackage = "Swagger\\Client"; + protected String groupId = "swagger"; protected String artifactId = "swagger-client"; - protected String artifactVersion = "1.0.0"; + protected String artifactVersion = null; public PhpClientCodegen() { super(); - invokerPackage = camelize("SwaggerClient"); - - String packagePath = invokerPackage + "-php"; - - modelPackage = packagePath + "/lib/models"; - apiPackage = packagePath + "/lib"; outputFolder = "generated-code/php"; modelTemplateFiles.put("model.mustache", ".php"); apiTemplateFiles.put("api.mustache", ".php"); templateDir = "php"; + apiPackage = invokerPackage + "\\Api"; + modelPackage = invokerPackage + "\\Model"; reservedWords = new HashSet( Arrays.asList( @@ -39,6 +36,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { ); additionalProperties.put("invokerPackage", invokerPackage); + additionalProperties.put("modelPackage", modelPackage); + additionalProperties.put("apiPackage", apiPackage); + additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); additionalProperties.put("groupId", groupId); additionalProperties.put("artifactId", artifactId); additionalProperties.put("artifactVersion", artifactVersion); @@ -46,6 +46,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { // ref: http://php.net/manual/en/language.types.intro.php languageSpecificPrimitives = new HashSet( Arrays.asList( + "bool", "boolean", "int", "integer", @@ -55,7 +56,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { "object", "DateTime", "mixed", - "number") + "number", + "void", + "byte") ); instantiationTypes.put("array", "array"); @@ -69,20 +72,41 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("double", "double"); typeMapping.put("string", "string"); typeMapping.put("byte", "int"); - typeMapping.put("boolean", "boolean"); - typeMapping.put("date", "DateTime"); - typeMapping.put("datetime", "DateTime"); + typeMapping.put("boolean", "bool"); + typeMapping.put("date", "\\DateTime"); + typeMapping.put("datetime", "\\DateTime"); typeMapping.put("file", "string"); typeMapping.put("map", "map"); typeMapping.put("array", "array"); typeMapping.put("list", "array"); typeMapping.put("object", "object"); + typeMapping.put("DateTime", "\\DateTime"); - 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")); + supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); + supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, "lib"), "Configuration.php")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); + supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); + supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); + } + + public String getPackagePath() { + //invokerPackage.replace("\\", "") + return "SwaggerClient-php"; + } + + public String toPackagePath(String packageName, String basePath) { + packageName = packageName.replace(invokerPackage, ""); + if (basePath != null && basePath.length() > 0) { + basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar; + } + + return (getPackagePath() + File.separatorChar + basePath + // Replace period, backslash, forward slash with file separator in package name + + packageName.replaceAll("[\\.\\\\/]", File.separator) + // Trim prefix file separators from package path + .replaceAll("^" + File.separator, "")) + // Trim trailing file separators from the overall path + .replaceAll(File.separator + "$", ""); } public CodegenType getTag() { @@ -104,11 +128,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar); + return (outputFolder + "/" + toPackagePath(apiPackage(), "lib")); } public String modelFileFolder() { - return (outputFolder + "/" + modelPackage()).replace('/', File.separatorChar); + return (outputFolder + "/" + toPackagePath(modelPackage(), "lib")); } @Override @@ -116,15 +140,27 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { if (p instanceof ArrayProperty) { ArrayProperty ap = (ArrayProperty) p; Property inner = ap.getItems(); - return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + return getTypeDeclaration(inner) + "[]"; } else if (p instanceof MapProperty) { MapProperty mp = (MapProperty) p; Property inner = mp.getAdditionalProperties(); return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + } else if (p instanceof RefProperty) { + String type = super.getTypeDeclaration(p); + return (!languageSpecificPrimitives.contains(type)) + ? "\\" + modelPackage + "\\" + type : type; } return super.getTypeDeclaration(p); } + @Override + public String getTypeDeclaration(String name) { + if (!languageSpecificPrimitives.contains(name)) { + return "\\" + modelPackage + "\\" + name; + } + return super.getTypeDeclaration(name); + } + @Override public String getSwaggerType(Property p) { String swaggerType = super.getSwaggerType(p); diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index b116eee0829..9badb4dbb37 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -24,17 +24,14 @@ class ApiClient { public static $GET = "GET"; public static $PUT = "PUT"; public static $DELETE = "DELETE"; - + + /** @var string[] Array of default headers where the key is the header name and the value is the header value */ private $default_header = array(); - /* - * @var string timeout (second) of the HTTP request, by default set to 0, no timeout - */ + /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ protected $curl_timeout = 0; - /* - * @var string user agent of the HTTP request, set to "PHP-Swagger" by default - */ + /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ protected $user_agent = "PHP-Swagger"; /** @@ -386,8 +383,8 @@ class ApiClient { $deserialized[$key] = $this->deserialize($value, $subClass); } } - } elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) { - $subClass = substr($class, 6, -1); + } elseif (strcasecmp(substr($class, -2),'[]') == 0) { + $subClass = substr($class, 0, -2); $values = array(); foreach ($data as $key => $value) { $values[] = $this->deserialize($value, $subClass); @@ -399,7 +396,6 @@ class ApiClient { settype($data, $class); $deserialized = $data; } else { - $class = "{{invokerPackage}}\\models\\".$class; $instance = new $class(); foreach ($instance::$swaggerTypes as $property => $type) { $original_property_name = $instance::$attributeMap[$property]; diff --git a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache index b66c3a51eb7..a835d579d32 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache @@ -21,14 +21,10 @@ use \Exception; class ApiException extends Exception { - /** - * The HTTP body of the server response. - */ + /** @var string The HTTP body of the server response. */ protected $response_body; - /** - * The HTTP header of the server response. - */ + /** @var string[] The HTTP header of the server response. */ protected $response_headers; public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 755d0e70452..1946e26bf34 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -20,11 +20,17 @@ * NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. */ -namespace {{invokerPackage}}; +namespace {{apiPackage}}; + +use \{{invokerPackage}}\ApiClient; +use \{{invokerPackage}}\Configuration; {{#operations}} class {{classname}} { + /** + * @param \{{invokerPackage}}\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration + */ function __construct($apiClient = null) { if (null === $apiClient) { if (Configuration::$apiClient === null) { @@ -41,14 +47,14 @@ class {{classname}} { private $apiClient; // instance of the ApiClient /** - * get the API client - */ + * @return \{{invokerPackage}}\ApiClient get the API client + */ public function getApiClient() { return $this->apiClient; } /** - * set the API client + * @param \{{invokerPackage}} $apiClient set the API client */ public function setApiClient($apiClient) { $this->apiClient = $apiClient; @@ -123,7 +129,6 @@ class {{classname}} { $response = $this->apiClient->callAPI($resourcePath, $method, $queryParams, $httpBody, $headerParams, $authSettings); - {{#returnType}}if(! $response) { return null; } diff --git a/modules/swagger-codegen/src/main/resources/php/autoload.mustache b/modules/swagger-codegen/src/main/resources/php/autoload.mustache new file mode 100644 index 00000000000..4f56a6e20c0 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php/autoload.mustache @@ -0,0 +1,41 @@ + '{{{datatype}}}'{{#hasMore}}, {{/hasMore}}{{/vars}} ); + /** @var string[] Array of attributes where the key is the local name, and the value is the original name */ static $attributeMap = array( {{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}}, {{/hasMore}}{{/vars}} ); - - {{#vars}}{{#description}} + {{#vars}} + /** @var {{datatype}} ${{name}} {{#description}}{{{description}}} {{/description}}*/ + public ${{name}}; + {{/vars}} /** - * {{{description}}} - */{{/description}} - public ${{name}}; /* {{{datatype}}} */{{/vars}} - + * @param mixed[] Array of parameters to initialize the object with + */ public function __construct(array $data = null) { - {{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}} + {{#vars}}$this->{{name}} = @$data["{{name}}"];{{#hasMore}} {{/hasMore}}{{/vars}} } diff --git a/modules/swagger-codegen/src/main/resources/php/require.mustache b/modules/swagger-codegen/src/main/resources/php/require.mustache deleted file mode 100644 index 3c02d861ef1..00000000000 --- a/modules/swagger-codegen/src/main/resources/php/require.mustache +++ /dev/null @@ -1,13 +0,0 @@ - From 719a0b732ee0c64e958c53cd93329793854af7d5 Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Fri, 12 Jun 2015 15:01:25 -0700 Subject: [PATCH 065/499] Update sample client --- .../php/SwaggerClient-php/SwaggerClient.php | 13 - .../php/SwaggerClient-php/autoload.php | 41 ++ .../php/SwaggerClient-php/composer.json | 4 +- .../php/SwaggerClient-php/lib/Api/PetApi.php | 541 ++++++++++++++++++ .../SwaggerClient-php/lib/Api/StoreApi.php | 296 ++++++++++ .../php/SwaggerClient-php/lib/Api/UserApi.php | 516 +++++++++++++++++ .../php/SwaggerClient-php/lib/ApiClient.php | 18 +- .../SwaggerClient-php/lib/ApiException.php | 10 +- .../SwaggerClient-php/lib/Configuration.php | 33 +- .../lib/{models => Model}/Category.php | 21 +- .../lib/{models => Model}/Order.php | 50 +- .../lib/{models => Model}/Pet.php | 52 +- .../lib/{models => Model}/Tag.php | 21 +- .../lib/{models => Model}/User.php | 58 +- samples/client/petstore/php/test.php | 18 +- 15 files changed, 1551 insertions(+), 141 deletions(-) delete mode 100644 samples/client/petstore/php/SwaggerClient-php/SwaggerClient.php create mode 100644 samples/client/petstore/php/SwaggerClient-php/autoload.php create mode 100644 samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php create mode 100644 samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php create mode 100644 samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php rename samples/client/petstore/php/SwaggerClient-php/lib/{models => Model}/Category.php (76%) rename samples/client/petstore/php/SwaggerClient-php/lib/{models => Model}/Order.php (65%) rename samples/client/petstore/php/SwaggerClient-php/lib/{models => Model}/Pet.php (61%) rename samples/client/petstore/php/SwaggerClient-php/lib/{models => Model}/Tag.php (76%) rename samples/client/petstore/php/SwaggerClient-php/lib/{models => Model}/User.php (64%) diff --git a/samples/client/petstore/php/SwaggerClient-php/SwaggerClient.php b/samples/client/petstore/php/SwaggerClient-php/SwaggerClient.php deleted file mode 100644 index 3c02d861ef1..00000000000 --- a/samples/client/petstore/php/SwaggerClient-php/SwaggerClient.php +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/samples/client/petstore/php/SwaggerClient-php/autoload.php b/samples/client/petstore/php/SwaggerClient-php/autoload.php new file mode 100644 index 00000000000..acbd3968b23 --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/autoload.php @@ -0,0 +1,41 @@ +apiClient = Configuration::$apiClient; + } + else + $this->apiClient = Configuration::$apiClient; // use the default one + } else { + $this->apiClient = $apiClient; // use the one provided by the user + } + } + + private $apiClient; // instance of the ApiClient + + /** + * @return \Swagger\Client\ApiClient get the API client + */ + public function getApiClient() { + return $this->apiClient; + } + + /** + * @param \Swagger\Client $apiClient set the API client + */ + public function setApiClient($apiClient) { + $this->apiClient = $apiClient; + } + + + /** + * updatePet + * + * Update an existing pet + * + * @param \Swagger\Client\Model\Pet $body Pet object that needs to be added to the store (required) + * @return void + */ + public function updatePet($body) { + + + // parse inputs + $resourcePath = "/pet"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "PUT"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/json','application/xml')); + + + + + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * addPet + * + * Add a new pet to the store + * + * @param \Swagger\Client\Model\Pet $body Pet object that needs to be added to the store (required) + * @return void + */ + public function addPet($body) { + + + // parse inputs + $resourcePath = "/pet"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/json','application/xml')); + + + + + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * findPetsByStatus + * + * Finds Pets by status + * + * @param string[] $status Status values that need to be considered for filter (required) + * @return \Swagger\Client\Model\Pet[] + */ + public function findPetsByStatus($status) { + + + // parse inputs + $resourcePath = "/pet/findByStatus"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + // query params + if($status !== null) { + $queryParams['status'] = $this->apiClient->toQueryValue($status); + } + + + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet[]'); + return $responseObject; + } + + /** + * findPetsByTags + * + * Finds Pets by tags + * + * @param string[] $tags Tags to filter by (required) + * @return \Swagger\Client\Model\Pet[] + */ + public function findPetsByTags($tags) { + + + // parse inputs + $resourcePath = "/pet/findByTags"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + // query params + if($tags !== null) { + $queryParams['tags'] = $this->apiClient->toQueryValue($tags); + } + + + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet[]'); + return $responseObject; + } + + /** + * getPetById + * + * Find pet by ID + * + * @param int $pet_id ID of pet that needs to be fetched (required) + * @return \Swagger\Client\Model\Pet + */ + public function getPetById($pet_id) { + + // verify the required parameter 'pet_id' is set + if ($pet_id === null) { + throw new \InvalidArgumentException('Missing the required parameter $pet_id when calling getPetById'); + } + + + // parse inputs + $resourcePath = "/pet/{petId}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + // path params + if($pet_id !== null) { + $resourcePath = str_replace("{" . "petId" . "}", + $this->apiClient->toPathValue($pet_id), $resourcePath); + } + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('api_key', 'petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet'); + return $responseObject; + } + + /** + * updatePetWithForm + * + * Updates a pet in the store with form data + * + * @param string $pet_id ID of pet that needs to be updated (required) + * @param string $name Updated name of the pet (required) + * @param string $status Updated status of the pet (required) + * @return void + */ + public function updatePetWithForm($pet_id, $name, $status) { + + // verify the required parameter 'pet_id' is set + if ($pet_id === null) { + throw new \InvalidArgumentException('Missing the required parameter $pet_id when calling updatePetWithForm'); + } + + + // parse inputs + $resourcePath = "/pet/{petId}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/x-www-form-urlencoded')); + + + + // path params + if($pet_id !== null) { + $resourcePath = str_replace("{" . "petId" . "}", + $this->apiClient->toPathValue($pet_id), $resourcePath); + } + // form params + if ($name !== null) { + $formParams['name'] = $this->apiClient->toFormValue($name); + }// form params + if ($status !== null) { + $formParams['status'] = $this->apiClient->toFormValue($status); + } + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * deletePet + * + * Deletes a pet + * + * @param string $api_key (required) + * @param int $pet_id Pet id to delete (required) + * @return void + */ + public function deletePet($api_key, $pet_id) { + + // verify the required parameter 'pet_id' is set + if ($pet_id === null) { + throw new \InvalidArgumentException('Missing the required parameter $pet_id when calling deletePet'); + } + + + // parse inputs + $resourcePath = "/pet/{petId}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "DELETE"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + // header params + if($api_key !== null) { + $headerParams['api_key'] = $this->apiClient->toHeaderValue($api_key); + } + // path params + if($pet_id !== null) { + $resourcePath = str_replace("{" . "petId" . "}", + $this->apiClient->toPathValue($pet_id), $resourcePath); + } + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * uploadFile + * + * uploads an image + * + * @param int $pet_id ID of pet to update (required) + * @param string $additional_metadata Additional data to pass to server (required) + * @param string $file file to upload (required) + * @return void + */ + public function uploadFile($pet_id, $additional_metadata, $file) { + + // verify the required parameter 'pet_id' is set + if ($pet_id === null) { + throw new \InvalidArgumentException('Missing the required parameter $pet_id when calling uploadFile'); + } + + + // parse inputs + $resourcePath = "/pet/{petId}/uploadImage"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('multipart/form-data')); + + + + // path params + if($pet_id !== null) { + $resourcePath = str_replace("{" . "petId" . "}", + $this->apiClient->toPathValue($pet_id), $resourcePath); + } + // form params + if ($additional_metadata !== null) { + $formParams['additionalMetadata'] = $this->apiClient->toFormValue($additional_metadata); + }// form params + if ($file !== null) { + $formParams['file'] = '@' . $this->apiClient->toFormValue($file); + } + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('petstore_auth'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + +} diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php new file mode 100644 index 00000000000..b8b30977b59 --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php @@ -0,0 +1,296 @@ +apiClient = Configuration::$apiClient; + } + else + $this->apiClient = Configuration::$apiClient; // use the default one + } else { + $this->apiClient = $apiClient; // use the one provided by the user + } + } + + private $apiClient; // instance of the ApiClient + + /** + * @return \Swagger\Client\ApiClient get the API client + */ + public function getApiClient() { + return $this->apiClient; + } + + /** + * @param \Swagger\Client $apiClient set the API client + */ + public function setApiClient($apiClient) { + $this->apiClient = $apiClient; + } + + + /** + * getInventory + * + * Returns pet inventories by status + * + * @return map[string,int] + */ + public function getInventory() { + + + // parse inputs + $resourcePath = "/store/inventory"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array('api_key'); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'map[string,int]'); + return $responseObject; + } + + /** + * placeOrder + * + * Place an order for a pet + * + * @param \Swagger\Client\Model\Order $body order placed for purchasing the pet (required) + * @return \Swagger\Client\Model\Order + */ + public function placeOrder($body) { + + + // parse inputs + $resourcePath = "/store/order"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Order'); + return $responseObject; + } + + /** + * getOrderById + * + * Find purchase order by ID + * + * @param string $order_id ID of pet that needs to be fetched (required) + * @return \Swagger\Client\Model\Order + */ + public function getOrderById($order_id) { + + // verify the required parameter 'order_id' is set + if ($order_id === null) { + throw new \InvalidArgumentException('Missing the required parameter $order_id when calling getOrderById'); + } + + + // parse inputs + $resourcePath = "/store/order/{orderId}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + // path params + if($order_id !== null) { + $resourcePath = str_replace("{" . "orderId" . "}", + $this->apiClient->toPathValue($order_id), $resourcePath); + } + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Order'); + return $responseObject; + } + + /** + * deleteOrder + * + * Delete purchase order by ID + * + * @param string $order_id ID of the order that needs to be deleted (required) + * @return void + */ + public function deleteOrder($order_id) { + + // verify the required parameter 'order_id' is set + if ($order_id === null) { + throw new \InvalidArgumentException('Missing the required parameter $order_id when calling deleteOrder'); + } + + + // parse inputs + $resourcePath = "/store/order/{orderId}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "DELETE"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + // path params + if($order_id !== null) { + $resourcePath = str_replace("{" . "orderId" . "}", + $this->apiClient->toPathValue($order_id), $resourcePath); + } + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + +} diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php new file mode 100644 index 00000000000..2e83df74da4 --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php @@ -0,0 +1,516 @@ +apiClient = Configuration::$apiClient; + } + else + $this->apiClient = Configuration::$apiClient; // use the default one + } else { + $this->apiClient = $apiClient; // use the one provided by the user + } + } + + private $apiClient; // instance of the ApiClient + + /** + * @return \Swagger\Client\ApiClient get the API client + */ + public function getApiClient() { + return $this->apiClient; + } + + /** + * @param \Swagger\Client $apiClient set the API client + */ + public function setApiClient($apiClient) { + $this->apiClient = $apiClient; + } + + + /** + * createUser + * + * Create user + * + * @param \Swagger\Client\Model\User $body Created user object (required) + * @return void + */ + public function createUser($body) { + + + // parse inputs + $resourcePath = "/user"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * createUsersWithArrayInput + * + * Creates list of users with given input array + * + * @param \Swagger\Client\Model\User[] $body List of user object (required) + * @return void + */ + public function createUsersWithArrayInput($body) { + + + // parse inputs + $resourcePath = "/user/createWithArray"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * createUsersWithListInput + * + * Creates list of users with given input array + * + * @param \Swagger\Client\Model\User[] $body List of user object (required) + * @return void + */ + public function createUsersWithListInput($body) { + + + // parse inputs + $resourcePath = "/user/createWithList"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "POST"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * loginUser + * + * Logs user into the system + * + * @param string $username The user name for login (required) + * @param string $password The password for login in clear text (required) + * @return string + */ + public function loginUser($username, $password) { + + + // parse inputs + $resourcePath = "/user/login"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + // query params + if($username !== null) { + $queryParams['username'] = $this->apiClient->toQueryValue($username); + }// query params + if($password !== null) { + $queryParams['password'] = $this->apiClient->toQueryValue($password); + } + + + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'string'); + return $responseObject; + } + + /** + * logoutUser + * + * Logs out current logged in user session + * + * @return void + */ + public function logoutUser() { + + + // parse inputs + $resourcePath = "/user/logout"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * getUserByName + * + * Get user by user name + * + * @param string $username The name that needs to be fetched. Use user1 for testing. (required) + * @return \Swagger\Client\Model\User + */ + public function getUserByName($username) { + + // verify the required parameter 'username' is set + if ($username === null) { + throw new \InvalidArgumentException('Missing the required parameter $username when calling getUserByName'); + } + + + // parse inputs + $resourcePath = "/user/{username}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "GET"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + // path params + if($username !== null) { + $resourcePath = str_replace("{" . "username" . "}", + $this->apiClient->toPathValue($username), $resourcePath); + } + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + if(! $response) { + return null; + } + + $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\User'); + return $responseObject; + } + + /** + * updateUser + * + * Updated user + * + * @param string $username name that need to be deleted (required) + * @param \Swagger\Client\Model\User $body Updated user object (required) + * @return void + */ + public function updateUser($username, $body) { + + // verify the required parameter 'username' is set + if ($username === null) { + throw new \InvalidArgumentException('Missing the required parameter $username when calling updateUser'); + } + + + // parse inputs + $resourcePath = "/user/{username}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "PUT"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + // path params + if($username !== null) { + $resourcePath = str_replace("{" . "username" . "}", + $this->apiClient->toPathValue($username), $resourcePath); + } + + // body params + $_tempBody = null; + if (isset($body)) { + $_tempBody = $body; + } + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + /** + * deleteUser + * + * Delete user + * + * @param string $username The name that needs to be deleted (required) + * @return void + */ + public function deleteUser($username) { + + // verify the required parameter 'username' is set + if ($username === null) { + throw new \InvalidArgumentException('Missing the required parameter $username when calling deleteUser'); + } + + + // parse inputs + $resourcePath = "/user/{username}"; + $resourcePath = str_replace("{format}", "json", $resourcePath); + $method = "DELETE"; + $httpBody = ''; + $queryParams = array(); + $headerParams = array(); + $formParams = array(); + $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + if (!is_null($_header_accept)) { + $headerParams['Accept'] = $_header_accept; + } + $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + + + + // path params + if($username !== null) { + $resourcePath = str_replace("{" . "username" . "}", + $this->apiClient->toPathValue($username), $resourcePath); + } + + + + // for model (json/xml) + if (isset($_tempBody)) { + $httpBody = $_tempBody; // $_tempBody is the method argument, if present + } else if (count($formParams) > 0) { + // for HTTP post (form) + $httpBody = $formParams; + } + + // authentication setting, if any + $authSettings = array(); + + // make the API Call + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + + } + + +} diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php index 280fe9bdd71..bb5229fb170 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace SwaggerClient; +namespace Swagger\Client; class ApiClient { @@ -24,17 +24,14 @@ class ApiClient { public static $GET = "GET"; public static $PUT = "PUT"; public static $DELETE = "DELETE"; - + + /** @var string[] Array of default headers where the key is the header name and the value is the header value */ private $default_header = array(); - /* - * @var string timeout (second) of the HTTP request, by default set to 0, no timeout - */ + /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ protected $curl_timeout = 0; - /* - * @var string user agent of the HTTP request, set to "PHP-Swagger" by default - */ + /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ protected $user_agent = "PHP-Swagger"; /** @@ -391,8 +388,8 @@ class ApiClient { $deserialized[$key] = $this->deserialize($value, $subClass); } } - } elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) { - $subClass = substr($class, 6, -1); + } elseif (strcasecmp(substr($class, -2),'[]') == 0) { + $subClass = substr($class, 0, -2); $values = array(); foreach ($data as $key => $value) { $values[] = $this->deserialize($value, $subClass); @@ -404,7 +401,6 @@ class ApiClient { settype($data, $class); $deserialized = $data; } else { - $class = "SwaggerClient\\models\\".$class; $instance = new $class(); foreach ($instance::$swaggerTypes as $property => $type) { $original_property_name = $instance::$attributeMap[$property]; diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php index 51f2c4b877e..5f3b1812261 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php @@ -15,20 +15,16 @@ * limitations under the License. */ -namespace SwaggerClient; +namespace Swagger\Client; use \Exception; class ApiException extends Exception { - /** - * The HTTP body of the server response. - */ + /** @var string The HTTP body of the server response. */ protected $response_body; - /** - * The HTTP header of the server response. - */ + /** @var string[] The HTTP header of the server response. */ protected $response_headers; public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php index cd514956a29..e6381781bb0 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php @@ -15,43 +15,31 @@ * limitations under the License. */ -namespace SwaggerClient; +namespace Swagger\Client; + +use \Swagger\Client\ApiClient; class Configuration { - /** - * Associate array to store API key(s) - */ + /** @var string[] Associate array to store API key(s) */ public static $apiKey = array(); - /** - * Associate array to store API prefix (e.g. Bearer) - */ + /** string[] Associate array to store API prefix (e.g. Bearer) */ public static $apiKeyPrefix = array(); - /** - * Username for HTTP basic authentication - */ + /** @var string Username for HTTP basic authentication */ public static $username = ''; - /** - * Password for HTTP basic authentication - */ + /** @var string Password for HTTP basic authentication */ public static $password = ''; - /** - * The default instance of ApiClient - */ + /** @var \Swagger\Client\ApiClient The default instance of ApiClient */ public static $apiClient; - /** - * Debug switch (default set to false) - */ + /** @var bool Debug switch (default set to false) */ public static $debug = false; - /** - * Debug file location (log to STDOUT by default) - */ + /** @var string Debug file location (log to STDOUT by default) */ public static $debug_file = 'php://output'; /* @@ -63,4 +51,3 @@ class Configuration { } } - diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php similarity index 76% rename from samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php rename to samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php index c49c711fa8e..750a8fee5df 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Category.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php @@ -22,28 +22,35 @@ * */ -namespace SwaggerClient\models; +namespace Swagger\Client\Model; use \ArrayAccess; class Category implements ArrayAccess { + /** @var string[] Array of property to type mappings. Used for (de)serialization */ static $swaggerTypes = array( 'id' => 'int', 'name' => 'string' ); + /** @var string[] Array of attributes where the key is the local name, and the value is the original name */ static $attributeMap = array( 'id' => 'id', 'name' => 'name' ); - - public $id; /* int */ - public $name; /* string */ - + /** @var int $id */ + public $id; + + /** @var string $name */ + public $name; + + /** + * @param mixed[] Array of parameters to initialize the object with + */ public function __construct(array $data = null) { - $this->id = $data["id"]; - $this->name = $data["name"]; + $this->id = @$data["id"]; + $this->name = @$data["name"]; } public function offsetExists($offset) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php similarity index 65% rename from samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php rename to samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php index bf8a0178e4c..64552afb763 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Order.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php @@ -22,20 +22,22 @@ * */ -namespace SwaggerClient\models; +namespace Swagger\Client\Model; use \ArrayAccess; class Order implements ArrayAccess { + /** @var string[] Array of property to type mappings. Used for (de)serialization */ static $swaggerTypes = array( 'id' => 'int', 'pet_id' => 'int', 'quantity' => 'int', - 'ship_date' => 'DateTime', + 'ship_date' => '\DateTime', 'status' => 'string', - 'complete' => 'boolean' + 'complete' => 'bool' ); + /** @var string[] Array of attributes where the key is the local name, and the value is the original name */ static $attributeMap = array( 'id' => 'id', 'pet_id' => 'petId', @@ -44,25 +46,35 @@ class Order implements ArrayAccess { 'status' => 'status', 'complete' => 'complete' ); - - public $id; /* int */ - public $pet_id; /* int */ - public $quantity; /* int */ - public $ship_date; /* DateTime */ + /** @var int $id */ + public $id; + + /** @var int $pet_id */ + public $pet_id; + + /** @var int $quantity */ + public $quantity; + + /** @var \DateTime $ship_date */ + public $ship_date; + + /** @var string $status Order Status */ + public $status; + + /** @var bool $complete */ + public $complete; + /** - * Order Status - */ - public $status; /* string */ - public $complete; /* boolean */ - + * @param mixed[] Array of parameters to initialize the object with + */ public function __construct(array $data = null) { - $this->id = $data["id"]; - $this->pet_id = $data["pet_id"]; - $this->quantity = $data["quantity"]; - $this->ship_date = $data["ship_date"]; - $this->status = $data["status"]; - $this->complete = $data["complete"]; + $this->id = @$data["id"]; + $this->pet_id = @$data["pet_id"]; + $this->quantity = @$data["quantity"]; + $this->ship_date = @$data["ship_date"]; + $this->status = @$data["status"]; + $this->complete = @$data["complete"]; } public function offsetExists($offset) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php similarity index 61% rename from samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php rename to samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php index 2009cc373cf..ef2a4c76a0d 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Pet.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php @@ -22,20 +22,22 @@ * */ -namespace SwaggerClient\models; +namespace Swagger\Client\Model; use \ArrayAccess; class Pet implements ArrayAccess { + /** @var string[] Array of property to type mappings. Used for (de)serialization */ static $swaggerTypes = array( 'id' => 'int', - 'category' => 'Category', + 'category' => '\Swagger\Client\Model\Category', 'name' => 'string', - 'photo_urls' => 'array[string]', - 'tags' => 'array[Tag]', + 'photo_urls' => 'string[]', + 'tags' => '\Swagger\Client\Model\Tag[]', 'status' => 'string' ); + /** @var string[] Array of attributes where the key is the local name, and the value is the original name */ static $attributeMap = array( 'id' => 'id', 'category' => 'category', @@ -44,25 +46,35 @@ class Pet implements ArrayAccess { 'tags' => 'tags', 'status' => 'status' ); - - public $id; /* int */ - public $category; /* Category */ - public $name; /* string */ - public $photo_urls; /* array[string] */ - public $tags; /* array[Tag] */ + /** @var int $id */ + public $id; + + /** @var \Swagger\Client\Model\Category $category */ + public $category; + + /** @var string $name */ + public $name; + + /** @var string[] $photo_urls */ + public $photo_urls; + + /** @var \Swagger\Client\Model\Tag[] $tags */ + public $tags; + + /** @var string $status pet status in the store */ + public $status; + /** - * pet status in the store - */ - public $status; /* string */ - + * @param mixed[] Array of parameters to initialize the object with + */ public function __construct(array $data = null) { - $this->id = $data["id"]; - $this->category = $data["category"]; - $this->name = $data["name"]; - $this->photo_urls = $data["photo_urls"]; - $this->tags = $data["tags"]; - $this->status = $data["status"]; + $this->id = @$data["id"]; + $this->category = @$data["category"]; + $this->name = @$data["name"]; + $this->photo_urls = @$data["photo_urls"]; + $this->tags = @$data["tags"]; + $this->status = @$data["status"]; } public function offsetExists($offset) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php similarity index 76% rename from samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php rename to samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php index 37729c68d9e..5959cb20a6a 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/Tag.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php @@ -22,28 +22,35 @@ * */ -namespace SwaggerClient\models; +namespace Swagger\Client\Model; use \ArrayAccess; class Tag implements ArrayAccess { + /** @var string[] Array of property to type mappings. Used for (de)serialization */ static $swaggerTypes = array( 'id' => 'int', 'name' => 'string' ); + /** @var string[] Array of attributes where the key is the local name, and the value is the original name */ static $attributeMap = array( 'id' => 'id', 'name' => 'name' ); - - public $id; /* int */ - public $name; /* string */ - + /** @var int $id */ + public $id; + + /** @var string $name */ + public $name; + + /** + * @param mixed[] Array of parameters to initialize the object with + */ public function __construct(array $data = null) { - $this->id = $data["id"]; - $this->name = $data["name"]; + $this->id = @$data["id"]; + $this->name = @$data["name"]; } public function offsetExists($offset) { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/models/User.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php similarity index 64% rename from samples/client/petstore/php/SwaggerClient-php/lib/models/User.php rename to samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php index 0ec53c409e6..1bfb7f332db 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/models/User.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php @@ -22,11 +22,12 @@ * */ -namespace SwaggerClient\models; +namespace Swagger\Client\Model; use \ArrayAccess; class User implements ArrayAccess { + /** @var string[] Array of property to type mappings. Used for (de)serialization */ static $swaggerTypes = array( 'id' => 'int', 'username' => 'string', @@ -38,6 +39,7 @@ class User implements ArrayAccess { 'user_status' => 'int' ); + /** @var string[] Array of attributes where the key is the local name, and the value is the original name */ static $attributeMap = array( 'id' => 'id', 'username' => 'username', @@ -48,29 +50,43 @@ class User implements ArrayAccess { 'phone' => 'phone', 'user_status' => 'userStatus' ); - - public $id; /* int */ - public $username; /* string */ - public $first_name; /* string */ - public $last_name; /* string */ - public $email; /* string */ - public $password; /* string */ - public $phone; /* string */ + /** @var int $id */ + public $id; + + /** @var string $username */ + public $username; + + /** @var string $first_name */ + public $first_name; + + /** @var string $last_name */ + public $last_name; + + /** @var string $email */ + public $email; + + /** @var string $password */ + public $password; + + /** @var string $phone */ + public $phone; + + /** @var int $user_status User Status */ + public $user_status; + /** - * User Status - */ - public $user_status; /* int */ - + * @param mixed[] Array of parameters to initialize the object with + */ public function __construct(array $data = null) { - $this->id = $data["id"]; - $this->username = $data["username"]; - $this->first_name = $data["first_name"]; - $this->last_name = $data["last_name"]; - $this->email = $data["email"]; - $this->password = $data["password"]; - $this->phone = $data["phone"]; - $this->user_status = $data["user_status"]; + $this->id = @$data["id"]; + $this->username = @$data["username"]; + $this->first_name = @$data["first_name"]; + $this->last_name = @$data["last_name"]; + $this->email = @$data["email"]; + $this->password = @$data["password"]; + $this->phone = @$data["phone"]; + $this->user_status = @$data["user_status"]; } public function offsetExists($offset) { diff --git a/samples/client/petstore/php/test.php b/samples/client/petstore/php/test.php index 0c52f0fdb8a..f5383a9a4dc 100644 --- a/samples/client/petstore/php/test.php +++ b/samples/client/petstore/php/test.php @@ -1,6 +1,5 @@ getApiClient()->addDefaultHeader("TEST_API_KEY", "09182sdkanafndsl903"); // return Pet (model) @@ -28,34 +27,31 @@ try { // add pet (post json) $new_pet_id = 10005; - $new_pet = new SwaggerClient\models\Pet; + $new_pet = new Swagger\Client\Model\Pet; $new_pet->id = $new_pet_id; $new_pet->name = "PHP Unit Test"; // new tag - $tag= new SwaggerClient\models\Tag; + $tag= new Swagger\Client\Model\Tag; $tag->id = $new_pet_id; // use the same id as pet //$tag->name = "test php tag"; // new category - $category = new SwaggerClient\models\Category; + $category = new Swagger\Client\Model\Category; $category->id = 0; // use the same id as pet //$category->name = "test php category"; $new_pet->tags = array($tag); $new_pet->category = $category; - $pet_api = new SwaggerClient\PetAPI(); + $pet_api = new Swagger\Client\Api\PetAPI(); // add a new pet (model) $add_response = $pet_api->addPet($new_pet); // test upload file (exception) $upload_response = $pet_api->uploadFile($petId, "test meta", NULL); -} catch (Exception $e) { +} catch (Swagger\Client\Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; echo 'HTTP response headers: ', $e->getResponseHeaders(), "\n"; echo 'HTTP response body: ', $e->getResponseBody(), "\n"; echo 'HTTP status code: ', $e->getCode(), "\n"; } - - -?> From 5119299e8ac2b40be22441c5e7d1a0c5e05650e3 Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Fri, 12 Jun 2015 15:45:36 -0700 Subject: [PATCH 066/499] Remove unused code --- .../main/java/io/swagger/codegen/languages/PhpClientCodegen.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 2134bfe75dc..0690163f137 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -90,7 +90,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { } public String getPackagePath() { - //invokerPackage.replace("\\", "") return "SwaggerClient-php"; } From 69c2f6f945e55450cfd5c9ce209364ed245f218e Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Fri, 12 Jun 2015 16:05:45 -0700 Subject: [PATCH 067/499] Add phpdoc for the api.apiClient --- modules/swagger-codegen/src/main/resources/php/api.mustache | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 1946e26bf34..05f6944e720 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -44,7 +44,8 @@ class {{classname}} { } } - private $apiClient; // instance of the ApiClient + /** @var \{{invokerPackage}}\ApiClient instance of the ApiClient + private $apiClient; /** * @return \{{invokerPackage}}\ApiClient get the API client From eed45a41a391be9a87482bead63bc7b90e3c5b0f Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Fri, 12 Jun 2015 16:21:37 -0700 Subject: [PATCH 068/499] Fixed the missing closing doc chars and updated sample --- .../swagger-codegen/src/main/resources/php/api.mustache | 6 +++--- .../petstore/php/SwaggerClient-php/lib/Api/PetApi.php | 7 ++++--- .../petstore/php/SwaggerClient-php/lib/Api/StoreApi.php | 7 ++++--- .../petstore/php/SwaggerClient-php/lib/Api/UserApi.php | 7 ++++--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 05f6944e720..3ed7f18c579 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -44,12 +44,12 @@ class {{classname}} { } } - /** @var \{{invokerPackage}}\ApiClient instance of the ApiClient + /** @var \{{invokerPackage}}\ApiClient instance of the ApiClient */ private $apiClient; /** - * @return \{{invokerPackage}}\ApiClient get the API client - */ + * @return \{{invokerPackage}}\ApiClient get the API client + */ public function getApiClient() { return $this->apiClient; } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php index 01ecd6771e4..f4f6ea8538a 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php @@ -43,11 +43,12 @@ class PetApi { } } - private $apiClient; // instance of the ApiClient + /** @var \Swagger\Client\ApiClient instance of the ApiClient */ + private $apiClient; /** - * @return \Swagger\Client\ApiClient get the API client - */ + * @return \Swagger\Client\ApiClient get the API client + */ public function getApiClient() { return $this->apiClient; } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php index b8b30977b59..07a922aab0a 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php @@ -43,11 +43,12 @@ class StoreApi { } } - private $apiClient; // instance of the ApiClient + /** @var \Swagger\Client\ApiClient instance of the ApiClient */ + private $apiClient; /** - * @return \Swagger\Client\ApiClient get the API client - */ + * @return \Swagger\Client\ApiClient get the API client + */ public function getApiClient() { return $this->apiClient; } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php index 2e83df74da4..f4d35a3a7a0 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php @@ -43,11 +43,12 @@ class UserApi { } } - private $apiClient; // instance of the ApiClient + /** @var \Swagger\Client\ApiClient instance of the ApiClient */ + private $apiClient; /** - * @return \Swagger\Client\ApiClient get the API client - */ + * @return \Swagger\Client\ApiClient get the API client + */ public function getApiClient() { return $this->apiClient; } From 2ac7384abf841f63a6170916256baa68ab9696d4 Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Fri, 12 Jun 2015 16:49:17 -0700 Subject: [PATCH 069/499] Fix tests --- .../src/test/scala/php/PhpModelTest.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala b/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala index ade8a09e80d..ffb9c8683db 100644 --- a/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala +++ b/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala @@ -51,16 +51,16 @@ class PhpModelTest extends FlatSpec with Matchers { vars.get(1).isNotContainer should equal(true) vars.get(2).baseName should be("createdAt") - vars.get(2).complexType should be(null) - vars.get(2).datatype should be("DateTime") + vars.get(2).complexType should be("\\DateTime") + vars.get(2).datatype should be("\\DateTime") vars.get(2).name should be("created_at") vars.get(2).defaultValue should be("null") - vars.get(2).baseType should be("DateTime") + vars.get(2).baseType should be("\\DateTime") vars.get(2).hasMore should equal(null) vars.get(2).required should equal(null) vars.get(2).isNotContainer should equal(true) - cm.imports.size() should be(0) + cm.imports.size() should be(1) } it should "convert a model with list property" in { @@ -91,7 +91,7 @@ class PhpModelTest extends FlatSpec with Matchers { vars.get(0).isNotContainer should equal(true) vars.get(1).baseName should be("urls") - vars.get(1).datatype should be("array[string]") + vars.get(1).datatype should be("string[]") vars.get(1).name should be("urls") vars.get(1).baseType should be("array") vars.get(1).hasMore should be(null) @@ -142,7 +142,7 @@ class PhpModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") - vars.get(0).datatype should be("Children") + vars.get(0).datatype should be("\\Swagger\\Client\\Model\\Children") vars.get(0).name should be("children") vars.get(0).baseType should be("Children") vars.get(0).required should equal(null) @@ -166,7 +166,7 @@ class PhpModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") vars.get(0).complexType should be("Children") - vars.get(0).datatype should be("array[Children]") + vars.get(0).datatype should be("\\Swagger\\Client\\Model\\Children[]") vars.get(0).name should be("children") vars.get(0).baseType should be("array") vars.get(0).containerType should be("array") @@ -192,7 +192,7 @@ class PhpModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") vars.get(0).complexType should be("Children") - vars.get(0).datatype should be("map[string,Children]") + vars.get(0).datatype should be("map[string,\\Swagger\\Client\\Model\\Children]") vars.get(0).name should be("children") vars.get(0).baseType should be("map") vars.get(0).containerType should be("map") From b74050dd7bc3d4ff73fe2bd77406953559e0a993 Mon Sep 17 00:00:00 2001 From: Branden Cash Date: Sat, 13 Jun 2015 09:40:32 -0700 Subject: [PATCH 070/499] Change to use the autoload.php and change the namespacing --- .../SwaggerClient-php/tests/PetApiTest.php | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index 5131fb7649c..131a79dba92 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -1,6 +1,6 @@ id = $new_pet_id; $new_pet->name = "PHP Unit Test"; // new tag - $tag= new SwaggerClient\models\Tag; + $tag= new Swagger\Client\Model\Tag; $tag->id = $new_pet_id; // use the same id as pet $tag->name = "test php tag"; // new category - $category = new SwaggerClient\models\Category; + $category = new Swagger\Client\Model\Category; $category->id = $new_pet_id; // use the same id as pet $category->name = "test php category"; $new_pet->tags = array($tag); $new_pet->category = $category; - $pet_api = new SwaggerClient\PetAPI(); + $pet_api = new Swagger\Client\Api\PetAPI(); // add a new pet (model) $add_response = $pet_api->addPet($new_pet); } @@ -45,7 +45,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testApiClient() { // test selectHeaderAccept - $api_client = new SwaggerClient\ApiClient(); + $api_client = new Swagger\Client\ApiClient(); $this->assertSame('application/json', $api_client->selectHeaderAccept(array('application/xml','application/json'))); $this->assertSame(NULL, $api_client->selectHeaderAccept(array())); $this->assertSame('application/yaml,application/xml', $api_client->selectHeaderAccept(array('application/yaml','application/xml'))); @@ -67,22 +67,22 @@ class PetApiTest extends \PHPUnit_Framework_TestCase $defaultHeader = $api_client->getDefaultHeader(); $this->assertFalse(isset($defaultHeader['test2'])); - $pet_api = new SwaggerClient\PetAPI(); - $pet_api2 = new SwaggerClient\PetAPI(); - $apiClient3 = new SwaggerClient\ApiClient(); + $pet_api = new Swagger\Client\Api\PetAPI(); + $pet_api2 = new Swagger\Client\Api\PetAPI(); + $apiClient3 = new Swagger\Client\ApiClient(); $apiClient3->setUserAgent = 'api client 3'; - $apiClient4 = new SwaggerClient\ApiClient(); + $apiClient4 = new Swagger\Client\ApiClient(); $apiClient4->setUserAgent = 'api client 4'; - $pet_api3 = new SwaggerClient\PetAPI($apiClient3); + $pet_api3 = new Swagger\Client\Api\PetAPI($apiClient3); // same default api client $this->assertSame($pet_api->getApiClient(), $pet_api2->getApiClient()); // confirm using the default api client in the Configuration - $this->assertSame($pet_api->getApiClient(), SwaggerClient\Configuration::$apiClient); + $this->assertSame($pet_api->getApiClient(), Swagger\Client\Configuration::$apiClient); // 2 different api clients are not the same $this->assertNotEquals($apiClient3, $apiClient4); // customized pet api not using the default (configuration) api client - $this->assertNotEquals($pet_api3->getApiClient(), SwaggerClient\Configuration::$apiClient); + $this->assertNotEquals($pet_api3->getApiClient(), Swagger\Client\Configuration::$apiClient); // customied pet api not using the old pet api's api client $this->assertNotEquals($pet_api2->getApiClient(), $pet_api3->getApiClient()); @@ -96,10 +96,10 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testGetPetById() { // initialize the API client without host - $api_client = new SwaggerClient\ApiClient(); - SwaggerClient\Configuration::$apiKey['api_key'] = '111222333444555'; + $api_client = new Swagger\Client\ApiClient(); + Swagger\Client\Configuration::$apiKey['api_key'] = '111222333444555'; $pet_id = 10005; // ID of pet that needs to be fetched - $pet_api = new SwaggerClient\PetAPI($api_client); + $pet_api = new Swagger\Client\Api\PetAPI($api_client); // return Pet (model) $response = $pet_api->getPetById($pet_id); $this->assertSame($response->id, $pet_id); @@ -114,12 +114,12 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testFindPetByStatus() { // initialize the API client - $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); - $pet_api = new SwaggerClient\PetAPI($api_client); + $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $pet_api = new Swagger\Client\Api\PetAPI($api_client); // return Pet (model) $response = $pet_api->findPetsByStatus("available"); $this->assertGreaterThan(0, count($response)); // at least one object returned - $this->assertSame(get_class($response[0]), "SwaggerClient\models\Pet"); // verify the object is Pet + $this->assertSame(get_class($response[0]), "Swagger\\Client\\Model\\Pet"); // verify the object is Pet // loop through result to ensure status is "available" foreach ($response as $_pet) { $this->assertSame($_pet['status'], "available"); @@ -133,11 +133,11 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUpdatePet() { // initialize the API client - $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); $pet_id = 10001; // ID of pet that needs to be fetched - $pet_api = new SwaggerClient\PetAPI($api_client); + $pet_api = new Swagger\Client\Api\PetAPI($api_client); // create updated pet object - $updated_pet = new SwaggerClient\models\Pet; + $updated_pet = new Swagger\Client\Model\Pet; $updated_pet->id = $pet_id; $updated_pet->name = 'updatePet'; // new name $updated_pet->status = 'pending'; // new status @@ -156,9 +156,9 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUpdatePetWithForm() { // initialize the API client - $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); $pet_id = 10001; // ID of pet that needs to be fetched - $pet_api = new SwaggerClient\PetAPI($api_client); + $pet_api = new Swagger\Client\Api\PetAPI($api_client); // update Pet (form) $update_response = $pet_api->updatePetWithForm($pet_id, 'update pet with form', 'sold'); // return nothing (void) @@ -173,12 +173,12 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testAddPet() { // initialize the API client - $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); $new_pet_id = 10001; - $new_pet = new SwaggerClient\models\Pet; + $new_pet = new Swagger\Client\Model\Pet; $new_pet->id = $new_pet_id; $new_pet->name = "PHP Unit Test"; - $pet_api = new SwaggerClient\PetAPI($api_client); + $pet_api = new Swagger\Client\Api\PetAPI($api_client); // add a new pet (model) $add_response = $pet_api->addPet($new_pet); // return nothing (void) @@ -193,8 +193,8 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUploadFile() { // initialize the API client - $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); - $pet_api = new SwaggerClient\PetAPI($api_client); + $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $pet_api = new Swagger\Client\Api\PetAPI($api_client); // upload file $pet_id = 10001; $add_response = $pet_api->uploadFile($pet_id, "test meta", "./composer.json"); @@ -206,8 +206,8 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testGetInventory() { // initialize the API client - $api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); - $store_api = new SwaggerClient\StoreAPI($api_client); + $api_client = new Swagger\Client\APIClient('http://petstore.swagger.io/v2'); + $store_api = new Swagger\Client\Api\StoreAPI($api_client); // get inventory $get_response = $store_api->getInventory(); From 1aeb50feefe1de90be296332f927ce0da962f5f0 Mon Sep 17 00:00:00 2001 From: Andrew B Date: Thu, 18 Jun 2015 14:41:17 -0700 Subject: [PATCH 071/499] Replacing getClientResponseStatus() with getStatusInfo() --- .../src/main/resources/Java/ApiClient.mustache | 6 +++--- .../java/src/main/java/io/swagger/client/ApiClient.java | 6 +++--- .../java/src/main/java/io/swagger/client/api/PetApi.java | 2 +- .../java/src/main/java/io/swagger/client/model/Pet.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index 352401ba0d8..e12c835a90a 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -421,10 +421,10 @@ public class ApiClient { throw new ApiException(500, "unknown method type " + method); } - if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) { + if(response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) { return null; } - else if(response.getClientResponseStatus().getFamily() == Family.SUCCESSFUL) { + else if(response.getStatusInfo().getFamily() == Family.SUCCESSFUL) { if(response.hasEntity()) { return (String) response.getEntity(String.class); } @@ -445,7 +445,7 @@ public class ApiClient { } } throw new ApiException( - response.getClientResponseStatus().getStatusCode(), + response.getStatusInfo().getStatusCode(), message, response.getHeaders(), respBody); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index 0adcbe7031d..a95f5f7a960 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -420,10 +420,10 @@ public class ApiClient { throw new ApiException(500, "unknown method type " + method); } - if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) { + if(response.getStatusInfo() == ClientResponse.Status.NO_CONTENT) { return null; } - else if(response.getClientResponseStatus().getFamily() == Family.SUCCESSFUL) { + else if(response.getStatusInfo().getFamily() == Family.SUCCESSFUL) { if(response.hasEntity()) { return (String) response.getEntity(String.class); } @@ -444,7 +444,7 @@ public class ApiClient { } } throw new ApiException( - response.getClientResponseStatus().getStatusCode(), + response.getStatusInfo().getStatusCode(), message, response.getHeaders(), respBody); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index c102cf00b51..bc793fd41ee 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -322,7 +322,7 @@ public class PetApi { } try { - String[] authNames = new String[] { "petstore_auth", "api_key" }; + String[] authNames = new String[] { "api_key", "petstore_auth" }; String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); if(response != null){ return (Pet) apiClient.deserialize(response, "", Pet.class); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java index ddd0e1038c0..cf7ace02309 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import java.util.*; import io.swagger.client.model.Tag; +import java.util.*; import io.swagger.annotations.*; import com.fasterxml.jackson.annotation.JsonProperty; From 4495774fd5b0b59ea4e5d98e28482a47499b8a06 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Thu, 18 Jun 2015 15:08:45 -0700 Subject: [PATCH 072/499] proper autoloader and move generated files to PSR-4 compliant locations --- .../codegen/languages/PhpClientCodegen.java | 95 ++++++++++++++++--- .../src/main/resources/php/autoload.mustache | 29 ++++++ .../src/main/resources/php/require.mustache | 13 --- 3 files changed, 113 insertions(+), 24 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/php/autoload.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/php/require.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 10c03fe4381..af4867108a8 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -1,5 +1,6 @@ package io.swagger.codegen.languages; +import io.swagger.codegen.CliOption; import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenType; import io.swagger.codegen.DefaultCodegen; @@ -12,22 +13,25 @@ import java.io.File; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { protected String invokerPackage = "io.swagger.client"; protected String groupId = "io.swagger"; protected String artifactId = "swagger-client"; protected String artifactVersion = "1.0.0"; + protected String rootNamespace; + protected String invokerNamespace; + protected String modelNamespace; + protected String apiNamespace; public PhpClientCodegen() { super(); - invokerPackage = camelize("SwaggerClient"); - - String packagePath = invokerPackage + "-php"; - - modelPackage = packagePath + "/lib/models"; - apiPackage = packagePath + "/lib"; + rootNamespace = "Swagger"; + invokerPackage = "Client"; + modelPackage = "Models"; + apiPackage = "Api"; outputFolder = "generated-code/php"; modelTemplateFiles.put("model.mustache", ".php"); apiTemplateFiles.put("api.mustache", ".php"); @@ -78,11 +82,8 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("list", "array"); typeMapping.put("object", "object"); - 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")); + cliOptions.add(new CliOption("rootNamespace", "root namespace from which other namespaces derive")); + cliOptions.add(new CliOption("invokerPackage", "namespace for core, non-api-specific classes")); } public CodegenType getTag() { @@ -97,6 +98,38 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return "Generates a PHP client library."; } + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey("invokerPackage")) { + this.setInvokerPackage((String) additionalProperties.get("invokerPackage")); + } + + if (additionalProperties.containsKey("rootNamespace")) { + this.setRootNamespace((String) additionalProperties.get("rootNamespace")); + } + + setNamespacesFromPackages(); + prefixPackages(); + + supportingFiles.add(new SupportingFile("configuration.mustache", invokerPackage.replace('/', File.separatorChar), "Configuration.php")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerPackage.replace('/', File.separatorChar), "ApiClient.php")); + supportingFiles.add(new SupportingFile("ApiException.mustache", invokerPackage.replace('/', File.separatorChar), "ApiException.php")); + supportingFiles.add(new SupportingFile("composer.mustache", "", "composer.json")); + supportingFiles.add(new SupportingFile("autoload.mustache", "", "autoload.php")); + } + + protected String getSrcDir(String packageName) { + return rootNamespace + "/src/" + packageName; + } + + protected void prefixPackages() { + setApiPackage(getSrcDir(apiPackage)); + setInvokerPackage(getSrcDir(invokerPackage)); + setModelPackage(getSrcDir(modelPackage)); + } + @Override public String escapeReservedWord(String name) { return "_" + name; @@ -149,6 +182,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return "null"; } + public void setInvokerPackage(String invokerPackage) { + this.invokerPackage = invokerPackage; + } + + public void setRootNamespace(String rootNamespace) { + this.rootNamespace = rootNamespace; + } @Override public String toVarName(String name) { @@ -187,4 +227,37 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return toModelName(name); } + public String toNamespace(String packageName) { + return rootNamespace + "\\" + packageName.replace('/', '\\').replace('.', '\\'); + } + + protected void setNamespacesFromPackages() { + invokerNamespace = toNamespace(invokerPackage); + apiNamespace = toNamespace(apiPackage); + modelNamespace = toNamespace(modelPackage); + } + + @Override + public Map postProcessModels(Map objs) { + return addNamespaces(super.postProcessModels(objs)); + } + + @Override + public Map postProcessOperations(Map objs) { + return addNamespaces(super.postProcessOperations(objs)); + } + + @Override + public Map postProcessSupportingFileData(Map objs) { + return addNamespaces(super.postProcessSupportingFileData(objs)); + } + + protected Map addNamespaces(Map objs) { + objs.put("rootNamespace", rootNamespace); + objs.put("invokerNamespace", invokerNamespace); + objs.put("apiNamespace", apiNamespace); + objs.put("modelNamespace", modelNamespace); + + return objs; + } } diff --git a/modules/swagger-codegen/src/main/resources/php/autoload.mustache b/modules/swagger-codegen/src/main/resources/php/autoload.mustache new file mode 100644 index 00000000000..5ed11c11041 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php/autoload.mustache @@ -0,0 +1,29 @@ + From bb113229194935651573c48030d1dec94c1e7c62 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Thu, 18 Jun 2015 15:41:12 -0700 Subject: [PATCH 073/499] use proper namespaces, getters/setters, and phpdocs --- .../src/main/resources/php/ApiClient.mustache | 2 +- .../main/resources/php/ApiException.mustache | 2 +- .../src/main/resources/php/api.mustache | 10 +++-- .../src/main/resources/php/autoload.mustache | 40 +++++++++---------- .../main/resources/php/configuration.mustache | 2 +- .../src/main/resources/php/model.mustache | 31 ++++++++++---- 6 files changed, 54 insertions(+), 33 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 6356143f914..564bc1ddd66 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace {{invokerPackage}}; +namespace {{invokerNamespace}}; class ApiClient { diff --git a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache index b66c3a51eb7..096979c11cb 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace {{invokerPackage}}; +namespace {{invokerNamespace}}; use \Exception; diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 12d2eb80744..5d84e0541da 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -20,11 +20,17 @@ * NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. */ -namespace {{invokerPackage}}; +namespace {{apiNamespace}}; + +use {{invokerNamespace}}\Configuration; +use {{invokerNamespace}}\ApiClient; {{#operations}} class {{classname}} { + /** @var ApiClient */ + private $apiClient; + function __construct($apiClient = null) { if (null === $apiClient) { if (Configuration::$apiClient === null) { @@ -38,8 +44,6 @@ class {{classname}} { } } - private $apiClient; // instance of the ApiClient - /** * get the API client */ diff --git a/modules/swagger-codegen/src/main/resources/php/autoload.mustache b/modules/swagger-codegen/src/main/resources/php/autoload.mustache index 5ed11c11041..41e4790da22 100644 --- a/modules/swagger-codegen/src/main/resources/php/autoload.mustache +++ b/modules/swagger-codegen/src/main/resources/php/autoload.mustache @@ -1,29 +1,29 @@ {{name}} = $data["{{name}}"];{{#hasMore}} {{/hasMore}}{{/vars}} } + {{#vars}} + /** + * get {{name}} + * @return {{datatype}} + */ + public function {{getter}}() { + return $this->{{name}}; + } + /** + * set {{name}} + * @param {{datatype}} ${{name}} + */ + public function {{setter}}(${{name}}) { + $this->{{name}} = ${{name}}; + } + {{/vars}} public function offsetExists($offset) { return isset($this->$offset); } From f9f58596b8ab3cb840513ebd35efbdf730c688d3 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Thu, 18 Jun 2015 16:51:24 -0700 Subject: [PATCH 074/499] account for return type where the response type is in a list container, and properly import models into operations --- .../codegen/languages/PhpClientCodegen.java | 29 ++++++++++++++++++- .../src/main/resources/php/api.mustache | 9 ++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index af4867108a8..ad9ca3aa9b1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -10,9 +10,12 @@ import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; import java.io.File; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @@ -244,7 +247,31 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public Map postProcessOperations(Map objs) { - return addNamespaces(super.postProcessOperations(objs)); + objs = addNamespaces(super.postProcessOperations(objs)); + + if (objs.containsKey("imports")) { + List> imports = new ArrayList>(); + LinkedHashMap newImport; + String currentImport; + String modelName; + + for (Map importMap : (List>) objs.get("imports")) { + currentImport = importMap.get("import"); + modelName = currentImport.replace(modelPackage + ".", ""); + + if (reservedWords.contains(modelName)) { + continue; + } + + newImport = new LinkedHashMap(); + newImport.put("import", modelNamespace + "\\" + modelName); + imports.add(newImport); + } + + objs.put("imports", imports); + } + + return objs; } @Override diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 5d84e0541da..5798ef6f882 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -25,6 +25,10 @@ namespace {{apiNamespace}}; use {{invokerNamespace}}\Configuration; use {{invokerNamespace}}\ApiClient; +{{#imports}} +use {{{import}}}; +{{/imports}} + {{#operations}} class {{classname}} { @@ -65,7 +69,7 @@ class {{classname}} { * {{{summary}}} * {{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} -{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} +{{/allParams}} * @return {{#returnType}}{{#isListContainer}}{{returnBaseType}}[]{{/isListContainer}}{{^isListContainer}}{{{returnType}}}{{/isListContainer}}{{/returnType}}{{^returnType}}void{{/returnType}} */ public function {{nickname}}({{#allParams}}${{paramName}}{{#optional}}=null{{/optional}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} @@ -136,6 +140,5 @@ class {{classname}} { return $responseObject;{{/returnType}} } {{/operation}} -{{newline}} -{{/operations}} } +{{/operations}} From 5c409884b95bd4bbdae756d03083c8a90d71038a Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Fri, 19 Jun 2015 10:31:05 -0700 Subject: [PATCH 075/499] make setters fluent --- modules/swagger-codegen/src/main/resources/php/model.mustache | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/php/model.mustache b/modules/swagger-codegen/src/main/resources/php/model.mustache index 7f78311ade4..9e50edcb567 100644 --- a/modules/swagger-codegen/src/main/resources/php/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php/model.mustache @@ -62,9 +62,11 @@ class {{classname}} implements ArrayAccess { /** * set {{name}} * @param {{datatype}} ${{name}} + * @return $this */ public function {{setter}}(${{name}}) { $this->{{name}} = ${{name}}; + return $this; } {{/vars}} public function offsetExists($offset) { From 3252dd0d189f692ec8c49cf8b1eb3e434388a8d8 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Fri, 19 Jun 2015 10:32:38 -0700 Subject: [PATCH 076/499] check for null array in constructor --- .../swagger-codegen/src/main/resources/php/model.mustache | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/model.mustache b/modules/swagger-codegen/src/main/resources/php/model.mustache index 9e50edcb567..86dafc99d99 100644 --- a/modules/swagger-codegen/src/main/resources/php/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php/model.mustache @@ -47,8 +47,10 @@ class {{classname}} implements ArrayAccess { public ${{name}}; {{/vars}} public function __construct(array $data = null) { - {{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}} - {{/hasMore}}{{/vars}} + if ($data != null) { + {{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}} + {{/hasMore}}{{/vars}} + } } {{#vars}} /** From acdc5328fe5da0178024b721846912f08c749751 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Fri, 19 Jun 2015 11:24:56 -0700 Subject: [PATCH 077/499] deserialize thrown exceptions --- .../codegen/languages/PhpClientCodegen.java | 33 +++++++++++-------- .../src/main/resources/php/api.mustache | 25 +++++++++++--- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index ad9ca3aa9b1..073c7ff1c96 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -248,7 +248,26 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public Map postProcessOperations(Map objs) { objs = addNamespaces(super.postProcessOperations(objs)); + objs = formatImports(objs); + return objs; + } + + @Override + public Map postProcessSupportingFileData(Map objs) { + return addNamespaces(super.postProcessSupportingFileData(objs)); + } + + protected Map addNamespaces(Map objs) { + objs.put("rootNamespace", rootNamespace); + objs.put("invokerNamespace", invokerNamespace); + objs.put("apiNamespace", apiNamespace); + objs.put("modelNamespace", modelNamespace); + + return objs; + } + + protected Map formatImports(Map objs) { if (objs.containsKey("imports")) { List> imports = new ArrayList>(); LinkedHashMap newImport; @@ -273,18 +292,4 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return objs; } - - @Override - public Map postProcessSupportingFileData(Map objs) { - return addNamespaces(super.postProcessSupportingFileData(objs)); - } - - protected Map addNamespaces(Map objs) { - objs.put("rootNamespace", rootNamespace); - objs.put("invokerNamespace", invokerNamespace); - objs.put("apiNamespace", apiNamespace); - objs.put("modelNamespace", modelNamespace); - - return objs; - } } diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 5798ef6f882..704f1c5ebab 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -24,6 +24,7 @@ namespace {{apiNamespace}}; use {{invokerNamespace}}\Configuration; use {{invokerNamespace}}\ApiClient; +use {{invokerNamespace}}\ApiException; {{#imports}} use {{{import}}}; @@ -128,16 +129,30 @@ class {{classname}} { $authSettings = array({{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}); // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams, $authSettings); + } catch (ApiException $e) { + $throw = $e; - {{#returnType}}if(! $response) { + switch ($e->getCode()) { {{#responses}}{{#dataType}} + case {{code}}: + $data = $this->apiClient->deserialize($e->getResponseBody(), '{{dataType}}'); + $throw = new ApiException("{{message}}", $e->getCode(), $e->getResponseHeaders(), $data); + break;{{/dataType}}{{/responses}} + } + + throw $throw; + } + {{#returnType}} + if(!$response) { return null; } $responseObject = $this->apiClient->deserialize($response,'{{returnType}}'); - return $responseObject;{{/returnType}} + return $responseObject; + {{/returnType}} } {{/operation}} } From 7a9a41fe01d4c7d1f7bfc53c2c36440913c43e84 Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Fri, 19 Jun 2015 14:06:25 -0700 Subject: [PATCH 078/499] Java and Android template changes to accommodate query params defined by the collection-format. --- .../languages/AndroidClientCodegen.java | 2 + .../codegen/languages/JavaClientCodegen.java | 1 + .../main/resources/Java/ApiClient.mustache | 79 ++++++++++++++++--- .../main/resources/Java/QueryParam.mustache | 38 +++++++++ .../src/main/resources/Java/api.mustache | 9 ++- .../resources/Java/auth/ApiKeyAuth.mustache | 7 +- .../Java/auth/Authentication.mustache | 5 +- .../Java/auth/HttpBasicAuth.mustache | 5 +- .../main/resources/Java/auth/OAuth.mustache | 5 +- .../android-java/QueryParam.mustache | 38 +++++++++ .../main/resources/android-java/api.mustache | 10 ++- .../android-java/apiInvoker.mustache | 78 +++++++++++++++--- .../java/io/swagger/client/ApiInvoker.java | 78 +++++++++++++++--- .../java/io/swagger/client/QueryParam.java | 38 +++++++++ .../java/io/swagger/client/api/PetApi.java | 26 +++--- .../java/io/swagger/client/api/StoreApi.java | 9 ++- .../java/io/swagger/client/api/UserApi.java | 25 +++--- .../java/io/swagger/client/model/Pet.java | 2 +- .../java/io/swagger/client/ApiClient.java | 79 ++++++++++++++++--- .../java/io/swagger/client/QueryParam.java | 38 +++++++++ .../java/io/swagger/client/api/PetApi.java | 29 +++---- .../java/io/swagger/client/api/StoreApi.java | 9 ++- .../java/io/swagger/client/api/UserApi.java | 25 +++--- .../io/swagger/client/auth/ApiKeyAuth.java | 7 +- .../swagger/client/auth/Authentication.java | 5 +- .../io/swagger/client/auth/HttpBasicAuth.java | 5 +- .../java/io/swagger/client/auth/OAuth.java | 5 +- .../java/io/swagger/client/model/Pet.java | 2 +- .../swagger/client/auth/ApiKeyAuthTest.java | 12 ++- .../client/auth/HttpBasicAuthTest.java | 5 +- 30 files changed, 556 insertions(+), 120 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache create mode 100644 samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java create mode 100644 samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java index 9a3237d92ca..2d0af4c6c0b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java @@ -232,6 +232,8 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java")); supportingFiles.add(new SupportingFile("apiException.mustache", (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java")); + supportingFiles.add(new SupportingFile("QueryParam.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "QueryParam.java")); } public Boolean getUseAndroidMavenGradlePlugin() { diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java index fcec455e9b3..0f4e8c212ac 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java @@ -116,6 +116,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java")); supportingFiles.add(new SupportingFile("JsonUtil.mustache", invokerFolder, "JsonUtil.java")); supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java")); + supportingFiles.add(new SupportingFile("QueryParam.mustache", invokerFolder, "QueryParam.java")); final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator); supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java")); diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index 352401ba0d8..59a0ee73281 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -22,6 +22,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; +import java.util.Set; +import java.util.HashSet; import java.util.Date; import java.util.TimeZone; @@ -238,6 +240,61 @@ public class ApiClient { } } + /* + Format to {@code QueryParam} objects. + */ + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } + + if (valueCollection == null) { + params.add(new QueryParam(name, String.valueOf(value))); + return params; + } else if (valueCollection.isEmpty()) { + return params; + } + + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + if (collectionFormat.equals("csv")) { + params.add(new QueryParam(name, parameterToString(value))); + } else if (collectionFormat.equals("multi")) { + for (String item : valueCollection) { + params.add(new QueryParam(name, item)); + } + } else if (collectionFormat.equals("ssv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append(" "); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("tsv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("\t"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("pipes")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("|"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } + + return params; + } + /** * Select the Accept header's value from the given accepts array: * if JSON exists in the given array, use it; @@ -341,23 +398,25 @@ public class ApiClient { * @param authNames The authentications to apply * @return The response body in type of string */ - public String invokeAPI(String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { updateParamsForAuth(authNames, queryParams, headerParams); Client client = getClient(); StringBuilder b = new StringBuilder(); - for(String key : queryParams.keySet()) { - String value = queryParams.get(key); - if (value != null){ - if(b.toString().length() == 0) - b.append("?"); - else + b.append("?"); + if (queryParams != null){ + for (QueryParam queryParam : queryParams){ + if (!queryParam.getName().isEmpty()) { + b.append(escapeString(queryParam.getName())); + b.append("="); + b.append(escapeString(queryParam.getValue())); b.append("&"); - b.append(escapeString(key)).append("=").append(escapeString(value)); + } } } - String querystring = b.toString(); + + String querystring = b.substring(0, b.length() - 1); Builder builder; if (accept == null) @@ -457,7 +516,7 @@ public class ApiClient { * * @param authNames The authentications to apply */ - private void updateParamsForAuth(String[] authNames, Map queryParams, Map headerParams) { + private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { for (String authName : authNames) { Authentication auth = authentications.get(authName); if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); diff --git a/modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache b/modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache new file mode 100644 index 00000000000..23b1b26f55c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache @@ -0,0 +1,38 @@ +package {{invokerPackage}}; + +public class QueryParam { + private String name = ""; + private String value = ""; + + public QueryParam(String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) return; + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) return; + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) return false; + if (arg.trim().isEmpty()) return false; + + return true; + } +} diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache index 63357afd896..66dc25d66bf 100644 --- a/modules/swagger-codegen/src/main/resources/Java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache @@ -3,6 +3,7 @@ package {{package}}; import {{invokerPackage}}.ApiException; import {{invokerPackage}}.ApiClient; import {{invokerPackage}}.Configuration; +import {{invokerPackage}}.QueryParam; import {{modelPackage}}.*; @@ -61,16 +62,16 @@ public class {{classname}} { .replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); - {{#queryParams}}if ({{paramName}} != null) - queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}})); + {{#queryParams}} + queryParams.addAll(apiClient.parameterToQueryParams("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); {{/queryParams}} {{#headerParams}}if ({{paramName}} != null) - headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}})); + headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}})); {{/headerParams}} final String[] accepts = { diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache index 65720b958cb..46fa51087b6 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache @@ -1,6 +1,9 @@ package {{invokerPackage}}.auth; +import {{invokerPackage}}.QueryParam; + import java.util.Map; +import java.util.Set; public class ApiKeyAuth implements Authentication { private final String location; @@ -39,7 +42,7 @@ public class ApiKeyAuth implements Authentication { } @Override - public void applyToParams(Map queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; @@ -47,7 +50,7 @@ public class ApiKeyAuth implements Authentication { value = apiKey; } if (location == "query") { - queryParams.put(paramName, value); + queryParams.add(new QueryParam(paramName, value)); } else if (location == "header") { headerParams.put(paramName, value); } diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache index 1b2e2bc2fbe..1f39a402b2c 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache @@ -1,8 +1,11 @@ package {{invokerPackage}}.auth; +import {{invokerPackage}}.QueryParam; + import java.util.Map; +import java.util.Set; public interface Authentication { /** Apply authentication settings to header and query params. */ - void applyToParams(Map queryParams, Map headerParams); + void applyToParams(Set queryParams, Map headerParams); } diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache index 22a64b1a24e..b5bc993f7c4 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache @@ -1,6 +1,9 @@ package {{invokerPackage}}.auth; +import {{invokerPackage}}.QueryParam; + import java.util.Map; +import java.util.Set; import java.io.UnsupportedEncodingException; import javax.xml.bind.DatatypeConverter; @@ -26,7 +29,7 @@ public class HttpBasicAuth implements Authentication { } @Override - public void applyToParams(Map queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); try { headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"))); diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache index ef84b8cc05e..ab634489eda 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache @@ -1,10 +1,13 @@ package {{invokerPackage}}.auth; +import {{invokerPackage}}.QueryParam; + import java.util.Map; +import java.util.Set; public class OAuth implements Authentication { @Override - public void applyToParams(Map queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { // TODO: support oauth } } diff --git a/modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache b/modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache new file mode 100644 index 00000000000..23b1b26f55c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache @@ -0,0 +1,38 @@ +package {{invokerPackage}}; + +public class QueryParam { + private String name = ""; + private String value = ""; + + public QueryParam(String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) return; + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) return; + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) return false; + if (arg.trim().isEmpty()) return false; + + return true; + } +} diff --git a/modules/swagger-codegen/src/main/resources/android-java/api.mustache b/modules/swagger-codegen/src/main/resources/android-java/api.mustache index ed9538c1594..6e34a898ad0 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/api.mustache @@ -2,6 +2,7 @@ package {{package}}; import {{invokerPackage}}.ApiException; import {{invokerPackage}}.ApiInvoker; +import {{invokerPackage}}.QueryParam; import {{modelPackage}}.*; @@ -58,17 +59,18 @@ public class {{classname}} { String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params Map formParams = new HashMap(); - {{#queryParams}}if ({{paramName}} != null) - queryParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}})); + {{#queryParams}} + queryParams.addAll(ApiInvoker.parameterToQueryParams("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); {{/queryParams}} - {{#headerParams}}headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}})); + {{#headerParams}} + headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}})); {{/headerParams}} String[] contentTypes = { diff --git a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache index e759f8264a4..d7a9d8b357c 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache @@ -23,6 +23,8 @@ import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.List; +import java.util.Set; +import java.util.HashSet; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -132,6 +134,61 @@ public class ApiInvoker { } } + /* + Format to {@code QueryParam} objects. + */ + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } + + if (valueCollection == null) { + params.add(new QueryParam(name, String.valueOf(value))); + return params; + } else if (valueCollection.isEmpty()) { + return params; + } + + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + if (collectionFormat.equals("csv")) { + params.add(new QueryParam(name, parameterToString(value))); + } else if (collectionFormat.equals("multi")) { + for (String item : valueCollection) { + params.add(new QueryParam(name, item)); + } + } else if (collectionFormat.equals("ssv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append(" "); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("tsv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("\t"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("pipes")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("|"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } + + return params; + } + public ApiInvoker() { initConnectionManager(); } @@ -184,21 +241,24 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { HttpClient client = getClient(host); StringBuilder b = new StringBuilder(); - for(String key : queryParams.keySet()) { - String value = queryParams.get(key); - if (value != null){ - if(b.toString().length() == 0) - b.append("?"); - else + b.append("?"); + if (queryParams != null){ + for (QueryParam queryParam : queryParams){ + if (!queryParam.getName().isEmpty()) { + b.append(escapeString(queryParam.getName())); + b.append("="); + b.append(escapeString(queryParam.getValue())); b.append("&"); - b.append(escapeString(key)).append("=").append(escapeString(value)); + } } } - String url = host + path + b.toString(); + + String querystring = b.substring(0, b.length() - 1); + String url = host + path + querystring; HashMap headers = new HashMap(); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java index ec6218e602c..58ecbde38c6 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java @@ -23,6 +23,8 @@ import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.List; +import java.util.Set; +import java.util.HashSet; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -132,6 +134,61 @@ public class ApiInvoker { } } + /* + Format to {@code QueryParam} objects. + */ + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } + + if (valueCollection == null) { + params.add(new QueryParam(name, String.valueOf(value))); + return params; + } else if (valueCollection.isEmpty()) { + return params; + } + + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + if (collectionFormat.equals("csv")) { + params.add(new QueryParam(name, parameterToString(value))); + } else if (collectionFormat.equals("multi")) { + for (String item : valueCollection) { + params.add(new QueryParam(name, item)); + } + } else if (collectionFormat.equals("ssv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append(" "); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("tsv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("\t"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("pipes")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("|"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } + + return params; + } + public ApiInvoker() { initConnectionManager(); } @@ -184,21 +241,24 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { HttpClient client = getClient(host); StringBuilder b = new StringBuilder(); - for(String key : queryParams.keySet()) { - String value = queryParams.get(key); - if (value != null){ - if(b.toString().length() == 0) - b.append("?"); - else + b.append("?"); + if (queryParams != null){ + for (QueryParam queryParam : queryParams){ + if (!queryParam.getName().isEmpty()) { + b.append(escapeString(queryParam.getName())); + b.append("="); + b.append(escapeString(queryParam.getValue())); b.append("&"); - b.append(escapeString(key)).append("=").append(escapeString(value)); + } } } - String url = host + path + b.toString(); + + String querystring = b.substring(0, b.length() - 1); + String url = host + path + querystring; HashMap headers = new HashMap(); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java new file mode 100644 index 00000000000..240352e890f --- /dev/null +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java @@ -0,0 +1,38 @@ +package io.swagger.client; + +public class QueryParam { + private String name = ""; + private String value = ""; + + public QueryParam(String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) return; + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) return; + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) return false; + if (arg.trim().isEmpty()) return false; + + return true; + } +} diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java index ebf600d787e..db10c57f112 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java @@ -2,6 +2,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiInvoker; +import io.swagger.client.QueryParam; import io.swagger.client.model.*; @@ -52,7 +53,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -106,7 +107,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -160,14 +161,14 @@ public class PetApi { String path = "/pet/findByStatus".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params Map formParams = new HashMap(); - if (status != null) - queryParams.put("status", ApiInvoker.parameterToString(status)); + + queryParams.addAll(ApiInvoker.parameterToQueryParams("multi", "status", status)); @@ -216,14 +217,14 @@ public class PetApi { String path = "/pet/findByTags".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params Map formParams = new HashMap(); - if (tags != null) - queryParams.put("tags", ApiInvoker.parameterToString(tags)); + + queryParams.addAll(ApiInvoker.parameterToQueryParams("multi", "tags", tags)); @@ -277,7 +278,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -338,7 +339,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -408,7 +409,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -416,6 +417,7 @@ public class PetApi { + headerParams.put("api_key", ApiInvoker.parameterToString(apiKey)); @@ -470,7 +472,7 @@ public class PetApi { String path = "/pet/{petId}/uploadImage".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java index ecd8e833049..e8d50c30df7 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java @@ -2,6 +2,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiInvoker; +import io.swagger.client.QueryParam; import io.swagger.client.model.*; @@ -51,7 +52,7 @@ public class StoreApi { String path = "/store/inventory".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -105,7 +106,7 @@ public class StoreApi { String path = "/store/order".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -164,7 +165,7 @@ public class StoreApi { String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -223,7 +224,7 @@ public class StoreApi { String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java index e1df3fd4f12..d7505874940 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java @@ -2,6 +2,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiInvoker; +import io.swagger.client.QueryParam; import io.swagger.client.model.*; @@ -52,7 +53,7 @@ public class UserApi { String path = "/user".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -106,7 +107,7 @@ public class UserApi { String path = "/user/createWithArray".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -160,7 +161,7 @@ public class UserApi { String path = "/user/createWithList".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -215,16 +216,16 @@ public class UserApi { String path = "/user/login".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params Map formParams = new HashMap(); - if (username != null) - queryParams.put("username", ApiInvoker.parameterToString(username)); - if (password != null) - queryParams.put("password", ApiInvoker.parameterToString(password)); + + queryParams.addAll(ApiInvoker.parameterToQueryParams("", "username", username)); + + queryParams.addAll(ApiInvoker.parameterToQueryParams("", "password", password)); @@ -272,7 +273,7 @@ public class UserApi { String path = "/user/logout".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -331,7 +332,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -391,7 +392,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -450,7 +451,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java index 26219b16a45..90a840e6e42 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import java.util.*; import io.swagger.client.model.Tag; +import java.util.*; import io.swagger.annotations.*; import com.google.gson.annotations.SerializedName; diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index 0adcbe7031d..dd14a1c2454 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -22,6 +22,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; +import java.util.Set; +import java.util.HashSet; import java.util.Date; import java.util.TimeZone; @@ -237,6 +239,61 @@ public class ApiClient { } } + /* + Format to {@code QueryParam} objects. + */ + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } + + if (valueCollection == null) { + params.add(new QueryParam(name, String.valueOf(value))); + return params; + } else if (valueCollection.isEmpty()) { + return params; + } + + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + if (collectionFormat.equals("csv")) { + params.add(new QueryParam(name, parameterToString(value))); + } else if (collectionFormat.equals("multi")) { + for (String item : valueCollection) { + params.add(new QueryParam(name, item)); + } + } else if (collectionFormat.equals("ssv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append(" "); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("tsv")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("\t"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } else if (collectionFormat.equals("pipes")) { + StringBuilder sb = new StringBuilder() ; + for (String item : valueCollection) { + sb.append("|"); + sb.append(item); + } + params.add(new QueryParam(name, sb.substring(1))); + } + + return params; + } + /** * Select the Accept header's value from the given accepts array: * if JSON exists in the given array, use it; @@ -340,23 +397,25 @@ public class ApiClient { * @param authNames The authentications to apply * @return The response body in type of string */ - public String invokeAPI(String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { updateParamsForAuth(authNames, queryParams, headerParams); Client client = getClient(); StringBuilder b = new StringBuilder(); - for(String key : queryParams.keySet()) { - String value = queryParams.get(key); - if (value != null){ - if(b.toString().length() == 0) - b.append("?"); - else + b.append("?"); + if (queryParams != null){ + for (QueryParam queryParam : queryParams){ + if (!queryParam.getName().isEmpty()) { + b.append(escapeString(queryParam.getName())); + b.append("="); + b.append(escapeString(queryParam.getValue())); b.append("&"); - b.append(escapeString(key)).append("=").append(escapeString(value)); + } } } - String querystring = b.toString(); + + String querystring = b.substring(0, b.length() - 1); Builder builder; if (accept == null) @@ -456,7 +515,7 @@ public class ApiClient { * * @param authNames The authentications to apply */ - private void updateParamsForAuth(String[] authNames, Map queryParams, Map headerParams) { + private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { for (String authName : authNames) { Authentication auth = authentications.get(authName); if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java b/samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java new file mode 100644 index 00000000000..240352e890f --- /dev/null +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java @@ -0,0 +1,38 @@ +package io.swagger.client; + +public class QueryParam { + private String name = ""; + private String value = ""; + + public QueryParam(String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) return; + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) return; + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) return false; + if (arg.trim().isEmpty()) return false; + + return true; + } +} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index c102cf00b51..3fc9bd267e4 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -3,6 +3,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiClient; import io.swagger.client.Configuration; +import io.swagger.client.QueryParam; import io.swagger.client.model.*; @@ -54,7 +55,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -111,7 +112,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -168,12 +169,12 @@ public class PetApi { String path = "/pet/findByStatus".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); - if (status != null) - queryParams.put("status", apiClient.parameterToString(status)); + + queryParams.addAll(apiClient.parameterToQueryParams("multi", "status", status)); @@ -227,12 +228,12 @@ public class PetApi { String path = "/pet/findByTags".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); - if (tags != null) - queryParams.put("tags", apiClient.parameterToString(tags)); + + queryParams.addAll(apiClient.parameterToQueryParams("multi", "tags", tags)); @@ -292,7 +293,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -322,7 +323,7 @@ public class PetApi { } try { - String[] authNames = new String[] { "petstore_auth", "api_key" }; + String[] authNames = new String[] { "api_key", "petstore_auth" }; String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); if(response != null){ return (Pet) apiClient.deserialize(response, "", Pet.class); @@ -357,7 +358,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -435,14 +436,14 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); if (apiKey != null) - headerParams.put("api_key", apiClient.parameterToString(apiKey)); + headerParams.put("api_key", apiClient.parameterToString(apiKey)); final String[] accepts = { @@ -502,7 +503,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java index 727e791c603..f15b7140a5c 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java @@ -3,6 +3,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiClient; import io.swagger.client.Configuration; +import io.swagger.client.QueryParam; import io.swagger.client.model.*; @@ -53,7 +54,7 @@ public class StoreApi { String path = "/store/inventory".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -110,7 +111,7 @@ public class StoreApi { String path = "/store/order".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -173,7 +174,7 @@ public class StoreApi { .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -236,7 +237,7 @@ public class StoreApi { .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java index 9e55bbed590..a0c977c7256 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java @@ -3,6 +3,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiClient; import io.swagger.client.Configuration; +import io.swagger.client.QueryParam; import io.swagger.client.model.*; @@ -54,7 +55,7 @@ public class UserApi { String path = "/user".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -111,7 +112,7 @@ public class UserApi { String path = "/user/createWithArray".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -168,7 +169,7 @@ public class UserApi { String path = "/user/createWithList".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -226,14 +227,14 @@ public class UserApi { String path = "/user/login".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); - if (username != null) - queryParams.put("username", apiClient.parameterToString(username)); - if (password != null) - queryParams.put("password", apiClient.parameterToString(password)); + + queryParams.addAll(apiClient.parameterToQueryParams("", "username", username)); + + queryParams.addAll(apiClient.parameterToQueryParams("", "password", password)); @@ -286,7 +287,7 @@ public class UserApi { String path = "/user/logout".replaceAll("\\{format\\}","json"); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -349,7 +350,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -413,7 +414,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -476,7 +477,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java index ce55babb51d..d72432ce2e9 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java @@ -1,6 +1,9 @@ package io.swagger.client.auth; +import io.swagger.client.QueryParam; + import java.util.Map; +import java.util.Set; public class ApiKeyAuth implements Authentication { private final String location; @@ -39,7 +42,7 @@ public class ApiKeyAuth implements Authentication { } @Override - public void applyToParams(Map queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; @@ -47,7 +50,7 @@ public class ApiKeyAuth implements Authentication { value = apiKey; } if (location == "query") { - queryParams.put(paramName, value); + queryParams.add(new QueryParam(paramName, value)); } else if (location == "header") { headerParams.put(paramName, value); } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java index 3f372404c8d..4f661852f34 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java @@ -1,8 +1,11 @@ package io.swagger.client.auth; +import io.swagger.client.QueryParam; + import java.util.Map; +import java.util.Set; public interface Authentication { /** Apply authentication settings to header and query params. */ - void applyToParams(Map queryParams, Map headerParams); + void applyToParams(Set queryParams, Map headerParams); } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java index 24bff8c2266..4beaee8b675 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java @@ -1,6 +1,9 @@ package io.swagger.client.auth; +import io.swagger.client.QueryParam; + import java.util.Map; +import java.util.Set; import java.io.UnsupportedEncodingException; import javax.xml.bind.DatatypeConverter; @@ -26,7 +29,7 @@ public class HttpBasicAuth implements Authentication { } @Override - public void applyToParams(Map queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); try { headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"))); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java index d834f4580c2..b754567564f 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java @@ -1,10 +1,13 @@ package io.swagger.client.auth; +import io.swagger.client.QueryParam; + import java.util.Map; +import java.util.Set; public class OAuth implements Authentication { @Override - public void applyToParams(Map queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { // TODO: support oauth } } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java index ddd0e1038c0..cf7ace02309 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import java.util.*; import io.swagger.client.model.Tag; +import java.util.*; import io.swagger.annotations.*; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java index 0a0bf57da61..e99f310f94f 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java @@ -1,8 +1,11 @@ package io.swagger.client.auth; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import io.swagger.client.QueryParam; import org.junit.*; import static org.junit.Assert.*; @@ -10,7 +13,7 @@ import static org.junit.Assert.*; public class ApiKeyAuthTest { @Test public void testApplyToParamsInQuery() { - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); ApiKeyAuth auth = new ApiKeyAuth("query", "api_key"); @@ -18,14 +21,17 @@ public class ApiKeyAuthTest { auth.applyToParams(queryParams, headerParams); assertEquals(1, queryParams.size()); - assertEquals("my-api-key", queryParams.get("api_key")); + for (QueryParam queryParam : queryParams) { + assertEquals("my-api-key", queryParam.getValue()); + } + // no changes to header parameters assertEquals(0, headerParams.size()); } @Test public void testApplyToParamsInHeaderWithPrefix() { - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); ApiKeyAuth auth = new ApiKeyAuth("header", "X-API-TOKEN"); diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java index a621cb60e48..5125abce49b 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java @@ -1,8 +1,11 @@ package io.swagger.client.auth; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import io.swagger.client.QueryParam; import org.junit.*; import static org.junit.Assert.*; @@ -17,7 +20,7 @@ public class HttpBasicAuthTest { @Test public void testApplyToParams() { - Map queryParams = new HashMap(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); auth.setUsername("my-username"); From caa1b7f4111ea2bf4ffafdb5244bc364cece0442 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Fri, 19 Jun 2015 15:20:29 -0700 Subject: [PATCH 079/499] generate model imports for support files, and use them as imports --- .../codegen/languages/PhpClientCodegen.java | 27 +++++++++---------- .../src/main/resources/php/ApiClient.mustache | 5 +++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 073c7ff1c96..7fb23157b36 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -248,14 +248,17 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public Map postProcessOperations(Map objs) { objs = addNamespaces(super.postProcessOperations(objs)); - objs = formatImports(objs); + objs = formatImports(objs, "imports", "import"); return objs; } @Override public Map postProcessSupportingFileData(Map objs) { - return addNamespaces(super.postProcessSupportingFileData(objs)); + objs = addNamespaces(super.postProcessSupportingFileData(objs)); + objs = formatImports(objs, "models", "importPath"); + + return objs; } protected Map addNamespaces(Map objs) { @@ -267,27 +270,23 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return objs; } - protected Map formatImports(Map objs) { - if (objs.containsKey("imports")) { - List> imports = new ArrayList>(); - LinkedHashMap newImport; - String currentImport; + protected Map formatImports(Map objs, String objsKey, String importKey) { + if (objs.containsKey(objsKey)) { String modelName; + List> newImportList = new ArrayList>(); - for (Map importMap : (List>) objs.get("imports")) { - currentImport = importMap.get("import"); - modelName = currentImport.replace(modelPackage + ".", ""); + for (Map importMap : (List>) objs.get(objsKey)) { + modelName = ((String) importMap.get(importKey)).replace(modelPackage + ".", ""); if (reservedWords.contains(modelName)) { continue; } - newImport = new LinkedHashMap(); - newImport.put("import", modelNamespace + "\\" + modelName); - imports.add(newImport); + importMap.put(importKey, modelNamespace + "\\" + modelName); + newImportList.add(importMap); } - objs.put("imports", imports); + objs.put(objsKey, newImportList); } return objs; diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 564bc1ddd66..4a3e50dd50b 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -17,6 +17,10 @@ namespace {{invokerNamespace}}; +{{#models}} +use {{importPath}}; +{{/models}} + class ApiClient { public static $PATCH = "PATCH"; @@ -399,7 +403,6 @@ class ApiClient { settype($data, $class); $deserialized = $data; } else { - $class = "{{invokerPackage}}\\models\\".$class; $instance = new $class(); foreach ($instance::$swaggerTypes as $property => $type) { $original_property_name = $instance::$attributeMap[$property]; From 1d59937150c5b79d192487fd2e9c7d007e4994f6 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 22 Jun 2015 11:53:44 +0800 Subject: [PATCH 080/499] add nunit test for csharp --- bin/csharp-petstore.sh | 2 +- .../SwaggerClient}/bin/Newtonsoft.Json.dll | Bin .../Lib/SwaggerClient}/bin/RestSharp.dll | Bin .../Lib/SwaggerClient}/compile.bat | 0 .../src/main/csharp/IO/Swagger}/Api/PetApi.cs | 0 .../main/csharp/IO/Swagger}/Api/StoreApi.cs | 0 .../main/csharp/IO/Swagger}/Api/UserApi.cs | 0 .../csharp/IO/Swagger/Client}/ApiClient.cs | 0 .../csharp/IO/Swagger/Client}/ApiException.cs | 0 .../IO/Swagger/Client}/Configuration.cs | 0 .../main/csharp/IO/Swagger}/Model/Category.cs | 0 .../main/csharp/IO/Swagger}/Model/Order.cs | 0 .../src/main/csharp/IO/Swagger}/Model/Pet.cs | 0 .../src/main/csharp/IO/Swagger}/Model/Tag.cs | 0 .../src/main/csharp/IO/Swagger}/Model/User.cs | 0 .../SwaggerClientTest.csproj | 68 + .../SwaggerClientTest/SwaggerClientTest.sln | 17 + .../SwaggerClientTest.userprefs | 13 + .../csharp/SwaggerClientTest/TestPet.cs | 109 + .../bin/Debug/Newtonsoft.Json.dll | Bin 0 -> 426496 bytes .../SwaggerClientTest/bin/Debug/RestSharp.dll | Bin 0 -> 167936 bytes .../bin/Debug/SwaggerClientTest.dll | Bin 0 -> 51200 bytes .../bin/Debug/SwaggerClientTest.dll.mdb | Bin 0 -> 15782 bytes .../bin/Debug/nunit.framework.dll | Bin 0 -> 151552 bytes ...ramework,Version=v4.5.AssemblyAttribute.cs | 2 + ...ClientTest.csproj.FilesWrittenAbsolute.txt | 8 + .../obj/Debug/SwaggerClientTest.dll | Bin 0 -> 51200 bytes .../obj/Debug/SwaggerClientTest.dll.mdb | Bin 0 -> 15782 bytes .../csharp/SwaggerClientTest/packages.config | 4 + .../packages/NUnit.2.6.3/NUnit.2.6.3.nupkg | Bin 0 -> 98508 bytes .../NUnit.2.6.3/lib/nunit.framework.dll | Bin 0 -> 151552 bytes .../NUnit.2.6.3/lib/nunit.framework.xml | 10960 ++++++++++++++++ .../packages/NUnit.2.6.3/license.txt | 15 + .../packages/repositories.config | 4 + 34 files changed, 11201 insertions(+), 1 deletion(-) rename samples/client/petstore/csharp/{ => SwaggerClientTest/Lib/SwaggerClient}/bin/Newtonsoft.Json.dll (100%) rename samples/client/petstore/csharp/{ => SwaggerClientTest/Lib/SwaggerClient}/bin/RestSharp.dll (100%) rename samples/client/petstore/csharp/{ => SwaggerClientTest/Lib/SwaggerClient}/compile.bat (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Api/PetApi.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Api/StoreApi.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Api/UserApi.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger/client => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client}/ApiClient.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger/client => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client}/ApiException.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger/client => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client}/Configuration.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Model/Category.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Model/Order.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Model/Pet.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Model/Tag.cs (100%) rename samples/client/petstore/csharp/{src/main/csharp/io/swagger => SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger}/Model/User.cs (100%) create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.sln create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/Newtonsoft.Json.dll create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/RestSharp.dll create mode 100755 samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/nunit.framework.dll create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttribute.cs create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt create mode 100755 samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/packages.config create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/NUnit.2.6.3.nupkg create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/lib/nunit.framework.dll create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/lib/nunit.framework.xml create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/license.txt create mode 100644 samples/client/petstore/csharp/SwaggerClientTest/packages/repositories.config diff --git a/bin/csharp-petstore.sh b/bin/csharp-petstore.sh index a72a6cf84f0..c3fe78f0f36 100755 --- a/bin/csharp-petstore.sh +++ b/bin/csharp-petstore.sh @@ -26,6 +26,6 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l csharp -o samples/client/petstore/csharp" +ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l csharp -o samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient" java $JAVA_OPTS -jar $executable $ags diff --git a/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/bin/Newtonsoft.Json.dll similarity index 100% rename from samples/client/petstore/csharp/bin/Newtonsoft.Json.dll rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/bin/Newtonsoft.Json.dll diff --git a/samples/client/petstore/csharp/bin/RestSharp.dll b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/bin/RestSharp.dll similarity index 100% rename from samples/client/petstore/csharp/bin/RestSharp.dll rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/bin/RestSharp.dll diff --git a/samples/client/petstore/csharp/compile.bat b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/compile.bat similarity index 100% rename from samples/client/petstore/csharp/compile.bat rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/compile.bat diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/PetApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/PetApi.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/StoreApi.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/UserApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/UserApi.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiClient.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiClient.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiException.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiException.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiException.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiException.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Category.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Category.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Order.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Order.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Pet.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Pet.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Tag.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/Tag.cs diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/User.cs similarity index 100% rename from samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs rename to samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Model/User.cs diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj new file mode 100644 index 00000000000..7a0b8f7674b --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj @@ -0,0 +1,68 @@ + + + + Debug + AnyCPU + {1011E844-3414-4D65-BF1F-7C8CE0167174} + Library + SwaggerClientTest + SwaggerClientTest + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + packages\NUnit.2.6.3\lib\nunit.framework.dll + + + Lib\SwaggerClient\bin\Newtonsoft.Json.dll + + + Lib\SwaggerClient\bin\RestSharp.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.sln b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.sln new file mode 100644 index 00000000000..dfb6e762ce2 --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.sln @@ -0,0 +1,17 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SwaggerClientTest", "SwaggerClientTest.csproj", "{1011E844-3414-4D65-BF1F-7C8CE0167174}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1011E844-3414-4D65-BF1F-7C8CE0167174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1011E844-3414-4D65-BF1F-7C8CE0167174}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1011E844-3414-4D65-BF1F-7C8CE0167174}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1011E844-3414-4D65-BF1F-7C8CE0167174}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs new file mode 100644 index 00000000000..4fa44c936ae --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs b/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs new file mode 100644 index 00000000000..8e6ea0f99d2 --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs @@ -0,0 +1,109 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using IO.Swagger.Api; +using IO.Swagger.Model; +using IO.Swagger.Client; + + +namespace SwaggerClient.TestPet +{ + [TestFixture ()] + public class TestPet + { + public long petId = 11088; + + [SetUp] public void Init() + { + // create pet + Pet p = new Pet(); + p.Id = petId; + p.Name = "Csharp test"; + p.Status = "available"; + // create Category object + Category category = new Category(); + category.Id = 56; + category.Name = "sample category name2"; + List photoUrls = new List(new String[] {"sample photoUrls"}); + // create Tag object + Tag tag = new Tag(); + tag.Id = petId; + tag.Name = "sample tag name1"; + List tags = new List(new Tag[] {tag}); + p.Tags = tags; + p.Category = category; + p.PhotoUrls = photoUrls; + + // add pet before testing + PetApi petApi = new PetApi("http://petstore.swagger.io/v2/"); + petApi.AddPet (p); + + } + + [TearDown] public void Cleanup() + { + // remove the pet after testing + PetApi petApi = new PetApi (); + petApi.DeletePet("test key", petId); + } + + + [Test ()] + public void TestGetPetById () + { + PetApi petApi = new PetApi (); + Pet response = petApi.GetPetById (petId); + Assert.IsInstanceOf (response, "Response is a Pet"); + + Assert.AreEqual ("Csharp test", response.Name); + Assert.AreEqual ("available", response.Status); + + Assert.IsInstanceOf> (response.Tags, "Response.Tags is a Array"); + Assert.AreEqual (petId, response.Tags [0].Id); + Assert.AreEqual ("sample tag name1", response.Tags [0].Name); + + Assert.IsInstanceOf> (response.PhotoUrls, "Response.PhotoUrls is a Array"); + Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]); + + Assert.IsInstanceOf (response.Category, "Response.Category is a Category"); + Assert.AreEqual (56, response.Category.Id); + Assert.AreEqual ("sample category name2", response.Category.Name); + + } + + [Test ()] + public void TestUpdatePetWithForm () + { + PetApi petApi = new PetApi (); + petApi.UpdatePetWithForm (petId.ToString(), "new form name", "pending"); + + Pet response = petApi.GetPetById (petId); + Assert.IsInstanceOf (response, "Response is a Pet"); + Assert.IsInstanceOf (response.Category, "Response.Category is a Category"); + Assert.IsInstanceOf> (response.Tags, "Response.Tags is a Array"); + + Assert.AreEqual ("new form name", response.Name); + Assert.AreEqual ("pending", response.Status); + + Assert.AreEqual (petId, response.Tags [0].Id); + Assert.AreEqual (56, response.Category.Id); + } + + [Test ()] + public void TestFindPetByStatus () + { + PetApi petApi = new PetApi (); + List statusList = new List(new String[] {"available"}); + + List listPet = petApi.FindPetsByStatus (statusList); + foreach (Pet pet in listPet) // Loop through List with foreach. + { + Assert.IsInstanceOf (pet, "Response is a Pet"); + Assert.AreEqual ("available", pet.Status); + } + + } + + } +} + diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/Newtonsoft.Json.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/Newtonsoft.Json.dll new file mode 100644 index 0000000000000000000000000000000000000000..26fdaffec145b1795af118d07ef764406d78f6f8 GIT binary patch literal 426496 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

BWZ_eV|^M^miQ6%*;qfy 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ΝZNt?r4^ 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 We5D(VilUEh|3}=%-*#gGP_xT_I literal 0 HcmV?d00001 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/RestSharp.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/RestSharp.dll new file mode 100644 index 0000000000000000000000000000000000000000..a7331ed6e2379bbb0b9680ff82d86ce4cb1b03bc GIT binary patch literal 167936 zcmb@P37lM2mH(^XtA17Ws=Jfw>Qr|Y(j6e-QB~b!k(dMsVHHr>R1Ca^dL`LWH&nI2)+}}NS zJNMjs&t2Yq&phSEoS)0(^87vVL@xILPyO3qzfb-%gZIGb#|CmAEd9%p2YR0IFH4?% z;YIDSOIz^;t+QS*cFtLsToP{{JNvw`)@7HBU3AIV;m18|>;>_;=S}qYhkGYcAAdwH z_lzDt*ZZnNo|C5bc+Oi=?kVSTukdoYz@ew#3q1z?X`Z>G`4@2?)#aYpeBKqC zai4o_QZAJ>$#=>|kTWM*?bbN}mN)Wf1-&lIxFMI@Fwr{i;uuEdHAkK;t{ZmYJ5=7? z|29aj{8Qe%TyO69-k#hm?&!(&82XR@RF~&-PazoLD_%4|mkXl>{Iqai>gS_{&@plh zqdoWuy;cQ0h!*3Rf+b%+#*3fj=YrN!@P+Xhc>OQ=I0Tv|qxtd5(2jt*4%$obnh|7p zMBv7FHE-d(Nkuh39w*eY`bsa_3*M+esQNn3&$rRN#MyFL^vBDsLrAbqs^J#TpF$Dx z_0@TAQbatTcN_r%)>fZh}^0sv)o97X_;r~`}uKqnkv1VAYTi~tBzzz6^u zf(v2<0CnsDBLMnSzzBeW6fgo{P6`+SK$CEB7y&>*M z)MC;Pc#w!5#1s^~ct{UFt~rpvK_Lw43Qx>xofXfI_5luqyec>d>frJ}l;=Mde?A^j z{Jk+c78Hi#G&RMS&ykZPy?k%9ucbJUm-dn5-}c|LZtsMhBJe zWqQodY69|en+EVLHub)qe?;i zprcWmApWGIX~99vD50>l;UIpOqen%5*wM7jApV%6hef~N(R2qv{6R{w;|QW$m^V=h zYK0g@48wffN7=4N2%fRUR8`pD{%>Ng=JT+`A+ooUuk>2i%Hui2Y00+FCVc!$e&E{=zVWYa@2iB( z0!}I+d@SjDX-O`P;F1(GbdBn!JuvTwGCeWcfyDI)!qOK){2Jwem@=}NDk^!i3K2zU{D>X3>-nDv~ij;r<{4?<^Gae zv$Cg;GJwCJXa74>`ujcm4|)k+_Lm>v8;wn&ChOa8j6Q|+oX>c}kZ=FG8~jSo}G+gMq)&dV_2U^aukdW>`=9l6ug(8;{{v!`4#`DnTvreK9O|R)Xk6o-qOq zm-*9-Yfivx0Neb8GlC3{e+E`7`_uHNj%lr!tQG_rZnY3m;f=mxypHhILgTo>LWG`$ z{e|I;S8w9dS7-n#y0S@h2NA{iecJ~H z3p;9bK?_~gx!#3Nr&nWp&s^2ht+`YGm>ZD57dxv9W6TUh3@V22yeuqxVqryOIH;eP zZ~ZHI@|5RbI5Fo|dw#2@CwFPIK`fgRUN7H5`j`6Adh#>1P|-b!CCR|<G<7hrxGU@%F!7H%(i(x~vUpe{X8mw4~J z5~1{DQpwa8w4cRe3vJBH?Fk-s$`%I0CtJrxld>sGUC}Ao$LguxjpV!qF20p6zUyg7 z3+r1t%4ag3t%oU9L;aFeG*u#jvQTUWpqdT*V63(td6{h!Kn>NI|= z{!fRX{{7rXiO8fh1lIMxmgj~1t+|083TQD7yN5Tah^Efq2faI!N8>qEwz((e z+&XoZ{Jcp$E|U!J*3T3sgit-E=-8zdiWjX|jaFC^o<%Uc(V}$@7xN7lt-Q^P&V}76 z!g)|A0=Y|d;r{zOx}eBAx}Z83h0p1NQrT4(T+B=WClz$(YPXzqRl6k4?9NH0GhZ2S zb$q@h;7wh?)AA=>Y?A&Q)o+YY!*XMw5MLxdKZrN+EVxna-?oQ^W>9b)qv^Oukrpgb z)}4JG@kI42e*ApJQ|oKg3dOCV7ZB0KAn^uq*xF5*0c3;(vu8y>%EbPa)?1zzrcTON_xbz5!At$zbP7 zwqKFypm`F~I*?Cbismr~^4()fsvBNzIQO*Eojss_nTDBT{Hb`?ldHt0CXZ-EYhM+n z1&s;5+zaYKp|wg-8_4Q;AHvdsRJ^5Ob1Y~*70(FyhU0UB*3&zVd?R10k1z$XHmkNh zL>OD$@N7v#^?sQpV~ZP1H=@fG%fjS|p1cV6^cDPA{LCAM(N2G1^kSeI^P6;JTJrkNCz+qotJ$+RB^JLH>TXiqBMfB|1?6wwr}`s!$!2dz$y}K{uX4}!%M$k?~ZQRO^5e%w~p$;%&8B^|v-aDupbwLtpuawCMLhYRbMgS~L0V4pY z7#FV*0Q;nX5!PHaD zU8ILuS7}oz;miSKD7r-yV{YEGeC8mig|9{cJ?Km81!&lvh2hoMPb-R|+f+w_a(_k=9N2oZot*Jr}gzYR{R23AEtVY9QgX(huS{kd>eo z-O8i=MrCUqF#T(gdmj0wEmlV7y7p1)n^xwR_78f|Ryb?r#xgpxw-fWU0@aL+Z^J8o zlYVaJ=XUGX1G?^SY!8dgpcK6s^s%7*79RD)E)R1Xj&WnrM05vuME@lFrAK3%##q|? zSwK?bw^}&qB>B&cnctOQZn8t37EVht1xA|Uw2E8U8sCY(8(++i%zQ5yN7CNz5pU@v zqRO}aKxzC4)1@&!FsCQFOSw6Pq#K3QH3KvyUe}KNoSsWmzh_yW*xKUdE;R;^Zt-k& zi+3xQkT?TNga8^Z77z~gr))1#*@D(f2x#M8gjJ1B){jgUdg!w+jgAMa-{2)P#VxpE zYh}r7(Ew|2+q>tQ(LJO+KIoWyH?b5{--QWz`?*Q-L~E;f?faPg)??8-C-XZ& zhTHtEj9u|_{FVjNhorn$i}zkqnGs}ogr(XDrVmY7=s1%(r69v?PKjlsy8S-+ppjR+ zq3Ay1X_i|v2*)jsJA0$WZpEd^G?7Uj6WO=JcxR<|*o)ucsOUrzDYxDPV`j$tPQ0&2 zUOnlI7n?zWTlc_e!(tOeT%*VD=xOxS`V;^AJN|Q=|JcWSayesR)>=pni*byVX2JBJ z(Nj!NPpgz+;&6iyWmJEC8c+JKjvXbN!KuNsm482aE)NZ+fd*-38AbBy%SY6gL;E|) zrwNuaX-#-FKR*;*1%G{l?zT6f>t2nO6Cmrz^$rXMtdr1T|C-H#$(+Z-_h;OG=E0^pbwFam&v=7Jaj z@Qf5N0^pe`U<3epbwP{(I4%W@0HCEh4kG|gNC6`NP)x^R1i-UWzz6{9*KrsDfT8RF zBLJA>Ilu@2)WiWs0BlSFBLGfL0VC4B506t)4#`G(TRjHS)P$M7JD-GO&ZPNAr)q3FUk7=fx$f zH=q~!I1exW1iwWuMsEXaYyEAys6dNTe*9LbO0O4xif8<`#6e36;%gI!;)u}4Abw4P zD8Be^bClwn>>0$bwr3%Jl|8M43YLxs%UTP3Ojc|(OXfp74b?DZjX8dO;`ITZ>IjWb zd5!Nihnl)9v!VDaxalW)bBpQsB9qA@K(jLO;xFJfQ$95LlubT;UcOLt@^J&NlMnss ztbEuvQJP+?Y*}ORL$E=uf z%&IJoon#I&tFlFQvaFpKOHO6k`Efc6+ir9gbXHAq%xWf%+3F}(3zY(D%3efI?r5I+ z=X$W{I4T0W>u{vmCZF2KQQlMhhAv#Or}$SocpC3nE?VMM-;nYR<^QkoIY)9tkZuY5Pa!VJ6_9qICB-A+pAN>>ZqZihj$Oiq_NEHAMLrC!}E>LNQV zTa86fH_J!6SspMJL9;A@E#37u21>SYSN01r25DI8tYVg!Kqjl0nD2AZRd&1p71Pf+VDyTRR8$Uh?gT`KQ?sgQq22u=nMovp;wk8wMW-sDy$thPX<`IVm=Lrx9p-8nXA^{3>o`RcivudYPsQ6C&w)wW|< zzsH;0gpoA;e12>?_@5FUIuOnXGCb-}LY#wNCj`B(3-RYp2tm{OaUqUPSB=^qCcY`9 zqkXv_!p~~qc15OTLnG4i9n0$EZDiTjYeK6q+jn>#D5RR4G4BYsUyTpIu0r z`;n$Am{lr8)?mhdg3GSy;A;4m!#5oI(HyEmyAH$bI`p%xB$1RfaE52hZae%qXcpLh zsO|7{+{Nb3^N3@G%ICT~b}$vvPW!Ni>|9pC(&T?tW>-7Vx1OcL@@Z0<^`gHBQ9+A~ zlQa)yJe8?VxX*SwK9}KR8qgid!x>LT!mjlGDa-mrIVIiirP6&&1iG&_VLm@fi64k? zvYa?Dn9Xe({!ARRnn zeib&uL4U`*A^b~qTQYTiwuaFDG7RB1c}D*N+5QSYdij~UdS5LTqHF`4)=Kn49? zq15enMv}m&5@>YCf>E1E5Bqk>Y@GXKSbIGeO{I5pAmNU67~S5o+VB3Vr$~7)9=021 zv%fHKuJ{oO)}&RNU;K4kb!l__4N=65{lC5^mm@yvTvDKW`X-NQ*67^W!De94eiUd% zkl|4UNk)U}Hwy8$@T&H$VTi~L_C?>u#fg*e@aQjYqdW3UF>3L5#l~coK4e9$lCN#u zEKi+-iF-()+S@1=V;Y^#s`a{Ep=y7nzcxB?J4dIkmPa99Ee^TK$4M2=sBQJ4g#?XQ z5DqHEr8^2LY@7BPMpg1wEpx7He`Xi-Tf-->>aP?zV`X)csHnPyd#DU>?ikeK)5F@8H+s=aKf_9k1Z=^ntIxeH$D z_EN9%T%s)LTB3d?QS16CS3dVw%C%;;Txv~}>)%LZdNNg%siE92k89*>rkqzI;lvKJaawzF$y`j3(jM~<@J^nT% z(alxPH;Z{|pm;i=4CMVJl^G;W;NMDA13r!2n#Glds&np+s2J4Rzk{*v?<_s`#{F%S zq>Foe(BF1V25DYIFH6L(mz+mhawRGLo_Na*^){A)SK(9MIZDik>y-#;Wn*5eHvkIJ zABf|6`M_{(HtFN@m%Rd{Ihem&&x@l!idRgWty{+oBK{A6=5R1}FV&G`;!m?Y3G$yE z#NT#ZHid<*F2;*N`_FJSdZ+(O%;F+DwJh@<0S)jk_%{p1>*ZGuqW>1V(MhGB<0`$s zv~&9{Y2Q_2O1-r0z-+|JQaw_7>rH#XSwc?syuvzwKFR7o2t* z+g52n(P+JMJVS2097cHSI&B+M#`RM+1}(EK<(JT2%?dGsfp{tfi~yKU0V4ojngT{- zhw2FxLhYwFr?L6~rQKzJln3+9{$M3E!RdZ9Q2h@NM(uqF@APr0!6Obecr#Kc1bhfMlJ<*w^irecbcv7C7-om)qp7^$kxXvu&cXW!WggcrM_IDTHq z`v0{)36+weuUdl1X;D-qU-24oho$Ios>_B#te3F4FwaSRtE3^As(l`7u6>nq^c1*@ zex>XTlQnN=n0ARYHo+5`#|2m)xkd5QbvOi^j=fq=6}6=`|J`qV_H&Q6^khs_f*aGLZ0o zhf%b&^T4$@3FL;a>KypzB>ZnT{+)~gF%%O9y4n9Vy2-?svl@B>10V*k}-{E zHds}Qjrko0D;XOLsaIDzW0p>KTx(vKgsjf3%r)7s`>!69bZ#^vfnsM?DmLJ`yng>N zJUJ6TI9Q4}rxr9>NvRAvzs3lm7;kqI>K;Osb{;UJY@Ryk{{FcDMjy|mLl=5;rPn#Z2?_o$4n zX69PVaAi1NfIymc2#k&}V)SZMM=HaWk*b~4%&*kahEq%A+3p^et&3;gm!#!- z_v!+&yC7jdJSoWF!mhemn0W4!Z|<#@?=rTivIwiSR9O_SrV^`r5X&Bpu`l8^SFU|}$83B-$4TQ_nS2u~eeO)-H9LD+_vTH$Ssct_?aXs;?i}=F19=>(2JH)26s#6_rOvG6 zK8PP$R}?npKrbOo3UC7AalEX5EVI(Ivr1r2g?$y4ALKEmOckRM^kICgQm{N)AJ(Nr z{Va4@poA|<_>%U2vkKSM-RBuPGW<*OF;lIu5{%EO6m|p`YI$>S08MKpEMC5F8F*Uz zB9)R+rBax>os5atZI-4asU+Io9l@qFN*A3M6bq)riMYl`y+XdXE01R3EFJfj<;@OR z#txHo=@@jvY`R$`a`s>;A2Y!ZIRKK(D&{$WsYRy;4;yoR6TECe7p=3`{M^%s_Yl=% z=r=debWHinh4Fc!*CM{YVlyh5c@j283o&!TusOG2ZFaoKfl#>%1(yd~Wr?Un>^MBRmLt!G-ZbHvt;nx2m}EbW`V zDz&i=By(-XuW&|?;dKAj942{RLX_n~8`GbjEvZX0g!ThT026*b?#Mmv^6QfO zE*w)XBSm7GzB(=5`cCl#8E(ak*nJIYyRphBQ&y+98|q7SCQJH#IQgxGz0qRua-q4< znSo2k^ULy$UMn9fFR?Gh2%6O{#b^IpcDW{My^+j8NscnGj7;-lnxOYJ@@hZ1BS>RR zJ)%1w+GgZuCS587H8u^Py`aW9&Y1Z|xU{df{O1Mr&zWU zv!fA=Kc4m#^nMdEo4ymzrG1jD<>d^d0W>eX}?3ozN(xXwL{XIK;y4QmGE4N-ku9B+_ zZn!99%3CuftNXQ;c|TZLZoNVbOy$BY`P#}LANVJ)D7S8z1>4Ns!m^*=*ypo9?3HdR z)S~B*k<#$S{!($}Z=5pP8P==mPoH7wvYh1#Fdo=B#(GVMmYcK`iLS3Wx@=;&IJ)P= zU~%-oiT>i~`iWw3>@8$_MSeJJxK|Vtq5X59nXer^RW?d(BvWq3*O3RxvV>t@4--=S} zj~z}{ZmY$?;`AM8bwszG99}K8{?cJ-l(f7{uN^Mqq~=DM9F^XKf3@R@C)~QH)yHSa z9lDDi?7luQA7<+#RDJYPAFFn$f^Y9y1^F6_)~9(apPKwhp3sZZL@omhvlaPl|(H_vY^K>=nk{mB$-hW^dZhTa_wH@|ucM znZBCdRw2)5POVy4vxt~Hru3HiVrhKu3M#p3E*l9h2gChq{y?=9Qumsl;xeA~!~K<@ zSqld9J68`;C#^d<|67Y0cDMsznTvDHTZyAIyy_U@IbhY^wf+ouC#k>%ThoTygErPxMRO?MDQy8(@0p^HwReGZlw)Le#F92Px|23si&C&-AuoA-%}J;eHKJ@>&Su3Pym5SpGC5SqkIp>>*P*z0Cv6yp=iod{o`ZOXc#bYV zIq{-djaLA!m_RzC8&~xXqpeFvo}}hxrO0a&>Q0IWKlVRQJQ2i)lR|C9oJ?IchEaj) z?h0m-ufN9|T{5w^HyTZhdZYVJEbvC_6Z5>$@rk+K=)^?X8$Dwp@J9EsJ1u0NV|e6_ zQ#&0)dbt(ncx8WdX?z4J`=giHvoP9sPUug+l@1|z?IR9ae9q{cGj;|S><-+OukMYG ztzgV~HhR%y*mF?|T~+c&8y55mKF1q9Wd+n(EBV>7Vq?C!k2m_# z6?^WSReyAOl6CiN6jKgw!8v`d48^1j9y!|ys&_KuZ1k5Qk>e$s(IrZFdc}#h4Lv7k zdg7?_VFyntAm%0J($H-3;RSCJ6zZ&v)GBkK9$AJ6!z&Xc8RdhWU-eBdnk*&LYORu zE}gtZ*ypm?9l}1J#oi_C;VkxmurFk>hlOdErz?$b2>W6d`;jn>D_wlQ5%$kn?9al! zoW+6?7#m#OVTXi$C5w#-`)U@e3)_~(RtnQl*OiwI!XC+D#|ry;7CTkgH?r7;!oHcs zE*JJ_7Ml_Ftt@uEuy1Fvt-`*O#qJaK-7NNDVc*MQ4+(oLi+x$x_p{h{g>BDbKNI$Y zEcSb0k7qHabC-_&FpCWc`%xBKAneCkj92$A9s5ZZTPf_PS!}(qpJlOQg#A2=Z4~y4 zEOx%If6Zc>h5cI=n-Qkf>MlLFPS~%q*sa2ToyG1E_M0sBeqsNf#U2#)+bs4uVZX~_ zj|gLbqB}2-3;RPB`;9R6$-DXfB8;u_Zmd`a`%@Mh6!xE4Y)sgnv)F{N|H@(q3j0eI zJ4V=lXR(un{WXi7DeQl;*d@YtWU(#6WG{8q$JN4Ex9!Gm5O$NF!L}M-7Q0K>YqQw> z!d{of9u)TaEcRt#w`8$Lg}ot*Z5MWH7W+40Z_HwU6t*>saYX0RvD>oPfUq}Zu_0l% zXR!ss-kin8guNw;Ef;o27F#Xstyyfnu(xHgV}#w6#ZDA5tJun%Ri&k6f*7W;~@k7Th&g*}kP zekAOpS?pKBK9?X7xuL*_GV#^WU+S$ zdo+u^U)Y{w86A31*s?74C1ESG*rUQ$Ww9R#Tc5>#Bkb@j_7`CzOET#e2f!*>Y)IIm zEVfwKo>{CeZ2v5_PS}lE>~LW>WwB$0-JHcX3VUr9J6qW6ve?DKK9t3-5VkFgT_x;m zS?qdYk7Ti1gnd1W-68B7S?nFc^xA$`+kZfqm&G0u=4Y|52xWU=do9hk*lC+vtU_GV#6WwCb%J2Q*jFYK%= z_MotHv)Dtz&dXx|BtUU7f{#B%d0FgD!p_fP_koS>+0~%mFJM_0@G$`gb^)Iju)Yg;7+~zgo=lz|5vB#w zF23!;&dg%J5_VP=`-`wEvRJ+X_OO?UZ$Q{%S!{tYFWc|$EzHki6T(Va>_B0CS?ow* z{aNf-VFOw0Bw=&1*y+NmS!|QAp)7W}u#qfwm9Y6)>;_>Ave;H(i?Y}~!uH5w?-#Z> zi+xhqSQh)Tuq9dSyTX=dv0n&Vo5lVlY+V-14}!fb#X1|6m*~##0sPuWvrM;z?O60D zh>yV`9yvIKVC#(0>2jRJ#|i(spJ=mrwKZ;aY1x80_ZEwn_x-&YkqVZE-~=N!EuGrr4DEuZZV7) z@6x_3?}&K!n&llSjW$+k^E3%tER@n{S$St?Y*TRX;T#1m#K%*VYVT0l=NP6AWV#*B zBb`LF741josCL*J^7NiX?pcx-8!pRN^0Rh%FVxBPfEDZhVD$XuMW~ZU!;K(^2su*7 zA%@IzaqLSR&nAvqnD;l9{l3P0uXs~LpAqzz*jSoZ4;GwV+L*i+xAMn224iWjs7MSS%`C8c!wPiRh8^Jk9f{^OIBt)p?|$g4_CyzuqfR?N zUyiHHSG|K?C~({6H2p<1q3B#OxIKwm5!`cU>nYt*NBrU6*jD$0e0E#iRZ6m}emJ}8 zDg&jYkjP{i^wL#hrQ*oR`z`S3Dn=rSPkW+VBwp$LS~Xu9+1Ss{nGqe1RI^1Lz4v%7%JUDeRppm$w}P8_VBRbO_1O4YC+?@&eO zT2uHFa^XEda-KN+vQ zJG=}&vn>i6%F62J&PJBcvoe%hO%1zPl?=Nyvo#%;D@$|8J%_o&zvjlLgI5J@&YN(M zssqg4|Ja@+5$?F;GAanyKJ&Tnklv|E&xxz2?nN!}+5IazQ^WTD`{0>Z&Cjd$7THT) zp^kZoQw%Q6gH~~fLH$Z&u!AjI1<5vYIX!PtSotMh6lBlZod+5{cvW7lKr!*6VxdUr zc>%YD6i*&@`|Z9N6KpQ`*7ob0*XMFWjI?UPF|6vuLx#1;rS=>_;M`AGoVTi{UM#FX zieAo*JAoZrInBx$BTx?aB*(R^-%l=pm0Bz+w2nd0#nM*ZeA^mb470oW)%uNK<>Q59 zn|q+J)F?8nqYKHEohXb|z$M=7yS_Td6<#*PnPYnchAWf*wx5lW2O#g$$!mkJDzJJV zj{9DN6U;wT#;HCQ>N)&0%&DOzM9jsW+ZYRzchNS2jDN9auV0@G?e3~PMO1pw>mJ{B z-o42?IfZDignE;2g>=BM?wb#zQ6245o4SC!oIzgNmvZb+cNK`0yP*fqM zYTdeJXC%6wMCNjz@{V~M2<}A}5^tNKI}Eq`%eLbYZNkyqbFe450=8DG4M)!h8|=aJ zVhDF{Y~5>ZC3g27WWU$C4~HM!pfY%^zjk~^J-aS{HrLA5+@V=sKYF#oxbviXdw$^1 zoWBz1hrQMs_}nGDixUT9X4vE^UnkAvXc18oUT3y0MHc5Fi^X=!sxC}DkSKIv>IQp` zv<|oD{MI%0T+q7To(o&wwdbOiH&6U~v{u`bS(INJ?1?T>vR;A7lU$7I=F(*a^T=rl z9WLg6NZRL<_VlHAhklzumWJxZRCBoYVLYMR(Bvwn%9$p`m+=^mFXuOY5kC=w7%#35 z_UGPNzKi==b#$+-K5%+9rSgINMF}=wlvY-e(qW|{hga* z3TZmc+pbrT6>k5x`Kt~T)<(x}XGCP)h}3wCetB4^ZH-<>?9H>V5|87?5Nk@c6&rMU zNXcEwEJM~YVe94Nmy#{4RX29$^-dV3U!hp(y?!(G1nZR`s6%qW`8&DI?<$pqq-w*~ zeDm?k0C2nbqZ#tUjUj$?BRPp)tHN&b5?=R;M>pe2uXV9RY2x{$*Ww#8m$vQ`!fDm8 z^}($3Q90Gb&9|QN|0v5p>->%QS0PQuzq0jb0ME|F zU@_6L_mP-7_Z9pxIk0a-+`;q9{Amk&J^|M8M^~47C4V30Z_NYza8thJU{VQM_qdKR zG{>g^1Wdh+AMXDb3qyLs>-@Y)muIUpjGI5IJIZ5u^Rz!ZweRzz?9i> z7yU=ZiG2kgh?1QSNm308>z9`4PN_C3bXpMj`U0ny&=M}w4F-8AD`0XRy zro+(jTj(_2{}N7-^bU+H)EnNB8{b!?3nV*cp-x7Le1hnyaP!Vw zq#|#hTV__E4CkXXtM{+Rn>b`RevN@o$Bkxtomd#zk&2GQTlyD z{q1R09^-F*N&&ftWJ+P2u*+PrFJTu<*sl73PFNo9aonu!fbb@v1lZ9_q)7_Uyz_uWf>VuH4uG-0`-y7-RT^tPNU% zg=j^GcVozXvwSKvfN;L8)6vr;Ghy;3?5Dclgk=neKk#-0$MbA6TyfKmO#xj5(W>s) zDUb9{H#r>fN)564ev#`8sJHjJy1ZX?Y4xVE{}di<<4XHV)tNOoF{r^Ae~e)hZeC8r zT&>no&gLGb!+k}kpv7_l{kMpvR8m*Wv#@`sS}l2{Xf65W1so^oVP4UfsB5Xj-P>RN z9=Jptt>LHp?!BE_Tqnitdz14W!BwdixYo*Lt=!N$+g{br^e}1kSS5ejo1A>~X3F#K zb8YkuZ`?OBUx@7dah7&2dkPUVGw-R_ z$^oyN_1NoXd@}4bD+8b3N!~FF;?tD~E5UlkjHtQ;%hg*YS54kK(>rXe?dDq2%h^iM zwBe0}P-;Elc70dP^&Q@h1;u!4>eC$Pa)b>$x951tlQG9#g!U#&)b&xcfrVU_L42vM z-0V%hU+s1BebSg{9oclWH~9f6kJT}GQ=k2Eo^A3t)YpC)((f#GV=im+RaMoX54(;`QgX4BX{LDTOq?Fg<`z1~iqd6W4+sgmvUXx`R~b#vQy7+jg^ zxg+A-JoRPV&G;8WuoTP~9M&K4;)f{C@B~x$hatxIaMI#vMr%yzikRpxBs zF-%Kl3-tKBpqn%b8uEy^8TQqv>!LA1mA|Jz^VpvU4FZFJj>395dOHu03x3$UP!H!t zA?{`$5r~MfjKK1c&TNr~Trwx{7!orxA`GI$CCefV=EvA0tS(~NhP4=52wziZg%=TH zzJg?O0P{L=KW+U(`(bl!>D2;t)8V#BR?o|iOA?fkZq=G;naIc zgcpwuJ(^!hBK`}PkEU!N6Tw|Y`P|pi{7ow2*13$M z)1Qa38-Y$B{`SY=oe^Ys{2)%oKry$(%({zXKC#0r$nb7vE(y7G`U@%ZvpURz4DV*X zMa=({GC#Y+EXeR~<~v|!U_UVBGQawvt#^U9e#?)Wzq|FTr%~R^kW1^RVLnPur=ca? znz7v(u;_ISvD_Jqc=1(6%=hA}A?%)ie}sjrV1d~hciMMEk~0G*5GPHK`@r_EaFyF;qh^92BI;nNa{G<$q+b7rE zy||1OxfhY97cC-S{0VBM+&I1ve-a|8AMWs%*QY?5qpr#l=+i(9W3Q6;XP_Hox=PMAuu2g=P|4g?k&|q+EWqzGWT`8g4L*| zx>%g5AtT*pOJZhztlP{?mYzw|*&&0uV@`E>(Y;{O6aCxCoa^%=Jl({q?nOIDtU2Ph zE~V<-WXp?IE9t%X!5_1WQ3pA9W@EC)v_43Ccl)bmG27SCwHafV4cKHHf7z-x^W0*( zqj4pX#ylqtO?v{f?agRR3i;#iLUx(y{f#D{&5#f^k(7mQp$hQ~q#tj?hflo9I5#}0 zwJ&$q8Y>C1z0F_to7t6pxh3OHZXP#GteH&f)6e~g7CTAa^VNV$Nxnt`@%xolK7K^> zCmj8C(eH8eH$>kLosYi>iACW@2RN@s<@F&)e@iqsJ}Rnji~hLiVKcb$@pnMh{uQ}7 zGX5@Z-aDrA;_Y+0-EuQsdk;GLX@a$<_~8qW@%I$b**Ksd6Me3uzc2cHM{gH>p`(8w zdXu9c7k#m#e<=DAM+L^OL;O6#YhFL(6ML|@_PpNrn&=wFC_iRk!W zAt}awDE_)}UE4OVQgD}Ma^)G9W+oSC^C@(NVQGQ4k@eMxgYByk{SGhL_aQhM5Py9q@6{- zB7M5QU-Mw*!M7hFy7mp|BZPD<=tsZ7&7QB|?%e^w{eFRs`+tYR4s&18I7+#|p(UUw zb!Z(adRpS6Wu%V7mR(XGEk1R8v})9eK#NAs!TPza89Ba=%TltvxThl<#uUC^o2+Ua zN4jCsn~eX>RiA1yoF%J1(XoW0e|WkwZSi7%j7quuP5 z-=*;H1^+=VasN@odWipk;46`TNB9%AEdUYB)THJUIJBkm22i z!*9j>rIh)k4znP`yO{?T!2HiC^K(1Qf(-9wUL zAj7+vj~DY-Qsz@S%z_N>X5K93ucpk;>o5y4+?dT?JO&v~t3B9i8nat&-_(qFbYRs& z-_0xO7(0t+SPxn}t7ovhVZK{Xqc4|TFiyPe^t!dWe)f&D5LaSt^BFwL9@|5j7H=>2 zaT!*0j7Vvg8$Y!>T^Y-jSK?f_yhr!%=VqkCF_YJDGrdDkdHZ6TZP$Fg%TeCWe7!(q z>HK_PAh%fabFB#+L|j)YuIz#tCm=gxu^<1LWHbZSVoUec=cun11Jiu!OV*|2el?A+ z#}fBd7PrP~Eo#{6%+m3}Wp1@8S@>e8)A-B+nOmQ;^f>F&8L+cvS7KAF&h;PW#zU=z z{v&hg%#8LQnO7$>;=eg#ev&!%-#c&Ce0}GMdo#sE*j$?4s53wQhvwCq18+m?)vHVy z0l?hH0Y;>&Hh4UedKdxl^%O7y;2SAm1i&{_zzBdxQ@{v-Z>4|{0N+jlBLKdW0!9EZ z=(!9U0r0&PFaqGQ6fgqd`zc@q!1fd{0^kQJU_@7`A5T4ufb)kbUHDwCc)pBs z>0HVPU2|ZcP;asv<=h2sKZB>?zO0@Knb`g_jm-#vKc|2Z0RNQ&Mx1V+CFjr~=Z`pO z#;=>Trcqjc0{iCq)#PW}UYZXv)P;WB2lMsjW@VI~(Ez?EeDV^{>99_+!w3kM@304gOul5%EKXB zUTO|PLifhh|LhsTP2MD{z^rw!2F$O|FUc z(ghwKJI-?L;H#3Xu$B0UpGSI~>LV3~CgLyKZy&#%R5Xv+pEO>nH2U#T8cZ~l#vDDo zskuBz!@wN@D|{}E-uTp=5@A>)k*fW&F5O8aP2)PHF%J)=!Md^17}mp^V%=P67`P*t zkITx@8=s~$$e--6LwLT5I6S{MijYyby;-)ii`oRF96@o!P8TwHG$T)^5utTJu^4Vg z^SGmQ0Z}Wy)SfDrbIp}FWzH|ePse*2bvp=r9hPTuEV!07Dos!tX8Rj+V|UD*7Pu3$ z1x=e&`n=P735#F0hN@GVldNWhF-xaxEIEfCkD2RoZ<1xyFdnBgd@>!fn-}@?st$A4 zBOmr(SZCqrSbmE2l~9M8XUkG*F9n-g#!q`6enPgoBc5~_Zi8iC`PBJgKM6~-G1Y)B zy+kpgVwf>udz_zWf}dsVA(ti<7c*~j=bSUftm~3J7y%HZfDr(N6fgqduW81N04Sy$Mxf`q_v%AD^^Y4eC2EZf$rgozrM4BboG`i( z0ekH=B5yX5=};JPjYhx$Rkiay=(HoQ(7^qm-22VCAKS_Qw>!Cu3$x*|6*A#p$bxKF ze8bU;Nk$*FyI#rp@wIaD=^#0idq8>FN0BVWq}by5_SsX%hA2v@D2xCIQ@{v-ataus zu{F;wH=UgN&geBtCLc3p4gHq#rj^97Nq%mUPkbP*)-fdSfM}dPz|KF0o^7o}--peS z!Tjh4IFxydH9m;2%nw~e>&-D6rp~&S*y4lna7^(AkzFiiPrQ!2-auZ}ppNgzArZ}9 zE)vUmd14;9_AYXu0<)9V zjYNhlHipe}ohxS9(0y29{KPKA1%CkJeTtjG&<>7{S6j!Cj0@*%|5U&h zZ(`ODPaNj#`;m!tj#xCYBB`+cw8GxisW3s)`mqX&sFVipQhqddtZzDvtH)vI~^TP}(K^kcqxdy{NsK^niUow%I^0|Gx!h|B%W(Dz36`DE09(Zq z{a#0pie`Q#yeRtZqP=K~=yyVU(Q8FopHOLR7z*2O#Jb>|R>gXTDT&=_A$tzoJkAGu zT^~bppm%F8CPs z1*py{Al1!~%|0*@I+!5;mS`rx#5m&o9TC6VFze0drZRdj98N}pruAcOeVXR$q#4BOjub?&RdykbqovjMuYjK9}0mS*h{;@lf|xol}`}+2y3toRhE2*(^%O z5Q4_h3Od^XeqPxAPG;6e>BB&2(UEK3&$2`g zo3PS8fw`|*q#u8PEW~SY%JDuq^xC2v@0COEEz0q3IrQS991qK(#Q-@zCx;dY8i(u<9tJ!IELgT`8# ztIoBs3ws27?NcbDcGq7io@e8LewFBxM9+^m>JhW~$G2RZ`hGIIx9oQ5UGpp06$&(a z9ZKmB;=`1}CH$z9E5&Ci-e)OyIL?vdIf>&uIi8z1E|BBo#Bq@v&r2N7m*cd=@d7!{ zNF1>oXC;mo%5hHOXv=Y4;;#d!(6eRJ5T!xl(8^|3#G@l*KuUnT0~Igoqm5l)`kasQ#Z4iS%w zVCy{*tSuVW50yI~aaClH0q*Jmo1*8DCB1nOwog;$PUmMvhDFC@<-_6I=#?>0@pATN zKF72ycdPoT+c2QCxG5H7i%l(yN^3pw4^Z*$Sk3_S<1;N5&C?af8x;qQ7Hd5}bv93n zgNEzY<>EEyTm4Xfc2P0`W|zPcV5GBbnE(rR1{UrNEZP~EzcVnKtd-@^S%q+gJCx1y zWD6n%W|K{V%qE)vv&kmFY_bOMF7>&TKc>S9IWp|W>^U@0z;!&@=ga2+31t_y10CBz zPr`OpC%-W>Bt?4glX9npNx3&XDR)}Zl>3k;pL0}AC6Cb zeW#{UcUn=YyHm7;zmxgI-N|0!?qncwr>YVEP+H!VUgGYgm$*CWCGJjoiMx|t;_jqp z?rYriaKWl_>q;#D_Jydy7BAjT+P;mPopyF?I>CH|2DvaE)8vzOrackEKC6-02ZZy5df@tx;TvB zAPi+Wjk4$;ugZ?#oi3ugcws*Jlf;7+n0O50fpIzO|7ZE%L(9LI2*=s*!43%Syxn`gJ$nyS8&dZ$_!J#SgfSG_YoJ(pZ#H~KaHn+Z zS{Vs<2yyR+7NftaoJUgEy?k8oHhdf+J!7{i_h!?xd%>k=N&`Jp1Z*wdsRw&pcj@VZ zA?bc3>FZEs=;1OeTNF=J#jmf(`ke}#%k9Bm<4`a9C3*1U7*Ez|<%lnbE;m+r z(XVmk<2Fu5ci7~Su=UwJ4x#<>iea!I3gFjfk3rG@z*;}it3^YKCJPSl3LfgEVBQ5? z?77=9B$Itvptysw`1UDsYT=tG0^i;()~cm7Y)SALm`aHcyWen8bC{pnih<;7n$eMz zwUMv!0p9-7+OJdcV*DM#R`Yy^HpXDJS3TE$3=ftFF2}tVnTf`J)%O&8H`8zQ=u|2n zW7%9`4R<4z+1!M^{%hhH=gUJn3LcJED_vj8bhpYJk%W$(Mkb~kX@l7pd9+zl3TFfv z9vuaTEy7g`twnp}F0HuB2)LuC>fF7XufpuI6?$HBbDt$;wXc`BmhpX^jr!3K#*fIt7dXcxnn50k9?oi~v}h z0!9F=O93MQ_DcaH01ik2BLEIe0V4or5Rzrx2+jK#vvPN$>+LJ?(i-#rls3J8X_e^Y z{-qV7wTuCe=Jx6ROGk^=A_n-=MJIPLX@w!Ze@PNd?_YYF=;Z#TgGDFzFC8K}xqoS` z=;Z#T14P^XOJ2O6Xa+)-yHS@3h_2`4`n0r0P}+l2zzBd1DPRP^At_)4z@aH%1i)b_ zUz6n1i;f$zzBe&Qosm+qf@{LfMZg?2!N-jfDvh9NgIOg7e`ki z5V!dpT`k$rl&%ouN7Hhe4Z*x3_cqn{RaW12xs4Z1;jcAAjFGR=_}X9LhmFdY0k>by zPhUabWW5>&w<#vAe@2=kBLJS60!9EFn*v4v9G3z{034qJMv&i^lLSrw1mXDG^O&SZ zuubylMiphTAAQfB-sFjC6h;u{St(!yz_U}p2!Q9LfDt!)(LbxhsYP!jO1?Gr#1k)# zZWC$W@{Hb)By>_5$_S!)ZVDIyurURU05~}Xi~u+#1&mPpdj|D!7xm#qHOEiroWa}1u?WUM|>bMbWs~*@bKXt#}5tvQ^MDJAo&rf^R=w6&& zYu1N|wN6D7$=xlzxJG*6)S%3ZH%O+h5FL#H&|hi}mP&D&&0_o}V(Mc@;~r&aD>-Ph zK8@|-U$%syeeHe3Y_?Xl*WWB8CW)|GZnRhvKUAc)52SATuAC*I#r)UthhZ8`Ncx9kqx0+7qyqdK^RvV}qGF06>;Ejq_x(1N*lIqA}LpDQ&YtxD|h>2qmwHWhpq z!P>VH!Hgioqo>REJul^Ww>aJ?4nc-TG|Ksha&2ZXdIj%eH@iu^Dm^XX4cMZl@_% z%ayWg&YX!z=MsfYNawv6|GLCS6}(V*SV_c;boW%^MG+67H1)j-yK3q7guLR$Q0 zxjrLTuj?P)3GMoaer6&|Ivqr{v6(G8>mUXy{avkoHQPbfU9hF(x(l|5ngi?t%}StD znPZ|v3=Y=zSy#DSnJQkTQWW< zx7ZosFOudvNYlIQ#foCcyIW6vsoA1ERJhM1 zetPx~Vv8utZ*$?UmESz?Zauk9Fz-C?a-I(*o_bb$2Ya38-R9}&d!VbqV9! zdXY+UV`U?^^mw<%wJymChbl;j0m5ZWd#ic_)LeQ?xy$PVa?OTgLv)t&Lm5uCN4q&c zBIhO-=bWDCC*+lfvg{I1lVe*ptbZxPXZdL^%3_K>iNH?XXb{WDv^YchW2t77;%UD+WL3|Jkxk|B`Ws1QHwda_*0uVh=Tips!OF0@QwCpebu+^9 zP4Dh;V0?A3tw@}+Bg6RK#?y@q2HQq6q3kpCv`sd|*xe56SLw{``iUNzY3(~Iwy_@tSwkX2*2!42Jjf&CT zmEYo-++8V>yDO`;_Wdl&G8dox4#<>#Y@YjeP}--b^JKY_l}AC!1+Fo6gUTkJ$Me^? zkjo`4Iu}R$AgUIBl!T|gr$mO$v#}rdQpz2FOg`V05AVwHn0i$7h;a>v+m|K*5^l4k zKj%g7BR{opJ9iJi2kJ3*$6TJ|ue~-`;K5yAlZq(4Q;~Uw-tZ)?PToUw+*W=W33K|Z zD>_B|SVzA{a^8Y$d|Ns;wUu#JtW%OIresohE1Xu2tdPq|ShlN|tB{cDgZmm2Nhd-E z*S|fvCB4X~9On8ZXFGHFBJ*K++OC0Jy6rJiiXNhpXRd&n)=!(Y*>L8?P@|_A*UXFL zrJvC~NB6wlQKycc>Zrw|XD3kK==lj1j$V>b{iCgfDvfTw-Q`<5>88hw%-^I&n_f_F zJzMSIvt(ooWpjJC@1bnNq1WUZmNoR!T}ey#J5A_W-Y|=o+?X_MUxmPWnkg5>iM4NeC&BLJ1wI zq4(Z>!AUfS`b&h}cm;{b65M?#Q~r4!zX(h%w?)u~h1 zxG`)&c-E8He=UH-z5sch@)8sPY>%W}fZtSj)$lmOY?F2#0E){}kzFFv{o?X$2N~`C zqP;{9@ui&s$3dzkyXK$*{9>zX@7M=pBMDcw8;1*42-x*GGfR1&y$_^k8>Z()aB4>f zZyRssNl&1YV{rPWC)pX}O%HrTh9krDU}d}ThA4l(%vZ3IG2g2p9)GN3&LzK@7gkdu z0{-zAPmA!^^KXDT0RB_qADcGxxFVw+#)LViG3E=8;grX4S{rn+MlD+bT@kqCQZA41 z{TVD~OrHf^q!2Gc`h40icsmE78D>hGlyKPW?&fx^f$J~-AarhK8~8j&{e584YWUK6 zH@Dv!_~uXLJin;G{H>tzgSNWXc6*=g7TR7nw^O?fcEGp6sKMk<(q5qHc^Ys20J5rq zRyEiaY#BnpL-K+=4K%+l*^EF(f$S)itR|opx7d7G%z?kjXvOU{A3JG3xB$S4FM#}S zp@{twrZqVazmP$*4P0O`jZXo=eJ5>VrtF7GO*EmXXo3!Ne7FbBKPBAN#qIKZm?2Rd zhhkJsOTd#`CEkL?aIM);gfYFkc|wfK9SosGQ)rXtK%b`%UZ85*z}J}m9EnAdWL8fU zaA@PUYNfcX#9Pp1)QW@s8vYIsoSv}>Vv6h4Eu$(_EiE_G!BN^-s7Af{q7wpJJ)X<7 zZZ53&JT2T_M=82ap^t`7bmTg5A2C$qgigK-(mHtscG3qR-?J#IMs_slAwAiwKV$2S zL>vffxQxS5Qx1ZMbZyZ)R7BI50x#Jz68wi!Fue{x2(Q{o6foxYr<|e%jY2qHSTs-A zj_L6<$~I|VLayM@woUJ-UT_0c8$T+zAlKyP3Gf!L!nYy93V9(e`pgewb-WFl9VXs_ z>i1ORJK(sBTP?#CP+&&#U%Il=-X&MoGF(Lkns`MxX--xdsv56t(?26(ask9{IM(P7 zcvXi<0ltuQ#pv7%Fg-}WCnI|DD0E=9VHfbl52zCeims^Kvv4^=ehs?tb(lEVVJE5g zs$g)&=d?WKK)&*fNVvw^tnt?&!A536<=!nSLP&Tw2F}?2tN)td25xDx-J$v4`G*l) zI1~EzrdeAoKvnq1e$1ILTU)}lLeK5uTq+|pDm^;AVtPz^TzY(ZrSw?JdT+iipy$r5 zi`hsRk(UF%QN7kA49=?xrf4vY%Zmq7MKDdt3kOpSn1<)MAjh%2x+TE7o=jfQ^EC2;p0yXa786`vFB5Dp(`+x}Y%k*|7W5JT>tURid<=Pc3F;sUHY$cd zTY!5TgZxz5*VrEOVg4!1X|R@v4TOCpI6r<5T8*>teUK{cB00I2oFsu0*oTfZT!lNK z{kRH0@H)wuK|#Pif?L53BE0Q4?Gk#;7-*(l216!33;Ye)wCBx|c%^qs;8~UF(8AzZ zmAl|aU-cPjW>&D8yv%D6Wtd@B;Z+O)U&`yY6iro9c}`;DJ#*q^$fHG%E^+5UyWX%M zfHvqK5EYowA5OWz7^L5J1t^u{0@t|4y8jBvC(m~^Lg!cMzO$WsX?`*o?4hQOmk{Fbc>Y@Y&II;qj zPr?kSEu5KUsmQ?7)gwJ`j{E3zgiG(1VX?!PxAca(n*5MAXk6^;wSEPW+lt0+xLy^` z!No4TE@}E)_#xC~g}gY^GrGZs1I@c^izs-gjz>P+c;LBhMjJopnjja=u2+n%p$)Dz zS#Z}=FaL~c4!GR{-XrDc?I=715u`@?o1U@KBtNb-Jp1x|YvFnA1wQRyd$QxDGQ_m| zLw#<=wCg>y1oJO8&2;kf&q6kN`wX4!#@6q5BI3{${sLJHvwc zKe^}DW8N%SXQgBXrlx%dtu&+4KY@!W zhoP-Z`3S_^IpEYl`=8PN2-+V-`?((bU(o(zv_FRS^DtBq&r@TBIGSr9(Xcp;~aYTl#8;49PesLlG|84b*dVXoaK6%aHyjCfnS2_>zON#}UQ_eu3c*Cci?PvZe z+s(Y${sR1D<#F~iIQtNhZ}tnn1V^s4xbhKkNo>EZB;Y#YvgkR+Qx*$Erz6^oceEG& z4t15~Leq6HrQ@}O?@su|65=%|BlsG_S6B`KlQ%;r%CCQ*alv05x(CAd?yo@u&p8lmGE#dEq&|8fl(c*P%eb51eNB1tYy|vY3CrLe^NsP z^NO+EVi%CmDeXKsS%x8`t3z6NAqj`ru*3pHq?< z78cE=8cop!WTbFu#r}2LR760A;Rw)#$={x~3OfccpIN}fZ2&p*@=hA3|w>)Ns zsY9soCN~Sd3z-?A4xuBjZ6<^P_TbuU-wQGW_x`E6uftX68w@JwU|t=<@x>cTz2ZN) z#0HpE=o={6^jC*)pzwOkYO4<6g4xHWt~!Jxj*m@MbqLR0d~7PHL;K3xm}W*GOweeg z!O958hYpTsg?OhxT{v(R@TEbRhFH*C>u$var%5p4T?3K#!*QrH>i%&5LojdGF-0#= z1Y>wbcg0AzYqPszl-nO<;U#Df;jk%){W{zi@HJrMatK=%WV5FP{H z9F3t3dN@c73=5)z0t0?8f);K9xCYm6;UzT3=$`Q~^anA}Gsfti(H$6&9|HMMc-H4r z0B{T!kpBzV>2$!GKg%Zr(ud=SD*OiQ3om1mV>8;jV++4UW3byVEI9277{fvezk{F5 zT*Dm#R##CQ7Z#WHJs2o);kI>rSbW+KVC@G-q}3p&5EzXRTTe~El8uE#dmaUx_9%2n z_yAsAxQ9l#L&M<{C}H{r)Xe$5DUPCo3$Ns^6bZ+uKSJosuw89-SJH)x@jc36C>RfHoFt4QBWOl zj*{F-f67skZ;m|Kshkn(uB@{I55O932uZ4(!tOdV71lavz&Yiw;20*2)Um_euXN4fA#&%8Ip#F%lQYx6H5zEzcnwrI zH7w`;H*(+3oQAz~W;D1*1D(b`4Wm}t@1)N(@ne`W6TTcx=gpnr6DfG)jqASv1#_3* zpuRe1Snz3Sy(x`zg=LWTHz4hJzT*AfAvmyau)Yp~<4TBjMB!S&xtOEy2H3&`=_dTZ z-3{>V(!xK$h_mBc@SBqVy z<2de5wuN-Q3F(Za)>MSEJl(Khlg8V>Zgv#m#ING=A(ZXN$C~y>% zk>e_~z!2b@I9i17kZK!7H>N5!J;9b zGhzy9H2B99!mT-HAznDRO}mM`BCL6Re?*Il94o}wa1O?uzmAYfo?>IK!fKF1vtMy1#Q|a3`J*uAV@(%B;zR$zAMfFbd#YvtzR>turR2GA0G1gV#B}?wgbZj2tR7k$X`CM!7 zU>Lh~7<17Hcz^4!yr0+JleKq9tAoC$`Y!t410LY{A4-Ey9r;wWx2WhD8M+AJZqI+K z_Tjn5PocqcD}lpOBHc8Z zN_8WOf}X}Fm6#A{Nc-(XVxNbn7Vkq^4)ue%A`SC;Dgxi|g(uY@bDQDw1Q5gIVQ|qE zrh$b&Jkgz24Gb_F&DATQBJ4u!juqhA-(9Rxf9d*B|bOEdYOq$RCDg7S;gi9|3cQ8^CW-Jg13ERFDGIfry!s2kvJDZ+8zjaZ$YWK(*`@hz4)s`jgGGhMB7j zl~Z~0WTEAXF{zS_W-tJ5BlnG-pA4|vc{>E&$f$TO_#@i`gl z>M*s7!me=r_&cV;?p`dsS)?I6SV{Miz%wI-4ImD`^rl_gG?hYv4?z=)={2ioSI^7N z%c+Yt7Jh?LEQ5==3M@pf!Eg2?Fn66gdGv&lQ_w{k9AGEHa<5AFuA*R^6ro^OrB(OV z&EdBfa5k))sx%!}2or4j!}Ueahc{=qDgpkUk|!d;0*nx}SPuVi0SUNz1iUy?pZ1yh zMuAiC3x4TaPB2dr1Hj!fu)sbRaz|lcIN*(LF6a%vka<{9;GaL|&>?m+0S zgr7rHA(=z6i(g}~8Q_O*MuGGfrGAsa<^{heK)wNPg2frX!(hHb?r)F`aH7ku&H|@H zJQ;+3V}fr6`HN1$Il=zo{a~~S4nY}3@}m$8t%DnFM!RnYImEs0rEZ6KITCF?iNsX> z7>Oyl8vR+cLnKv1b6Fs28-h7Z+*ff)#W1mr!Kz*Fkp7Lzj|rJ*Fm_$L3?~#UO*lTlt4Uo*;RXWOQA$sYS9ANQZDY z5-|?Zh2#j3!D33|zKw%L2}p-{urcNO4wUya9osZm^l#a)r9&)fIRWG&Ez$4JmSdYb z#Cs%9koFg{4{wE9IMo8#mgF#!^GV)M^2Jsd^4nzof~2zm-RBpi6wHwAVE*Y4eG4$g z*&u_(1~Ts`Kwo=Fo+cUC8r@WF{jDQdv~AtEwZG`o8q2d7q(iI$dxsEhQAU8QAwGr$ zsza=3pHkoukGIE?JklOZxMc@yZ`V7Z%NiX~UL!fK6S`d332mMtxw{kkx<=+7I-|X- z3$~>&l388QrX$J0T`)(%UC}0$WF3%^V!Jh>t3%8Ov%h$x8)}~<`60y1U zybk(Z+8@hgE6F!Vz75h}{N5kyqT2wJB_!(&Li2zal!ah+h>Ane?_`p(!?1;)9)>A7 zKMX^tJp#?MMqx?*i)6qU%u7|0TQi^V^B3#JU@5&g21~X7Sgfy^Bv+2boK_r%AtaKl zO0o{gh9sMT^cO?MwHfCx?i@$u3Gzqr1a!bZiX9|%n;ASFTiV3&7~1pW*Nk_FkH%xF z{3f7HrwM4D2QpZkoPgKSRgzJKXs$}KF3BHAHlEnGG4_zyccPTy5%`U!8y}FcN6!JW zz+?~=5Se5XD*C{eeBo{@xEHe+TrMVE4BQEc{vH5|7P0Uh5~STsjYSbGX0Hen_Auf_ zGomc1sU1;6rjA4%h?3}QMxmm=91i}H1dJz%p`rw+CcIx`B&0c1lmg`gjS}EMJPPCz zY49aH3ABqSgXs`ab*A$~xj;qW@+Oc4V~FxY2wyQmI{rSvqA1r$WI zhiJN}Ky-v?j;KoXCD0sruYO|*C~iOuE}%Pz{7s}~OcjV$0=XdeIG`kW50Q3Rm2~$5 z6@#v}*#dTOHvwTD`j|tAS^&YoWvnZ4YDU`>> z9HMPZcM?=qwebq`P}{SJgrK5QWpO4B)V83bg3?mTQ1 zLLDib1soFn3@pzC(tRWb6QvWK5%Y-hh|Y_~wENw+W2syPkJD2lp~3(o=6YM(L^Og56iKddZBKUoIs@Gdqhqos@E5FkIKnJ zI`*w{7Evo$gTl2U=MX(h^o*QGRJT9so|DByX|N4!i5KJoAAj5BLZV-w`?bVQxtK_& z`c-*1(ZZpqdqXZIdWPsNxt!=Y(LTA7$Qp(&56DuY!9;J%HAE@HQTMJ~N7R|5O1k|p!dl{( zga%2Q|KR7PTXgF9Ris<2>G&(i z!yu&?5rT2eCD}co7F@QKL(!%I$sVC~!Dcd;9gdx$t&AQ;yF+V%ECcDWc{kLMJ&L{r z>9P4W)B!ed7!4AhcD3!p-2Pw_1F~~bvU`T;T$Dqy4#|cj3qa%$!jqTOOk=cEdr*cXKbLo5S=P_7~Kzd(9QUYGgwaLnU! zlA%=QTga@-e=nJJjhrI0w-%)Mjcg(!Fa%x8x_)(?>e|%d{9Rq^`qkmAcKabl3hnZCH?6zxjzu>|L4MwIQoLKl_d@v*NKai1hX=W#{$7wCn+IY}gU!PvA0xSi_2f#d}Dwer!ElaDmg6rrp zl4Vt~m-w=39NZ!aZx4fzlhcyGTpx}tr0AEH4(6h?8XzAcoBe5Zz{hJ{*i5h11LV?b7{b%l`uMv=m4WLkyTxdd&yoC@?XAOmBZk%6(S$)H%sW*?bPW#IQMej&5&NkTKxeJaTYndrV- zCc4qR%`X918vj(bo_6coJF&SshPk!KkGXGK?OD41ira7wy z`qCw-%diF646U&Tv^vcrLOzGNUH5=@tQ@f}Zx*cLAIzH{r0djEBf565ggy18>+$wl zUR4uw{c6pWU@1=2^w!RgHLHP5M6FzqIkoBryTwDpu_r%9GI#`Kt$iBes$Tn3kh;|kuiYd>iiIR~8`Ev+bXp6rPfqIq z^0C@jCfpCy?g=)!2l$HYbt|>%V43)~-o!es4D26zhG5_OLYiA-xA{KJA)430b~4we zcIu{&g)slSb@Y4MMDVpgtuB<0ZygP;vk2_}C)(ld{hLm6aUHyt@rw48jIT>?KOlwf zU9sns;?p{hKstYdQu6dd?)*nWdK5*HOeC2O(o^!j{VIm(7Eh1;x*GQC!Ra{0WrIB2 zv0HkNB1vQV%={xEor{*#ZDn*WT0`+u$X4o|xL;1CaAU=7@(H;E3F& zp(89wyw&(~D6s>L(_zB)apPJbGumOTZEuIy`cZfdy zeou6WbIopn{5x}O)5}TawTGLlWVCUCjBYX(a&fL%FqmCKD}&4)S`}o?p%`YHp_#UQ zpP@P&UtiNeTRxn>w#gmlOo2Q$i3B-gST&GKhG80VhdpWA4$6<-Zwf{aNT(%$o2iV+dF&uXDo}N$y zvU_2CjzfgBOau8sVIIj@Aj{joMD{P`;93CA*sW^L@lZRR5|I`~H+9Z}bA?BVE=bhD z^ISxw;@yIX2tV-!5xOjar#)^QH`j~HO{#Lo^Q@!n(kZ; zRFA31d9Mf-O_|m^Hv+X~dfK@eUPaZFX}9wUpngn8ozK9Eb{Nw)&TT;BiS`B|&Y+x(Z?s(+bcIt03C@iWsI z&{Y&SnSKCWMd7HdbF2JUz=?h^QVA=@!yZ z6r`ZPVzJHts%R_1KIwGQ(c%JD?pyr~CDZWia zL<@15sV7iN5k@hTiqbZtBU*`bX*!hbwiPQBh-*wU+K!HBBj!+iCD6)O!~J$kb?nX# zK`ZFZY3NU1Iqk$6J7ufkao~+aWdg69j^YI$U1#y8O|wK7@vV=`ZsG)yzQ%fp%nXcS zy_gr2E_;f0OiP1m%U+^pmewr|YA*YTUQ8>4ddPkv8jlab-^QR3a)8KZ+7>if4irU9 zuLLcSgT;2Hy+JGGP*F2m`#T)8P7V|Mm`(*fC`SrdHd2_EgC3QmL`|l&;3ws1(U)m> z@Gd!46f;c;enXBETbN3M_sI$3W2P0s@5+hdG}8v4$>K88_TZ1?RPi&@uHfTxy12=- z7ifmCaygyBr{qi##PmtEbHr4lQc<(x*~qzK zEz^vS-$%|98<<`JnlIYr>G%>uev?IFDpOjBFp9+{rdlBm<1XHX*BlzGvzNx<%qQrv9K?Bn&uF_VmJwMW7GeEh34^T!t&qSSl(J6*~i5ZlJ2H zdkDf@CTg(mDF}0!$YkM zYM^mM>qS&(Wn-0i%%%)utvE?k8eQVPVBROz*3u=o)qMph5N{WO_W2@Fv`s&Nt|rsB z?&ETUc#Y`~p!>y7Ou=C{%m>60csvh7sTO9ajUqH(Q=2fCdQjY88W0wu9umXrYTcb- zQR)#f$)*JLn3!u*HMK=7u_;$QEn+B!Qc#wlm=<^Qw5A$q~K+o&(y? z6dt}B=mRDkxn38?m~iBJU3|`z2>#v>Uoq7He{YDZOgI9)DXuZ$2=u0qc!MmI8IC}^ zg^LMCpxq*jsS$+vmWW|$2VuS?sxb8d-5!y_GzxTkL`^1~LF^R`m~aNMSF~WlS;9Wi zo(X3O`$P|-y#YAd?-v7@aJ1hqMl#`uUMBD>3pj(o5xq>zB+|2>1EPqi%!Q?UKrCUx z(mfzbnXrW%6dRbZg&Y){nK1UZ#a1Sa{cZ6g6Skgr#H&o$dfpNHm@sAUiuaf>W$%iQ znQ+eVo;byXbB6cC1tzS`_r(<^tj+huuS__f_(0rZ!uiAp!U+$zV2$A%>_ZXCgmbVD zMMWko-9sXY2}}2oNN2)YIV^ISuvQL>`b^kDJ`&BCu!Vdi+A(1ZIU>3-VGB7T`ZG<6 zSRsyz;YG}$y=a1A)dFXKz$}oHqyF?3I*zv5KT1YRp_KX7bSNf6^jlPO2il9B-1FO zc1^Wz0Z|##7NToR2P*VdUxrnQk%)Fp9@ z=^-M~(&KM7=wKqmp)6Eiiz-BA@|B>4>Kjo&R4ks1T&OOK-L}i6>RWM06X=$zDp2%@v{R^;nI6Kt1zfaWk|MwN(b;%=tgsDtX7xR62Gy(rIGN^ zzw~QOd2r1Fmr`z|S}7IxcKJEllpipC0HkCjxx~7itt^>f(?aEt_}WQNz5B^*o7O2m zS=Xke$|;)@l?f~}mmFm4f~)|!kVwzAL*z4B=fru4Tkc@Od5BxS!E_Yz9wy6}zKE(| zg~<;!(fSWhknpd}3W$!U^CY66sAyOpd2~TlqhWnyQytL3W(56}1+@U3m%4%u4o_G& z1ay(|6N>MG3w2TQb0*Y9$%{-FX0*J@gkeU@-D zjg=zXb=1_pVmGU*4DF(+4^TDv3x!!KHg&BLlOaRNU#Y0yEiWun=8?+_F3fwDtj~mH zmL;1rVcx6Dc1)P}>asf%=DmjO&xCoeAx9ADyl2Y^Oqlm6SgSujIzT!%&zC70# zX`k#<@d2x`Y|u|rLd?IcJLChEc*IpJ9>2}sh&LCP3cduTv zI>{m?zt~$=7kP%Mew4$}RYnZLP}Ym^*e_*w*@{Sq(nHoK(zERzvXds~+}K1%54n+O zz4M;fYCw-NttZ;5UD7PQhy0Yt6Xsc>HDYsY4e%E@SioPYD2uJ@=p&PvPQ)IU{bUi* z8u2Yqe|ePYdTdk20NHK``dcFch1GqEhj2+;qnT*@S6JT#;jO&%mF6)(qaaLkZ_^HEnS z-iUk1F;h0T>2b$wxr}JN*c<$eW1jr6NQY7u_p;+Isfs;xNiL9Xo8EAg$eK1abu5y{ znQ$e1x4dZ6J&t?i#=CSVyI}3ROdhqV%&}a$7HHk|*h_MijJD|wN2zRU)60%Ea+FO? z9c$%Grca>E?vjIYJ1}7jd06&f zx*7a|W0M?a(^1DG@+i?7aWnX&<5BtALJYGE-cYncJT9v)Lee$;xU506UPQ#7cRViJ z+H}S7gdD|`6#uJZi+qkLKVJH6l{;;6`8_RvVrmv2?)RJ=wHRYqFFMD^`)!laOEgW0 z&+vOu7BgY%*)H*ES9FQBvO@;ntqIHJB^k+tCGoPX#Dr~dr%Yv<8^25Lk~vI^;*ZN$ zWH+Wq;%oZ7Dzop=VLk`C*X1ChQgHxuZ^)BOC*m9U?UrvZ)h;i@zajU^kC?8+xA5C9 zPukSZ?|^)DnRa;{bnnQwnfxjpm+#4QOmUTV$@k^=OlhF|Kqf8M{^|gIC_6LV0dzJyB_)-)R}nw5`$#pg1Pn^Y~mQGvS`c=Q4{4_b$%JT1>ciaYi;`!g!mjnj;XI~-Mb0veCQLaUXgQ!n|zjEWYoOn3>IU??O#>_EJFnX`7U-r;(<`@h-m+thqjlxz zfy(WC;@b>FkFU_RvaNDgr!+XXL9bQr?ImkYrI($C(UY#R3ldAvForW>37WqlWV!cjX7(zu4(cdzY508b(%&bH*-}mmcWz_!<>`c z*%f7MCn^<-ll!_V8WH!Ru2ejcJlGX$>?A4{uY$jLqu+g6_g-?LE5R7cbTWCaE6LbI zR4i^Kmx#*7V@wrNN?etVLmSZF1&O7bYLM0pLn3@oM&(x79;C}R1;_OQl zO?1J9{Zg`#$b|h;vQdo*`=t~khY9<6=r%S_l0W*a{<8-@ zLz%E2tYeI0!oD@%n978GYrZj;3HyS&#zH3S3+fuHi1bXZo{_x~b6YGnr<90#M$m&u zrD9jg6|}HcDp9exoU+?h-#E-VnR>-+U|eKft<+Ck4UCx&=`foCH8esW z*3>z5g=l1KWEujxM#c@M$*HGZjg90@+GSB{oN zZpJTE)1|^1xT10o;}%m}pk4-S0K*@g!vgg&Qkgyh>St`Cbe4)`gH}`?U_8lm2xyS; zGE>Ch6_tk=yP0|c4KqGq+6Xkl_=M>U&?w_8rsN?jDvvSZp2XM}IlrxTLX9($nSQTU z!5U{|G5Mtr^dE23VhT_H#5LY%q={yS6O5Lu>yy4hOfWhyjYwY&)RSp)I=nE?7|2wd zo&q$AX;u0OHPM*Jv@yMcHPN_}X$yoo$tY%e5yG5g+{5$+_?v93W_kzwO*S52I+i}s ze~R%a(--N}fSzW$0{*5N+nKI|zp2LSOgI;wX6$Fex$rdO114w23NhU{#^lae4fHuv z4CrPUUolky-3;R@Q)b2qHPg7pR41c?HPet=b;&o)nCO3};bQ8PF%2k;3C~Pt88J+F zW;)BL!nDP8OwBejn6|st0oBw*wKB(Oz&cz_%rTlX;c8-z(Vhuc6LXF3Ot_kuYYbq* z)x zVczdDwlQJe?=oK1M4>D&_OcG+TVTA)gz+sfjxu2=CB{i645h?4uZcogXwT0uM_$4l zc?nB!k?j&o&`bL>SBS;7?$gZGKJ+ck*OfTVhyWG~{DC(unS*8A7 z+L3jy4;_RsSJ?hOg)qJJb=E`vD{bA)tjB=9^(pIBM!-{;mJ2Q{>s3ZL6PEQVBaR8n zy3|N!!m=(kvY4=}R~xmMu&h@bO_;E(*BE1&u&mb@Q<$)<*BEn{u&mb_B}`b>YmMbh zSk~)|bxc^+>x_q(u&mb`k27IeuQ#4!!m_^Cc$o>y`d(u<6PERT#z7)Ix4F+a%sMRj z4aTRe!}-ew;|tbdJ=|}6&4l%Ezwsjz*24qFbtbHb2Mjo@r_#lG*k}YYVLfa#qBYUX z_(7u$k)Cu~<* zC7ioGZtHOF=B4X3KJtIUqqE%EC(F@Q|0iu-rEFIKd>^50>*=YgrohFXGL3VZke5i@39ncP&8f3Q! zfUhdqx)uTOEg`1<*#iUKuxV5_+=*b*^z0JxmQ5wuBLcis3bfZpH!)zpO{Lir0}j}9 zCVPIs+di}|0Nzl~v45YvF5o>Mnji4KO;*mjfDe6We!wA{&SY;1fL8@`C}*;F1;7h} z?J#!*eC$J80*={a%sJ^p zcY*Gdty>E^FX3A4w5`LnnwL_Oz6|)>*40Y-)`uR?`PGMB$hql5ujRnbp6&1L9N5{j z=~#{mJZsa%9Dg6eldUgo9iD7?2~V%Sv~_rT<)z;tK6uX>=RF{IwGZJM_PnjbHLRDg zFSuaqurKfu_61+rI_wL)6qgHodA1H$m|nsarcGA0TzB9lk4vDKz{@_A5_r|7oZOm$ z@HR}H2P-GHK_I;HlBq5byq=M%1rWS_(WaV#zuD9&w^<;(2a$E1z~xPw`sB6?{KJR3 z2f`Z=*=3*H{(;i;(8%0Tf$%^s>m~s?Y?=)Oucc$%-9YdnHBCVewCUyCSzfY^ z96__j>W-VmoOH43CCi1!5qhjW3iWTEQYtru@1*#FX31WxAL?ItT;RRK! z!;#rbjg$5S!aL(w7nAgnzn5_I^%9Q0Uc%8g+V+Q|ua|K2g_q26m^k`+DL?OIAiN!p zb$8^Q1?r;5V!HPr*6hQCv)EX3C{vS=%Ykv`Sf(~1SAnK78LpoLm-h2@D1l@FfnBkM~g(WF%ym!Rm^Kd#loE(7?f&me->SqiXM42 zgVN16n1%vnnFooA#iYCzLD^>Db2?0S_ErCy=0qkOb84GMnc4x>HKU(Lm&KwuuYXVj zb0$%l#4(_WxyYvZ0e6`HV!|m{a$M^2$0wx^ayPM0HaDLXqT+4*>vmWMyOgIPY zY5t1|=U_d}XPL0y?Pb2ig#B(W^Gzn~cYB)$n6TgNZ60F6IanX_I1|pn`j}^#a1Pej zyu^fau)gLGL}f0VgY`3iXTmvHKhxZ<%M9mW{mlR-oP+f@BbaawHo%Ny!a3LgGmS{k zR0o=uY)WwsG_TpTS`0E1c3=#}&L{Iqf(DyanO@IZ0hG;jIB!GH5R<-61}@L$JpyzG z=`Of%mN(RF%`U&s+Zr^~?51@R=S0KI9ZWbU8eyJf!a31M6F;niE!nT;j-Zj|CZ@2O zuLg}W&k&fJAAOGW3@{Xt{RjZ9T*9ts*~2EM98sZ;Zlpz-FlH#N1Wc{Zrf z4Bd@XD!SFY7&Or=*rRm;(LV)EHm?$0kT}PjY6k8_U75t$=rr>lq6-pdYtzk5OgLMc zY3?Q}7L~HC;8|vqedw=LOsW|hJlAZ^R0K5N>_UWLh6NOxLx?cUi2-++QQeJgrkW!o zB9@sYOp`{AOI>d6V0spGE6hVo-;BH~b)_k(JWEB|sECMFW{J)b-RDti?j%|dy<4~7 zQuBsQBZJqP)%Ih`){Dr>^Mmg->oL^^y5DTe)CA~3vma9e&?a*{Q#GJR&3R0%fgU$k zGWi2NX>MYQto%Um)8-3IwSk^9_b@d9+GZYMN&wnno@1&8wA1{VsWs56rUN>BOtnAI z8)h=o#9G^e-!j`W%>~+PPG(vPwBOvsbRWGf!;Q6Fue@)u9<#7$500JzS)*( zZsonfADVrc76BbL$1*JiI%3XdDhB%4T*}lxcyI70<^xPCLHDWo6w`E|&&*eu=2ku$ ze9C;6X%W!p=4VVxfzF!WFckxRX5*3-FhyGMR98 zUs(-)U+ZvopR6V`;p{#|mDtohFjZ~0sefRay1|6A`wZ3N104#^?z7ZjCY;^ZP~(_z zcAukWXo6F(F9Y(_d?GycN)O3XOIU|%!qe#23aP0!unt#>wbUa_xKga8wld*L zv9{XAge%3`>QyFODb`VYnQ*08N4>{{E5&?ulnGag`HH>@0J9)mh16B&S%<5Ty6OrO zt|IHHUzl(eSx?wsoa z+lBME(RZiap^~YEl!^vpwudxTUs6q%ilQ;QWHU95{ORkVxteR!C$8pdnI_S(PKjut z93Z$wHE3S6Ry=-s^cD)uvTlS&NAUzt(CgOgln}{>IWuVs}-o< znQ*OEpv*(Mb!5V|T07N~ z3D;`v)F38YtF>37m~gGuUQJ@cwOR*tCljvKI;gvtaIMx+-9xm{xjto3NJq7Xb+~ft zq#j`1?3ArRoz!Ej!*yI|^)wT%<2tJyOt_BgqF!ghbzB!!#)Rv*uId9OT*q})pD^J% zuABOt3DX<09Inh8(Kda19N@U*PA`i==t%X+J8On6$>N5LZ{m@+4xmi19CCOj?c ztK3X@TGm&^FyU!gKUJ9tPs{qL3?@8#>96vbaMjvhHDJQivH_|&6P}h0Q0XSK2~KgVV^u!)nvkyjZ+PnFlFOZ z3non2c-5W>Q#M}pV8WD5Py?7SWfRm$qD4+zxfLq>usgOMT)7phnVO&kzw(=?788|` z%Smdbtt%0e)Mg@`he>LyCVGxxvf9RkX_>5EWx_FMirUMB`J1BNW5WDRRY#dHe^b>d zCd|V$b)E_HFil+{(pTej6@FCb0o(3$70ZNece+Yu!lylEs7xk&+GB>Q#e`2T%v24T z@b3MYswL9{bykMlsX8z{S!W$kPo|ga98g~TKV^c6sgNZrJ^8zdq}a`_ZjL+MX&r_A$O@J zCy{jPS)dA-uyhxw&P-UkC8{?QmTrj}!i247p&G-4HMUSqVZxGMq-HZ=$uCkPD4nHZ z^VmG!A-3Pso0Qnid|y%>`Je#lbwppS03 z`d2x6#-?>@xq68RCem={^a^#r)|CLAu<2yT3Ux)3b7|y-kd^8N(HgNX|C^9iYUU{_ zGkEsumyp$JG1I2}8zF1eI!&&p^JVBdwV8EIqi%$(Q_nN)$ajUVS8uY*hay8m?^EwF zEse~v?o%h2W<~uHvO!&9e@7ytLmyD;w2mF0;M%C%Ou12&LpQ4CO!cEOLmyN-HPJI$ z53Bu5_{`SB>L9yp3jQ8eCz;Mi=7(-lSBUiUW1IA6-T7|wP0IN>#$F~q%x?iM=QDkq z-yw9f+QbxCw|nTL>OH2kx`RR=SHChfuRA()i>i7?hcc+{l+dTt$+Mcq*PWuCQK4TT z>8CcHQEQ3Ti|O^A41GrJWLi@1+0bXzMO(Kc^m$e7OZ0~>cZa^H@@zU7x7&q> z)i9<9>wOx!Q?0UTd&nzl6Vo&Gj>}iovU8LcQC9D4=xZwOyrz%pT@8Ixl`x&EcO!I< zO1_|V7wb9P`&G@0ntrMm>OQFUFA`w++@GkEOg-zjaDS$TeXDgN>UVaZR*6^GUw&`* z8I}K?CcOH;P}_;tJJ;18;r>#+!}N0faX=q2{ak;h8@``Te`Qu~gL`~vdc9Kj1$B{J z>TC0&YIYT!?vqb9*cftAwIteWzSrQW`;r>QbfLj1_t&b^_vmu3`CEf;+~25vKOmJ! zjN!7H%7igoQBPk(-98!EP=sAoyP0Ad-sApW&G}91a)5qR$-g7%*7LKPO|)M0Z0H~M zvzo^g5g#7*i+YS{DCn-K#Ovq}pPQ%@_M2+SG`C^3u*^y_lW=U5Hg= zQ&Cu`^%~P2(1lqO|Io4TX;c&zZmnlJ)o6KG1?wT3)`vw}`6>9G-+P`dYFgGY!%|pRCZB42 zFf7%kmm41mt5(imx~*H^_(T|dFp0uMe`ms~+w^kd%VD|Y{N>rY^^JcFt7X$ujeiTP zZ4<^3LJSq+Ga#oWqP zcynti(^&|!g%zRD-vt=s+K0EaVwpDOcMmVHs%e5Tu5Wm2t2XPJMs){j$h0GWSa=%? z-$#tIi-#h|hqr^(g{GyE7SK?pSyAo7+goGU-;v1a;T^3>OgP4Mg4vW#OK#L%;hn7c zO!cEygm<DM-} zTCz4~l1o>9yOV+atj9FT3GGTmKkI3x4MdmO<wvP+D;zjc*J$KKxxsi9+! zga_9KSSxanbh!+$)@u^GJFJNuV9lxR)eW*rG>M9xW1V{f1HHoi#M8*%bGJSNztj?^u%qe(o}>p=WSYtJIDZj|+oCZYPQO&DdZT8_H2vQyuW6GvO; zn6Ms3TbG%z9!6U~tt6MOwS8BJ(bf%3R1fg3=T$lstcTH-rOAc$FxmLBTEl&GldR`iS7&H! z@+51yk8ZNHj&%cvUJaaVU3k_T<`nCSCUO7JMafgFcF%cr)2wcq#2(O1vtIDg&9HW{ z?h5E;SZAL1`n%J*s!6mO7MpUXbj;dtM?ISe-P9o1^251y;Lbp7`2_msmqIIYY;u z3|wT5VX86qNX#N@Dp47&mKIsZnetoDsJ6&Tq}5rOXgc~ z)pa7b&hq36ZeKKxA0Amo@;Z3g>U2q62m5*2wPzt@zJfa zK4aZ|pj!p+mGJso4ew;o{@w%KYAe8JZnM@3*Cf=W6Jcv%CLo2o34T8*8l)77WUfYL zU;F2q|5-c8`Deem_xH<$+jKQW`&Q`Aq*nzD3X&v8u0d2 zbm=R7?S0L@Zf-Ygm(w9kQ_Kgc#1fxawEbEidz}W~aCEEC@?r8@wKk>@&8E=yShj|E zlx&()%C*f4WP|of_}Y72dajhec5m@@)T1+&hHfXFn_^s#lZ|gW|KD!LQpGn`WA1dR z{ucoioxwIlbs{dXmEucijXI}FSw#Vf_V zU^c`Cve`^-yzWi$1lXu@E_E6(Gy~rLjNv>_zPvV4_?laF$2@9T))URX((BR_PCV84 z4hj>^x>tlzfNb6(c@U%_jzC^a@i|B(z9)O^If0sae0j>p4{Qt(1kx1n@>mE{_p!b* zhU`&#$|vqmHrkgbCE9N)xk)EqnPjd`=3J1b&^9_%+N@Ke&FD)C-?Y^t8w}HvT5aR& z2Gg%NWVDBG1K85=vG;_a^Q+zHlr$js+V7u3{=3l1r_(n~Z^(aDJ~~ESce=#%xQ5bz zH^O83y=IeICiL4>o7m>1XacD4^p1Xd5Z!fxXA&{bYXF$EC0K1+a$_qddMu=G&$2wRG;Zxr|(D za~}9L#UZdMKSq1)J?;PR`m6sv_Ik$k-;;*;lyZu`JZ5d9rB3;OFHA{uKTl}BA?q>p z9L4x8Nne|*U<30;vd5m&W4=!Iel)X%mr#R!44Hl1_?odbdi?5^sbkS|r2jp2@z1eT zq4cMb#9YJo7<^=P%403kHYBNY)RxRWNvrdPvwcJ8*|l%2dFLna4Iy%)OIxqwwDgV9 zw|owDz%X^%bokMIFopl8%>P`H|5y8;mjJd0&-Lu+W8VV0T z=@QU3IDat3^gBXB%a1_|p{&Z=FQe;y6_p{HrTDWngjZ{b2YuY=8Ly5}=f!LG%wxSa zlIEqJ)xqD{|L0}$?}y-Rb)J@kqshPDCY9JmrLh~NA@+kbY27Eq?KV0t>|IT97^LEn z>pw{Y_Uej4`}bNP#^uSWwoL@~gl`W=UoXCL)(A|GugyQ3y}35I{rq1W zEc4q-qx?>$x0L?BYyUH}OoQ8!He(+vh1YEIKIETmJUa=0w*M=?xC3B^H3rRk-tJrS{}X1tzWARASK5IRXO|BWUpP`4`ze4*m68(U4~l5-+}d_ zck0kam!TA!!M&&6^^TmDf9GDeI$y1?S^M2aY48p0WwO~rarxS7^C8mW_bv1;pGWGp zdh#}V^ks-kx7q(dHd@}YwH}xMj*a#k(h^hhpO}454=X}wo>8e2?YE%RD_>KfR`R~+ zpIv&cLG2!EP0vr%-}=g@YaHc&6~6Cvtye3)De+BzBBjvlUbhxc+REGiulF0eO=dw{ zrpTcfwM{KB>%a0duI=rx+_cntN5^3YNeaEsuUn~3o8FDr()VmaoAoY}4oB}`YISHj7djR+8=?dC_E<8W zyklL%^+M9yy5Q@Nc1zP{PknjYlE?n?L<~XOU!G{fHy;)JTk!9I|7eiW@a4y7_-8LI_<&W%#csdWdeazepAR;Y)-4MRoYECL3EZB_|&%*yS_jAy8<)LF4hDH9 zd^AXW7bD6$K~}Je$$U4-Qj!};K0@+Ik}r_lMe;3@Z-cC09VYXqB+rt(1oHdv-$1TY z(!|*RAKKmpKC0?m8((|R40i-1AtVIIgs{}?#qK_*Hbu4Y2=e>*WNNYzuJed|#H_Ul`%9~0~H|_FF*>X$;nAQ=dl1)Fy=x2uK z*)0X>eoIpETQ6=YO25hE{qk_}jTBc)Ik2l2cfHjQ?fE^D^UknK8Vo1{gVv47j;wkz( z#b3=mg%rn~eTu1^;;-hO;;-hO;;-qRQu1rMrhqYo-Xk^Uw;HRfX3g-lSIgIi_GA>K&+zQaH~>zp z`s)_%<5nL5eN*+*kcv;!&pp-nPn0P$3`5A?Vo>aRf|N{WIog z#ItaF)`T~i!vR&X{p0FA(rNgWrI9HgkY4AxZu`$?Z)BXeBe!XpTS-r`hSakrSXO1-uQD^i|2=T>>_2AadatjW zm^D$|S(lcziW0tx5?)|ESoa!!p=#rLe^v`~-i|!irN@}(0_&^rzsveoT?i<52#?SY zq^R!avkR=Z>OPzmvqV2g{Ey@K-urc5!v>g?`WR!l$(m6A`V`BWUN5QS)u+Kvtol#m zZnDaz{V?kT)Z}Y80vM_PTGs6*=HB|B&$g^<;eR4}!PGhUqSV|)b1dtV;0&OQMRSg; zr|Qq0Q|x`dzHH7qZ^N3+b7r8e|2l1*_pSOGaNerlJ!c!r{t30sdrx)ioX6B3>-W#u z<(^0>#mJ{OJJb4E!<6j%*uD?5q?wE%)4FWhBDlWYuq^utmgodA)B01x zyQqhWJER_F0TFY3C>wd$(Um>JbKVZQ%e-O7)7EkIR{d4kyS!U>T$^2tvRsSUE`xvZ zIVD?a{$tra-u@l`C%e!4$d11NPwXhh??T0@7tghE_ITTK!~KFZ_(`x?sNe*@z!qld@Fu*VERi_jb*MOg`E0r*WAc`2`ul z>*qi1Ju>gp^F^!NJAa1Cx#X*$&$(o9{`-jk*|TS;<(EtX`Y(A6u3Ikoulavvx&fds zM>P2z-Vty6B{Oqoc>Z3Sm-CY6t@`CTUX1u7Q@nQ9C9io!Tdo49Y})HnW_WJ6pF+e(AVeW`qENG|6!_@6ubq`QfZPfQ6Udkt6YZ9plA$J08s$z{v6>@;1EX1aS4G z-vG8(KMFs8ukB0EwXVu*9RG@U?d~Jvry$SI;+Bxyd95_`wYw+e2Jrh>1-Z9cpWpp) zRp66vG8Fhe0RI(Lcv(Sunk_mZ+ZIi@fT8ZP_Fne(lmg$O%WllQ%lhPH59Y4(Nz8uV ze_ZyZ+yb9`H=@8d?(&xqbNb~!$St&Gl-%aayZo3cWDKjwDZuYb%*-qB$roA*eDWo& z0^ei!+6Q9Bw>0`J`94^mCEqAJfL|i~*7!avbordTKI_)Y^YQ||&tES751FuSJ~uVV~Y^6iOj zKDooZ%_rZ|*yg*eDZ?JHzfKNt>13vjC!U3Or{osI4zH@+_j1d zZ|srQJbUpEAU{9YlVQ(LuQZJ0pJ2^jPwDFOU7J_DU==xiz8mITu;2u0reeWK*8I!% zCA%jsc-fv^wtw2o_Nnsj1+T&-+ToJ~{6jj`)AymOCAPW!{FYha2pLUQc7$tc63?7g}EPdOamA z6BbVKd;|0p&nqpkB0L{$@h(X79BL_8m<_FaOl8ym0z-@cLehoCkK7CSD@#$xu!SDE z4RROjYRK{g+ZQhIObK=avx7$#u3}oNnAR%Bvx=^(=vqq7M&edtJ#n{3?!nFQJlXJd ztHmQNzS|=!URga;NG=qN60@$yoq=_)4kgxw#|JW(LxWCbDu}7mlLE<5?}U+ zo_WPzs*qZ!~Ze$J~{7u z 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%0DIhxI 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 literal 0 HcmV?d00001 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb new file mode 100644 index 0000000000000000000000000000000000000000..a7a6c4d4364bdf59f6d3b8fd0b9f68752a88cea2 GIT binary patch literal 15782 zcmd5@c|cTE`+o1-8SV^&+YBNgi!6em0W#4n|ow+bD_I~rkj-}t8nTMo_Rf_s0qZ3efi`k6&H7mmJ?F)J@=1TB5~8lN;K zCvRkF!H6Oo?caa$%;|M2J5EYJkUqpNep5Ovd&=6MFrp~GVCbmgtj7d!Wmi&>f6q7f zY~gmj>hmyj8ZCNS0(b^<*|6Y*tkS%pBZ^HeG7w!N@R z_q4UTSJqG)t-f&IxoYrBhjUI1b3Z-lkzHeYYHp&^7-7@8jb>lFadM5@7mjmQ=>lJv zTb;0ga{vEs{p|j4JLP`s#?kM0v8EPMwziT#eL<%CFNJ*q3vLh0RutdQM#hyqj zEo~GWTevi8;3Bc7Kk-vJ&Y;ID%%FD-(-X%z1PdOThC)L?#Vyd$LfvW|tD5+E9B0(K zhK8||RD!dEiaVmC?{r7ahnI4kUT0uOg9HaB6?a2NH+8qn2P@dY&>S2L5%lgVZib#_ z>fg{y6|d(w9Pr}S>ghfGIxC|ew_Q&=^gCfxlX7HM>9fRXpC6T1{9?DP;;i8%q;PmP zFAEp5xyak+k0>5)E-3Bu3x?&H3o7-<5hbOj5xFmtokP~B(r0_-m6jG14J{!-U7S}k zazs%{9$F!G(0HzrBYq3VIT^EKj7DREzs}HUhHlz0*D}3pVPR+ti_%XJ^e(Q>&VrzG z6NC_h;2NX}&Ms|)Zu?$OpE!QyC`N}fxv5R5yy>*2|3VC}DgH4AA6qdDd7j0vs44x~ zbc&N4!+s|^;B*k>CzyvfxXsAJ{+bwk4JJb@pj}di{BXSLm#&|OivY{`UBii6h zb6l3X$PwLep_?wZP=10r+QL;KN2d`{Sw@U8+i1!T6)zcHt>C!>^|KTpxVAu8h{b&M zSfa`q)kts*^H6c)UFm}Bbyqp6J|?P_kRis}}0 zsl@~KS=_4?{J=W*RK-d!s_?4xvK-H|x~VF5dC_jKJ@V1vR(Dm!IWIczbwNHlO1!Nq z#(UFi-eumF8bzz0Vu3d;^j-w(6U%rY^K-PQ|)XX;OOfpQ$R)(C7&IYqQkDem~t z3Ey+RawzY&q>U{%wS1zXEaJWpW0{GYto2kU=Eg=$A%dGXo4`Y(>rCJ*MPgjrThhCJ z8~o(BrufrT|8oC-C9a?TYh2>w9rU=Ma$mp%pjhZn5B(>%k|R3VicYoqk(F&s0KAPw zbx6$&z+Y-bms>rQDpT_Hm(_e_0IdpG9Uywc33V3M{N4ciI^Y}maGj+!e=&f54XBn6 zn-|yoq(GV+I3>_hsbu!!-wLFqfy-ci(w7fkcYR%JsEH}T3avvjP z(!p1^rc13aqx|H9sI$PX8-%1~n)2zLhik}!v)xo!e<>e%QPSu;5<#2W?`SVaG&hpwMb3{D%St8R zlGE|m*)u7HJr>QbVXmR#^Q8txhh)J)XzSvjQob8WDKW2qNq1v<+z#$Kv!aw?sI5{pIG{WoMQ5VU%GLJg^l9w5P_!E7UW=mZQ8(mcS)Bek95Sd? z%4r?w^$ycJSQ=Bv=@W3Iji6Gl>_8PAD%lZUdJN^@Cvm$JiBo#B*1f>#v-M+hvh~?H zdR;C)s}kHaEgJf3nl)53Q7OOZK-)WZ? z-VhqiS|&7ZtP!*xg1g4QkxDtyK;?$T2J1>VSE&-$wycsx9OtMv&9hVxAZXj5o7jiH zG0;K78GKkl+N_ZUo%3GolQnD<9_6UztD#Yh?j;|qDk5W$IUBdA`C9I-PQPH?? zU5`LV^{B$o@W}Sz{55f$aUAccXut->3{KDpo{if&HSl+7&_FAAs+4DqRBe1DI#8G9 zjVU#~SenQFPE+#7QJ=vmj)?HqA%eR~xigv$L?4Wn5~<>waRwbKb!hIUx*AQ_qOZ$G zJUA0ZHtXaR!9k^(5<^pC%3~~_^A?Ya$NT1~8>kzoR24B)8M8`0L(3ZLrrH}rU&nl7 zZS_+96ho(D&dAm#>|7t!?HIZfbJyA$qAHK2X|b=zik@+r-SSv^JN6x^thD2u*=JkY zy&p>(V>ek_1MPOl(w^A8veiR6_s3YOiv7vj8fbSjmTtw~maRID*C`rtnW$Z_*V|3$ zNK-qOceJ!ZsOU(Q9al+ZrNE03G!r&=q%9pkwzj$n-*%+^9S_J>C)NsA;pdKYuH$)Y ztEcdLN4nqf4_G-;lw`9k3cLqKmm%6<$jHE3DBh%uwrVWc3-;d4{RDeo_dw_-Dq%(( z&5fHEC#6Z?gE+k_n-1IrSCz0ojt;~fl#aosu8yNiahJ{Ks?8y&@5j*}aSyDmZt9uw z^hW%wc&T1BFNL698BZ1QmDW~I_11X$EdF!Z+MI>!ral}`N8-P;wtA^A#?!Cy)v~n( zJJ(D7XFUBC|H#_vr=DY?xu$t0OB-5B^{zJ28q->9tC#u<6Kyx`kgb92TzB>NCi=m2 z%-ZU$zHFi^rr%)YEM2bVLu+@r*zYxOECXUL>ZPHjM;pPul~<_w&CfH)tdJV@_yn4q zFeSm#{IpuBQU97i)d`oRV`!;nLLyB}oRlb?t1+iWGdGduCC<0Dx@p!V(%QuLWUH8( z7Mksev?Fn+wY8<@heSG-cwDxMsd3d@Nu=KruUcC@HLoR6S<-|gOB=-0wA3t2qD4t> zT3Z7(>yv0h()+SiOpUwdt0dZ$wAh@tzv52G}n{pM$%1dtCwa{Cz{-8 zN~c<>(O9QO%!Q4&dZ`h!B3>o|-r?p8M$8XVqgm34-s!XgZrJsv;cKTxQSn(ynRX}dk*(5IV}B}{eoU^iwtCv%NT!>~ zw_ue=q5c2i!ndECLeo=bq(~vyTV43}yHjXS%3kRhLeT!4Lg!M>o6psnL(tw#p<5}p zt*vg_DXBCywLDd-S1Vok9@?d;v@CVGwbe)aVJdx;x>>f0qsvqKO)Bk6{npy*t38uS zXH$Qct>WnN(B4g@d#S%$TYa>zr_uDZ8EKX_h@-2y_MJ3Zk@l{&wT1TMH2Ng%Q`stx zE)VU2G&-1e$lB_oJ)cGw(teSx!EBOfuKgp89;7|Awzkl|(V1p-p558fhH!SShqj_K zRd!xwZS~Q9)|o!4#_^u}fy+v8Upy5dN#nQ257=+j=D|FuUt z)A7zH zck!?i;`!37p;%Dhy@XVD`1%*VgTpQs2fi`qXeom)W)+=ELJ{${0W1-Oy&Ne+l!*v;9h3MHZ+&jernAy^p2^MqJu1c-4tybAu zd~X>Tq*aDS8nwz0aI{w0MyvG3p~yHibwgMBs_U+QY(Zz%g5t7pG$IVHbQ$KRi0xpG z%}#x_O6C`}!*#G$8K6~)uHlP!*qBbc)Ayv4LRk~3eMxCn>8O$}1tq1V5Qc%U(~k5Y zBOEU+D}7(!xX`|w!qA7MXAo=2*l1UyPFLt^WIN`eVf>%snv&c5dLT zR5_^p9Uys!Mcrt7x5M2qTFl$aXB4w}Qu9?DcF3G^<_yvekY35A?7{05%Q>x~OmCPr zEi^{WqHD+g40aJ*1!ug($4Iqyniq7Zh22+l7e^w_OivP)1kZoVm zj&NBIn$Tlr582o09(1P1Syndtx}&IMaow!zD=~XcwzO+oJGy8?cA5Hhe70+Cr{=v| zF+_Ri_F50R-s3@y=Mz2YWY1GQ>v`VF*NO7KcuuqOEbXz1p5-0Z>Yj9|=N;w=|IokR z^`fJ_zVB7zc{zWC#XK3?8l2OLjF_A`0~SvUl~anx8v=K=R!-%p4O$OuGl~14HQ5zJ z@9ZyUaVPX#FFN1r8uKQ3Kir#+^!~1QjrZU9WlDHIA$rf2yl2;V@5DMjjJ-wH?s;ik z^|#f4T6>maQ=}csv%Tr(-oG)wQaeucp_6@1^{Hvc*Zc$43+q(2dm)K6A*y~85^OZV zytgQNmv$Db`_QF6cbGTH`?0=syzhy=HQq1rOIRU9s-?e4?jW5y}ZwLxgTBW zcaM1xJu3G1rvv>D_OJ1HTv5)89xvDR$mWsZw#J;%${~CDB!?(&+*I|apZZrbACk`< z8MHIw%ZwVIW&B5y&n@CLUVp@i!P@j4uWf;iaBF<5}u${xP$5?T96hVUO=> z6~AvFeLL_Nt6lWQuO38e2CW@r!<)@{yS}#++uqC@4WA66PY3N{)l2Rc4yHwe-yCei z-L1M)cio{R1($5woq0!K)nHmZ_(N8`{k;q@|gwS>2Ma`D$kmiRpUR4{>Xa3%H})sGXAjC<157(y8d-zJI{%>d|OQ$Dt>A$4yC_TmaoD(&aCDLDQ-w?HA4w<$L8oa%eU6!W@p z1HW9!3A_3G=JImoY!#>3qP(n>9%a6z+N{D7U(L6}4au>1;Jyf5VVP+_VRmT2xmbKz z?SGPnf^#w1`o%^^#VZbIH6B7Y#dK{lH8N=eqMMjZLPSKP2#r^pCJ_;m3<#H{Z?G&q z1DSN!G!gKGd37$W$t}yX^qBJPe0nE;MLx>rTzQ?vlT|c401ekGR&(|P)a} z?#hk%v?>2HcD6Xmm8bLRO#WGvo8bGV$@rpa0HA};2loQ>&=bHVfFtzV;8{RZ=*{5u zfD`mS@RvX{=vVM<)kMG=;B61et<7@8TeJ8C3M%u zM1Qhl(1W1|0Kw3U!Q+4s=&j&YKs)FY;JpBTaAbE6{0o2|7uh+W^LQW}+8gWwL_nVc zF9F&^Uk3jQL_$}fgL8l==*{2{fDX_vqqBnn12n!|OVa=&bUHd-0Pv$GyCL9#z%$Tq zfnNf;LT>}F0n(wX!25u1&=0|vfbP&bBux$UfDQnA0zIKmgI55(ps#_i0KK7CBC$h( zKF}Y5HvxU23z6iuKtJfQ;L$*T=oBRU4s-@|Kj_}T0B9|ee*}6UbaQBDU=Z|q@O)q} z^ldP{`ba~dKgIwV4rD^_1@8i~pvy5>;(=`FH^B>l9O!Ssl|U}^&)^dP9{Jn-4!#ED zLpQ+SQUXJveZa23v(UZ3MxX#X7n}tYLXQVO4?G9G7(4?Q2K^Cu6)+t70r(_P1l zwmC2Y`Xz8CFcSJ07+rQC2fPT~6c>jBFc!Kc*c%uJZ3Kq`FF|()rvNWQ4+RefUV(lYTnfAj zy#zcB7!Um(cs1}E^iJ?6KpFIL@Ihb#^i}W$U?Mb+i}C^VBxnulJgKh|HhHeY?1-3vZfDORM(EY*PfKQ-Dfb)S*p(lY~0=7ag z0nY(GgT~kKXf^OT^j`26z&2=;AFf|kh8_%^4s3@m1wRMufPM)60N4rb>rd1K_!7Dj zoCJIY-LMt<6M7f)bm;EDZs=<8yTBgk`{294Ug%x{M2p>x4mz&Fqb!Q+5^(5Jya z0^dTX1md&M`=R?m_XZ9??*Weh4niLT9|aCUcWq5{75XsrVCVtB5$OHkQNVZ5Rp67r zQRr@Mkay_sp);We0Y5;02_6j`gZ>VD2sjSizAdgh=o8SLpc8KcN0<;dg5%3Fi5jX(22>l9p9PlgjHSm0(8u}6VA#e%0upQJ-|(X>(EYNm=~dMK>I=a05_p~fun(2(7E6&fFtofAuh=L zQQ%R=0*?Izh!!ct-vLo?80}DQ3Zno%23CV-tE68qr{bVJ%725k;LSM60Xz&RvHEX; vQ5D?esDd7WS^bETdzaIP_?WJMB literal 0 HcmV?d00001 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/nunit.framework.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/nunit.framework.dll new file mode 100644 index 0000000000000000000000000000000000000000..780727f219d08aa635e12a56a326850ef82dbec5 GIT binary patch literal 151552 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%0ANEfz#`T+5knLeJ%5cmKE0sc26YHG1oPt)XZ; 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≺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 +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = "")] diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt new file mode 100644 index 00000000000..9afb7990f57 --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt @@ -0,0 +1,8 @@ +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttribute.cs +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/nunit.framework.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/Newtonsoft.Json.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/RestSharp.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll new file mode 100755 index 0000000000000000000000000000000000000000..bac89714b9cad85af8d64fd3230169073c376c63 GIT binary patch literal 51200 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 literal 0 HcmV?d00001 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb new file mode 100644 index 0000000000000000000000000000000000000000..a7a6c4d4364bdf59f6d3b8fd0b9f68752a88cea2 GIT binary patch literal 15782 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 vQ5D?esDd7WS^bETdzaIP_?WJMB literal 0 HcmV?d00001 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/packages.config b/samples/client/petstore/csharp/SwaggerClientTest/packages.config new file mode 100644 index 00000000000..d4e241a20a0 --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/NUnit.2.6.3.nupkg b/samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/NUnit.2.6.3.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..61e3a5ecfc122b969532f236ae4d08f73eaf6a67 GIT binary patch literal 98508 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%0D84oaW6e%A6a8UDh7;bSxoYne$N4r{Y{DLv`~ z%pmOGQJ{rl^XKoho2g}%=M_7X{}wuTnV!W}kdz0@2rgwjo%1mv_Gc|_I9ikussgp$ zFH9HA05gG-#9>T6vw;hbwx2?>P?uM!<3#g~AbW_P#RERMdY4)W2rK0_pY<0bIjz@O z*3>BbSc^TIoL~_3P-K;laY%;b!5{h?7BD zLAWXg@Pf#VUr(}H=M{yenK)0+wQ+m0o;LKG@1@tOzjxlO-s0P5VsO5zFnI?QEVs<5 z1Npv7>GZSA<7H#Wc8oE%N(S?p{jUjEjMnpHL!*oncjmmZGgbd!e!j09or-B=+j=@Ey=g6y;+ zub;pM8V*%4<-b+2O51{vng_y%F(#tv(prny;ZgEc<`|?er0aJ~OF7N&85?-YKV4=_ z*FRxq#xh3@k!!dVnT4=bG*EC3w(cong@S&bk8);++pv80r0qs0BKBF_x$uo_T=$AJ zieP&ZDob3H{z2JH&F{Cxv%+)oD`5H8;Hez%O(8XveC;7^ ztt`qV@g_`6CB7(~`U=pU#M3XzVN9IyQx2Yc1A0bJXSbqkX$z8H`Gu*_DN(7r@^|aR zg==#z3Ej#A|0`{`|9Bp5ML3?sxB`e*^^{~AgkyzmSK?TyDs??}9FO5VLI93 zBB3iWx7r5+f-KzXl>U#N(jlyJtC}GU(ZXGrDlCuPkBqe^9XFMsz?i@t&qyIfybe@s5PMn_nTob(I;U==6tEU)S}t%e z%^5WF34dYxnRS2g>sa{$aPnady#f(Sy>RzrG=Hl?IUi^v{g_HH`nlG5rSQ302N$H8 zGB-`ehq>O=SQ_6|roMqL%?-Hurd`p`ECyEDYuu6VzmikQ9-mxSLN}$&h6l7R0Po?> zpWQMZ-8gcA`zPR(SY%~SIo&>9j*s>UafaD|#!7nS*xTvc0yoyGq@2K&UhTO!t-AC8 zQ3cAjqJnmW*)XigzGF^_A-Soaaq2`Eg-MJv%zBEhQMaZ8vEK*sPM%(^{fV@G<|p-#RO zyaFP{9z$E=$7YC%PzPI|%T0pm4Yfoc4bUDwbKM`>%8#2MBsT~X`4>V_$R_zUZiBLk zQBZEX?}uk>lYRlSt+0`3xi&si%{5GyUNN7ijCV-0j`3GNir`)%DQnQ3AA{Qw~z)}^h?=S2OM;nDcXLegKoy}pX*4sjmFoF z#O2pP6(2zLN|-;}im1Xw&x(E|FN}fgb#9dY(Vabj$e7F!H5)ZF$X%K45B<1Gq(8bFH6e^2wn)eh4hE#qP&hG^ElFRc;e0R{6Sv zn#BwoD!i8e!DMu8Aj(h!Ex^rX%>olhz9upGIrK|B*c_q>yXPua8&9i9-o`TT3^HO@#DK}M3``G(CxIXl;s0*oX9%yA6|9QoTZ3R2^ro5(9RgufSF;FkKEI+`P2D z?;Yz-+*jqx40MLu2h*tg(RrS71YdKwM<3S*5#-@9<0)(KIg$*#Q$vfuVL!wcBGV6JlKK^^^Q>J* z=B+8@n>Iv@#4j6q;53R`$(*O^ng{lt(#qcfo~M^Q4k=L*kjtzO%?mYFJzd^rr(VG# zy!Byfb|c2L3(xENqia^Q1QrxulJpo9o8k6Z8>W3f?S2F1 zsYHcrK{_R(@X7Myc`8bOuB*l#61p?+OubfjwPJgi9o*`S5fVEU({fk-IMhE#Vl>+5 z_wld2+OC@lB&*vz%dN49mf6ZR`Dis?55fMQ3VE(M#MxnS4;${cj|w$MDy()h(Izw% z@0(sJ*VWMCM4#*Rc0o}?QHGxGiMX}n;xvBHd<>>%cMG{-H z2ICN#QPFx+IuW1fjc9GVcc{NRPW$}9{M8k&5*+5Cf)UKF1GT-znue753w(kRWUl!O z3?LNpv_Z%HHDIaKVFAwioI}y(T7ODqMO1KNb3TrBXSoj|Pvps>CfTf#k+clE{Ae)# z$vMAc0R(v_iicDhJY=#`c={j3+P)Ne^e#lFJVo`Lh3wpe%z6u@Id4_-(Exp02<{1Su3qWs(R43>Hh6(SK;7kz_g3yWss>nk)ksA)J5IO#>hrx? z_dKg)M>MsvtX;PTtLqKYo&$&+RqD8ru`Zrkdin}rZ zSn;aphF0~Ck_Ox`{QbQh4_#r#*uTRJI5UMA3nSQv4(MrA8Il9G+UkCPp$6$NwRMjn z3jiUcr+=cL?>)YXBZVpZ+_1909YN|_GK>BXA6l%&x3#8=sr`aY_EH7OSEj(Pg)38+ zhRYA}%L$={eDt%w-u2aWW`WnGNz_>{j9?#Oet%70nEE_Zr&)>U_{5l13k68h8ntzj z82eL*NSZ5z()i{3iwuu?Snu>bSf4f$=M_^ImgNnFfk^e|&dC^A3Y+ZQQ535f=3ccz zFV;XStB)Bgwg=Cbo&*Q_{IG48De_7TOk4EfMA{bdx;7KN0_uu$__Q-y?_y;k=vkAA zfteRe(y&~Mkh07sA0YcwXjws1$$1aIT?Cqt7g@>y<2oM4{R1|bt4t<7l^h!lUc2GV72V(BtSlvf=jCJ z;sZ7%@Bjdc8~szGI`_HHAn%+`Y3D0Cu1r&#bc#Mzg|F}@&zjxj%14JH0n=V`;z2Eo zR^?alNT^YHuX-|Y0bhiQqh5p_g@EJx5U9709p%j=GJ7V|^=$^Ypq`?yohv$nRW+=y z2|n`!>ry)|X+HW$+uEGI1$PT$9{FTw1SaHle4l?%x8C#J`>QcBDE-j0VPjm-XNbPS z^*Awo_M8mkkD5Zd#il22Ksp@8GbX|H~}vg`TgeV-L|cexRu z4cD`|w1xENuGN8_ED1Z!;NOy)TyNwKAY~My3wh5Z<2$VCI!h*AX6C1#e~WPQZ|Etvvfd+4U+fsCD1`dhf0f$1 zmC;I#njihCsDhSji{Xsgi0;bEK+Rd$d^=iPdywh!VRId61`tpQ$>>~j-sbda7#ihxuWg+%L6Kp*R4&77eRG{&6jx^z@7Knbm_ zJd~*uMF#;0rLchQ2&~oKtP`DmAe>g9ZX61bxc^ua_LhfB>#$^>*QZWJVrvL#F<*(r zIHRAA56h<~iY!i(VO*983SF3%D#fhxfr@kp7N{-^0YarN@*{%)7>xsZA1dA}NN@^n zN{mAE02I2$QLDjkf0g|J^#ko7ZoH8H^j!X5Z{j$g%0r0%D?aSJ z$>O_$oY7bt{%7-3CI{*N!Kq6F032XVv(*9L?O{q_D1a4b zH=&dLKl7C#YUQ!xo+22JbX@0ZVAKEgv8KZrfT22&K)U`{u=x=2UU>#XI|=BbI<6W+ zu032ZIf64D=dWZT$7V|&XgWlG-2ra;$GGjE7UKF>a23}{i7R?kSEu2W5eV=K5+%-fZYylro>i6&yv0povTa2Nny#D~HcJ9VQ~bqNcQeasl}qowa>11}5ZseC6`cb@(Bo>P7+^%)6%c{L4Q1_oP)C7@s+K{YTwe4g&TOEKCD3 zsyE2-c6F_YaLuMeym?2dy~Z`uj~r{IAib>PT0zR{3!pp+7$d@z(nkZ93C8Wd96`77 zRFW4_KAiV*U}N{=X%b=}RP?Byf0VtHVoS;H%xr|9E%1L%HYI(-w~lc2FYc! zv-UfJmFS^A5=bI|htC2i5V;MFoDB6l0DY?U*&KF@$L+m+;9LdoOYWLTH_=n0yK2oq zFWkxP>V!`jMaNz~tFyg*LZgDcxKR4#4&lwV~I?fKXXuf$@SXWSe=ZVl;8nl;@D%#U-4rDDko;qt=np%?x%HXO$RZq3w z71?ZCZv;{HZBi4gvmkT^-qu?74$=9Xy)SvN4nG2eLc)0<2sCF3u-Q;!%cJWVB>t9B z{Tdpf6*XwUH_%g_e$`as&LO|26l z%0%{>7F@JV5aa+m!ol+Vb!T1!U7Ulj7Q*KdAantuWxA;Va|j#XO7YBI`*8PN-^*tp>^4g9!q%wgL8 zLaYnOe9*oruC@3&YEQvET4vAi5{zaRmf15tF0{}@c^scyQF+Hacdjgr2g;TkUqu3# z-uf<1T=-+$x5hv=m_f{DX;Sds)F>C9@0`Sj47{1npwD?A7Bgzn_m6-;Lo07jQCZT+ zc?&InIjX{%nS13QD-WPMNQH9 zi>PUY0Ed0LZDaCnVnwt3XSQxY7uU9Q%u$QX3D0_H&cq>y@;lq=-58I~*}-t-q<^BP zElPP4qo{O~`N6AqVqraG9Pt$vDBO`sgjtMXd7Wy;zCiz0@W7*IvitsuclWvCmjIk( zR&|@HK!cIpILkefbk;p&Qqyb(m&C|XcKF=yon<@dD~a!YS@gjs3gA?fi=e zHT}=VSNJ{q4Em)5-`I2AbXZNZV5l6}3k!_dG3(4z`d281>YdapFA%DDqw!eTDbG7K z`e%ZZoAn=NMNFl~HhN72yq3zQZ zdylMZrUM4ei$-;+Y#aOSYYl9>$aH3l?fclt4Y?8UtlKNLteVa>eQ%RgTI-2$3fI6a7|iJ zuqp`#Hs>C}IUi_P1jV!-F&56n(d;eMghkAXzj^84gt%_+Uw~ZJ;nFq?kUt8o-9`0|!x__NQFlz$fCu6^ zIK~O_ysqqW19q9Vas0mS5~_6b-fG(P3b)@bHK5TbS+pz@*Nw7P7J#$xZ0@DESLYs| zeQV$Oq*T!?=aqiYe&v+(@AkEY@-&>jt#WR>w*Bgw>&<{Na&NDe>wEp3*LRw8E-J>( zs=2FLt}|2R``eL3w3nF|k_*pkYWx`iQZsvsF_My-csYKEYwhMv;BDn5w!&(l3`2z< zMHgTnbF9@Kt$ZL5EqM^C8d@yzYC%JB?*Uh4nbzI?DB~GG&T;{yDAC;xuF-c`jG$+! z5ZjyUo-9SIFb7&W47*jT?>YxqDaW=QPAe~q9c&4t9|0@k-Ms(|td9XfGV1Mg>oaf* zzyzy&B1$M}b~+HZ8ae~~o(73QcuHo}j|@v?ydtbNqf0MD6e}DS^KZR7XPd9Gm5T~v z=9X@}JC8Oo#T3;$Ons=hmD2A=y^iTDMNu0>bML15bNH}yK(eAJ4v1;VL7ewF6eJq2 z*LJMMxL76nqK)gP9AQ;ZnCQ#SGWGdH9+%?nkTFmu8q6Z}OMrdo=+mgKrrSGs@%r}5 zkDh*Bi1|ai8zZIaio(J^48)3L-QKCSZZ+TEwT8ca^@4l<+lS0eh$!0m@SGy=K^%H3 z%R^#$^>{;`nd1%=yBTrx`?VYmNc zqDXt%FJ^vG_SSx=(4rY-FSp2|?TdafOBQWk$7SrLn!~?dL33;_dpcW_}6w7=e1kG_|MwYP8vPF-i6g7R?lU zFNn)nC?Q<-eZR`(NG~0=Oe=~AWOb0vt7d?)3 zq5m$AnZH88HSc$kR)vz)s!D5qsWTy7xc90k*MVRlr;59IK; zjr3uh>jUD3(?4&aC9{z8cllNh{ad?@rwZg-IYw!%t!Hv<|A5Ya zZ|=Wm4E!r~@*3#mS#LrRryAK{O)xn;{`+*sHqaSs(HYBVc>|qti%$8!+|KXO`R7`d@7Gq#Cdc+4>aYJg z%l~)Evz&1rYhXE$Z{_?u)xT5yJJr8a{X5maQ~h_R`mZ?49BNDHj~ywswKVkq5o-HQ z`j1-sJ=EJZkT%o_>qKiE{U5kv`Ja4i^jQLHVa92A+xGuoeWx(aG)DQ|Bd45mPXoG) z(I=RN)eYj$GP=#exmru|^93KtX51)wAjc?qxkai5#N~fL=W4Uq+cJ<7IP1AiWA_PH zTQ^MohPM-cFR#XJ{_iO>Z+V`|jQjWUe^#m;jQ@5(+(;G3`H!XgJ?G{BTpe$tbHU2D zasu{|tIWaw`FAP*T&n#IT6MprRrh!O@6l;ki$K1W^S>e0|Fv=TuT1r4)}GvZw8pRI zRZi(@#{V@Q=I`|n4WEja`6x^EHKS)4eWV$stD4bNPc@^haW&4r$J_rOsk~QNZ36jL z&Oe)q>zrrwYUjjDOv=BrUt#gEZsv&nTT@EAHK#PO8%=eg<8Q?ynwd1CTOe)EG^vj* zlkVMUEgtJay{x|7jG2CQ`j4LAcq)~(25*PlZh^ZMKLuQ^Pq(%X#B8JS;yON_dciA(bc+H<2rMhwIz(6W~Ey3n{iH`W%O$? zQ~ut33A3!^zkdzq`qn+djLYQZZvQ-o+uz6N_HHKKeHF^v>anK3cYXLhz4MRKQ*2fF zSx^Z%*0TM!h5f89hr9V(Gwd|1*OM7$+Al5hv`<$v&iS04Wc2eE)WWeAfpI?0%UT;$ zB2!rWTbAm4w?La$v(qr&$GQZ@tvZc!B=Y`mTC?)`Y~^#%%5RvKx1rkIl$Klelt{+s zXRfQ!`0g~Xrc85YgH`Cut8g0HIsH3RNtRrUmGh)!HEX1V*4_D^;xrs-4RiVJ7j8-2 z%@Or{XG&AMnW+oVBh4S6dCr8>|~wn>AM(rRF}~n2w|K->-|eL0Xea%#O^Y3hCUvG5+t@ygL8d ztME^@puPu}a=)VQZ(6pl4A%JXX@Q3NSF`rpn!krbXOq;(dVaN)IdHX?Np|wI?BBna%jAxfGp(c9*H(^SUjJyBf2Y(xKDT>d85Ual z=xYAV+Kwh?ElazU=|9fsYF3M9Su64JbFyQgg&#ZqmT&W81N|=pJmi3#qQTnEcg(B# zX8&1nzW>g&_#s!@1+1;~+x&*}>mRjwwYk~HveR+8p?jdzx=S|H=X)8Y5{c*>m{-I8 zvd)f!txU?>jZ@CKS_|_z!gaX+V@=DcRiBR>YcAHfYPmglh1Gp08>{>tORGp6Sqr>p;b#lkFTDgm8*S{b;ce40i z7XQFTe=p+`M!#V6B%@~;y~wCdqBMxnC`J<``kOQ961CHY(F8(i7l@ya$znQr(q+dM zHBUNyt>#EzznhrO{vEl+B)rG9j(n2cd12UMmUga0q6!>yrJ^1Mj>Rl(F`>Wz`2lhD zsEHj-evOzC`vIYU8-6G8^|)kDx82)ge(YlMK#wIrAMUX{whdX`V-?U1J)VwD0RAOA z;ET1P`6FD`UN>9XYlR|r5 z25a=+q}wLNu{iw~>DsV5o+Trj)CKL7I`=$p-z!}Y^eh?J^9P{xub`bpor0eBxQm3g z@JT3tU675n&GU&AnnB_ zdD50%?zlGcd%dOww~-GZg_Z%18o!u)-s?QH=l4LfY!%QNS+*;^D7E))5}#$Gb)lNy z2hWv4T6B!hlcIZH8&B)rCw>NufdN2^dJKrCI_H9CFrDRuY1+8{&k=*;X^twysr_D1 z!V&RVtX_Fic5fJCwh^p1`#7eC=Si*N=ftc(SWoqW7I-Kj zPg>af^QL*yQb=1t=wD%@?Od2h=`DwG?XOkxeXRTNXNdX{g!txuo4pxK1}eUSNt z{w0u6?61r%1y3_KEQ8R$2e6tHwHgt&4oWpBax<&rW>)geB&W~9u+8LHt0}RY$%$4A z!?rW&b|&4>0@^L}2+%&6UjWU?{3>NG%=&LxzGqTqK>TkkE~hSszK#M)%dni}XEuTOEt#pQ zRN5Niw=>SFo|N91*(tRi()LTGWynpXWyno+17}3)M4;mte*)uANOc0|&eXZm+|2oq zc5dckNIN(451>Cca|P(n&0GaKb2FR7Zv^Soxb8srq$ZHe$nhl4c1z}oRJXh&^BmCI zGcN(XB~wXT45gitu$ZjKTpO~OJex`9;Py;9<_|K?$;`fKbUn;X>tef@=}Ai>Qr~;i zK9S=4t_0eu@6%~{wk^HZLA)o#gKUHQp0@|tMgTntE&md5s{2+apOo+H`)b-rd4Atr zz**e)-LxcFE6xCYtS?DVvhiJj{*8pQ@(X>n^t19?K=Y)deIwH89FI-!BGVa>C!Oe< z2%N#Ku1(Ldo$S~;s=e*k2m+i)n6uq&VV!cKy4#|GUX)D#K+(v%~bUB-?%h^1QQrKVEAZ#rq z^mh>{y)MR1?Bsg*2_-o|BS{_!C+*2rHJo%NJArm5?*Z*eY?_^9k_@2LpdU_FllOwc z$r_>t+sR>O;Rv&E6fD@uak2pTC&&XpPmw-Cy;Ch4ZS3!ISr=}2MZISo;2)+ z@)&ZA>1UHLmcBXi+mVy$^q)+g1^PP({oVIpV@hp=gaF=+p)3*dEs2QBkT{-=;cl6S z843@dRH$BuCe2ksK9X;X&t~Dg_!1Uwil4>8PvTdrTz?nCB;gqHZ5koJKx@ew$LWZ( zFwAEB4hc@gC8#$8@hpw!`=rM0?!s`l#`8OdSk`&ioQ1^+*%VrQSTVT^P0**oZp;e3F7sXgL&8-!#2URy^l4?MqI+erir_QdAg&)wBNHG09crYVLuGVVmKYc*&#e# zX()zaXeSKqgrgk{Gs3yNAL6kXPRH;#%2!9Ay+|A{Q9L}3;p%9V$DrK7LnW4nJ0Sds zmIFg@qgj{{hvh>|n(#0U!<;5uPU5lL81}=kG#>3EK8hhMm%Kd^aGW8 zGp?W09NReq=Wz=xUrVfKE6l$&9anEUj3k(Z!C8oo?gks{QF`% zT!-bq9`m`L>&@rF`q%az0wBpb}Ai&?VE@8Za{m3(Oy2z zn;}@fp=h@N?G|GBZbUo7&`uHBDMmZPvHUmj^^g8bq%>4U;P^n?55ut-PRDR1hC47k ziXj=v!;Fzw&XKfUH#Hf{LT{7lEL_@T2Mb?lLPpVWPm{D!IPXSb`ESPZ--6{Ijpe@; z%U_E1bs>K|^2;!Eqx^Q1Pe6VJ;%c-%5%p>?^r0Sx^k2+j;bbfahP&%g?+%nt#eTRG z?My>`3`_4q`E=Buf$3)=o{jQ3nEq}I??L&!m@kI2=c3*Fa2>jjkE5ga@o_YJ9_BwE z(=9;#`!W3@lrKj416ZCVJY2by+9^m@9>jDjFx{h=?lDaFIHp^P<$MC`@g$aiHKuiXEdIV;nBW1jj^2o#Rf&EXQ2O{f-A6k2qF2o^h;qyy)2Gc-=u_wb;i zk%VUxHYRLM*paZQ>0g^V67v#oN-RmNNxUQR?!@~OmnS}+_*CMC#5WTElz1@lY~rOv zJt;gXIVmHlZPGPKeUolVx-F?ZsVeF5q^FYBC+$djKk3J$$mAx;?UVZ?_fH;_>`tDV ze1Gyo$s3YiOIA`MQxa1;revmMr`(WoV@hSpjFbf_52dV4*_yI5<);*T>NTl@Q%9#x zOr4qfbn2$mt*P&&9!UK>H8QPPTIaOEX*Z>nr}@%mrrn>mKkY(VP~S`gT|LTEqQ}%BD>)f{wCQ%-XbrNx5-wrhrCJ-lASQB_Oj8`Hu@IuSJyip1TS?X zqnjDs%IK?%zTtQT=w3$OXY>%G+agy1T@d*U(B+Zqfqvz95$N}hZ9p$LUI%*F@g`6y z_FbSsu^#|Uiai9hee7o}$2B_5kGxO}!b7r(39((J2-VFY_rDPi(#{#Gu^1wG9t6 zH(Qdo&#~r>mx1U0qNSa0iVO{CXP!H6?X(O^+hs%wn>;O#^SpRTxE-EqRK`mo{%K!s zLF2nx(0TDTqx%>=*m4`351O?4jLj6<&c`FJffK@xR@B;M2c@T4y%J`|-wpd`=N-@Y zKR)|Lwx(q`*s>_xjL!(CG!f1wnCAom!ER_MhMREgm zN)v$IFI56vBzb@?mL>vyK=J}zBGuBbc~TwF2c>$T4@pyi{z1AE=rZXppv$EhKp&Q7 z(eJC$9H7rh_W)fd%>}w%ng{fGX#vm;()~a;N{fMRl9mA7EIkNxi}VMeFH6f|58nz@ zBHN@#ApS>2w@Z)G?^lezDm@OI*MLgob!ipEcL0^hPU%UY`=qCU^CzGZ`Am9-euV=n zk&Dt=pqHfQfc_$_2YOk00qC#NMxcL_UIePiTYv`3F9Qviw?Wznpc09cUx9cOP>Dp# zuR=TqDEJxj>ky9xDv>yOC&Zfol}Nn23*retVGPJ`(lH>v4V>okUfTPNX2|aXrv*?L zrShL3-U=x6ulzpkQ~3j+H_9K;-jom0ev}V^&Iq6qxmErI=xy?+z!?KnB4g#xAnpVz zk#X{0fR@N#04DPuM*v+RM*)38jsgCYKw;F$u|PM)W^(gkQYr5n)h$~8cHC_RAoRC)pJrSt*X zTj>k5uW~)meo7Y5EF~LgenuX$SZ--M0E;qnlhTC-U&2Wy^GdYok8oX&H`Gj z&H*}Hy$9$W>Rh0+)p@ix)djQ%)%$@iQWpbVtS$k%RDBTWL+T%Z{y|+1beZ}Ht%dq1 zt%dqHt%bUZ_NMwIt&92;t&92$t&6%A=vwtTDBH6@VYN}$Lwp@jSZ&l7fIhEo1iDpy z5$HB`3(&pl%eLX80t@)1OIy zAzhhHzou(MCdazjz+*3tnRPAYnE%e=l!J-UUg?01`#_6X5S4$NErO2!8s-! zelkfPaub|8Zh=$F1UPS0z)vOoRKZUToISkoGo9Q;X28!(_?ZPiv*BkB{49i%%Kh-O z63!p1fYSf2A!8$G*aO2}81})iFNW7+I2^+f7>>fQ3_~}D6EOTUhDR_wilJiTp@yLy z!(a@1W0;HKKnw?An1|s|3~$7+2*cqRmSE_@unfZr3~Mp0!>}I1CoptMJe-T+0t^>p z_#lSMF?|AOJq7+%Ei7Yu*J@Ct@D8SAg`a0-TZVK@uJdoY}b z;VKMm8V^+rhv+;kz;G{y?_&5qhF@cN5<}h2!ypWsW7q=2dJONv@EHuB!|(+RU&Qcb z3_r#2TMSQQcoxH7F#Hw6D;O38;W)r>IEHl?)?+vY!;8T@Ob8hp(UT-P^7TZ=br24P zuo%KiQlf*%iH^xZiHS1*L9?-w#x16IKIYN>8kV8Oz2ozQ9-gwd~Q!wv9qSk<@1uE!>Psq zLxU8%yuKV)g{#czbCE2s*Hz;q*`6w|ug2-F@(pm7_&hcBfvGy08eU8USqySjRJ&>@ zuC1iD>Z?lfswR0#oK!f>RR)xEZ}PZH8MJ~f&uOd7e)tGc*Z#^id;UQyQ<7f2G%-j zO35Inm*nM6u7*UplS^FH%zPg3Xd`Ajy{;Um&q?y`Ao*^ukC7qHYT6{joK>ZsO7|TQ zErQf;XT?p<3MgrjuLjIxmVQPUz&g@+R;jbvM=iO$wG{&K&V$NScv-y2M|;tT)lw#; zAL8w z7DJrAl5)b^%vCB{&C~-?g}cOU$s(_;%2VUA;Hr{}+EN#!rGd#WtZ@3qdul38PBt`6 ztu<+3jR%_FXQ@)Qr*fRT$_bqgonTRPx@+p(UQ5y<*Th;^mCsLWh;wqWyV7dkNoNGK zA#E0u%{tf8K)m}cww;yL6|Um?Y9=bP7#!xRb~$}kJh2uAX=zqzsk_QrIA4Rh0&jR; zqulBMIKVwQK&ckSfeDLU&YB!goh3gu!1+2t%&0Ym*XNJuKyJt>^3>Lp1n?V_#=;CJ zy+zWnjK$?Hzrjm;%2V60Exkp>Sq+&(8e_u5a5+l@`Zcf)c`zkC6_Z@%l4w~!$?z(# z%U3Y&b{PIJ8eQYvlP$umii$j+tI}&>^@qV(Q*YI&Dz%^iFx8>(iII)JR2Uaz~X z$~msWHK4{**{Gn{V`UpvXpEOT8CEa9f;qkJk_H7Wa?yDNYcd%3YXD=(ZIsC>ojbAC zS#h;AY<+H22+7=&oE0!N8xPK#8vwcL!rvW~zol|5|qi)R6G)%~J#Ge8~ih zJP^b33Io{-RfG<7H7X#Dv^V7KtoLii+{$WSeWU$~5`QeV)<6N@@+{m2jNGbH?+CZA z+{y|VD-63~UB}ipaA0>0bXCCsEeTME2E9sx#=6a-jU2YS=S~LKDBDx(Hx3yyU|Nbj zFMw~I%FN;bXNA{Kp~B;&-Urhd3N97Y#LKyPRX%XYpzCrxwJ`JYJym5K4}=8^N?2U( zwDypNTTm0&mU$3!R+YF4#s?HIABIPOA%oS>$`Ehaa36I;hB}8@*h4*ZuKO{p?KQNv zq9Oo-=|+c%XaMGl8vW*vpsVs2Bd~i(IQ$+(sWP`!}IV{RJsCpCRkZ&e1Q`amefF_u*e4X9d|Grn-egQT{Scg zZJ%d4{)R^hT>rCzMSyd=F&VTV&k{ykc|cJ-6|itZznU>PI{~VxwKg9N7jXXqn_y&R z#Z@;vBWf(nxZ4Y8*`f>b=krurJhBk|D7B!fdmgS<$)5%W-?FJ!~3af{xsMgGM7)IXrT|+)&Re zz`Y2MMHW}mP%%5v+Y!efJLW-Y*_O>*`i8nBPb@ik*0qXO+DA)F0T&=Ln`aWWJ7$dG zc`zTCJM5$*Te9c`m;i1lJN5G8AwL0UgHJP#dISC87+r;Gu(=vB+Tva!7COX*POq2k zP1v7)-3UX%39er~RF-+4^vnpyyBv>;PBk`O*i3>$F$>t127rg4LRWaeM$CXT$g1H* zfSQ)LE1g`3%>gntm<)ganQJuQ znY*PQV2#02_$l~drh{9twY%A_Y6x&=WjrIEXAUKtcYNFTiY6 zHR2e7UY0N4<@B1)PN3JrREBuG`~XJ#+0y0yy&W)otOqe-9%N|Q*wF+G&eMnKjA9&RoScPH-id5N}*z z-KuV&A-1iCiHVS9vth}WB)^-?5l*)cPLYK!)=Pr#rN?@DqeSoG*e>WIV<78EZcnY( z*z3lCt6RfQ&HPf)>779BVUa21n}?X`yzW_LWi_l+){WiTFJ6%VTA!9{K!vl++lWCw zaUO1)16@8C38pbJ#$!~A4+ay%_=AcU)WA6KiM@@o=*aL9(Hv}WLk}02hIr$Yk});4 zRRk}IYkeLlpUam!$>pC-)+E^d_{vc=k?9U`)=Z$zG`2C{Ka28m_8Fiz)e9OtnW zz+J@+VI1bV%UQ{;#F-NMAAW~Y)0xhyDXXP>ji`e^Ha6Ko;BZyA{5J+e)yoh%Ff=;I z={4?+E!+lI$&GV|I&l}H{*nNen`*vKF&C%QFu^XOErMaN570eVln~3&uw)HO)p&_S zX{;qNN+C+%m%FFN4elFk@?Mv#lsTQu0f#b_GvATah>r`{gbWwC#16vx44#E!HiTOZcKZ*i}#1ia{e|N{p48))ba5 za}H$tFXhHC7ZEYN8E1s2W`fBHNb9feugV=ToH_$w8Z*F%K+I!gi<}XwrG5fsAYh64 zr9BK`GtPZRw)uGdqkhKO2=E#aHaETe_~W(2GtugG6UL0`5Bmb$XWXueQj*E-Hsl+b zG?dVc8genG1_GlxSbn2GFgb?RR#oxi=md9lHHyvTACa_1HdU6ixG{p|)9!ue&_X_Eu!$8Cc}axqirKCf4zm-Y{{tv&Q9P zkZ*9-9h1KYFmKNq-<18ipbdU>sc>`xPI&yXja=PwL#tP}Xjm)3C6z4*>@>=6M;q=6 zf@7Q?D(Ozd`l=ROZG&6Re2^M8n;LH0jdI0elpBzPw-FvYq+0Ux24Fs~jgoo&5O;gb z@)_~KJgoN2)P{Bq-_p1{#iAIv`ImHPC?4`Y<#Deij-y5Jt#M<&L{&pXT?qPap_CG@ z`F)$+Opr=&C}EC}QW`0xv0=_Su;JrJLOuz2yvF*)8|z@@_@n-=@gDjy7&gDG@$@7w zwn2REVuaoR@6Q-kSf>W=C9=E?Sr#9Gr}hJW?k3)#c^iwC8n(G#U<$B-19CMpVV|E_ z7Cb5jPLU}wA-|C{B^Is^2+T;Y*k&2&%Gx|DA; zEE{O`66kjbx=_-UjKlAi;20U7FquPcN#hN`*3GThW2}p!3k{ZK3j$WL2iI8`kUTcb z#ZKW>K7NKCgT-V!v!{AYf47f4{D5Pmi3(~c$oG`No>F1llTj7sPr32#3$)mv`>oee z9UDFm=xDT_wX)PWGYm$@IsLu^R=CFd2pj^+ePq1#^M5|&4`X~|SML4$aih|Nt;HK7@jLWnS6csrm5i@o&|s@rTem;YC5<9zL> z?rq3|h1Gm)<|iqoj{@?lhPW%B5na$ErCw4E{u4AX`;IrsY21j2o2>C}dZ_f)jw^LT z0ZO1)c~vkM@gmPB?hi^T+|_)#8n=vI?y8RI5`eqn&4i!ag1cH@b-;8O(`=`UMj&!E>DToH+>ASsokWuB!FnVX_EYjq@$d z$hz5GGQlezl34t9s9hrty;-V8gtVewSW}8%(h8>E;~`idS-tsNAyGk8H9w(Pjbp3$ zwFqklqX}5`dDV?-8&&qJE>_i9WlT5r=_qeJyTb;K&rN57v3&81Kz{ve*%|p!!+HWS zB!iq@=8SNeKsBzcib{`{-&(M84|BQcz=aLMm*vf4AKEPp`mDmA!##9A7CP`;LQM>( z1i8$@a7J_U^YaRe@``A~)7}Z#mU6u%PWJl3SL3Om#{+g1!&MU8fW0fEP<0q&~OA#N}8kVV7NFJ$bI1%AzH>;Vd8yC=I!{dl-O`;7}& z>s&Qebp7Dt+3UA?d12iOe0$M<_<#Yq!^RZl-JEN2huBiazce+>#CsJ!_v8W#z&|=! z3&Fn~Tw`XI!5`MdwUG6HGARfwyZ%^!5%y?Q^ z;uW={caqukHHElCDss_}oDkzf+L+Po0})>LQV#26SPnc@)Zv0Pi{D~1HLFUsIObOw zt^l9;+y!Ohc0B#k=JSXbaxmycr}DXGND68K1m-SJ-9IX1zIlnW7B=vJ12W6da`(dd-FgKRMr{pRFzCw@jD$V2n;!zUI?$M+Ly5gQf~!(*PTGOebz*PTWgM%$1~?oebzQ zPj&eqc3XaN1F!Rq=}^k=wTaXJgC>3^^Rf?C5P*P2O2rj4d;J1cV;{n+jgJ=WQwXgn z{pn_AgI^1*w>ET%U=iaseLUXRjyEou-FRbL;hF?(QHh%(^GK_CrHzZmO5<9QI=Wu^ zl@ao%_j};klJTU}N2>8x5`e)U;(Nt$g-@VLs}}?#qS{bopEHbK%?iCx=9^> zlH{QsZX6Wc{x2(C=BpPc`tOrTJuGCfkkdO5%UCUi1}cZ{Dy62~%wwo@PG%kvj5Eri zjs@lMj>mgV?xfRdg9IH#6uEhGRMTC-<12@}`HIX|@M?o}VYI7dpg=b<|T=NS`y%Q(|!qte4;+LL7#UnTo!7sT@~P&)zW?!J(+3 zXt1lE{k~6Q0y;1n3fQh$Ro_rhSmS}U!`E1f>Uy@KH53)sI7?lX^uuxk(M>M4*EST; zrGcKw=@wmaRV^43r*DOGGJXsQ^2EvMaWarpT07rjQ=i{|8V)w~i;)AHaks9NUfZ3y=KzLtR0J03qmXeht6bLKfuWDP#=EQNi0fFw zW& zr&{r0(Ky0!XQRSXGJ$^SH=cdbcXSwIPaNoD4{Q&}pI9J`7SNAJF8aUB53U4_?uU(k&JI8HFPOM0m_V1c`J*T0nBtxfBrBT0st6WC+U=9r?^Kr4+k1Z73`;nDXr1q=V-Fo+g|__io2dUl`a5iXA}@Wf zKo1Rkd=^`$(u+Nd%;Gy){BLtmjO`*G1k;Y?%ZPCa&94Eoe58;XwhTu8 zc$gGbxL}ipvJP#&^?tvf#_?d- zeF^)tTrhq-jDJ&3CksEVh+gNXsv*wF^ty$uY0yo@9-JP<9$emlgWnU2J-F}{dyEhl zM8<#+hNbm|BtSTbfs0XMOyq#qkZf*?*A4t!S?nP>xc}gT5?9T5X9+e~o)^!~#tLbH zZ2fc_2^*ZT=~D`8VrmYyYkK%Le}UH=PVAuO57{bCT}3y3CdqfwUuUG>fRP0j*`J zD1SV4bRo1_asv-e3WQAbw?7PG;~4@c1pIKDHnlwo1V&(L(N>S}e5HDeNcy&0}%+X9s8?a1h)iGHb*rC`(Y_&y%9&~v5 zXtUP>pIW7Pb|l%LSIJ6P!CI+^(Mf=5mv})VOXO8Ve5^#UU_wY+(arM6V)cj90JKgm zlap)mST59773CYN1-R7fGchsABmwl+xi?#0Fle=o>hzGg^+lA2?RrIT@EvoisL9D*(CvzSS^m zN)nR=cFO=&vX-Ixq&c-w%i8{`R{C6B$A={}=0-hh89r8MtCO&NmRA|mBq7;sM$)`V z#1J+Dyim3>IyRDjt3OHB6w;a8iR0eo*AwMz{deGcAc17sM1t0lpf##nQ7Ki7T2hme3Yu0*6p%>bA4GB$+VUf6 zUCC+v!~J;P=bSrtW@i>QR84<$&d#3C_k6wQJxO zd7P_o7 zRjoT|sAUhUh$kz&x&r>ruy=na93X}W#YUlsjEWx{Qt~IYZbRx$@bMO%WesGlRN7O1{L2`pq-14}8h*&0xm9{*$rp(%KE6pl zN|Jtk#N*9aa$~by6>myuezZ;UGw9#L&bOdyu;qOALE&T zjF;3dgeB|`8K0kD!nhZetr^1{#t@$XpYGtSgnGj4F%|iW+C+Z@BR^nJd4c1rXarb0 zN-WUl#w^D1m^t(VPL4L$U+-(=tzMib;fO9vmM{)IVihavx!toI6!p<#nxSkBA&)+MnNIEhW%J z+GH!fU}~xpV@u9)Y5c5kUsO34|6GvO);y7McgnLyBGDoy$sKh|Cr!|&ue10)PMcEz z92@AI4|aHFs;Md(?yMi}GIOs}I@T{Vx%jxz4ZHGey}#$?%$YUS+<96LFsr>`RJBqr zMTed^yj65ux^H|I4 z6wkOhquuy(@2;sW#y(YC-0vas@UYQtwCqe$vfJ$jUlTjZy$0D?FI=j!SJAA-X#rHt zS>m??Dcve9Pa9o6*ilEi(re!9R@Iu(t~Hx`vG)8Yf!@G?nrVt@>%qQpNoe+swoau> z7$Bfy-TTQ#v~-JV-5A;5ssMLUs98@8jC$JN`295Kf=2Ud!XuRTCL1^O;vB4 zLN#y3ZB)H=-8eMWb}V83^X>Dmwip+hi+X$R=k^I&8bYkK=DgwXw7H?^26cKRpb*!d zS**3T3uOB+g2C@^(`bVRKgm!=^iYoJnp4#AKFRcT&87OBWsZ-NO$OZ4Isc`{@$vIl zW1a2!;@`e4mzs~-*4aYE^daRNJ6fu=j6mHK=)lY4KKnfU@wKM9jB0T^-Nv?9=u}MK z?Wh$qJZF4OQ>_&$T|3yQQ>_%4#S~(NwP>noUq9k0h_Zqim;6rBPNgsB(DSN;W_^8h zU!a|h&Hbg1J{gZSH?|MvK8QOr-It134AZrZG7 zePf!7YNgMmS@Od_O4R3<*5|t&Q*Add8v@Szvs>bhX0`;XqvVKxFa$?|ZhgLKL+V4M z^=fvSz%fe^iouTCPI3KaEH~4eCYO$$T>ciddr+IfY5Zo(G1-T)) zLE=5q*vG3{?c#4wgQ~AX=oeRx7Y0>vbmAawIneHc7mQY4+YQHr*p_XNr#%Gkd zf9vnGk<_};E|yb={=1=*N=8_rLGiO8lxHJyWwctThF&*gEtGc1R zepmZ=RoST79XG@4^%>b&qVavspp00QL3*C{$=5%bH4t3uIlfq|TD`*EwLnn2o zf<#4Q^KMS4^Ag-QJAAhe4{ZFm@^uK?4=N-!V^WS`U z@2V{qpNS1*8;;el5U#Vb^{YB;6ruy!O*;D~Bu^r_Req@^>V%>hCoGQ=4_o5NF9t+B z+sa)V@{|?x?Ce)}m-^%5p@ZEeatSrk7DJ8#*W972-J&p=7bQ5Th zk$f(OJR70Zv|XuUyM2~z4P@(YTGuHMt?08tElD@iXN6nS`CLLO^f8qbVjXqULfGdM zIp`ppLOi9y*=-23DXFSLej=`H6HSt$NP;*CB<`>rF?1I~t5WKqXGUXvmJBDQ$y1z| z%~(`f63X0}ALTgQ2xgj1$?S7x_BqZzCqJI-I3x^7M2Z|oauW%Yi-_bV5|SH_n_NUB zHy)SVWYXj!BDu+=@H{h~87C`3Iw}hzk+_Oj>2#W-4l^cI5vHYJAak$9!lV?MR6+=J zT>8u9On-<-I+Zf%REqtlQVv@-xrj(^IxP%H8wRAwfOHaBY?$1)P252dV^YI4HC&f$ zE%|IMX||T)=qp>y8S#=Bi;J>en&D9qnVcKJvROG{P4=PeLxwes3Tq@1r>O2TO-U?D zY2F9Hc0!JFA|3?nJz3@Ydrs8D20G(PUgJ!RiEJ@CY)O)tlk`8NKTLl+{ay4QWMdyN z{&U8kX8e-0TfdTH^RMb)yAE#G!7d%_$+1(<@6==REx@-w8C{C{b2=w{E_fAeM%)1X8ow3)iw-aI4biwmb0Ta zQYY~LB$0j#V#n-gjvJ(uE$SVZEfUlj$@^v4hb${)2Mtxpr$SaUiV7*aPpJ%KcqiQe>?qM^dBUf zK4ARkj6cozCB{#OJ(bTvJCT1I32Z@6x#5E37L@$kNFcYMI0n5>_mSV?1K*Ke6^>?W z&&i~!+1m3a{JLNV;NHro9e_$6rz1lg&Y~zC4Mm~ypx%qp7^3hAI?#s%mY^JAIJIxk z7n-t0Xb9@|HYd>*(XM>UFw4xGUA$eC!@lH+KbTlvQKc3 zHToyRj${;=A^u5ZXKK&VKZP8Li+?KaMF6^G*Cpf28$43s@_exMg6QT9C9-pCGd5vW<%lI>E7T+d_~nf%OHcBSU{#`U;7c7B3|O$c#%_ zruK?HA{rODJ3RXDQ*b=`?@RyZIOHN{c23tj$Elr@b#z_&4*j&8ktGod)Vm}L3~7)6 z!XN|=6NyAZ7o{agrBZsJPlG>DtkE)O3&;#d^XwPCkVvB7Co;7^=0QAxRjR+G`Jsc_ z3z(;!!;vJri04&I;y99^Nx9J1Y*f=PM>eBGcx1oti1v=akwzzUqkG~q7!qMt^(r>P zS{`aeJf>FKiLjFgL;4Z(nt53sZb2JY11EO>YlEXW(%K4nf_s=hjo%n#SFg#$N27}s&Chg(hJGt4b z4l8~jpXZubZrC^s-=sJxSOs6R(Zcqkq+CNEtMLz~)Zico9mu(d95#Pa_kdOVRMoxR zdKTz#7#LfcJ--zrcuVZJ*q9Z65*wco<6gvF|AR(c^C?K^zoX#U7a+w)))8Z7c(o;a zB|#F|@I?~YoVHk+-?*6kj^mtGrV~xMN+|+y5??^^5Hw4XdaBwes;NH>_LYyQVpHJmt8wb64p+WO+o}M)6!r z=BZUBT7FYa5I9pW&oAo>_EE3E@6XrDsh+;N-JHNo)$hD3H?+SBz{e3|(~Dr0+Kpb6$MXOWA4D=4UNvz#r8qTmyvBrLv0 z<`ME74jy$?nxc&uT~@V#G2OGLl-_Le<}bRUhf6^H(3w-w5`7ENWW;4eOsW>6_q+hm zE}yO@*CBXZ8&>j2w4CPyr76bvNQ$E&goDZY?a`}m^8Evqu64s#*@ThQG>wq;JYcLU z3rk3z0X0epb;7`&EA>KQeGRT?HX=X8vc+;?)Lqy8SI9eJ5)Irxn%vN2@p&E!9Be!o zJj$EZ^ceUD8dIe|NFF36s7?oq=MAY&dNuI%+tlDpjrq(*42r-~bpe96Q zQH@h!Q`-ZS*>3R5Qcq60&epgU1PD7qWFDlC=$e&L5nKR~dLF4-HZX2849>)_$;A-s zmYlgmgroI(#yQa~JZSJ12f8A+!qkf|~B z!elm@7Y)$pwX==PvWCGtZ_UF)ogEixa5%gs3ANV$rR?vBsD~O@6ph5U)88kBR?(y2 zM}i!6IEjEJRHa^z_<)4Nn>P`zdD1xF+GUFy$alGJCb~x?y*AN z*TJCAV+}-(0?S?U+1TIUG23dK);*vCM!Zhgmr=+fT z%4DQ9U`$eJ_7IL=EK?EQ_*@{dF@e~$83nagZ@v|IJ~fx|hLKxm7%vV4P3&mC_&FNk zoTXB0tL3O20(Rn{pytFm0=;InlFlXO?Yx>Fu<~%0dXX|3X7upPjLa$y)kazZ*mw@QSDFz%?dKmd+ljjv}8PtQ^*7E?lb2ld=riD`4&cbp{lU zkz}#713t~|h#dYv5&=+bTO}nPrx?9tgZ6mUzs^Io;Jz>4SmChElnpc%fiOY{B>zSWrboq zTo`#1Qt;$#ilMD4|mL!k!$(!L2 zK`|r~9wwbm%_C2-|L)J%4uVG$i2*$~ib0JZyUoDlZj@?w`$wY?D3evik6y(KoRQh% zyf&hbPV;F+Hp4f=^+G*?2$(F^^zY*V5If0fEaOOO2~^B9jMO+Te($HnWom;H{4FKF?Y&GPJ2a|&Eve@()2 zzl9%+HrpB!rA|uRCs==Cx|5?ohgA=1SNqg2(63FzB+Yl5Oq5~^8*eohL!6RaHbZz`KS9IIlpLTeg$OZJfnCVlww8Du^(d7a{@uk(ylw%Fj=$ z=wnaSVrF~P?0j@`J2pe0J<_77$rT0gLdr24ltU#+12g@)(w+)K_6Whp?M&F)OXy43 zlOxRm80KkZ+&_<^x`fV0)Hn}lcXmujlpJ?KhIVeL#1Ym^;%}eEs3YLfD5!Sfi);@b zG~#yEpD*5(M{;r;US($oApivaX|z6v7Iz`r&E!irJ1%Yj^Zg?lwWss)E?e((%l)z_ z8Y3q69MqcbublKUvFr1*OyuOfYL;!8Q65Xk&kW;0v{?t-|DEExr02fbt3eHwTkU!7 z)pctf_9f--;gOTUzod4q>p5yG+mS=+eSZ)7#p=L6?_)Hvw?||v zOhaj_(3O-Pkzh5Vt&Ow)`#yJG9xe1`h9m6H9;Phsy04vEYvW1Rhxv>A!_?4mD^ZG0 zw@fwk!&fh$hiv^Lo@0x1fO>nf)pxU_u^92_pd!8byH)H8lYmH;NZ^%bD4GWuKn7a# zB!b=eBkiD!%M4q&HgYBHXX74gm(mnFHSm4%t0Kgeapx@EE+1Q{gY&?T^^3EQP$*_f zC(KIG?(V=oFkvcP0gLfAA32*4BV#d+T5(3}WOkb2fw_Uk%oEKid5+*$*rAp1@B70j z5Z*WB?H{F}e z*r)6AQ|^RIaIUXFU$c(xXU@e>c>4dBzBz4IL!aRWd@sJA1U+j`{txNeZ{m|vQ3ezY z4G07X3g|LgTEv$j4}7fz2&ncL3J4Pj56IfWkkQt~*20;=)X~7k#LdppioxB+ny3H^ zh$;^a=>K$GcG<)oa3wOlzv=FNL2mK)o?+{_xxP#q3S2%euU%GDWq`HoDrWF?_4e(f zEtIe}lgkiv8LLg}fBiENjYkn1lb50(UpqE*>zHq$V%awkWx`?<_^hqXq;fyBz@WJ6 z@q0KJLfrYNRsWv({#>BZjQj@M_wzN>9OiVJYy7|!h*}HniHzc!WLz$PeNjpDeLM5| z_{IO!b+@X3dza=O!w=(w)@$_rHFed~^^HF4RXN-q5A1G?y^cVnJ^Z*y)X!)z#;!?cpJs+ zx9%ghc<)vstGUshZl=|^S&flq*br7$Ajj!6rWam3ddZ*)rT!QRb^`~eK@2axZ8 zG&5w;-6%taHL)s!Rhf8l__t zNZ;s$^-DC8U=hkeMVNhhZSHd*qw0j#nG}EBi}SK}Ey!qWo6kt#-FDjNbIE! zD|?_FO?o;!rX9Qgz6vIne?I*q5G6Tvw6^&4hB_23I9Tp)-DV*o2%G~Y|#OKfRnk)5z zv9E|i6kSKJM}^?*#86sgXWDY?m=_?E1X{0*1`!%2G_u}wYfiIZWAmeEW~vDgp-H?v z2I_g>qX+#h31T?(9@}7ifTLt5V=Fe0-(OWq^|K51B+U+#4*3jqf6c_R2znLnh=?v*u z0L4SKO;#L|KAz7Pg2$Y6wW#9#26VUq5){~1Ec&nawKoT3M};t)p2fe%#2>!*6u)L)d52`xfV`;b~Fz3p4F6Vna|d?M0PWtSwXQ)I98g z!1qm17z;^Y2_;gU*P|#C-PYksP&~cL?a>_VD19jgqS&#^4vc7oRxycOxwsK7AjXF- za=fwS6SV`#27X(A-Lr2q*C}3hMO`QWWC|p7eU@Dib!=PbSanItDetaHQ`PDENTXo7 z^HBNq`dkrKBn!@g2NJTtu_p$s;akUu1m{rU5m~N6%iDEe2fu4Vn)Ql;M2Y2+{A(1j zeRcz*@WHUZ+vSEZfQ>ub;dED^l(wQbz&`pmf5RoZ<*WpGY+;rC?hpL%gDHd>)(TnU zFq{cwS*kFDE65j5gIuyzRMnFWtv&Xn`))c_5Ixasxw1CQcTBW1&%pF2G-x{8(RR=sLD86{z`q+SI$M-je8V3CUmlpB z5;E<_QBk$UQ~cWO&|vWE<85T;iWQSV3H=M5Egz=h-^j^~z{diih!%F+et&RVbPz_v zn6?r*s?5QDY-~n$6)+PS#0G{0aPk9SZW5a#X71SGFas>^#FL9h#+w5oCuj<`4wLCC z?uXn^zag6L_Y^^;#050os8%J;0_%JFmcJU3vF3<}s9aRpF^O5;5Kd}l&cTs%^Vt_L z$QDfP6Ic%zG1Y7oIIYRbuQxjKPA%InbO0;pNIcjhR!t~4Yu_XgKaVO|uJN-LCYWkc zU%fpy4iWmu5?`qt!S@H9^`KKv>j!(`h9QRWj01{*oxT%zD;6#iB=uml{(RA-h6xDE z9;rRgfd_-R4x!w(bmMNV0R-&743j++mgg1&(Z4(ZxunO@!R=%uUT*au$W0|J+m-}x z6#1X1le}!lyR)>(S1hB5!{Wf#v<67~{rx9>n~x_m16#m7)!IE9tf7?ZUuan)kvFwO z_ULBt{XS3P=c?}2D(0JK==X~oscL7G zQMx79npM|i7{KIiwTPL8^n-Nds800#Q1;|*3G-FL34#ZK1uC(PeEcoZDq>)e2YKt} z)kDh}BR6rizsaxhG8m2O=xC}P;9T(Yw1=Idm;kc^gwVaQgOk%>Z*_66Wge6*n*i7m zx_T!elkCXWKzPAdV|o|LAKL1IBU09F^O%4W;aB1}2G}SbWjnIXk4#{b|@vf2z2W4Ot(+7O$O_?X$^B#)TV(FO0}7 zfR+T+4M!!~uoBqS*<&^I`?r$<7nRhTNe4a<1O9947v(dt`{9&cXWX^VZC>3_N5(7t zaqnzP;|xCp!2om%^DUk8xac(kVuNNy+*~J_+4T3GwP(`prB7m^ij}lYJ<0>rJ{jWp z`wMSiTil-P7M8o^93Xyz;jgD!P2%*UfP5t3uB-yA@3xr9Gm2j{4KXvse&F&YEMoEv`g6(+~ z_%O30_FkmEy2B>}VGwFE{kzGiL6&Zdt?z_=5+D3UNKJt@6n5Wz(W4?hANjr-`5TN2 z@Zcm=&( z;u(|*xJKCx;%8tYh#f{D*)IC-RM9{opmYJ6RLOl+V0c*sy#G}Y&Ja&?ADq%mi!K%i zz+6)M)k+?Z%noamR!Qm(=Z$RE8%{IO01(7``|MMHmwdpOm#4eppZI+Y6kH)zRvbaU z&%yo$7t2aWJD0z}7C_O_N|t3FxtS;!Xe)56jh3aOOWqXIy(z2rK7KD`yaY^|!n39c z-d42^c~n~ZKME=hYPu5^ zn%{fwR7OujJ%;ll4E`Momgt*Yk}SUVbMf4#T05Hpsg-yaoE5p2Bs#%BBY<#PCbN5G z*{n04`zp2h-B7T{$Jm8&h9H30x;8MyP6Plmt>8=CXP}|QyZ$%PPSH2V-eL$lfFvC+ zY-duooyIzJ{;uyb4l>j4jvx8NkBTJtxOcFQc>VLgqQ$G_Pe&j_4`JqV7w#O#^Lf^{ z1Vk1k%?JCya}J3|16dgd8VFZZtpJYh5@Cmu1RM(7f=ZU6%gtK;gsA62UJ3N&F|>X^Vx;^?Xvw@%@Wu8O;M5U+LOkNy$Ku-0)9-VJ z?4UK)|2<#RM0fxP_fFAT=#1;DzWWQ(wC0_ph*1;NLFPwv8PV0^Z_9f=0QoG*KFv~Z zy1yyrZ(N4>)Z0LW8jLXHkG)gJg_wqIzCt9!p=vwzkZJ}21+Q10wWzqL4a#$+kpj0^ z*wfXMR^KG?k#p;1Xqzg9Ysn`+gH#GBbncU=kPV{cSm~=7L72VeVsbEtsy^s*cXHp|- zQ-39HtwE30@s(!M+z^X$99O7Y{y6e8QkC?lxqn8gX|-$#jqxt`d9xJaf71f;H0!@< zvHfmb5ltFXID-4vmtW~3Mq);j>-!oK^4@#ADpY#O-w5t}}Hjv)% zk0EYKTb`Y?RULna8b+)Qv!jG2PY#$#wv*shZBEW0Ft?zqyUrt#&{rvr1N0uimkbMN#>sdkwfe>F&M zddT`$hZ7G_E55!qZ?Toaagde&(vGV}p>u)h2DO`C=HswrX_cw&VD89<(*6_;2>?RJ zs28O}mx}j{eH{Ag_W04XOo<109`u$9_!NVL0L^KcTRqd}>!U-h*>HeYoK{~b)M#%A zt&{1sroF7da3JDi3|!tE>dCxal<$p)aq^%2y3=w-vUUFFnc@bHfi9&I8AljW)!NXL zs*bh$c-3DeOJ}rx0**tH@P4|m(Ew5F4mOQcR4QtKf8Y|8;f|a8!hZ|@IENQKb+%iO zN=^;{hAGLutNlgvt5dvO_F-YB308zj8Co^wU^&&@apy6~RXfub>)NMBOA36cgnK62 zpNuUv6fgPrUg+6OuJlT_%vEn*LdodfCRU>bAvF4eQxTr-IQqdOVI2V7*WjX;lWt>z z=ho`g+J$W3m0|B#{D>7bhs7iva#&L3+Zx+F11O(HvGa0m^1LjHR$e`-xQk)b_L@%-^Mj5}$? zR6mnUCeyD?E-X<3HrBM{-)raCXOYLb0^h4Sn)YahSju%SmfI~(`5$Wu*5${W$JAkZ zKyi>04r4nIynLWnIWVS1Fay;4MQDab=?fSGLG_3APGHJ^A>H@{@RNMK|E+Qel&t)T zF_@O+>flV`GabepXQ(<_I5;3C>xpgr*%y5o@FkSXzKP~%g-!==b_?T`Al`6|vKR*R zT;Kp}7_Kzu?xJy-$E+51z|tvwgUy6YMNBDg^1R@<2XkT8BV<8R_BHQ; zeL0Q)u;q&_U2uIL5MtQ)t=43AA}r9Q<>Lmzzpx>`@|VOyduI%afAg%xUVGvPN4lB( z({#dteAHy(U2~PjlD+XGOSOR2{`En*N2$Ih7y2b+N=QQN3WpT|?{RF{O&Q2%I0I3S zzO2?8TAp5=j$R$h|*W^7K&q-C+K2ptAoU zK*XqtRXK!_c$M_o8tDQ_g+RW(_jL7>JF4renjlMo-Q^4{Qqi*<^R{v!uqGb zV)O*4JBN`Y5NI5T!&g&Cw>-^fvQnDonD|@Xg`5P(r)3tS=H`A6^#?z&N|Sqm48xOX zQY*P>%F#B`t|?hKZb{Q<3H=Yi*EEdK3u9W;BA5WC5rf>OF)MQ&mpNdz&}G@&C5$pI zZ;f~qp^;J!=TSesnad*cXft`I>@1L=wsE*pM$`jt3PB`wmG5_CURZzCkkkg9S?SlX z48o&%HoMl=-WaL5D^$b4B{V7sADSt>?7As8=MtwOO`gO>)!aFP0)bGYNPO|c7I)FN zhvKAG)qlN{woe=sh}+OSaD_AWpqoOFfu!{Em8|_zt24i!?9sw7PlUiTC0Fxn0OCGI zJ7}Sv7Lr03Xd1cYHeBT!2h^Cx(rzH7%QOljCU`{U{1mJE$S-xz7P@a!5rCQzXtGMA zg3?+-&?E2(9@BfSmvHHU^T;iT#O-+){Xh1Y7>jr~q@LlE+K)|g4&CQY6>1R#Ll5G2 zSX>XIf4Cd0gY@~Y(D)>e>3#pRC+GPcBo=qzao~% zkCR%Up>6^ba=ozy5{DFHO$<@BMp{x#KqW_N;3ImN9C2 zP$^kx^?!8F;mjEk%NkjoWOmi~bE}gmR{3E7kJC41c#!@uzhTM^>B9pwP0)P;sW$@j z5dVk0sLIg~GD-PvH19r}V|Ged;F!ob zpOkuc@C2H{>zyV(7Gk$jT?Y-ea!WGY)>?xm@j8W=0CN*iv(7;VxqEbP;>w%9BYLduw))&;)+cz|r(Qw8hWbkux*RM$el|Yhz zF;faqA*DMTs@v^(U_0|4#l-wOvRhQWETfpJ5D*OJ5CKu?e}#YRi5(Ggu#Db`Qn{;{ zL+^SisbMShI!chpmWEm~VxWCo9^cK~IaJq?fwm?n^_(6|yS{tJ0~2!S3-bVp=RLHN zufcWcdKXIo@#aDScPmyWpCotth{QlR+Z{(ZcqY{8q7sgXQuo&Qp6>P$z!xgjE_fP+ z9eDKl;JGvJq=!6o; z5p{HdKYK)=*;J9TxFy)?si6c|Qx%+8*lRnRCM8B-mnJVNg_0=q6@_Z#=m6947SBU3}^`F zl7F?Qx?)IVq9IDOrRgyK?RikDJNT95m+tnNFogS3vc(zp|Lo8kON*uh9m~$?`|bl6 zdwLtlT`p!ogV2gKiO`$~7^0w>a&chFe*f7>nm>6sA>>n)MurZ3wow+ae3FRi#++S& zNEM71AQ!f|hd*tcZRj1cQ<2vdz1voMV;Qe7QR>`) z#OTm`UjT(f-URFRZL;_^D$?&y3|t!j*u5G)u-dekFm0y3p^ue;LvVH`<(l!`ubJva zb5)F@V>YQjqw0psS~#KOx{))Hdluo6(IZ2#W6@ZGl-^3X9ERP&I4_Y{^yMu@=ux$6 zKMCi^3|au2HHGCVgXU3EcNxwv61}BTGT!{^4~=U>cZj5UUigb`T>>BA3PGC_8fSk* z1Bt3@ zo5U|jLl3~!J!z=n^Zpfjj%5OldVRWf?J1wvepF#su;p$iCKai zP^MP{jbp+0J=C4%T9i=_~? zFr6R{YG>q4e#P`ZA9-I~n-PXoAkhs_9G5cKb^)2LuxUvaqmJmy|9%e=dKi!Mu)hkY zcWDz$Oq@uclvmoq8Up$e8{tIW!=- zBfQi=M-Zk9w*fPg*y-kQZMTR@DF=pKVeAfWOC7Q^+_;qcAPj|5mmFRBm7I2Lh>^1E zQ{a2JiN116nT34fvU4j`Z4Lep7$Wm$tpqLjJ{v5<)-j*8VW)L1G3qV$maQrdisCyfkSRe`WfEw>4<$_|4app{cjzwnUMIX;CNPik2g@$Jhco0 z>d6TRsXy5E|D;HQJ5s!{NyH~_G-Ex)#F5;!m510S_)3>_#pfI-M1%;E-KT~2RrFA{ z$#8u;*(QUa_WuTv9aAt@A6`7|_}(F_sEClQ)~F!eViN3}Ad1{%^2FE6|9y9NVd+P- z;L+;G$9}jUm!GN64Ae+}Qeewv6{d7FUpM% zb1$6*XU8537sh~GUF1g7Y0q!hT9D98eRMm`usDvi{=jOyCVC{x ztZWcSxQ)ulqr8Rc$gb8lBIb24tG0FPhZ=OQ_Nu@EchoA8k5{|p!*s{M#eQa7o~VAP z-gJiBqhvw;5R!N9=pkHNcbo$CbA|@_@P_wQpYayNUABp)Rw23-{AnRI!9Rge-+v=Y zihEb&*!J!PifD6$n;G4BfdUUs>E(5D#IZ}GXq~%pil3g5kKR#d5>J&XJ?H)|5}?a5 z·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%0D|(AT|jZ@uFm#D0a&sL-FN5NomG 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%0ANEfz#`T+5knLeJ%5cmKE0sc26YHG1oPt)XZ; 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≺zl~odM_}pNxJI&yx~|y;NNuk%yg!@(1;U+Z?rBnh6}r!L5h{HEpml;z8;Tx?l8fAj; zjn?JHAxYQO6~;9|_(tmrBczO%@N}TAy<{W`!Z%u9GSVgK+RMfwLHI`N%f?Pg4(%1A zQV_n;`ify&>FnSXWzVv=)SKw5~LU2*Nj7R~eHzu{T;@HCBo^e53VMqg)Wa(fXQk zUQ#!$%jS_}1z=qf!vQ zr@G#-y}?Vs_f$6+O$FhbsT+;Hg7D4MH;sHj_-5)`#!^A}X6hzmH=`0;gNFM(w-`&; zV4fwm_6_%VY%yMCge!ER{cU3}C)nRTe6|{=7#$>dO4tft&w}arezeVSFv8v5&u6>Q zT2hG54kKAoJ)fOMzNGtob{UH##rwQtY-LnJdNq8+=UwACkAu1l_1SGyN=otBW5llG zrDI+88CxZt@%+HZUypGM$n1urefArt7-6k1dzKrUHt=+KRy<&w5`<@|gT^IBd@ugc z2;YdFeAoWaXw8UU?IEKxBfgIvHhMDR?RnT(DLk=ehmF&gbRQW%S<-!M+^~3lY^1*F zuGtYIUl7*p6XR1xyu72vc@c*t95wvka;N*$h-Sn+j~NXa;m%y_am6_V~hB#HbuvaI(*FhQMjf1$8hPIjIX`9HXp`huEdJ1}uQI4Qxj1~!6 z&1k2f&5TY7`hXGsU<01djx>56$_p1XyZ-Y&Um4vcz3B57BVW=RK3^LvC2jLLWgL;T z$LAa41|vQ@zBL-XjU^l;c)$5qBT*2x*=gfEqY~l~dBo?8@zYlHEFlq*U;2D!tl7rt zM5Dj@oHx2}=k)hRmwhf7(K|SKHoocelW{{(bYtE3nsIw4#w{SN8#{b&8oPIK&mQ3U zo6-Fp7RT=Y?uwp1s2}iK?{(K$!{QDqI~uR|Qq0?omcR)x##c2R?_xTnM!uTaRMLIE zx|t}c6Z}Tca7n#$&7G>JmhUN=QBD8f3LmX%WiIwaU*>_&2meemsu$Y zYvyA%+>Lc9B_A|~`+jo~C&)9I1ehxrVF@|D0p=z~yo5mWZ!)fzcaV9_5*KVXdJpr& zbR)e(%y>pTU8p%u#wC+5vq;h;-!OBj@Wh!DVJ7auT=>cmX>MbLc{cHkGLMNk^o%y| zSUh7)@AqA$H}R}vhBM-KyLHV`GA^0Kn%PyTunNs*w1m`eGSxTM?6ep2M0(b@fq6qv zyCw^K8=JBFc-$jRmiRU?`wAM~WVvrsbF!f9CM$iLnX4J`cio$tn;790722Dd`x)`8 zZDF1kgxA;7Z1Dk>z&%@;4>RJP_n9LFq38YP7U|iQqabjKB$7>53X6|=8jk(tcmFwYFX$z~?^gdOj?ZL(P^=<}xD`ebvy zpfgRc+nzGl2)YSzPnlZ<`8Uhjb^YS63*sFKk+1(z=u=1w zNY`dl{YuRoLFvtA`%O1b37XdINixH1{S8m|Mze)}v&@x(-fgzrZ?<_`(1*>|`pq+s ze9Jw*YPQ2~f$8;EPUo7v=eN+bokm(ferf8n>(?D;p0<1P52*@+SV zB>P2kB#$G*n^XT6%@vGF$e89H{wvIPEa_e{k4ld*WgcgQr8o9kWmbwf9J{ZXwJUi#oGWE!XGZ)KwAxH(gwL#k{9iXq z1#NGRv{IzQTwWLbUarrsy~FPf^Eiv+r^B_T-*;HTB66_#PT#fWkaL{AXddRj&OF43 zx5P&C5+kf6-c{=ob+uS1v=k!+d z7$aV@ZRQO|mHY`I(~RKnVO!+;e`so#u=FLiZjkP<87(Q@ z|6?;=(s2Jz%pr^xkQR{cQ**M2ORhJ?|1)znBfN&XUZ0!0McjZEv;4m>k2B)WLynu* z7@bq_na*+3>$20vXhwWTIAL}XguU{mnIb)lJu1u`M&oUQVZ_Jv74sw`zCT_AaWJs&cU<8pKaI7Xij$Y zyk^ERLeGzYdRjbxF>@@QznC)_@iFm>xk=I)&+Fz$_n(u3_m|LNd8& zhBI0MPYbUG+%)3_g|$R_RC*TLZ%bULDLzP3VM#wPC?5UT@tjKQS^15=VnI9f<9n0Q&6v# z@aeJn8YgzOx6R#*_&xeO*^GEDifs`m+bL)X#kN7vrIv+u#kNz>ZHS|`V}iU}722uo6r+Ro$X4q;RNFN{ ztr%fVaGZ5%6&tA9ylx`#dne82V04gRoMyuq^ek<4)?2qVws;!0`>Ie+kq$i#TN)#N z4W=zq#9^MMZ7C-k*34!*BnWF}ljY5C)g;hnyTRgk%{*-67S@I5>0xWg=paE)4_g8w z?&)RgDLtEbdf6rmPb}Tr_N9zVvisQ1i#V*cug&%wyIO+eXNzXU%k#H2tU`S)p8mFU zOI(0$zKFw`1=u$5IQFKR!&WXmi#;5+Yr+$27G&#t+g*CFEu9fBy_PMf3e6Fon68%X zYfD^+?V5=9}Ul+-q`wk?_ww%LP$;kITnuGk~e)=pB}z$jZ+i)V~& zfQ&2lsB0S`scm4aEz{yz-&Q2!iai?Irb%iW*vR(0#j}a*_XB?21DgRUX_V^|^on&s(O%pbo|Nr7)|b%j-yTTP2bc!{l8 z=~yECJ{3#rwkQO{3hBUn9;z000i_0$^lyd zehU|5)%sMoE3B=!Cw|lNy;D`UTRjz43S}+qYCT?m-j5jmb3WBeaa~Jw`@g4jcaOWS z!fkPl0k`Gf?~}xO&^jjF7KLD#%c?E^@AJX$-lS|!RUJ{)?f4D4E>COt|J_vmp)WKx z{&lf>xLZIa?%1lWf%ck~{~h_@m~qV=YfbokbX%&H{-0Ftmid2otp5349s;AN>e}MA zCt3d!G463!o1;|V&W@i?{u#+r{gK4d z|C!wWjDH?GF#prztB>`m(Kn&2 zzu39D=F_%+E&u>$57`KGhg~D8y2aJ1Zo5L<;r}WX zuc7sB)NOIyce^dtk;(7G|9KxAMfYkYx82oN?lH{AQq|83taH#kqN?Ux-EJL|*6{z- zRL9szu=bAIq7V#oS@o&NzuO0ALDd%HCA#gdTJiZ(J=Qg1tK0w2rLvACYq zwVYpDSHwBkhl#J>Fum{Bw5v9Un+_zk9^~4xjDf@0_9x13QIZpZrH* zUp9KVjAi*)WmA>|p0QQZ8p0am-@g`7tIhur}fK8O1Do7t3K`eiq7yu*&8* z{#vfPR{VPZ-F4%&;x+uob(_fQJcY?;n8f=Xg_K&t(^=TvdahRDE#`g$L18WCdIG@L zRlXAPab+EEf7I_*yLEImWFyTQ%fqu+-4-%=8FmCpR{X;-k6p)n_{xkk#riD88dk|I z)*AeM5AOd*EA}d=VbxWg`&;)2cUUDmSRMW~3$Mcw)+W1IK3tZwa81eE>SZ>&|IGSO zvz`C@mP>3^!QT{B*e{Dx_~m5`TkH0ZOF71_?j)1$++6w8ysp<+&+`i!9Z3Oa44JYg%iV*TGsYu8Iob z79O_x+}lFox1{fV6*c|&n#Sj#HD_y>m(JTzZ|%+*S2KlhyC1Xjd#*o{A>czvZRYt5 zYZL1##7n7ZshJzj<*I#j?^KkyOX2%0{H8W5m)mRR%v*zBJCFTmEj344%~JmH8*bsO zefWravn5_>6tnOV%VT+%`&jMPwA^0voXk^M_bJ|be@6ay&dGl!f9tMY)8D-wx>g46 zV;!qCTia^kqZDTch2I~?wsnV9F=u&hd>#0s)qszDK4PtCT(d;XhqAMZ%AQMWq$L|a)$M#$`7@q>l!HbdxM$89{Bk{>i+C(Q^K|?JPhL0c z%3uxu(N$aRHT|uYKMM04tg(N_g0qQ|n(KMZb(LFqpSo9gm2_t9P}A~9yBi-5JRj?r zv07@D{%2D4U^U^VyFM&z?J2ZVG8pVC8O35TPuJbbIIw8qL}#@>!|Zq}uDU+gY_UJu zp{(PX*U&1hWz{^B|DUwLxfib8wY%LrtP);BYhVAFE1CfJ6qFRRI}6^|R!fz#EPeD} zw}$Jij&1I$o4Y>N*s9@KY&=-&FppVyPr1i-)iJP^)t~n-hACOZQoX`t8AwXjfm8_} zKYWL>jt9J7_~Ww;znif7^EqPOHLS6Gud!PAj%ls`zaz}|-)Ai65Nz|RZN)9tR^r$4 zNA{ZY>z~cj+78ya$#+0rI+vSRe{uhsyJSs&zL%k-#Fy=B*0QW&p1*Z=oM?b8!zFJw zF1h88dWX*u?!(VN*0elqP0L4)wG?X@pAxwKn&4e_?fckRpsPqQSqrvx@P8XQMz_QN%?kdV)-I6V`aTvu%)+06 zEcW<{$umq|VDbu+HW1vMgNZC8QZ)b{nDP_W;!p?yox zDtgEF-Jl{eH(-f>8adJSF!*0=`)SZx`fFRXb5Hzc`6SxLZ?X@@o)6kZz2a^|ZupyY zyJ#>A<1f-RV%Kf;3Qfa_eAg&7Mny@#bpE+fqyde;;y*t;G49p z?axrd%MTO;V-Ce0MaqY9lfnKml-`OQk6Z5%s+?%MMh{iKikob2r2H-JmEcxTdXl{r zxg56+!pGzGF-tNDWjVKE{;in5qGDO?Se~s=+U@GpI==<`Gkd5yzunbZ?I5?CwUX$z zb{WBq)T8Z+JsPRUg@l#?iypFoeB16iwET}C6O>G7jRfUxJCwHewL%gUycYEQ(PI|% ztk*mwi3YTP0Ay)ghmaB&16@H5XxlXeeXeM1z9e)P>#26o0!u=Z z=)Csd)=r{}AZ;e})I4u&=e}VmhcTHRR-|rgzdbCJ{WUnYKYafhYnh?Sm+k)&W>+q@ z|6ABl<)`*PfW+9z}|~B6;<@c*jDxyI&a@&|t9l2B=kczpd;Vx3ZdVC5av8d2fYpUz-%P6}~TR zp7(ARyPL)CX0f|j>~0oY4zaEL9Wa(ohaZ8NGSB-6!I9%&sT{1fo7G_*JR=k(r9&jh z(H-hVU@x?eutPuQL>y;x=M>97LHV`qx`;|ho8x;4WH0Y)AV+#BKJXy4T<~=WRiUW z8Sj6}6WcHu{yz3xhg;B|&o&qliSo(FB>GE-$sikqltJ3N9kzf}Rg^85}hZe6dM+UA;&Be{j>j>7f>|!acLbjo+jfa=rQD3q zjt(cZ2$60WFkbu?nGs0TqN(bFA$L6*h^#k5j! zMkLYm9mBu^-SvXg?_?9`gUl zKT-Lh#XkR@?AsDE)X)d_$7HB=m~6^q9FvJm4t(&Vm?F03EQ7R7JeRTAx{S?Je+@@e z5%e#tr6Ah|qI@vWMr`CE`0qs$LHdy-;zOE}ow^Tc3E%GSLt2xgAmfN)*hoBy1(^f> zKBSBswfm4YM2A06J;`!7#d0_eIoL=gnG5#wRSPjzlNSR4L!XyEXz-u>j6h;_{r3eI;aPbFPKgxx0vogevd)>7}D8+I*)kPMLmf) zm=1&MM803d2a>bQzccY>>FWx66LKM@Gx$vf|Gl6Wk~@KE3L&1rTzXtjuX;!PQPRJMP;~|}yo*k0P^p=pROn((p1{(9(&zOXs6?VlSSg{U69UFr(m2=qmAwpM4ssZ7@nD+i6~PJ<4F zegCfK`HKAfxQ_Mb zx>D$}01+Q3;vHOTL0sPnY}yEtV0{0sGI(6}B|!o3{xYa`+x5ZqSiIAL!mxINdT15dBTbB^uEb>f3u zr#-~=Y0y|sX(!HQ30#*y%ylI!kXXLfh3nX^Tqkzpnsn#w70vYbjx^BdUz)^q*&|$+ z_u#s+C)b^NiTd^C9NUNM#J*go_2as%?54^SQ1R z8h!D5Hx=iTuBH=et#82ir_9?Cti@7cnI_+r@KZR?pgzL&@1ec2VX zpUHK((516Dr#;K{UeGx2PBZpvi8;*^Rw;j72?>k745#$vV5EK#=85A4TIH+aN13~dY4+nJ* z>K!yZ=*ggxpy@#yf=&kg7(|2PgS!Ox3oZ#>82m!;>fkqncLaYJd@T6O;ID)K8eAEC zKKRGr>%pX!UdyXiV6D(vQMDS@A|ak3;UNhj{X!aq&JJB3x-N8c=+4l+p<8NySKASm z6gDU=1N`7k(h z4ksggN2H*FyoqR}kl0)P@a)RuGQFWN$XlfiV49=??9g8(WHZ!@E$(>BT$K(f&djsS$zl|WzIo<~OqhlAy8;BT$K(f&H^F|G$xoTAU~;3yf0y5S8m>=4MN;hj7Px#ZggWJYKYkR8IY4oOUoWippZ?ms{L zG4NRuj%VA+5m^7yh^Y|fJ_UZ5c6J0_5pUbIk$;6)ETNrv~}q^;&z1*NXR7bS&o6Bo_OZ=gHIZFfWVOgy+Lk4UOFnwY8?* zQ4jOkUk~TYhfE$}@bvRLf0Njzd!X*$sQ9sO=ko3kVvzeUCWC@eAn4HJtA|_WbS;pjMCM$g( z_QMwV2IPtQcWFMso$WYo0WNq34WEgD)GMwHIGK#hV z8BN=QjG^s7)}b9hHl!UvHiBm?lr*LZAe+$6Ae+)IAe+%{Ae+Ne7fM>t9w1xNULaf1 zJ|OR-{XpJN2Y~EO2ZHQR2ZJ0yhk{I|!$1zCkAWOSM}QnmQ$P-(sUU|^C&)+XD3HTw z2FMgT2IO;eEXesZ8{`5y4&?JR59C5x0CEv61i6?Nfm}i-fqa2J1#&5U8ssus0`f&V z734ZP4di+{1LOue3*<&R8|0gGF33&vIgp#_0+3tiLXcbOVvyVD3m|vUWw3|u1WDl& zlI0M7hsoXaC9u59J_y$W32(co`ym_(62^df0A!Tv z3Nlqa12RoL3w9?+N}g1|gYYPjl%%WQLpTE@C8N~~5FP`Pl1%j?gvWxUBul*v;cSqU zJ_l$GMTSl1$zNVO2(_dK)4VjB@@(NAzZ}dB=sg(CNlZ7`Wu9&sCOXt z8TBrNOF$}Qx~eFYOk;9}3X04GNy#i#2l=dOf}E|whh1b2NJ{3ao)De~62`6S4dMA9 zDOs-if?T2cgM3vD1p8|sVbrNXAUCVEKyFb(L7q{=KweQJK;BWKKq^`c$PleA$SAEI z$Y`wr$XKlr$a-26kS(=lAX{lIK;Ead0(rl7KgiZv8<1_awjkrQb|Bkn9YD6%I)dz| zJp{6omH;wA>kRT?tqaJ`S~rl1S`x@ES`Uz2wO$~*X?;L;*ZP4>(guKhTpI{7OB)PV zlns)SaoSLj)3sqBpVuA(xl9`Y@+)|yl704C(Yan0JSA%?6e*@$z`dW}{_4QE0bs%B2(KkYP14vkH^tV91sc#0kQ-2%e zE`1xw!}<vJ_*A<#sRJkfR%D)bzazd`I}f@RQ*`gy%<0k0_5g5^+4@R77ROwTRmh=b|5uc_bz+W=hN(F>l3a zQ}F!*1KutLJtsnpwOv8JB1!4bf(Y+LKg~MB=oC7r%+zc zSwhbhdV$c3gUs zCP_%m&&bY7PRSkR%+Dje2ckz;mj_99=H(|kGo7PS@|`3hFVC5qPdaC3<>lw5WMt)c zO-aqq&Mm5*s=3=EPb7jOx;ry-oVmyaV==Fytkk5e@!6>n&3gkN{6IoKrqQ?k;s$7W1~-~dRSk&-zmB@=2oAU_wf7e!Xd zgn_t53@49fggN54C!t05ZbM$;pOca1T?S#pcXQ&COt~;WmmQdZpy2rW4*~&NSI- zZa;|1%t+0!6p=J4D?8We_DIS~%`8ZBLRwUAd*95I{3o+>$GR<@p=k=NN&DtzL-Xfb zE~#_&*e5cwQlQhJ6Wl5Lrex$6X5?9NAK)BU;LOUe;?*l)o))CQ9aBVLoG_Li8MbxcloRvEn5Q`rTUYKgYY8<3pfu9?f&>t4p>^jv33 zn%kN6YxQeLf+?AuIo|1B5-sZ|8JLyl%s%3w4F54kNrTPD+9U$Px$3NXDqFlqWKsU30U?-ZLUO+iG@o*u89BCcqL_ zrD7?08L1XeUeN(goJX)GL#dWX_mX>0BfID>;|fwT?->n7wm#o85|U+%PsxO-dC%xR zxoJ+AFZYZaQ1AqF#yz8wQ!+D)px?&kq~vDgWoNmTTW)dYx;WAKWC|=Y|E1%|Ry8y0 znw{%TSH;0nC74;zENq~;c4g-3+K?YE$jF2%Bz$|z&V_Y86<&0a8+LVuEImt<+s25izbBa+X_bbw|GCS*$e-U9!^h2501_ zTYRdI6~-B`u8UpK#nrp3n==arXsRn(xI=@wEY%WJ>6Mz^!oqgF_N={G7vNWH?+9#J?x+O9RIxZzE)!FCCY8C7Wq21dgYB8n2*Ph z-YLB;nfK1dxn9L!oq)XyGObGhB4mvtt;VR34Zsetu72YOQx`$^C9&x0-OJr-So=Fu z3vzL8z!{1i1Yx<(<_k!F=aaCGK(pYze=_jeZLRgENY#DJr$J5y$;R&(@0Q=i;{S+J&9 zowLU}tM5#(vgGDhpO~mXedRGvQtV`jyBK+&cl~7FaqE#z6)g|Ef2^kg;$_ z@CO^7Yk0U8X0h8#bT6IK1lzw1^X*h3?D{f1z?u0Z9{_ME(kf3S(&Ao`q^WmymeT_H zGTbLu263cH7yunFfw!SVT$3g6dlr~FvMUKcw_7+XH5-rac^TvJ@Gfqb1{9>G!ouP< z+N95I53lLtF~6Lw%H&GFuq-~<@sBuNQ)zYXIA8i?N&cZM^~ z6L>m!7;e3@gd1$Gt`MHT@?fbE3msb>^GM&6JlJI5m?`=b@^^P5OskZ9@^BGcEIWPT zJtN%SC1yMGV5+h4!e$cO6yt<~d|*oh;2K(n{%WdO1xS9Egt=QV#1b0;;BE-(hY_2d24cD-Pp2a6LeA~~HO_qx15I7aW6P^+5 zOafu(w_N8~I4AQY%nV08w$>;DZ7~eY5j2@?n+W#p0tV3DB?T!MhMcd}U_F znzta#Ty2%+XT9WXu_d}18c#OXuxM=XOUUo(gaw9m0rRSM>R~RuvcUs;v=97|gFHc5 zf~>cz4Iei`9x$54jSSX}-I_pNc!}a3hV*ideF8dC9)<9bj;k4LXY9O=iP%=_nt&n# zQnFpXJIP3Yy5ToKABcl3fa5XL*pYWa> z9?~cnsT_o#NS&1Zz6qbMdr4I3*(=?jrj-SuaU@9^TgD6D53P z$96#{839F)&&V#oQx|(sIs%TmaG=H0H)DL#ius8uBl68d&UAk538O~kvWLU&>0Gs6 z@?-*NeH=YqGgIJ+Y0V6)L?_`b542D>XFiMsnRgx;k?nez%Ljv-Vf?{`_sNBE01sQm z-i9WE7I8-m&BO+`GtF&qHBK5Ckz0^O#6#kO{A{>jXMUIQ&?=T<^Ag6x?#FhIE?IC0 zgl()>O70juOp7+=8z>H79;(qFWCSdl*kL2`*aKN`Wk*R^uU%_J9>3kfY2b>2iNO|0 zi%AS?zRru)LTr5Q<%91tas^4svjknE9m`;gj94#R55CzrPGYC}41AOgb-)=9VOVvX zDPsvf5@$~0{88nmR34$BPNQJY&B~Y8P?cSqYP)j(T_!nXm~RbhZ#*Jk_V~7gJYpP6W1w&)e7b}e$e3_gejR->`8fiJLsH{ z+@)Ke{z+X15cuGUjg36wWNWVM&h#1`>~fHu%XZNkR@RjHu8vJ}fBZn;E`ZHEc!mm# zFD@nd8L)9>{5j>St3@eC5>X3a4=fOh`f>Sa4zIafRShCvHFqfOhdXABM0y zjCQg4pxF|vk~tdz=)eM)2p6~vC=iXVaJ(qt!7(F7JPf-rZbKRWtG#oLjq^J5`uj?{(zHMpiGl2{KRAGk-M0P^v@YOn{XxC_{?9pQ-gh`u z>`jX;&{CK4p8I*ubDs0u&UxRdEzY|`zTeLLI7nxS2I|ZWBXtzSsRj5WKrq777njW& z@1`%*IR%`D|C;G*))h{CH?g+HMm{2M1o}N)>kLUJieIZzNI^=AulI69?bb&QS9a#3RFH5$ZSErqptGj4qr-je!49ktXd zq}ya^nG*q5DuG+67K}=mOjX1*MUMv8N+&>CUaI)W`RbbG9fi7em}Ci?pOK=vh(`HR z+q}lt)~Z(nev)YD+GAaPTg>xaA2-<=vV#rW8rxTnkXS0B$rj#nJg$=Tk?LA)-I5}v z7E?9S^7jFxz|7gvd3$LTdF{E>=CCJtrjViSrI5UwZD@YFX|P?-oxR?;$JiUt*{QU# z9kWK^!+1wq!XyEr7N|Aa4@+`R*jimg3y-~1 zaJuffX((4qP@?1ZfTkoKSeTN zsU+v%T6T)z<7>6liFcSoI;ZVK9M={%0BR=u#us$((Gr73gfc_?wHM(zEvzG1+5EOq zFGE&(fm5}D6h~UqZCgSBw8+IP9Uir&Y^0*|7H46-GNO)r^?=~GN!*QwzW^;)s zLM(#*PI_xR{@}e2FbV_ z4Yycrte?8rI3IMh$%bD~BdBo{JrEC-&m^ZRwni+d`CU%e<}Y&CYEF)LeBaguJ8bR( z2x-{KzR*ioP6OiSScSkz#3M(lt<~CYQPhpk*iyhqk=Ct4@?adcSJ!Tb;iL~?xoQ-T z)wh()>r%kv^6~m2NUVX9`G#A?HO-3KIUdSE@QAcLSqr!i8m@8i?0kIp_>|8eUaBb8t&~Oldq5ZRM%-7)uzv<=PH(uq9*6pVcHCm`)dy zV@60PR*nFXMdkR39oiN}glSb~7oiJ9PU!>_W~cbk>Q$flAiUYfj@OsDOXuU$0c)z- zhDK$~)aNd63omZ0z#aT-(|UU-NTAxLP&049Q>L-@TPA=`by}B)9;mI`y!~CF)&xW6 z$q`Dr^MI8$j2Ids3T*m*>T%j}%5BpPQ`IE}F$#`fbwWJ30IRi}^|}skB3JW{K=1x# zKSs%D;LFzvnfrJw!8c;ch%alUxEZ*(gsafFjKO`nR@b=+0)kT#Xc*Npm7!}D?KxgU zZ>tm(cweF}W)*~7>tWWyiK(f{Q`3{v@~~)iwuq&P#$45IbFHtfEXwrYL?AXNVGt-m5F_F@fjFoA7 zgpS&XPwZ>EeAS=m06@9vJ^O*>W3Z_8N%?rC=roek*^>*Nh=qC4j=9~!@h>`4 zaBj)qxlr?+v}zftHB!yD0EHio6%GKjd{;P|tYKt*K9TInR(*ecIbB_x&{y9MFP%7P z$43i-t6v&(-n)3@d~J@Cfv{MxCx7;2*J2igG1f|=K**6#@`!FzwA@Y8HMY0>m7b*I zj99;I7LYvs#)v#3sTw3dptYn3i_?uN!E9af|R zSMaKAOsGI-Rdcm@-L~?D=?sA*O*b~smQSZu-lkxgN+Yc}wun8THN{a{jZ%4DG2d6{M?ch*TQQZ}BSWh58j|@knKET}pX8NZd{XM_mk;ilmR5N8U?))Sx(t6@P_z z$xa`k$Z-6%=AFV-J}a@rErKe>H0G9Wad0u+cuR7Nh0RBGU3Zf@JI{$bG0~k0$P&>k zhubt{W5-v67^?*HCJ$TR&L4<|MA_l8VQSMrYgV zfquxU@jxq91ZB~Dl2_d&dre}=AB2mQfB?uzMZOY~6yJUw1fK?Ue*F zm_NgyActFjegiF~b!Toht;UKD6_L{f&h@#IBO{Hg>#oX-&FXfS{kt10h)r4EW^3RB zPv5MpCAVIx;acn!z6*l60HhFnidN^ji*??i0!VGu_nN0a+r?k&V$qE9WU%KhJ?U;TQu%uOm@ziV$*~eq?G|GHbD3 zO}}swHVz{6A~?9J1Jjkukhk8^GPSvtFT^{7miX^f)IBF-mccD4F#f@&K4$7ms2m3#8EiO!Kh2UY7h&KtgK#L6Qk(tjQaxfwIv-acL4AZ zQ(;?l7Kk;-R;Lh^_eQl~84LAu7ZJN{oowMinheI-8ocL{t+vmwMyJ8r6^o@%8k`4) z1oZQ|nU*csx4d}9HDxXVBr^zut1;I-me(ay7Tp9)Xl3nwT@DpRC)KwUKy--wz=XV8 z!ri}u+~W#Q083ln`#&Xcm6Bc@auCLMkICK0PdZ3FC!q(aX?8f4#>unnDmY65fi8C~ zaNP!q8=13vcK%WZ1m&5Xi4Z#wG_Ip-swgeE5|FH>3|Tg?go7c~4`*+358U8JqOWXM z_0_t}_uLy?s5nXum%8(>z(fROz!OB8`oAiXs>Rqbq z4Gw9T%V6AmG;W4jnTIo+3wd{E>+FWxi6&|6P|CV**wP!3DUI{|g3uZG@uZkK*U4Hy z&q_CFrIP#^lMM|#V)Z5O&4@zQx;}cp9iKs92S3iePwherbsjdo%Ju_Ymmp5GN_q0F z%`_|=7u(9z%4Md>D`}1OmEOA+UTtjU^=Ds}ZFYDJ7$t6ew=AJw%KqH^p- zk7TQsv8#mQQguwPH6829OvaMb(|tbe|gwVFV+y!z$(Hwn>^Y!@qz%% zDct_zcoRW4eij#&-B=!p{#M(cE2}M5%LEY@Q`M_&@2C0n=a9Z^I?k?7E-XO*$(jK~ zI7n@+y0@y1bDn~`#dsRaG_w-62flF6-pC2(i8CvK@y)Dw2IwOp}7~ zmW{2e6sg)qu!!phTn~y^H)hpBm>+FR(zrNs(GGOav2muVyt-)T@~tckQR8bWCT=9> zUE<1yrd81LnkXTL9jMk?if^?lh@({N%MD%XI3)^+6m+%CI!3ceE^f4!;44}LeeSco z_7`bOw9HAuxr>WcZrVo8zTpo?Puk14+~YG%-ZS&Eo(EI7| z%1vKfU0qp2(@J(&+@9@{o6n(*^Nk4Z`tY@gb-sBw!S^CAx+>q1Xz-1R2H(3|A9R3 z0bP@-FqsC5wFWy+T3~5PetH-Ay!NVruZh(yH%_z4r~0boEfSt3)TI4HtMs9M*ZEuH za~tUFr28$W;x02v)%vYd@0`{2$Xn(oG!kekw5%DND~4XxzQhP~){jS^VDe-6FwUgH z7~J8ZRP)i8>bF8aO4nTG;xu!{G%@&u_KW0WJ=mBd?g;e+w`M0SO0RaSW0N+Ddc<0!?^6b+C$CG?@O{nksgfB=)Elk( z9ww$0a|Mw{gWeXEy1RW2E6j8UT2rf$&B*_dl!R}@gS zXQVm5wU!M7d>eL8XB#&j`xExosVO{Hj8+#(iAvw2*Fw6b+cOSS=V&Qv6pd7z`>^`Z z9#QHBuzmW*b^P9|(4XHMnyLB{t!PKM!jz45j=b}HK~>b~>C^2xPKg*&m3q*|@Gn|V zH~u&IJm=%|F1lB{1lsfTAd1sIt?)7VgH~@97*<#z(Z@QNcQ>D5FN{Nt6MWS3B>QBN z*fih2Il)JDmVsAH@ffwMhM&u{UW0l^Xrb}Yq{tE0JUzHuWB$>O)poZ&99nNvwkNh5 zaVNr9Nne6MdxDp2V%cp;eeJPiPIZIJ-ICr(BVpeOO4m~XAMVyV_|?kBHK{;N;vuSW zmumDJQkWZIt|Qj!Go&5>kDuUIv!H8AMn&H}54d~D;fu$Xqvr!|%<`6qf0U1?9&njH zt%26c6*Rt&|E6=dD5agMH4!~)&wNTFTgm;*TQunToAN0ci0z5@MG9~Of;x=R*V;kD zhisMNEG6I~O){TdhZrxF9{5n`;X{maM~L6yGQY-8iP+x*@WA8DXP&v<3*1}EZX0I~N$gErG4b~9b)`tW~lwO z!d$eAg>8>hVKQP>dD_?H-MTeTWn;ct|dK z(%r9vyLG$VfRSC|6(0MhecTy$bGwEhta;s1b*~V2pH6CSm6Gq-_V(@Pv;~$M%)Gsp z%nRi5Ucn_tz2+<}$nY_A2;8;JFQ?i-f3tLeZCZ3u)}?ijW_H$AO8W{awI`h;&7Qp5 zj<8PBAHAWYS!ow&m9+!i?Z3F(>yqyC zWZOuK_S%i7F<~j{!G3MMUMt82jrgp)Ls*hUgJ+L<9;c0H(aVz94^(=udS0M~C_CA+ zOWW4>xc9xf+q5S;TekM%#rD(OF<*h)u2M?)Z_k>e(blPS2?1g{na}@n5Z$;( zcl$Vfw=2L}9xZI5{<{a#>?ks=1w*mOL`xvz7y7;Wy0wp>?A<=iLPZrvqb6G>8NvOn zhv``gw>FcMcbT1aFrZ$v$dMSm@yhX{<%&=jZIdac4H=0`inS-1b`dTJI*C0|^#p6x zlsu_(Y%5dsM2dcEXsZWR@Ad@#ga}2ziCBVI8}0K~srt}dJr@1;JSc<)xVE!NFef|6CV9c<~b48oi?Ao|=c$tU&VHBGlqBlwvm z8`W>qPy@}Wy@sr?*q#kki29L9LCW?AZTn8_pkwqccOWC*;{7ku9z4s?cG4=j&ux`Z z?UGYkqp+8F!y*&cTDCg`-N74;5?OhN9=KP1H-Jj8h(*~vZr++3r2HQ35V0CB9}WJG zcIMr1w4T529>s?FB0mtKkni&nRxLbhA({j^V1*DZm=MWJ$glSdeUX(A?R?5T!cU4o zcRAVgC$PJ;s5(>K=V6R%CQS=zahyEFEg%r4r$TWYS%vg)gb zr6?E@QQ&*$x&&~|v9ex>NK{2<@B*z@n3*&ZzwYw0DlRUfJ)HJAL4)J+w_M==3Oc$3 zl(Z?WiiAZJJYHytwmZjmeX-QtcRy`CtM42s?YHvt5Kg>3C;zA0bA;B3-Zw+aEu8=o zFFrlx%QqbTZJoA~XiL^o(obUdX*F+DdI(DyZM86wa*DeH?R?d9El(rf56pW!Koe{e z+v{m>$}euOeO&|Zt@b^FPg-15NaPa{|M?J5w`}U0MUin0xN}E);}Gn`=vNYDgxoHq zRFCT9QFV0UpS+o$XU^kquE6UX9Ua7%i>Npn}`ATeQNW ze|bX_zI<0$6ZrFOo;u<#>%hn^`BFvQ!a4iwR(X*8-sq@%ASv^fxTkebu^qMh(&CURTCV7;n*j7BGh>SMPv=gPFvv#L~Xl~QHPuPSe zAeHv1dPW&f<&w!TxuqEXhz zF^A_qF>=|Hi9)2)O*#L)Th;C3!kyI+?zVLZefSXTqB=LK0b#ixy>)Ki_LesD{00rr+cTx+b^qMl-@CVT&}V-vQ`&rj-b zz4@-*p?o)8@_W7tvIISqY^MAH{2iHGC0iOVO_X~onM`TC$7QqSGGV4%?j@79Fm-(Qh(yrZ^u2ix( zv^&$CP7jy+)nK<(9#CZ;Ef!QU#D~jy1}F{E-=OO*-N&;u$guscD<=9}Hbe)k#-vr~ zvkHpS0p-LPu8YCcJkQ7$&F#(zT7ExB{i%paTddb*^wiufU&tZS!%RzqnteIUzHGAx z&hAV;PaePPpokEY&nvgTKjacoZa+V++@0y`3%Nv;+t;Vufq{@qM7aY4!uingq2uHW z7K>_O6zOw4nL?pJQI1-QX>gte73>}QJaG!aODhH9VqD{uH48N&qV%9ppfnMUKL`TU zbI2v4+(JPJP^P5}0fhmwY)G*W#NE0QS}dswy%L_qZ~l)gZH>rYXkMtSP0TzWKgrI@Lx;;F^v7 z+tz>c^`e3BegAmX9?f@r>Kp#?ZU6Y5f4p2Qj%Kp(ooj3l{Wa$DLD#ciSW^gM6wX`t zmW87h9=34G!bcQ>7}fl_#h>H3$qwl_P^u#e~5yfH4@M=sX0{Tbks5HOG`|@Bkyt`+8lbR4LW{qe@=31uE@penwn1h~lYR%5CXK0=$gr)V&8U5--O1krq1J4yMOG_H zgF*O=uSml7>MR4Oak*%lnWvaF`&2E%K2-Ej(=Dl!cEdWMin#&n^C>#oso3z%eui z977K{h8}PXJ>VF6z%ld?$1pG|mK4XZ8 z;WFBZ{%1+B1uL%DyvCRnHBA_-U8__~FvQ@TO{VQJD5 z@XKuJN-;c;BuW)Dg)3rmG*tNf$KUJ3JsJq|3M4m1K9J@i>5CeIctgPx00X^0-^~&} zW+V&+kB$M6qy$E<(%S(q;8ifqOWCX=KrBT`3N19nr}e4 zl)aJ9tJ4|Z>8UhllbjPGd03Bf>; z%OVIP>;+)|DFuokK>qfiOakUtj^Hc4}@%bHG9v<=ye0~^$6taX&^}$kk;Sp zrMNuG*7Ahx=5>REj*MLL+M5C^kMWf$2ST*5-WGipt@hiZls7H+U4!7=2*JB)2uLIl zyxW36*@B=Cy{@$JT)FHA-FU88Ech(sF#qxcA@ykK(N-J@&HZ^)3{?2M zLH4c@#dYZ@Oyj!7G=jJu#`Ls8%E-7?Br;}B8?V^fZMSi&Py4XFtL9=3oLW~U#Du%(9m8~ZpN_1c#MEd(fq^~bT@_8Z{WZDMemaE1g zSD8$H55(J7iNk0~KcL_)1shiRF|Od57TLTWW1IVdKMNO`1k*4zo?<@N%jE)H!MFJ* z2z}~#WROzg1;yfkYOsKQF7#r09E^&X7TiF4tZ#p7%n;k$-><#&Z?mP%CtxU4rxR96 zX#{nb?XRb`Ac!lG!RFJpfImnUP*E*lkp=AP^>NKVa8)+m<_igjZN!l2NibXo%%u6f7GM@#{HyeWG1y<7 zgYPr{dmc9=*QQs8-_+ujl|tHDD5}b{)Niuj%F(jFsXhEhPzHPdM+2hEATUi2Dcxr> zapSe2jXxGCYW+ou8{cprL1)?E7va%edb0$iPfw2@MDn@}e}DYhfq(h2&nfxUa{JXy~_WNJI^qH@A|M#yw`<(-8^`G_qtAG8QKYZxWpZ&d;{^2cq{@|PU{mI`i zoLm0WpZ)Mx-#vEyKb&{}qHD6N`a8G&FzJKtEPks1L4?gsty8h&czxVXVU)y)vOPbM8b2u+p z^rzQB=_tXuOtvrArCDw~m+kI{i4}6an0ytPeWm-d-8rZcpH>cfoE&N%AdOtMK6>`b z5hPYq=+0%)bEt|9Pl&;yaNfeVEF87)u!U0=KB5rKT{VAh@h2_*w#DDI_)8WZweXaM z6$>BSmvLpjZ&!(5NV&QWZe#63R z7XG${uPfaAzJ;$^&N~*jnw#IY`1dS)S)NpRH2QLA0~QnB&a+W#pfB&Tr8<1hRNy`6 zx0zCRtTuv+$(1k=NEMm-(=B zWv=y!iv#-1*nEW-^4EEP%;jlm99PrcX!gLJnqM~h`7#mfviW5UDa4Xwl{mK5dEBzf zGJ^8up7Av!zE%&BwE)A*e8)g9;Z*i&@p*cvd)CME%F4>c+krE-Va@bh(qX_0)E>r9ktY6RC<9VawE6^%lRVqAYxf{Ol3A$i5&l6&i zFhwj6nI>db_w%dSMn#Rv9G~=RRCu?#(y(t&rLe^LR+%5)_7z8X$BQ@W!V6t`W7JhL z?$%JqYf{@(_!WM}yREgoL2qqabj)k3*71aWKi#>GHoRD<57RT=u8ivs-SH+oBo9S3 zzv`J9sLg^j39|A)t~Z}&A+!csn*3010F?5loP{u(kC%oZ$|4f)SrvD&qO2<&VA8Se zkw@7~m+kw_H#~#+=C5Yl1nh+$WX={Cd*yQcE=gu4+c&w)OaFY4U_L`j)D8;)Ay3sd-n*K?Mt7a--!_E|J8?*~vOR!pb!AEo7l*rYw)uyU^{FL)bC;u&yEskFAz45SrZ5m=>-uCsq;xbo+I&Vb7=vS|`Nxut_GDH!Gx6rz z-W#F5Vm?ePlecBWt*r%_K_cU4*?7u7nwr%{GfOT`VH|g&s-~aQ+t%RS>@690Q+V~( z3s0meO!y8|EFr+WkNv=gBYkr}*dgpEH(;E@R$+X9c2BO~TRv=fSTJ&pLon8FI4^x{ zhJdXn>XT^eMQ{yM=cOZEy5%_Pc8U(=qq1f{QS^yy3G$L=vP1^ zX3D?={e51*uI>Uu*vh3Uq*0nQ>cIXMJ#0Q^dM6Zyku43>XbqclsQC)6PX3`(5%1F! z$!fk5$}BE*O#L>mQ(zUKI5W#NP9Cn&!*KR54~s#&A_2^(q+&!>56zI6%ys_7z2&7B z>x4e{sA#zPLPBxqhthpBOkj78MSh%rFbi#jtik$U6mERWAhsEZx@6x=JN!zn(v=_X z!C6UW|K8ldaL;g0sreWD!@~;SpqIY1wGYMb$!ITcKB4|I?1^k|m!a-yX(C;w+2BPI z{~m_MhH`~s7ZG?mR61Pb5WsaoeNrP4F2-s6E|XV4yBhq#O^plcNsVii$g@%`4sA-n zVC!pTiz<7ay(*k+{-jhXo1HZv&hQh?3pamax@z55vq73N_N|9E385R2X7iPTfAkN5 zLG)?QAdDwtpCQU_%D7!4BfrK!|J|JiAOCR046oYpi!tjXD|{Kt^=DjB}tv7m4<+FSgsZn`&q;jHm`9gi| z!d;c)^||xa+G6F%NM+{o%3YQ5#oCoxy)r&hd1!^7YF}@xT-vU`QN|q|tDHK|H-uIz zN7kzKb5uj6tk?(F8Wlbtre95(=aL_Sd!NmsQg2kM6+T4aznWB8S*WBY%NfmVA#5i5*B)N0uJTh;t?w7u7e^ZzH+65;>M2-OywXaxMZT1( zmlW{z$+e@4i^uuCga5t4T5V)rdO3go=k2a?*kU`u4hD8Gu!Dge4D4Xw{~iW1j+;O3 z1E>S-FnDJJFP(JctKNhBf8=o1z0|Fg|MOD!JwzUI)9wu61TW`L^K!yTUOG9$^MpG_ zTz|gX{h$Ab+(5nf0sidnuGaI{trV|1&qVtA%%eOq^s1}f$G9=88^pTRq#L~Y^AT&M zV+vi>=4QKdw8t&do} z8EUOq`8c_H4MH#3RQR-jdU=R4UCb8_^@71Aa^D|(qhY?IHs4c>E6UXRYGh$s*z>(< zWI=S=@`O>%!{5r$YWvSmpxaXGLv3r}sah`t>eUF%6!$ZK5}MPUa({PTchfa)y0(8E zP1w?_Pr7|RVlx(vo-+D5NgF|`*B!L_k!D-3p}cQ8x{KYMp;zH^9@^7e$lLD|=MEXo zx7XcD`8T5b!`613S?eaeUc&LOB);GFhQOU*2Ln48*ulUK26iy8gMl3k>|kIA1OGo@ zU^I*NjA76B6nFmYU|FtCGx9SrPXU + + + nunit.framework + + + +

+ The different targets a test action attribute can be applied to + + + + + Default target, which is determined by where the action attribute is attached + + + + + Target a individual test case + + + + + Target a suite of test cases + + + + + Delegate used by tests that execute code and + capture any thrown exception. + + + + + The Assert class contains a collection of static methods that + implement the most common assertions used in NUnit. + + + + + We don't actually want any instances of this object, but some people + like to inherit from it to add other static methods. Hence, the + protected constructor disallows any instances of this object. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Throws a with the message and arguments + that are passed in. This allows a test to be cut short, with a result + of success returned to NUnit. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws a with the message and arguments + that are passed in. This allows a test to be cut short, with a result + of success returned to NUnit. + + The message to initialize the with. + + + + Throws a with the message and arguments + that are passed in. This allows a test to be cut short, with a result + of success returned to NUnit. + + + + + Throws an with the message and arguments + that are passed in. This is used by the other Assert functions. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws an with the message that is + passed in. This is used by the other Assert functions. + + The message to initialize the with. + + + + Throws an . + This is used by the other Assert functions. + + + + + Throws an with the message and arguments + that are passed in. This causes the test to be reported as ignored. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws an with the message that is + passed in. This causes the test to be reported as ignored. + + The message to initialize the with. + + + + Throws an . + This causes the test to be reported as ignored. + + + + + Throws an with the message and arguments + that are passed in. This causes the test to be reported as inconclusive. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws an with the message that is + passed in. This causes the test to be reported as inconclusive. + + The message to initialize the with. + + + + Throws an . + This causes the test to be reported as Inconclusive. + + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + The message that will be displayed on failure + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that the code represented by a delegate throws an exception + that satisfies the constraint provided. + + A TestDelegate to be executed + A ThrowsConstraint used in the test + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + Used as a synonym for That in rare cases where a private setter + causes a Visual Basic compilation error. + + The actual value to test + A Constraint to be applied + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + Used as a synonym for That in rare cases where a private setter + causes a Visual Basic compilation error. + + The actual value to test + A Constraint to be applied + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + Used as a synonym for That in rare cases where a private setter + causes a Visual Basic compilation error. + + + This method is provided for use by VB developers needing to test + the value of properties with private setters. + + The actual value to test + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + A constraint to be satisfied by the exception + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + A constraint to be satisfied by the exception + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws a particular exception when called. + + A constraint to be satisfied by the exception + A TestDelegate + + + + Verifies that a delegate throws a particular exception when called. + + The exception Type expected + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + The exception Type expected + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws a particular exception when called. + + The exception Type expected + A TestDelegate + + + + Verifies that a delegate throws a particular exception when called. + + Type of the expected exception + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + Type of the expected exception + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws a particular exception when called. + + Type of the expected exception + A TestDelegate + + + + Verifies that a delegate throws an exception when called + and returns it. + + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws an exception when called + and returns it. + + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws an exception when called + and returns it. + + A TestDelegate + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + + + + Verifies that a delegate does not throw an exception + + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate does not throw an exception. + + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate does not throw an exception. + + A TestDelegate + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + + + + Verifies that two ints are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two ints are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two ints are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two longs are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two longs are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two longs are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two unsigned ints are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two unsigned ints are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two unsigned ints are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two unsigned longs are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two unsigned longs are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two unsigned longs are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two decimals are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two decimals are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two decimals are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are not equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are not equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are not equal an is thrown. + + The value that is expected + The actual value + + + + Verifies that two ints are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two ints are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two ints are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two longs are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two longs are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two longs are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two unsigned ints are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two unsigned ints are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two unsigned ints are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two unsigned longs are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two unsigned longs are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two unsigned longs are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two decimals are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two decimals are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two decimals are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two floats are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two floats are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two floats are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two doubles are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two doubles are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two doubles are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two objects are not equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two objects are not equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + + + + Verifies that two objects are not equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are equal an is thrown. + + The value that is expected + The actual value + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object + The actual object + + + + Asserts that two objects do not refer to the same object. If they + are the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that two objects do not refer to the same object. If they + are the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + + + + Asserts that two objects do not refer to the same object. If they + are the same an is thrown. + + The expected object + The actual object + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection + + + + Assert that a string is not empty - that is not equal to string.Empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is not empty - that is not equal to string.Empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is not empty - that is not equal to string.Empty + + The string to be tested + + + + Assert that an array, list or other collection is not empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that an array, list or other collection is not empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + + + + Assert that an array, list or other collection is not empty + + An array, list or other collection implementing ICollection + + + + Assert that a string is either null or equal to string.Empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is either null or equal to string.Empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is either null or equal to string.Empty + + The string to be tested + + + + Assert that a string is not null or empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is not null or empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is not null or empty + + The string to be tested + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Asserts that an object is contained in a list. + + The expected object + The list to be examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is contained in a list. + + The expected object + The list to be examined + The message to display in case of failure + + + + Asserts that an object is contained in a list. + + The expected object + The list to be examined + + + + Helper for Assert.AreEqual(double expected, double actual, ...) + allowing code generation to work consistently. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Gets the number of assertions executed so far and + resets the counter to zero. + + + + + AssertionHelper is an optional base class for user tests, + allowing the use of shorter names for constraints and + asserts and avoiding conflict with the definition of + , from which it inherits much of its + behavior, in certain mock object frameworks. + + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding only if a specified number of them succeed. + + + + + Returns a new PropertyConstraintExpression, which will either + test for the existence of the named property on the object + being tested or apply any following constraint to that property. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a constraint that tests two items for equality + + + + + Returns a constraint that tests that two references are the same object + + + + + Returns a constraint that tests whether the + actual value is greater than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a collection containing the same elements as the + collection supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a subset of the collection supplied as an argument. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new ContainsConstraint. This constraint + will, in turn, make use of the appropriate second-level + constraint, depending on the type of the actual argument. + This overload is only used if the item sought is a string, + since any other type implies that we are looking for a + collection member. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the regular expression supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the regular expression supplied as an argument. + + + + + Returns a constraint that fails if the actual + value matches the pattern supplied as an argument. + + + + + Returns a constraint that tests whether the path provided + is the same as an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the actual value falls + within a specified range. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if at least one of them succeeds. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them fail. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Length property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Count property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Message property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the InnerException property of the object being tested. + + + + + Returns a constraint that tests for null + + + + + Returns a constraint that tests for True + + + + + Returns a constraint that tests for False + + + + + Returns a constraint that tests for a positive value + + + + + Returns a constraint that tests for a negative value + + + + + Returns a constraint that tests for NaN + + + + + Returns a constraint that tests for empty + + + + + Returns a constraint that tests whether a collection + contains all unique items. + + + + + Returns a constraint that tests whether an object graph is serializable in binary format. + + + + + Returns a constraint that tests whether an object graph is serializable in xml format. + + + + + Returns a constraint that tests whether a collection is ordered + + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. Works + identically to Assert.That. + + The actual value to test + A Constraint to be applied + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. Works + identically to Assert.That. + + The actual value to test + A Constraint to be applied + The message to be displayed in case of failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. Works + identically to Assert.That. + + The actual value to test + A Constraint to be applied + The message to be displayed in case of failure + Arguments to use in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . Works Identically to + . + + The evaluated condition + The message to display if the condition is false + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . Works Identically to + . + + The evaluated condition + The message to display if the condition is false + + + + Asserts that a condition is true. If the condition is false the method throws + an . Works Identically to . + + The evaluated condition + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + The message that will be displayed on failure + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + The actual value to test + A Constraint to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that the code represented by a delegate throws an exception + that satisfies the constraint provided. + + A TestDelegate to be executed + A ThrowsConstraint used in the test + + + + Returns a ListMapper based on a collection. + + The original collection + + + + + Provides static methods to express the assumptions + that must be met for a test to give a meaningful + result. If an assumption is not met, the test + should produce an inconclusive result. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + + + + Asserts that a condition is true. If the condition is false the + method throws an . + + The evaluated condition + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that the code represented by a delegate throws an exception + that satisfies the constraint provided. + + A TestDelegate to be executed + A ThrowsConstraint used in the test + + + + Waits for pending asynchronous operations to complete, if appropriate, + and returns a proper result of the invocation by unwrapping task results + + The raw result of the method invocation + The unwrapped result, if necessary + + + + A set of Assert methods operationg on one or more collections + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + IEnumerable containing objects to be considered + System.Type that all objects in collection must be instances of + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + IEnumerable containing objects to be considered + System.Type that all objects in collection must be instances of + The message that will be displayed on failure + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + IEnumerable containing objects to be considered + System.Type that all objects in collection must be instances of + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that all items contained in collection are not equal to null. + + IEnumerable containing objects to be considered + + + + Asserts that all items contained in collection are not equal to null. + + IEnumerable containing objects to be considered + The message that will be displayed on failure + + + + Asserts that all items contained in collection are not equal to null. + + IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + IEnumerable of objects to be considered + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are not exactly equal. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + + + + Asserts that expected and actual are not exactly equal. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + + + + Asserts that expected and actual are not exactly equal. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are not equivalent. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are not equivalent. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are not equivalent. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that collection contains actual as an item. + + IEnumerable of objects to be considered + Object to be found within collection + + + + Asserts that collection contains actual as an item. + + IEnumerable of objects to be considered + Object to be found within collection + The message that will be displayed on failure + + + + Asserts that collection contains actual as an item. + + IEnumerable of objects to be considered + Object to be found within collection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that collection does not contain actual as an item. + + IEnumerable of objects to be considered + Object that cannot exist within collection + + + + Asserts that collection does not contain actual as an item. + + IEnumerable of objects to be considered + Object that cannot exist within collection + The message that will be displayed on failure + + + + Asserts that collection does not contain actual as an item. + + IEnumerable of objects to be considered + Object that cannot exist within collection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that superset is not a subject of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + + + + Asserts that superset is not a subject of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + + + + Asserts that superset is not a subject of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that superset is a subset of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + + + + Asserts that superset is a subset of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + + + + Asserts that superset is a subset of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing IEnumerable + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing IEnumerable + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + A custom comparer to perform the comparisons + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + A custom comparer to perform the comparisons + The message to be displayed on failure + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + A custom comparer to perform the comparisons + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Summary description for DirectoryAssert + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + We don't actually want any instances of this object, but some people + like to inherit from it to add other static methods. Hence, the + protected constructor disallows any instances of this object. + + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are not equal + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are equal + Arguments to be used in formatting the message + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are equal + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Summary description for FileAssert. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + We don't actually want any instances of this object, but some people + like to inherit from it to add other static methods. Hence, the + protected constructor disallows any instances of this object. + + + + + Verifies that two Streams are equal. Two Streams are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The expected Stream + The actual Stream + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Verifies that two Streams are equal. Two Streams are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The expected Stream + The actual Stream + The message to display if objects are not equal + + + + Verifies that two Streams are equal. Two Streams are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The expected Stream + The actual Stream + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if objects are not equal + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A file containing the value that is expected + A file containing the actual value + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if objects are not equal + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + + + + Asserts that two Streams are not equal. If they are equal + an is thrown. + + The expected Stream + The actual Stream + The message to be displayed when the two Stream are the same. + Arguments to be used in formatting the message + + + + Asserts that two Streams are not equal. If they are equal + an is thrown. + + The expected Stream + The actual Stream + The message to be displayed when the Streams are the same. + + + + Asserts that two Streams are not equal. If they are equal + an is thrown. + + The expected Stream + The actual Stream + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if objects are not equal + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + A file containing the value that is expected + A file containing the actual value + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if objects are not equal + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + + + + GlobalSettings is a place for setting default values used + by the framework in performing asserts. + + + + + Default tolerance for floating point equality + + + + + Class used to guard against unexpected argument values + by throwing an appropriate exception. + + + + + Throws an exception if an argument is null + + The value to be tested + The name of the argument + + + + Throws an exception if a string argument is null or empty + + The value to be tested + The name of the argument + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding only if a specified number of them succeed. + + + + + Returns a new PropertyConstraintExpression, which will either + test for the existence of the named property on the object + being tested or apply any following constraint to that property. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if at least one of them succeeds. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them fail. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Length property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Count property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Message property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the InnerException property of the object being tested. + + + + + Interface implemented by a user fixture in order to + validate any expected exceptions. It is only called + for test methods marked with the ExpectedException + attribute. + + + + + Method to handle an expected exception + + The exception to be handled + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a constraint that tests two items for equality + + + + + Returns a constraint that tests that two references are the same object + + + + + Returns a constraint that tests whether the + actual value is greater than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a collection containing the same elements as the + collection supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a subset of the collection supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the regular expression supplied as an argument. + + + + + Returns a constraint that tests whether the path provided + is the same as an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the actual value falls + within a specified range. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a constraint that tests for null + + + + + Returns a constraint that tests for True + + + + + Returns a constraint that tests for False + + + + + Returns a constraint that tests for a positive value + + + + + Returns a constraint that tests for a negative value + + + + + Returns a constraint that tests for NaN + + + + + Returns a constraint that tests for empty + + + + + Returns a constraint that tests whether a collection + contains all unique items. + + + + + Returns a constraint that tests whether an object graph is serializable in binary format. + + + + + Returns a constraint that tests whether an object graph is serializable in xml format. + + + + + Returns a constraint that tests whether a collection is ordered + + + + + The ITestCaseData interface is implemented by a class + that is able to return complete testcases for use by + a parameterized test method. + + NOTE: This interface is used in both the framework + and the core, even though that results in two different + types. However, sharing the source code guarantees that + the various implementations will be compatible and that + the core is able to reflect successfully over the + framework implementations of ITestCaseData. + + + + + Gets the argument list to be provided to the test + + + + + Gets the expected result + + + + + Indicates whether a result has been specified. + This is necessary because the result may be + null, so it's value cannot be checked. + + + + + Gets the expected exception Type + + + + + Gets the FullName of the expected exception + + + + + Gets the name to be used for the test + + + + + Gets the description of the test + + + + + Gets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets a value indicating whether this is explicit. + + true if explicit; otherwise, false. + + + + Gets the ignore reason. + + The ignore reason. + + + + The Iz class is a synonym for Is intended for use in VB, + which regards Is as a keyword. + + + + + The List class is a helper class with properties and methods + that supply a number of constraints used with lists and collections. + + + + + List.Map returns a ListMapper, which can be used to map + the original collection to another collection. + + + + + + + ListMapper is used to transform a collection used as an actual argument + producing another collection to be used in the assertion. + + + + + Construct a ListMapper based on a collection + + The collection to be transformed + + + + Produces a collection containing all the values of a property + + The collection of property values + + + + + Randomizer returns a set of random values in a repeatable + way, to allow re-running of tests if necessary. + + + + + Get a randomizer for a particular member, returning + one that has already been created if it exists. + This ensures that the same values are generated + each time the tests are reloaded. + + + + + Get a randomizer for a particular parameter, returning + one that has already been created if it exists. + This ensures that the same values are generated + each time the tests are reloaded. + + + + + Construct a randomizer using a random seed + + + + + Construct a randomizer using a specified seed + + + + + Return an array of random doubles between 0.0 and 1.0. + + + + + + + Return an array of random doubles with values in a specified range. + + + + + Return an array of random ints with values in a specified range. + + + + + Get a random seed for use in creating a randomizer. + + + + + The SpecialValue enum is used to represent TestCase arguments + that cannot be used as arguments to an Attribute. + + + + + Null represents a null value, which cannot be used as an + argument to an attribute under .NET 1.x + + + + + Basic Asserts on strings. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + + + + Asserts that a string is not found within another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + + + + Asserts that a string starts with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string starts with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string starts with another string. + + The expected string + The string to be examined + + + + Asserts that a string does not start with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string does not start with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string does not start with another string. + + The expected string + The string to be examined + + + + Asserts that a string ends with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string ends with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string ends with another string. + + The expected string + The string to be examined + + + + Asserts that a string does not end with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string does not end with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string does not end with another string. + + The expected string + The string to be examined + + + + Asserts that two strings are equal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that two strings are equal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + + + + Asserts that two strings are equal, without regard to case. + + The expected string + The actual string + + + + Asserts that two strings are not equal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that two strings are Notequal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + + + + Asserts that two strings are not equal, without regard to case. + + The expected string + The actual string + + + + Asserts that a string matches an expected regular expression pattern. + + The regex pattern to be matched + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string matches an expected regular expression pattern. + + The regex pattern to be matched + The actual string + The message to display in case of failure + + + + Asserts that a string matches an expected regular expression pattern. + + The regex pattern to be matched + The actual string + + + + Asserts that a string does not match an expected regular expression pattern. + + The regex pattern to be used + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string does not match an expected regular expression pattern. + + The regex pattern to be used + The actual string + The message to display in case of failure + + + + Asserts that a string does not match an expected regular expression pattern. + + The regex pattern to be used + The actual string + + + + The TestCaseData class represents a set of arguments + and other parameter info to be used for a parameterized + test case. It provides a number of instance modifiers + for use in initializing the test case. + + Note: Instance modifiers are getters that return + the same instance after modifying it's state. + + + + + The argument list to be provided to the test + + + + + The expected result to be returned + + + + + Set to true if this has an expected result + + + + + The expected exception Type + + + + + The FullName of the expected exception + + + + + The name to be used for the test + + + + + The description of the test + + + + + A dictionary of properties, used to add information + to tests without requiring the class to change. + + + + + If true, indicates that the test case is to be ignored + + + + + If true, indicates that the test case is marked explicit + + + + + The reason for ignoring a test case + + + + + Initializes a new instance of the class. + + The arguments. + + + + Initializes a new instance of the class. + + The argument. + + + + Initializes a new instance of the class. + + The first argument. + The second argument. + + + + Initializes a new instance of the class. + + The first argument. + The second argument. + The third argument. + + + + Sets the expected result for the test + + The expected result + A modified TestCaseData + + + + Sets the expected exception type for the test + + Type of the expected exception. + The modified TestCaseData instance + + + + Sets the expected exception type for the test + + FullName of the expected exception. + The modified TestCaseData instance + + + + Sets the name of the test case + + The modified TestCaseData instance + + + + Sets the description for the test case + being constructed. + + The description. + The modified TestCaseData instance. + + + + Applies a category to the test + + + + + + + Applies a named property to the test + + + + + + + + Applies a named property to the test + + + + + + + + Applies a named property to the test + + + + + + + + Ignores this TestCase. + + + + + + Ignores this TestCase, specifying the reason. + + The reason. + + + + + Marks this TestCase as Explicit + + + + + + Marks this TestCase as Explicit, specifying the reason. + + The reason. + + + + + Gets the argument list to be provided to the test + + + + + Gets the expected result + + + + + Returns true if the result has been set + + + + + Gets the expected exception Type + + + + + Gets the FullName of the expected exception + + + + + Gets the name to be used for the test + + + + + Gets the description of the test + + + + + Gets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets a value indicating whether this is explicit. + + true if explicit; otherwise, false. + + + + Gets the ignore reason. + + The ignore reason. + + + + Gets a list of categories associated with this test. + + + + + Gets the property dictionary for this test + + + + + Provide the context information of the current test + + + + + Constructs a TestContext using the provided context dictionary + + A context dictionary + + + + Get the current test context. This is created + as needed. The user may save the context for + use within a test, but it should not be used + outside the test for which it is created. + + + + + Gets a TestAdapter representing the currently executing test in this context. + + + + + Gets a ResultAdapter representing the current result for the test + executing in this context. + + + + + Gets the directory containing the current test assembly. + + + + + Gets the directory to be used for outputing files created + by this test run. + + + + + TestAdapter adapts a Test for consumption by + the user test code. + + + + + Constructs a TestAdapter for this context + + The context dictionary + + + + The name of the test. + + + + + The FullName of the test + + + + + The properties of the test. + + + + + ResultAdapter adapts a TestResult for consumption by + the user test code. + + + + + Construct a ResultAdapter for a context + + The context holding the result + + + + The TestState of current test. This maps to the ResultState + used in nunit.core and is subject to change in the future. + + + + + The TestStatus of current test. This enum will be used + in future versions of NUnit and so is to be preferred + to the TestState value. + + + + + Provides details about a test + + + + + Creates an instance of TestDetails + + The fixture that the test is a member of, if available. + The method that implements the test, if available. + The full name of the test. + A string representing the type of test, e.g. "Test Case". + Indicates if the test represents a suite of tests. + + + + The fixture that the test is a member of, if available. + + + + + The method that implements the test, if available. + + + + + The full name of the test. + + + + + A string representing the type of test, e.g. "Test Case". + + + + + Indicates if the test represents a suite of tests. + + + + + The ResultState enum indicates the result of running a test + + + + + The result is inconclusive + + + + + The test was not runnable. + + + + + The test has been skipped. + + + + + The test has been ignored. + + + + + The test succeeded + + + + + The test failed + + + + + The test encountered an unexpected exception + + + + + The test was cancelled by the user + + + + + The TestStatus enum indicates the result of running a test + + + + + The test was inconclusive + + + + + The test has skipped + + + + + The test succeeded + + + + + The test failed + + + + + Helper class with static methods used to supply constraints + that operate on strings. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that fails if the actual + value matches the pattern supplied as an argument. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + TextMessageWriter writes constraint descriptions and messages + in displayable form as a text stream. It tailors the display + of individual message components to form the standard message + format of NUnit assertion failure messages. + + + + + MessageWriter is the abstract base for classes that write + constraint descriptions and messages in some form. The + class has separate methods for writing various components + of a message, allowing implementations to tailor the + presentation as needed. + + + + + Construct a MessageWriter given a culture + + + + + Method to write single line message with optional args, usually + written to precede the general failure message. + + The message to be written + Any arguments used in formatting the message + + + + Method to write single line message with optional args, usually + written to precede the general failure message, at a givel + indentation level. + + The indentation level of the message + The message to be written + Any arguments used in formatting the message + + + + Display Expected and Actual lines for a constraint. This + is called by MessageWriter's default implementation of + WriteMessageTo and provides the generic two-line display. + + The constraint that failed + + + + Display Expected and Actual lines for given values. This + method may be called by constraints that need more control over + the display of actual and expected values than is provided + by the default implementation. + + The expected value + The actual value causing the failure + + + + Display Expected and Actual lines for given values, including + a tolerance value on the Expected line. + + The expected value + The actual value causing the failure + The tolerance within which the test was made + + + + Display the expected and actual string values on separate lines. + If the mismatch parameter is >=0, an additional line is displayed + line containing a caret that points to the mismatch point. + + The expected string value + The actual string value + The point at which the strings don't match or -1 + If true, case is ignored in locating the point where the strings differ + If true, the strings should be clipped to fit the line + + + + Writes the text for a connector. + + The connector. + + + + Writes the text for a predicate. + + The predicate. + + + + Writes the text for an expected value. + + The expected value. + + + + Writes the text for a modifier + + The modifier. + + + + Writes the text for an actual value. + + The actual value. + + + + Writes the text for a generalized value. + + The value. + + + + Writes the text for a collection value, + starting at a particular point, to a max length + + The collection containing elements to write. + The starting point of the elements to write + The maximum number of elements to write + + + + Abstract method to get the max line length + + + + + Prefix used for the expected value line of a message + + + + + Prefix used for the actual value line of a message + + + + + Length of a message prefix + + + + + Construct a TextMessageWriter + + + + + Construct a TextMessageWriter, specifying a user message + and optional formatting arguments. + + + + + + + Method to write single line message with optional args, usually + written to precede the general failure message, at a givel + indentation level. + + The indentation level of the message + The message to be written + Any arguments used in formatting the message + + + + Display Expected and Actual lines for a constraint. This + is called by MessageWriter's default implementation of + WriteMessageTo and provides the generic two-line display. + + The constraint that failed + + + + Display Expected and Actual lines for given values. This + method may be called by constraints that need more control over + the display of actual and expected values than is provided + by the default implementation. + + The expected value + The actual value causing the failure + + + + Display Expected and Actual lines for given values, including + a tolerance value on the expected line. + + The expected value + The actual value causing the failure + The tolerance within which the test was made + + + + Display the expected and actual string values on separate lines. + If the mismatch parameter is >=0, an additional line is displayed + line containing a caret that points to the mismatch point. + + The expected string value + The actual string value + The point at which the strings don't match or -1 + If true, case is ignored in string comparisons + If true, clip the strings to fit the max line length + + + + Writes the text for a connector. + + The connector. + + + + Writes the text for a predicate. + + The predicate. + + + + Write the text for a modifier. + + The modifier. + + + + Writes the text for an expected value. + + The expected value. + + + + Writes the text for an actual value. + + The actual value. + + + + Writes the text for a generalized value. + + The value. + + + + Writes the text for a collection value, + starting at a particular point, to a max length + + The collection containing elements to write. + The starting point of the elements to write + The maximum number of elements to write + + + + Write the generic 'Expected' line for a constraint + + The constraint that failed + + + + Write the generic 'Expected' line for a given value + + The expected value + + + + Write the generic 'Expected' line for a given value + and tolerance. + + The expected value + The tolerance within which the test was made + + + + Write the generic 'Actual' line for a constraint + + The constraint for which the actual value is to be written + + + + Write the generic 'Actual' line for a given value + + The actual value causing a failure + + + + Gets or sets the maximum line length for this writer + + + + + Helper class with properties and methods that supply + constraints that operate on exceptions. + + + + + Creates a constraint specifying the exact type of exception expected + + + + + Creates a constraint specifying the exact type of exception expected + + + + + Creates a constraint specifying the type of exception expected + + + + + Creates a constraint specifying the type of exception expected + + + + + Creates a constraint specifying an expected exception + + + + + Creates a constraint specifying an exception with a given InnerException + + + + + Creates a constraint specifying an expected TargetInvocationException + + + + + Creates a constraint specifying an expected TargetInvocationException + + + + + Creates a constraint specifying an expected TargetInvocationException + + + + + Creates a constraint specifying that no exception is thrown + + + + + Attribute used to apply a category to a test + + + + + The name of the category + + + + + Construct attribute for a given category based on + a name. The name may not contain the characters ',', + '+', '-' or '!'. However, this is not checked in the + constructor since it would cause an error to arise at + as the test was loaded without giving a clear indication + of where the problem is located. The error is handled + in NUnitFramework.cs by marking the test as not + runnable. + + The name of the category + + + + Protected constructor uses the Type name as the name + of the category. + + + + + The name of the category + + + + + Used to mark a field for use as a datapoint when executing a theory + within the same fixture that requires an argument of the field's Type. + + + + + Used to mark an array as containing a set of datapoints to be used + executing a theory within the same fixture that requires an argument + of the Type of the array elements. + + + + + Attribute used to provide descriptive text about a + test case or fixture. + + + + + Construct the attribute + + Text describing the test + + + + Gets the test description + + + + + Enumeration indicating how the expected message parameter is to be used + + + + Expect an exact match + + + Expect a message containing the parameter string + + + Match the regular expression provided as a parameter + + + Expect a message that starts with the parameter string + + + + ExpectedExceptionAttribute + + + + + + Constructor for a non-specific exception + + + + + Constructor for a given type of exception + + The type of the expected exception + + + + Constructor for a given exception name + + The full name of the expected exception + + + + Gets or sets the expected exception type + + + + + Gets or sets the full Type name of the expected exception + + + + + Gets or sets the expected message text + + + + + Gets or sets the user message displayed in case of failure + + + + + Gets or sets the type of match to be performed on the expected message + + + + + Gets the name of a method to be used as an exception handler + + + + + ExplicitAttribute marks a test or test fixture so that it will + only be run if explicitly executed from the gui or command line + or if it is included by use of a filter. The test will not be + run simply because an enclosing suite is run. + + + + + Default constructor + + + + + Constructor with a reason + + The reason test is marked explicit + + + + The reason test is marked explicit + + + + + Attribute used to mark a test that is to be ignored. + Ignored tests result in a warning message when the + tests are run. + + + + + Constructs the attribute without giving a reason + for ignoring the test. + + + + + Constructs the attribute giving a reason for ignoring the test + + The reason for ignoring the test + + + + The reason for ignoring a test + + + + + Abstract base for Attributes that are used to include tests + in the test run based on environmental settings. + + + + + Constructor with no included items specified, for use + with named property syntax. + + + + + Constructor taking one or more included items + + Comma-delimited list of included items + + + + Name of the item that is needed in order for + a test to run. Multiple itemss may be given, + separated by a comma. + + + + + Name of the item to be excluded. Multiple items + may be given, separated by a comma. + + + + + The reason for including or excluding the test + + + + + PlatformAttribute is used to mark a test fixture or an + individual method as applying to a particular platform only. + + + + + Constructor with no platforms specified, for use + with named property syntax. + + + + + Constructor taking one or more platforms + + Comma-deliminted list of platforms + + + + CultureAttribute is used to mark a test fixture or an + individual method as applying to a particular Culture only. + + + + + Constructor with no cultures specified, for use + with named property syntax. + + + + + Constructor taking one or more cultures + + Comma-deliminted list of cultures + + + + Marks a test to use a combinatorial join of any argument data + provided. NUnit will create a test case for every combination of + the arguments provided. This can result in a large number of test + cases and so should be used judiciously. This is the default join + type, so the attribute need not be used except as documentation. + + + + + PropertyAttribute is used to attach information to a test as a name/value pair.. + + + + + Construct a PropertyAttribute with a name and string value + + The name of the property + The property value + + + + Construct a PropertyAttribute with a name and int value + + The name of the property + The property value + + + + Construct a PropertyAttribute with a name and double value + + The name of the property + The property value + + + + Constructor for derived classes that set the + property dictionary directly. + + + + + Constructor for use by derived classes that use the + name of the type as the property name. Derived classes + must ensure that the Type of the property value is + a standard type supported by the BCL. Any custom + types will cause a serialization Exception when + in the client. + + + + + Gets the property dictionary for this attribute + + + + + Default constructor + + + + + Marks a test to use pairwise join of any argument data provided. + NUnit will attempt too excercise every pair of argument values at + least once, using as small a number of test cases as it can. With + only two arguments, this is the same as a combinatorial join. + + + + + Default constructor + + + + + Marks a test to use a sequential join of any argument data + provided. NUnit will use arguements for each parameter in + sequence, generating test cases up to the largest number + of argument values provided and using null for any arguments + for which it runs out of values. Normally, this should be + used with the same number of arguments for each parameter. + + + + + Default constructor + + + + + Summary description for MaxTimeAttribute. + + + + + Construct a MaxTimeAttribute, given a time in milliseconds. + + The maximum elapsed time in milliseconds + + + + RandomAttribute is used to supply a set of random values + to a single parameter of a parameterized test. + + + + + ValuesAttribute is used to provide literal arguments for + an individual parameter of a test. + + + + + Abstract base class for attributes that apply to parameters + and supply data for the parameter. + + + + + Gets the data to be provided to the specified parameter + + + + + The collection of data to be returned. Must + be set by any derived attribute classes. + We use an object[] so that the individual + elements may have their type changed in GetData + if necessary. + + + + + Construct with one argument + + + + + + Construct with two arguments + + + + + + + Construct with three arguments + + + + + + + + Construct with an array of arguments + + + + + + Get the collection of values to be used as arguments + + + + + Construct a set of doubles from 0.0 to 1.0, + specifying only the count. + + + + + + Construct a set of doubles from min to max + + + + + + + + Construct a set of ints from min to max + + + + + + + + Get the collection of values to be used as arguments + + + + + RangeAttribute is used to supply a range of values to an + individual parameter of a parameterized test. + + + + + Construct a range of ints using default step of 1 + + + + + + + Construct a range of ints specifying the step size + + + + + + + + Construct a range of longs + + + + + + + + Construct a range of doubles + + + + + + + + Construct a range of floats + + + + + + + + RepeatAttribute may be applied to test case in order + to run it multiple times. + + + + + Construct a RepeatAttribute + + The number of times to run the test + + + + RequiredAddinAttribute may be used to indicate the names of any addins + that must be present in order to run some or all of the tests in an + assembly. If the addin is not loaded, the entire assembly is marked + as NotRunnable. + + + + + Initializes a new instance of the class. + + The required addin. + + + + Gets the name of required addin. + + The required addin name. + + + + Summary description for SetCultureAttribute. + + + + + Construct given the name of a culture + + + + + + Summary description for SetUICultureAttribute. + + + + + Construct given the name of a culture + + + + + + SetUpAttribute is used in a TestFixture to identify a method + that is called immediately before each test is run. It is + also used in a SetUpFixture to identify the method that is + called once, before any of the subordinate tests are run. + + + + + Attribute used to mark a class that contains one-time SetUp + and/or TearDown methods that apply to all the tests in a + namespace or an assembly. + + + + + Attribute used to mark a static (shared in VB) property + that returns a list of tests. + + + + + Attribute used in a TestFixture to identify a method that is + called immediately after each test is run. It is also used + in a SetUpFixture to identify the method that is called once, + after all subordinate tests have run. In either case, the method + is guaranteed to be called, even if an exception is thrown. + + + + + Provide actions to execute before and after tests. + + + + + When implemented by an attribute, this interface implemented to provide actions to execute before and after tests. + + + + + Executed before each test is run + + Provides details about the test that is going to be run. + + + + Executed after each test is run + + Provides details about the test that has just been run. + + + + Provides the target for the action attribute + + The target for the action attribute + + + + Adding this attribute to a method within a + class makes the method callable from the NUnit test runner. There is a property + called Description which is optional which you can provide a more detailed test + description. This class cannot be inherited. + + + + [TestFixture] + public class Fixture + { + [Test] + public void MethodToTest() + {} + + [Test(Description = "more detailed description")] + publc void TestDescriptionMethod() + {} + } + + + + + + Descriptive text for this test + + + + + TestCaseAttribute is used to mark parameterized test cases + and provide them with their arguments. + + + + + Construct a TestCaseAttribute with a list of arguments. + This constructor is not CLS-Compliant + + + + + + Construct a TestCaseAttribute with a single argument + + + + + + Construct a TestCaseAttribute with a two arguments + + + + + + + Construct a TestCaseAttribute with a three arguments + + + + + + + + Gets the list of arguments to a test case + + + + + Gets or sets the expected result. Use + ExpectedResult by preference. + + The result. + + + + Gets or sets the expected result. + + The result. + + + + Gets a flag indicating whether an expected + result has been set. + + + + + Gets a list of categories associated with this test; + + + + + Gets or sets the category associated with this test. + May be a single category or a comma-separated list. + + + + + Gets or sets the expected exception. + + The expected exception. + + + + Gets or sets the name the expected exception. + + The expected name of the exception. + + + + Gets or sets the expected message of the expected exception + + The expected message of the exception. + + + + Gets or sets the type of match to be performed on the expected message + + + + + Gets or sets the description. + + The description. + + + + Gets or sets the name of the test. + + The name of the test. + + + + Gets or sets the ignored status of the test + + + + + Gets or sets the ignored status of the test + + + + + Gets or sets the explicit status of the test + + + + + Gets or sets the reason for not running the test + + + + + Gets or sets the reason for not running the test. + Set has the side effect of marking the test as ignored. + + The ignore reason. + + + + FactoryAttribute indicates the source to be used to + provide test cases for a test method. + + + + + Construct with the name of the data source, which must + be a property, field or method of the test class itself. + + An array of the names of the factories that will provide data + + + + Construct with a Type, which must implement IEnumerable + + The Type that will provide data + + + + Construct with a Type and name. + that don't support params arrays. + + The Type that will provide data + The name of the method, property or field that will provide data + + + + The name of a the method, property or fiend to be used as a source + + + + + A Type to be used as a source + + + + + Gets or sets the category associated with this test. + May be a single category or a comma-separated list. + + + + + [TestFixture] + public class ExampleClass + {} + + + + + Default constructor + + + + + Construct with a object[] representing a set of arguments. + In .NET 2.0, the arguments may later be separated into + type arguments and constructor arguments. + + + + + + Descriptive text for this fixture + + + + + Gets and sets the category for this fixture. + May be a comma-separated list of categories. + + + + + Gets a list of categories for this fixture + + + + + The arguments originally provided to the attribute + + + + + Gets or sets a value indicating whether this should be ignored. + + true if ignore; otherwise, false. + + + + Gets or sets the ignore reason. May set Ignored as a side effect. + + The ignore reason. + + + + Get or set the type arguments. If not set + explicitly, any leading arguments that are + Types are taken as type arguments. + + + + + Attribute used to identify a method that is + called before any tests in a fixture are run. + + + + + Attribute used to identify a method that is called after + all the tests in a fixture have run. The method is + guaranteed to be called, even if an exception is thrown. + + + + + Adding this attribute to a method within a + class makes the method callable from the NUnit test runner. There is a property + called Description which is optional which you can provide a more detailed test + description. This class cannot be inherited. + + + + [TestFixture] + public class Fixture + { + [Test] + public void MethodToTest() + {} + + [Test(Description = "more detailed description")] + publc void TestDescriptionMethod() + {} + } + + + + + + Used on a method, marks the test with a timeout value in milliseconds. + The test will be run in a separate thread and is cancelled if the timeout + is exceeded. Used on a method or assembly, sets the default timeout + for all contained test methods. + + + + + Construct a TimeoutAttribute given a time in milliseconds + + The timeout value in milliseconds + + + + Marks a test that must run in the STA, causing it + to run in a separate thread if necessary. + + On methods, you may also use STAThreadAttribute + to serve the same purpose. + + + + + Construct a RequiresSTAAttribute + + + + + Marks a test that must run in the MTA, causing it + to run in a separate thread if necessary. + + On methods, you may also use MTAThreadAttribute + to serve the same purpose. + + + + + Construct a RequiresMTAAttribute + + + + + Marks a test that must run on a separate thread. + + + + + Construct a RequiresThreadAttribute + + + + + Construct a RequiresThreadAttribute, specifying the apartment + + + + + ValueSourceAttribute indicates the source to be used to + provide data for one parameter of a test method. + + + + + Construct with the name of the factory - for use with languages + that don't support params arrays. + + The name of the data source to be used + + + + Construct with a Type and name - for use with languages + that don't support params arrays. + + The Type that will provide data + The name of the method, property or field that will provide data + + + + The name of a the method, property or fiend to be used as a source + + + + + A Type to be used as a source + + + + + AllItemsConstraint applies another constraint to each + item in a collection, succeeding if they all succeed. + + + + + Abstract base class used for prefixes + + + + + The Constraint class is the base of all built-in constraints + within NUnit. It provides the operator overloads used to combine + constraints. + + + + + The IConstraintExpression interface is implemented by all + complete and resolvable constraints and expressions. + + + + + Return the top-level constraint for this expression + + + + + + Static UnsetObject used to detect derived constraints + failing to set the actual value. + + + + + The actual value being tested against a constraint + + + + + The display name of this Constraint for use by ToString() + + + + + Argument fields used by ToString(); + + + + + The builder holding this constraint + + + + + Construct a constraint with no arguments + + + + + Construct a constraint with one argument + + + + + Construct a constraint with two arguments + + + + + Sets the ConstraintBuilder holding this constraint + + + + + Write the failure message to the MessageWriter provided + as an argument. The default implementation simply passes + the constraint and the actual value to the writer, which + then displays the constraint description and the value. + + Constraints that need to provide additional details, + such as where the error occured can override this. + + The MessageWriter on which to display the message + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Test whether the constraint is satisfied by an + ActualValueDelegate that returns the value to be tested. + The default implementation simply evaluates the delegate + but derived classes may override it to provide for delayed + processing. + + An + True for success, false for failure + + + + Test whether the constraint is satisfied by a given reference. + The default implementation simply dereferences the value but + derived classes may override it to provide for delayed processing. + + A reference to the value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Default override of ToString returns the constraint DisplayName + followed by any arguments within angle brackets. + + + + + + Returns the string representation of this constraint + + + + + This operator creates a constraint that is satisfied only if both + argument constraints are satisfied. + + + + + This operator creates a constraint that is satisfied if either + of the argument constraints is satisfied. + + + + + This operator creates a constraint that is satisfied if the + argument constraint is not satisfied. + + + + + Returns a DelayedConstraint with the specified delay time. + + The delay in milliseconds. + + + + + Returns a DelayedConstraint with the specified delay time + and polling interval. + + The delay in milliseconds. + The interval at which to test the constraint. + + + + + The display name of this Constraint for use by ToString(). + The default value is the name of the constraint with + trailing "Constraint" removed. Derived classes may set + this to another name in their constructors. + + + + + Returns a ConstraintExpression by appending And + to the current constraint. + + + + + Returns a ConstraintExpression by appending And + to the current constraint. + + + + + Returns a ConstraintExpression by appending Or + to the current constraint. + + + + + Class used to detect any derived constraints + that fail to set the actual value in their + Matches override. + + + + + The base constraint + + + + + Construct given a base constraint + + + + + + Construct an AllItemsConstraint on top of an existing constraint + + + + + + Apply the item constraint to each item in the collection, + failing if any item fails. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + AndConstraint succeeds only if both members succeed. + + + + + BinaryConstraint is the abstract base of all constraints + that combine two other constraints in some fashion. + + + + + The first constraint being combined + + + + + The second constraint being combined + + + + + Construct a BinaryConstraint from two other constraints + + The first constraint + The second constraint + + + + Create an AndConstraint from two other constraints + + The first constraint + The second constraint + + + + Apply both member constraints to an actual value, succeeding + succeeding only if both of them succeed. + + The actual value + True if the constraints both succeeded + + + + Write a description for this contraint to a MessageWriter + + The MessageWriter to receive the description + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + AssignableFromConstraint is used to test that an object + can be assigned from a given Type. + + + + + TypeConstraint is the abstract base for constraints + that take a Type as their expected value. + + + + + The expected Type used by the constraint + + + + + Construct a TypeConstraint for a given Type + + + + + + Write the actual value for a failing constraint test to a + MessageWriter. TypeConstraints override this method to write + the name of the type. + + The writer on which the actual value is displayed + + + + Construct an AssignableFromConstraint for the type provided + + + + + + Test whether an object can be assigned from the specified type + + The object to be tested + True if the object can be assigned a value of the expected Type, otherwise false. + + + + Write a description of this constraint to a MessageWriter + + The MessageWriter to use + + + + AssignableToConstraint is used to test that an object + can be assigned to a given Type. + + + + + Construct an AssignableToConstraint for the type provided + + + + + + Test whether an object can be assigned to the specified type + + The object to be tested + True if the object can be assigned a value of the expected Type, otherwise false. + + + + Write a description of this constraint to a MessageWriter + + The MessageWriter to use + + + + AttributeConstraint tests that a specified attribute is present + on a Type or other provider and that the value of the attribute + satisfies some other constraint. + + + + + Constructs an AttributeConstraint for a specified attriute + Type and base constraint. + + + + + + + Determines whether the Type or other provider has the + expected attribute and if its value matches the + additional constraint specified. + + + + + Writes a description of the attribute to the specified writer. + + + + + Writes the actual value supplied to the specified writer. + + + + + Returns a string representation of the constraint. + + + + + AttributeExistsConstraint tests for the presence of a + specified attribute on a Type. + + + + + Constructs an AttributeExistsConstraint for a specific attribute Type + + + + + + Tests whether the object provides the expected attribute. + + A Type, MethodInfo, or other ICustomAttributeProvider + True if the expected attribute is present, otherwise false + + + + Writes the description of the constraint to the specified writer + + + + + BasicConstraint is the abstract base for constraints that + perform a simple comparison to a constant value. + + + + + Initializes a new instance of the class. + + The expected. + The description. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + BinarySerializableConstraint tests whether + an object is serializable in binary format. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation + + + + + CollectionConstraint is the abstract base class for + constraints that operate on collections. + + + + + Construct an empty CollectionConstraint + + + + + Construct a CollectionConstraint + + + + + + Determines whether the specified enumerable is empty. + + The enumerable. + + true if the specified enumerable is empty; otherwise, false. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Protected method to be implemented by derived classes + + + + + + + CollectionContainsConstraint is used to test whether a collection + contains an expected object as a member. + + + + + CollectionItemsEqualConstraint is the abstract base class for all + collection constraints that apply some notion of item equality + as a part of their operation. + + + + + Construct an empty CollectionConstraint + + + + + Construct a CollectionConstraint + + + + + + Flag the constraint to use the supplied EqualityAdapter. + NOTE: For internal use only. + + The EqualityAdapter to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied Comparison object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Compares two collection members for equality + + + + + Return a new CollectionTally for use in making tests + + The collection to be included in the tally + + + + Flag the constraint to ignore case and return self. + + + + + Construct a CollectionContainsConstraint + + + + + + Test whether the expected item is contained in the collection + + + + + + + Write a descripton of the constraint to a MessageWriter + + + + + + CollectionEquivalentCOnstraint is used to determine whether two + collections are equivalent. + + + + + Construct a CollectionEquivalentConstraint + + + + + + Test whether two collections are equivalent + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + CollectionOrderedConstraint is used to test whether a collection is ordered. + + + + + Construct a CollectionOrderedConstraint + + + + + Modifies the constraint to use an IComparer and returns self. + + + + + Modifies the constraint to use an IComparer<T> and returns self. + + + + + Modifies the constraint to use a Comparison<T> and returns self. + + + + + Modifies the constraint to test ordering by the value of + a specified property and returns self. + + + + + Test whether the collection is ordered + + + + + + + Write a description of the constraint to a MessageWriter + + + + + + Returns the string representation of the constraint. + + + + + + If used performs a reverse comparison + + + + + CollectionSubsetConstraint is used to determine whether + one collection is a subset of another + + + + + Construct a CollectionSubsetConstraint + + The collection that the actual value is expected to be a subset of + + + + Test whether the actual collection is a subset of + the expected collection provided. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + CollectionTally counts (tallies) the number of + occurences of each object in one or more enumerations. + + + + + Construct a CollectionTally object from a comparer and a collection + + + + + Try to remove an object from the tally + + The object to remove + True if successful, false if the object was not found + + + + Try to remove a set of objects from the tally + + The objects to remove + True if successful, false if any object was not found + + + + The number of objects remaining in the tally + + + + + ComparisonAdapter class centralizes all comparisons of + values in NUnit, adapting to the use of any provided + IComparer, IComparer<T> or Comparison<T> + + + + + Returns a ComparisonAdapter that wraps an IComparer + + + + + Returns a ComparisonAdapter that wraps an IComparer<T> + + + + + Returns a ComparisonAdapter that wraps a Comparison<T> + + + + + Compares two objects + + + + + Gets the default ComparisonAdapter, which wraps an + NUnitComparer object. + + + + + Construct a ComparisonAdapter for an IComparer + + + + + Compares two objects + + + + + + + + Construct a default ComparisonAdapter + + + + + ComparisonAdapter<T> extends ComparisonAdapter and + allows use of an IComparer<T> or Comparison<T> + to actually perform the comparison. + + + + + Construct a ComparisonAdapter for an IComparer<T> + + + + + Compare a Type T to an object + + + + + Construct a ComparisonAdapter for a Comparison<T> + + + + + Compare a Type T to an object + + + + + Abstract base class for constraints that compare values to + determine if one is greater than, equal to or less than + the other. This class supplies the Using modifiers. + + + + + ComparisonAdapter to be used in making the comparison + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + + + + Modifies the constraint to use an IComparer and returns self + + + + + Modifies the constraint to use an IComparer<T> and returns self + + + + + Modifies the constraint to use a Comparison<T> and returns self + + + + + Delegate used to delay evaluation of the actual value + to be used in evaluating a constraint + + + + + ConstraintBuilder maintains the stacks that are used in + processing a ConstraintExpression. An OperatorStack + is used to hold operators that are waiting for their + operands to be reognized. a ConstraintStack holds + input constraints as well as the results of each + operator applied. + + + + + Initializes a new instance of the class. + + + + + Appends the specified operator to the expression by first + reducing the operator stack and then pushing the new + operator on the stack. + + The operator to push. + + + + Appends the specified constraint to the expresson by pushing + it on the constraint stack. + + The constraint to push. + + + + Sets the top operator right context. + + The right context. + + + + Reduces the operator stack until the topmost item + precedence is greater than or equal to the target precedence. + + The target precedence. + + + + Resolves this instance, returning a Constraint. If the builder + is not currently in a resolvable state, an exception is thrown. + + The resolved constraint + + + + Gets a value indicating whether this instance is resolvable. + + + true if this instance is resolvable; otherwise, false. + + + + + OperatorStack is a type-safe stack for holding ConstraintOperators + + + + + Initializes a new instance of the class. + + The builder. + + + + Pushes the specified operator onto the stack. + + The op. + + + + Pops the topmost operator from the stack. + + + + + + Gets a value indicating whether this is empty. + + true if empty; otherwise, false. + + + + Gets the topmost operator without modifying the stack. + + The top. + + + + ConstraintStack is a type-safe stack for holding Constraints + + + + + Initializes a new instance of the class. + + The builder. + + + + Pushes the specified constraint. As a side effect, + the constraint's builder field is set to the + ConstraintBuilder owning this stack. + + The constraint. + + + + Pops this topmost constrait from the stack. + As a side effect, the constraint's builder + field is set to null. + + + + + + Gets a value indicating whether this is empty. + + true if empty; otherwise, false. + + + + Gets the topmost constraint without modifying the stack. + + The topmost constraint + + + + ConstraintExpression represents a compound constraint in the + process of being constructed from a series of syntactic elements. + + Individual elements are appended to the expression as they are + reognized. Once an actual Constraint is appended, the expression + returns a resolvable Constraint. + + + + + ConstraintExpressionBase is the abstract base class for the + ConstraintExpression class, which represents a + compound constraint in the process of being constructed + from a series of syntactic elements. + + NOTE: ConstraintExpressionBase is separate because the + ConstraintExpression class was generated in earlier + versions of NUnit. The two classes may be combined + in a future version. + + + + + The ConstraintBuilder holding the elements recognized so far + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the + class passing in a ConstraintBuilder, which may be pre-populated. + + The builder. + + + + Returns a string representation of the expression as it + currently stands. This should only be used for testing, + since it has the side-effect of resolving the expression. + + + + + + Appends an operator to the expression and returns the + resulting expression itself. + + + + + Appends a self-resolving operator to the expression and + returns a new ResolvableConstraintExpression. + + + + + Appends a constraint to the expression and returns that + constraint, which is associated with the current state + of the expression being built. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the + class passing in a ConstraintBuilder, which may be pre-populated. + + The builder. + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding only if a specified number of them succeed. + + + + + Returns a new PropertyConstraintExpression, which will either + test for the existence of the named property on the object + being tested or apply any following constraint to that property. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns the constraint provided as an argument - used to allow custom + custom constraints to easily participate in the syntax. + + + + + Returns the constraint provided as an argument - used to allow custom + custom constraints to easily participate in the syntax. + + + + + Returns a constraint that tests two items for equality + + + + + Returns a constraint that tests that two references are the same object + + + + + Returns a constraint that tests whether the + actual value is greater than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a collection containing the same elements as the + collection supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a subset of the collection supplied as an argument. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new ContainsConstraint. This constraint + will, in turn, make use of the appropriate second-level + constraint, depending on the type of the actual argument. + This overload is only used if the item sought is a string, + since any other type implies that we are looking for a + collection member. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the regular expression supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the regular expression supplied as an argument. + + + + + Returns a constraint that tests whether the path provided + is the same as an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the actual value falls + within a specified range. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if at least one of them succeeds. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them fail. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Length property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Count property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Message property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the InnerException property of the object being tested. + + + + + With is currently a NOP - reserved for future use. + + + + + Returns a constraint that tests for null + + + + + Returns a constraint that tests for True + + + + + Returns a constraint that tests for False + + + + + Returns a constraint that tests for a positive value + + + + + Returns a constraint that tests for a negative value + + + + + Returns a constraint that tests for NaN + + + + + Returns a constraint that tests for empty + + + + + Returns a constraint that tests whether a collection + contains all unique items. + + + + + Returns a constraint that tests whether an object graph is serializable in binary format. + + + + + Returns a constraint that tests whether an object graph is serializable in xml format. + + + + + Returns a constraint that tests whether a collection is ordered + + + + + ContainsConstraint tests a whether a string contains a substring + or a collection contains an object. It postpones the decision of + which test to use until the type of the actual argument is known. + This allows testing whether a string is contained in a collection + or as a substring of another string using the same syntax. + + + + + Initializes a new instance of the class. + + The expected. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied Comparison object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to ignore case and return self. + + + + + Applies a delay to the match so that a match can be evaluated in the future. + + + + + Creates a new DelayedConstraint + + The inner constraint two decorate + The time interval after which the match is performed + If the value of is less than 0 + + + + Creates a new DelayedConstraint + + The inner constraint two decorate + The time interval after which the match is performed + The time interval used for polling + If the value of is less than 0 + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for if the base constraint fails, false if it succeeds + + + + Test whether the constraint is satisfied by a delegate + + The delegate whose value is to be tested + True for if the base constraint fails, false if it succeeds + + + + Test whether the constraint is satisfied by a given reference. + Overridden to wait for the specified delay period before + calling the base constraint with the dereferenced value. + + A reference to the value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a MessageWriter. + + The writer on which the actual value is displayed + + + + Returns the string representation of the constraint. + + + + + EmptyCollectionConstraint tests whether a collection is empty. + + + + + Check that the collection is empty + + + + + + + Write the constraint description to a MessageWriter + + + + + + EmptyConstraint tests a whether a string or collection is empty, + postponing the decision about which test is applied until the + type of the actual argument is known. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + EmptyDirectoryConstraint is used to test that a directory is empty + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + EmptyStringConstraint tests whether a string is empty. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + EndsWithConstraint can test whether a string ends + with an expected substring. + + + + + StringConstraint is the abstract base for constraints + that operate on strings. It supports the IgnoreCase + modifier for string operations. + + + + + The expected value + + + + + Indicates whether tests should be case-insensitive + + + + + Constructs a StringConstraint given an expected value + + The expected value + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Test whether the constraint is satisfied by a given string + + The string to be tested + True for success, false for failure + + + + Modify the constraint to ignore case in matching. + + + + + Initializes a new instance of the class. + + The expected string + + + + Test whether the constraint is matched by the actual value. + This is a template method, which calls the IsMatch method + of the derived class. + + + + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + EqualConstraint is able to compare an actual value with the + expected value provided in its constructor. Two objects are + considered equal if both are null, or if both have the same + value. NUnit has special semantics for some object types. + + + + + If true, strings in error messages will be clipped + + + + + NUnitEqualityComparer used to test equality. + + + + + Initializes a new instance of the class. + + The expected value. + + + + Flag the constraint to use a tolerance when determining equality. + + Tolerance value to be used + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied Comparison object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write a failure message. Overridden to provide custom + failure messages for EqualConstraint. + + The MessageWriter to write to + + + + Write description of this constraint + + The MessageWriter to write to + + + + Display the failure information for two collections that did not match. + + The MessageWriter on which to display + The expected collection. + The actual collection + The depth of this failure in a set of nested collections + + + + Displays a single line showing the types and sizes of the expected + and actual enumerations, collections or arrays. If both are identical, + the value is only shown once. + + The MessageWriter on which to display + The expected collection or array + The actual collection or array + The indentation level for the message line + + + + Displays a single line showing the point in the expected and actual + arrays at which the comparison failed. If the arrays have different + structures or dimensions, both values are shown. + + The MessageWriter on which to display + The expected array + The actual array + Index of the failure point in the underlying collections + The indentation level for the message line + + + + Display the failure information for two IEnumerables that did not match. + + The MessageWriter on which to display + The expected enumeration. + The actual enumeration + The depth of this failure in a set of nested collections + + + + Flag the constraint to ignore case and return self. + + + + + Flag the constraint to suppress string clipping + and return self. + + + + + Flag the constraint to compare arrays as collections + and return self. + + + + + Switches the .Within() modifier to interpret its tolerance as + a distance in representable values (see remarks). + + Self. + + Ulp stands for "unit in the last place" and describes the minimum + amount a given value can change. For any integers, an ulp is 1 whole + digit. For floating point values, the accuracy of which is better + for smaller numbers and worse for larger numbers, an ulp depends + on the size of the number. Using ulps for comparison of floating + point results instead of fixed tolerances is safer because it will + automatically compensate for the added inaccuracy of larger numbers. + + + + + Switches the .Within() modifier to interpret its tolerance as + a percentage that the actual values is allowed to deviate from + the expected value. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in days. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in hours. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in minutes. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in seconds. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in milliseconds. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in clock ticks. + + Self + + + + EqualityAdapter class handles all equality comparisons + that use an IEqualityComparer, IEqualityComparer<T> + or a ComparisonAdapter. + + + + + Compares two objects, returning true if they are equal + + + + + Returns true if the two objects can be compared by this adapter. + The base adapter cannot handle IEnumerables except for strings. + + + + + Returns an EqualityAdapter that wraps an IComparer. + + + + + Returns an EqualityAdapter that wraps an IEqualityComparer. + + + + + Returns an EqualityAdapter that wraps an IEqualityComparer<T>. + + + + + Returns an EqualityAdapter that wraps an IComparer<T>. + + + + + Returns an EqualityAdapter that wraps a Comparison<T>. + + + + + EqualityAdapter that wraps an IComparer. + + + + + Returns true if the two objects can be compared by this adapter. + Generic adapter requires objects of the specified type. + + + + + EqualityAdapter that wraps an IComparer. + + + + + EqualityAdapterList represents a list of EqualityAdapters + in a common class across platforms. + + + + + ExactCountConstraint applies another constraint to each + item in a collection, succeeding only if a specified + number of items succeed. + + + + + Construct an ExactCountConstraint on top of an existing constraint + + + + + + + Apply the item constraint to each item in the collection, + succeeding only if the expected number of items pass. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + ExactTypeConstraint is used to test that an object + is of the exact type provided in the constructor + + + + + Construct an ExactTypeConstraint for a given Type + + The expected Type. + + + + Test that an object is of the exact type specified + + The actual value. + True if the tested object is of the exact type provided, otherwise false. + + + + Write the description of this constraint to a MessageWriter + + The MessageWriter to use + + + + ExceptionTypeConstraint is a special version of ExactTypeConstraint + used to provided detailed info about the exception thrown in + an error message. + + + + + Constructs an ExceptionTypeConstraint + + + + + Write the actual value for a failing constraint test to a + MessageWriter. Overriden to write additional information + in the case of an Exception. + + The MessageWriter to use + + + + FailurePoint class represents one point of failure + in an equality test. + + + + + The location of the failure + + + + + The expected value + + + + + The actual value + + + + + Indicates whether the expected value is valid + + + + + Indicates whether the actual value is valid + + + + + FailurePointList represents a set of FailurePoints + in a cross-platform way. + + + + + FalseConstraint tests that the actual value is false + + + + + Initializes a new instance of the class. + + + + Helper routines for working with floating point numbers + + + The floating point comparison code is based on this excellent article: + http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm + + + "ULP" means Unit in the Last Place and in the context of this library refers to + the distance between two adjacent floating point numbers. IEEE floating point + numbers can only represent a finite subset of natural numbers, with greater + accuracy for smaller numbers and lower accuracy for very large numbers. + + + If a comparison is allowed "2 ulps" of deviation, that means the values are + allowed to deviate by up to 2 adjacent floating point values, which might be + as low as 0.0000001 for small numbers or as high as 10.0 for large numbers. + + + + + Compares two floating point values for equality + First floating point value to be compared + Second floating point value t be compared + + Maximum number of representable floating point values that are allowed to + be between the left and the right floating point values + + True if both numbers are equal or close to being equal + + + Floating point values can only represent a finite subset of natural numbers. + For example, the values 2.00000000 and 2.00000024 can be stored in a float, + but nothing inbetween them. + + + This comparison will count how many possible floating point values are between + the left and the right number. If the number of possible values between both + numbers is less than or equal to maxUlps, then the numbers are considered as + being equal. + + + Implementation partially follows the code outlined here: + http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ + + + + + Compares two double precision floating point values for equality + First double precision floating point value to be compared + Second double precision floating point value t be compared + + Maximum number of representable double precision floating point values that are + allowed to be between the left and the right double precision floating point values + + True if both numbers are equal or close to being equal + + + Double precision floating point values can only represent a limited series of + natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004 + can be stored in a double, but nothing inbetween them. + + + This comparison will count how many possible double precision floating point + values are between the left and the right number. If the number of possible + values between both numbers is less than or equal to maxUlps, then the numbers + are considered as being equal. + + + Implementation partially follows the code outlined here: + http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ + + + + + + Reinterprets the memory contents of a floating point value as an integer value + + + Floating point value whose memory contents to reinterpret + + + The memory contents of the floating point value interpreted as an integer + + + + + Reinterprets the memory contents of a double precision floating point + value as an integer value + + + Double precision floating point value whose memory contents to reinterpret + + + The memory contents of the double precision floating point value + interpreted as an integer + + + + + Reinterprets the memory contents of an integer as a floating point value + + Integer value whose memory contents to reinterpret + + The memory contents of the integer value interpreted as a floating point value + + + + + Reinterprets the memory contents of an integer value as a double precision + floating point value + + Integer whose memory contents to reinterpret + + The memory contents of the integer interpreted as a double precision + floating point value + + + + Union of a floating point variable and an integer + + + The union's value as a floating point variable + + + The union's value as an integer + + + The union's value as an unsigned integer + + + Union of a double precision floating point variable and a long + + + The union's value as a double precision floating point variable + + + The union's value as a long + + + The union's value as an unsigned long + + + + Tests whether a value is greater than the value supplied to its constructor + + + + + The value against which a comparison is to be made + + + + + Initializes a new instance of the class. + + The expected value. + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Tests whether a value is greater than or equal to the value supplied to its constructor + + + + + The value against which a comparison is to be made + + + + + Initializes a new instance of the class. + + The expected value. + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + InstanceOfTypeConstraint is used to test that an object + is of the same type provided or derived from it. + + + + + Construct an InstanceOfTypeConstraint for the type provided + + The expected Type + + + + Test whether an object is of the specified type or a derived type + + The object to be tested + True if the object is of the provided type or derives from it, otherwise false. + + + + Write a description of this constraint to a MessageWriter + + The MessageWriter to use + + + + Tests whether a value is less than the value supplied to its constructor + + + + + The value against which a comparison is to be made + + + + + Initializes a new instance of the class. + + The expected value. + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Tests whether a value is less than or equal to the value supplied to its constructor + + + + + The value against which a comparison is to be made + + + + + Initializes a new instance of the class. + + The expected value. + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Static methods used in creating messages + + + + + Static string used when strings are clipped + + + + + Returns the representation of a type as used in NUnitLite. + This is the same as Type.ToString() except for arrays, + which are displayed with their declared sizes. + + + + + + + Converts any control characters in a string + to their escaped representation. + + The string to be converted + The converted string + + + + Return the a string representation for a set of indices into an array + + Array of indices for which a string is needed + + + + Get an array of indices representing the point in a enumerable, + collection or array corresponding to a single int index into the + collection. + + The collection to which the indices apply + Index in the collection + Array of indices + + + + Clip a string to a given length, starting at a particular offset, returning the clipped + string with ellipses representing the removed parts + + The string to be clipped + The maximum permitted length of the result string + The point at which to start clipping + The clipped string + + + + Clip the expected and actual strings in a coordinated fashion, + so that they may be displayed together. + + + + + + + + + Shows the position two strings start to differ. Comparison + starts at the start index. + + The expected string + The actual string + The index in the strings at which comparison should start + Boolean indicating whether case should be ignored + -1 if no mismatch found, or the index where mismatch found + + + + NaNConstraint tests that the actual value is a double or float NaN + + + + + Test that the actual value is an NaN + + + + + + + Write the constraint description to a specified writer + + + + + + NoItemConstraint applies another constraint to each + item in a collection, failing if any of them succeeds. + + + + + Construct a NoItemConstraint on top of an existing constraint + + + + + + Apply the item constraint to each item in the collection, + failing if any item fails. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + NotConstraint negates the effect of some other constraint + + + + + Initializes a new instance of the class. + + The base constraint to be negated. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for if the base constraint fails, false if it succeeds + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a MessageWriter. + + The writer on which the actual value is displayed + + + + NullConstraint tests that the actual value is null + + + + + Initializes a new instance of the class. + + + + + NullEmptyStringConstraint tests whether a string is either null or empty. + + + + + Constructs a new NullOrEmptyStringConstraint + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + The Numerics class contains common operations on numeric values. + + + + + Checks the type of the object, returning true if + the object is a numeric type. + + The object to check + true if the object is a numeric type + + + + Checks the type of the object, returning true if + the object is a floating point numeric type. + + The object to check + true if the object is a floating point numeric type + + + + Checks the type of the object, returning true if + the object is a fixed point numeric type. + + The object to check + true if the object is a fixed point numeric type + + + + Test two numeric values for equality, performing the usual numeric + conversions and using a provided or default tolerance. If the tolerance + provided is Empty, this method may set it to a default tolerance. + + The expected value + The actual value + A reference to the tolerance in effect + True if the values are equal + + + + Compare two numeric values, performing the usual numeric conversions. + + The expected value + The actual value + The relationship of the values to each other + + + + NUnitComparer encapsulates NUnit's default behavior + in comparing two objects. + + + + + Compares two objects + + + + + + + + Returns the default NUnitComparer. + + + + + Generic version of NUnitComparer + + + + + + Compare two objects of the same type + + + + + NUnitEqualityComparer encapsulates NUnit's handling of + equality tests between objects. + + + + + + + + + + Compares two objects for equality within a tolerance + + The first object to compare + The second object to compare + The tolerance to use in the comparison + + + + + If true, all string comparisons will ignore case + + + + + If true, arrays will be treated as collections, allowing + those of different dimensions to be compared + + + + + Comparison objects used in comparisons for some constraints. + + + + + List of points at which a failure occured. + + + + + RecursionDetector used to check for recursion when + evaluating self-referencing enumerables. + + + + + Compares two objects for equality within a tolerance, setting + the tolerance to the actual tolerance used if an empty + tolerance is supplied. + + + + + Helper method to compare two arrays + + + + + Method to compare two DirectoryInfo objects + + first directory to compare + second directory to compare + true if equivalent, false if not + + + + Returns the default NUnitEqualityComparer + + + + + Gets and sets a flag indicating whether case should + be ignored in determining equality. + + + + + Gets and sets a flag indicating that arrays should be + compared as collections, without regard to their shape. + + + + + Gets the list of external comparers to be used to + test for equality. They are applied to members of + collections, in place of NUnit's own logic. + + + + + Gets the list of failure points for the last Match performed. + The list consists of objects to be interpreted by the caller. + This generally means that the caller may only make use of + objects it has placed on the list at a particular depthy. + + + + + RecursionDetector detects when a comparison + between two enumerables has reached a point + where the same objects that were previously + compared are again being compared. This allows + the caller to stop the comparison if desired. + + + + + Check whether two objects have previously + been compared, returning true if they have. + The two objects are remembered, so that a + second call will always return true. + + + + + OrConstraint succeeds if either member succeeds + + + + + Create an OrConstraint from two other constraints + + The first constraint + The second constraint + + + + Apply the member constraints to an actual value, succeeding + succeeding as soon as one of them succeeds. + + The actual value + True if either constraint succeeded + + + + Write a description for this contraint to a MessageWriter + + The MessageWriter to receive the description + + + + PathConstraint serves as the abstract base of constraints + that operate on paths and provides several helper methods. + + + + + The expected path used in the constraint + + + + + Flag indicating whether a caseInsensitive comparison should be made + + + + + Construct a PathConstraint for a give expected path + + The expected path + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Returns true if the expected path and actual path match + + + + + Returns the string representation of this constraint + + + + + Transform the provided path to its canonical form so that it + may be more easily be compared with other paths. + + The original path + The path in canonical form + + + + Test whether one path in canonical form is under another. + + The first path - supposed to be the parent path + The second path - supposed to be the child path + Indicates whether case should be ignored + + + + + Modifies the current instance to be case-insensitve + and returns it. + + + + + Modifies the current instance to be case-sensitve + and returns it. + + + + + Predicate constraint wraps a Predicate in a constraint, + returning success if the predicate is true. + + + + + Construct a PredicateConstraint from a predicate + + + + + Determines whether the predicate succeeds when applied + to the actual value. + + + + + Writes the description to a MessageWriter + + + + + PropertyConstraint extracts a named property and uses + its value as the actual value for a chained constraint. + + + + + Initializes a new instance of the class. + + The name. + The constraint to apply to the property. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation of the constraint. + + + + + + PropertyExistsConstraint tests that a named property + exists on the object provided through Match. + + Originally, PropertyConstraint provided this feature + in addition to making optional tests on the vaue + of the property. The two constraints are now separate. + + + + + Initializes a new instance of the class. + + The name of the property. + + + + Test whether the property exists for a given object + + The object to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. + + The writer on which the actual value is displayed + + + + Returns the string representation of the constraint. + + + + + + RangeConstraint tests whether two values are within a + specified range. + + + + + Initializes a new instance of the class. + + From. + To. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + RegexConstraint can test whether a string matches + the pattern provided. + + + + + Initializes a new instance of the class. + + The pattern. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + ResolvableConstraintExpression is used to represent a compound + constraint being constructed at a point where the last operator + may either terminate the expression or may have additional + qualifying constraints added to it. + + It is used, for example, for a Property element or for + an Exception element, either of which may be optionally + followed by constraints that apply to the property or + exception. + + + + + Create a new instance of ResolvableConstraintExpression + + + + + Create a new instance of ResolvableConstraintExpression, + passing in a pre-populated ConstraintBuilder. + + + + + Resolve the current expression to a Constraint + + + + + This operator creates a constraint that is satisfied only if both + argument constraints are satisfied. + + + + + This operator creates a constraint that is satisfied only if both + argument constraints are satisfied. + + + + + This operator creates a constraint that is satisfied only if both + argument constraints are satisfied. + + + + + This operator creates a constraint that is satisfied if either + of the argument constraints is satisfied. + + + + + This operator creates a constraint that is satisfied if either + of the argument constraints is satisfied. + + + + + This operator creates a constraint that is satisfied if either + of the argument constraints is satisfied. + + + + + This operator creates a constraint that is satisfied if the + argument constraint is not satisfied. + + + + + Appends an And Operator to the expression + + + + + Appends an Or operator to the expression. + + + + + ReusableConstraint wraps a constraint expression after + resolving it so that it can be reused consistently. + + + + + Construct a ReusableConstraint from a constraint expression + + The expression to be resolved and reused + + + + Converts a constraint to a ReusableConstraint + + The constraint to be converted + A ReusableConstraint + + + + Returns the string representation of the constraint. + + A string representing the constraint + + + + Resolves the ReusableConstraint by returning the constraint + that it originally wrapped. + + A resolved constraint + + + + SameAsConstraint tests whether an object is identical to + the object passed to its constructor + + + + + Initializes a new instance of the class. + + The expected object. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Summary description for SamePathConstraint. + + + + + Initializes a new instance of the class. + + The expected path + + + + Test whether the constraint is satisfied by a given value + + The expected path + The actual path + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + SamePathOrUnderConstraint tests that one path is under another + + + + + Initializes a new instance of the class. + + The expected path + + + + Test whether the constraint is satisfied by a given value + + The expected path + The actual path + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + SomeItemsConstraint applies another constraint to each + item in a collection, succeeding if any of them succeeds. + + + + + Construct a SomeItemsConstraint on top of an existing constraint + + + + + + Apply the item constraint to each item in the collection, + succeeding if any item succeeds. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + StartsWithConstraint can test whether a string starts + with an expected substring. + + + + + Initializes a new instance of the class. + + The expected string + + + + Test whether the constraint is matched by the actual value. + This is a template method, which calls the IsMatch method + of the derived class. + + + + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + SubPathConstraint tests that the actual path is under the expected path + + + + + Initializes a new instance of the class. + + The expected path + + + + Test whether the constraint is satisfied by a given value + + The expected path + The actual path + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + SubstringConstraint can test whether a string contains + the expected substring. + + + + + Initializes a new instance of the class. + + The expected. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + ThrowsConstraint is used to test the exception thrown by + a delegate by applying a constraint to it. + + + + + Initializes a new instance of the class, + using a constraint to be applied to the exception. + + A constraint to apply to the caught exception. + + + + Executes the code of the delegate and captures any exception. + If a non-null base constraint was provided, it applies that + constraint to the exception. + + A delegate representing the code to be tested + True if an exception is thrown and the constraint succeeds, otherwise false + + + + Converts an ActualValueDelegate to a TestDelegate + before calling the primary overload. + + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation of this constraint + + + + + Get the actual exception thrown - used by Assert.Throws. + + + + + ThrowsNothingConstraint tests that a delegate does not + throw an exception. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True if no exception is thrown, otherwise false + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. Overridden in ThrowsNothingConstraint to write + information about the exception that was actually caught. + + The writer on which the actual value is displayed + + + + The Tolerance class generalizes the notion of a tolerance + within which an equality test succeeds. Normally, it is + used with numeric types, but it can be used with any + type that supports taking a difference between two + objects and comparing that difference to a value. + + + + + Constructs a linear tolerance of a specdified amount + + + + + Constructs a tolerance given an amount and ToleranceMode + + + + + Tests that the current Tolerance is linear with a + numeric value, throwing an exception if it is not. + + + + + Returns an empty Tolerance object, equivalent to + specifying no tolerance. In most cases, it results + in an exact match but for floats and doubles a + default tolerance may be used. + + + + + Returns a zero Tolerance object, equivalent to + specifying an exact match. + + + + + Gets the ToleranceMode for the current Tolerance + + + + + Gets the value of the current Tolerance instance. + + + + + Returns a new tolerance, using the current amount as a percentage. + + + + + Returns a new tolerance, using the current amount in Ulps. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of days. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of hours. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of minutes. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of seconds. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of milliseconds. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of clock ticks. + + + + + Returns true if the current tolerance is empty. + + + + + Modes in which the tolerance value for a comparison can be interpreted. + + + + + The tolerance was created with a value, without specifying + how the value would be used. This is used to prevent setting + the mode more than once and is generally changed to Linear + upon execution of the test. + + + + + The tolerance is used as a numeric range within which + two compared values are considered to be equal. + + + + + Interprets the tolerance as the percentage by which + the two compared values my deviate from each other. + + + + + Compares two values based in their distance in + representable numbers. + + + + + TrueConstraint tests that the actual value is true + + + + + Initializes a new instance of the class. + + + + + UniqueItemsConstraint tests whether all the items in a + collection are unique. + + + + + Check that all items are unique. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + XmlSerializableConstraint tests whether + an object is serializable in XML format. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation of this constraint + + + + + Represents a constraint that succeeds if all the + members of a collection match a base constraint. + + + + + Abstract base for operators that indicate how to + apply a constraint to items in a collection. + + + + + PrefixOperator takes a single constraint and modifies + it's action in some way. + + + + + The ConstraintOperator class is used internally by a + ConstraintBuilder to represent an operator that + modifies or combines constraints. + + Constraint operators use left and right precedence + values to determine whether the top operator on the + stack should be reduced before pushing a new operator. + + + + + The precedence value used when the operator + is about to be pushed to the stack. + + + + + The precedence value used when the operator + is on the top of the stack. + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + The syntax element preceding this operator + + + + + The syntax element folowing this operator + + + + + The precedence value used when the operator + is about to be pushed to the stack. + + + + + The precedence value used when the operator + is on the top of the stack. + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + Returns the constraint created by applying this + prefix to another constraint. + + + + + + + Constructs a CollectionOperator + + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + they all succeed. + + + + + Operator that requires both it's arguments to succeed + + + + + Abstract base class for all binary operators + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + Abstract method that produces a constraint by applying + the operator to its left and right constraint arguments. + + + + + Gets the left precedence of the operator + + + + + Gets the right precedence of the operator + + + + + Construct an AndOperator + + + + + Apply the operator to produce an AndConstraint + + + + + Operator that tests for the presence of a particular attribute + on a type and optionally applies further tests to the attribute. + + + + + Abstract base class for operators that are able to reduce to a + constraint whether or not another syntactic element follows. + + + + + Construct an AttributeOperator for a particular Type + + The Type of attribute tested + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + Represents a constraint that succeeds if the specified + count of members of a collection match a base constraint. + + + + + Construct an ExactCountOperator for a specified count + + The expected count + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + none of them succeed. + + + + + Represents a constraint that succeeds if none of the + members of a collection match a base constraint. + + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + none of them succeed. + + + + + Negates the test of the constraint it wraps. + + + + + Constructs a new NotOperator + + + + + Returns a NotConstraint applied to its argument. + + + + + Operator that requires at least one of it's arguments to succeed + + + + + Construct an OrOperator + + + + + Apply the operator to produce an OrConstraint + + + + + Operator used to test for the presence of a named Property + on an object and optionally apply further tests to the + value of that property. + + + + + Constructs a PropOperator for a particular named property + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + Gets the name of the property to which the operator applies + + + + + Represents a constraint that succeeds if any of the + members of a collection match a base constraint. + + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + any of them succeed. + + + + + Operator that tests that an exception is thrown and + optionally applies further tests to the exception. + + + + + Construct a ThrowsOperator + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + Represents a constraint that simply wraps the + constraint provided as an argument, without any + further functionality, but which modifes the + order of evaluation because of its precedence. + + + + + Constructor for the WithOperator + + + + + Returns a constraint that wraps its argument + + + + + Thrown when an assertion failed. + + + + The error message that explains + the reason for the exception + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + Thrown when an assertion failed. + + + + + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + Thrown when a test executes inconclusively. + + + + The error message that explains + the reason for the exception + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + Thrown when an assertion failed. + + + + + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + + + + + + + Compares two objects of a given Type for equality within a tolerance + + The first object to compare + The second object to compare + The tolerance to use in the comparison + + + + diff --git a/samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/license.txt b/samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/license.txt new file mode 100644 index 00000000000..b12903afb5e --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/packages/NUnit.2.6.3/license.txt @@ -0,0 +1,15 @@ +Copyright © 2002-2013 Charlie Poole +Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov +Copyright © 2000-2002 Philip A. Craig + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required. + +Portions Copyright © 2002-2013 Charlie Poole or Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/samples/client/petstore/csharp/SwaggerClientTest/packages/repositories.config b/samples/client/petstore/csharp/SwaggerClientTest/packages/repositories.config new file mode 100644 index 00000000000..ba8d0d576a8 --- /dev/null +++ b/samples/client/petstore/csharp/SwaggerClientTest/packages/repositories.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From acf09da5787728fdfc56defd29f0912f5bb5743c Mon Sep 17 00:00:00 2001 From: geekerzp Date: Mon, 22 Jun 2015 16:35:15 +0800 Subject: [PATCH 081/499] Fix typo in python codegen --- .../codegen/languages/PythonClientCodegen.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index cdafa337c21..475a816aa5c 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -81,17 +81,17 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig additionalProperties.put("packageName", packageName); additionalProperties.put("packageVersion", packageVersion); - String swaggerFoler = packageName; + String swaggerFolder = packageName; - modelPackage = swaggerFoler + File.separatorChar + "models"; - apiPackage = swaggerFoler + File.separatorChar + "apis"; + modelPackage = swaggerFolder + File.separatorChar + "models"; + apiPackage = swaggerFolder + File.separatorChar + "apis"; supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py")); - supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFoler, "api_client.py")); - supportingFiles.add(new SupportingFile("rest.mustache", swaggerFoler, "rest.py")); - supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFoler, "configuration.py")); - supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFoler, "__init__.py")); + supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFolder, "api_client.py")); + supportingFiles.add(new SupportingFile("rest.mustache", swaggerFolder, "rest.py")); + supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFolder, "configuration.py")); + supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFolder, "__init__.py")); supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py")); supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py")); } From b9ca19168a92d989bd91a2096bd16f7dceb8b540 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 08:28:22 -0700 Subject: [PATCH 082/499] remove static fields in Configuration and make variable case more consistent --- .../src/main/resources/php/ApiClient.mustache | 116 +++++++------ .../src/main/resources/php/api.mustache | 30 ++-- .../main/resources/php/configuration.mustache | 159 ++++++++++++++++-- .../src/main/resources/php/model.mustache | 2 +- 4 files changed, 221 insertions(+), 86 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 4a3e50dd50b..8a030079fa0 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -29,40 +29,46 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - private static $default_header = array(); + protected $defaultHeaders = array(); /* * @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ - protected $curl_timeout = 0; + protected $curlTimeout = 0; /* * @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ - protected $user_agent = "PHP-Swagger"; + protected $userAgent = "PHP-Swagger"; /** - * @param string $host Base url of the API server (optional) + * @var ApiConfiguration */ - function __construct($host = null) { - if ($host === null) { - $this->host = '{{basePath}}'; - } else { - $this->host = $host; + protected $config; + + /** + * @param ApiConfiguration $config config for this ApiClient + */ + function __construct(ApiConfiguration $config = null) { + if ($config == null) { + $config = ApiConfiguration::getDefaultConfiguration(); } + + $this->config = $config; } /** * add default header * - * @param string $header_name header name (e.g. Token) - * @param string $header_value header value (e.g. 1z8wp3) + * @param string $headerName header name (e.g. Token) + * @param string $headerValue header value (e.g. 1z8wp3) */ - public function addDefaultHeader($header_name, $header_value) { - if (!is_string($header_name)) + public function addDefaultHeader($headerName, $headerValue) { + if (!is_string($headerName)) { throw new \InvalidArgumentException('Header name must be a string.'); + } - self::$default_header[$header_name] = $header_value; + $this->defaultHeaders[$headerName] = $headerValue; } /** @@ -70,29 +76,29 @@ class ApiClient { * * @return array default header */ - public function getDefaultHeader() { - return self::$default_header; + public function getDefaultHeaders() { + return $this->defaultHeaders; } /** * delete the default header based on header name * - * @param string $header_name header name (e.g. Token) + * @param string $headerName header name (e.g. Token) */ - public function deleteDefaultHeader($header_name) { - unset(self::$default_header[$header_name]); + public function deleteDefaultHeader($headerName) { + unset($this->defaultHeaders[$headerName]); } /** * set the user agent of the api client * - * @param string $user_agent the user agent of the api client + * @param string $userAgent the user agent of the api client */ - public function setUserAgent($user_agent) { - if (!is_string($user_agent)) + public function setUserAgent($userAgent) { + if (!is_string($userAgent)) throw new \InvalidArgumentException('User-agent must be a string.'); - $this->user_agent= $user_agent; + $this->userAgent = $userAgent; } /** @@ -100,8 +106,8 @@ class ApiClient { * * @return string user agent */ - public function getUserAgent($user_agent) { - return $this->user_agent; + public function getUserAgent() { + return $this->userAgent; } /** @@ -113,7 +119,7 @@ class ApiClient { if (!is_numeric($seconds) || $seconds < 0) throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); - $this->curl_timeout = $seconds; + $this->curlTimeout = $seconds; } /** @@ -122,27 +128,34 @@ class ApiClient { * @return string HTTP timeout value */ public function getTimeout() { - return $this->curl_timeout; + return $this->curlTimeout; } /** * Get API key (with prefix if set) - * @param string key name + * @param string $apiKey name of apikey * @return string API key with the prefix */ public function getApiKeyWithPrefix($apiKey) { - if (isset(Configuration::$apiKeyPrefix[$apiKey])) { - return Configuration::$apiKeyPrefix[$apiKey]." ".Configuration::$apiKey[$apiKey]; - } else if (isset(Configuration::$apiKey[$apiKey])) { - return Configuration::$apiKey[$apiKey]; - } else { - return; + $prefix = $this->config->getApiKeyPrefix($apiKey); + $apiKey = $this->config->getApiKey($apiKey); + + if (!isset($apiKey)) { + return null; } + + if (isset($prefix)) { + $keyWithPrefix = $prefix." ".$apiKey; + } else { + $keyWithPrefix = $apiKey; + } + + return $keyWithPrefix; } /** - * update hearder and query param based on authentication setting + * update header and query param based on authentication setting * * @param array $headerParams header parameters (by ref) * @param array $queryParams query parameters (by ref) @@ -159,7 +172,7 @@ class ApiClient { switch($auth) { {{#authMethods}} case '{{name}}': - {{#isApiKey}}{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode(Configuration::$username.":".Configuration::$password);{{/isBasic}} + {{#isApiKey}}{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode($this->config->getUsername().":".$this->config->getPassword());{{/isBasic}} {{#isOAuth}}//TODO support oauth{{/isOAuth}} break; {{/authMethods}} @@ -175,6 +188,8 @@ class ApiClient { * @param array $queryParams parameters to be place in query URL * @param array $postData parameters to be placed in POST body * @param array $headerParams parameters to be place in request header + * @param array $authSettings parameters for authentication + * @throws \{{invokerNamespace}}\ApiException on a non 2xx response * @return mixed */ public function callApi($resourcePath, $method, $queryParams, $postData, @@ -186,7 +201,7 @@ class ApiClient { $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); # construct the http header - $headerParams = array_merge((array)self::$default_header, (array)$headerParams); + $headerParams = array_merge((array)$this->defaultHeaders, (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -200,12 +215,12 @@ class ApiClient { $postData = json_encode($this->sanitizeForSerialization($postData)); } - $url = $this->host . $resourcePath; + $url = $this->config->getHost() . $resourcePath; $curl = curl_init(); // set timeout, if needed - if ($this->curl_timeout != 0) { - curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_timeout); + if ($this->curlTimeout != 0) { + curl_setopt($curl, CURLOPT_TIMEOUT, $this->curlTimeout); } // return the result on success, rather than just TRUE curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @@ -234,14 +249,14 @@ class ApiClient { curl_setopt($curl, CURLOPT_URL, $url); // Set user agent - curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + curl_setopt($curl, CURLOPT_USERAGENT, $this->userAgent); // debugging for curl - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile()); curl_setopt($curl, CURLOPT_VERBOSE, 1); - curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a')); + curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a')); } else { curl_setopt($curl, CURLOPT_VERBOSE, 0); } @@ -257,8 +272,8 @@ class ApiClient { $response_info = curl_getinfo($curl); // debug HTTP response body - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile()); } // Handle the response @@ -278,9 +293,10 @@ class ApiClient { /** * Build a JSON POST object + * @param mixed $data the data to serialize + * @return string serialized form of $data */ - protected function sanitizeForSerialization($data) - { + protected function sanitizeForSerialization($data) { if (is_scalar($data) || null === $data) { $sanitized = $data; } else if ($data instanceof \DateTime) { @@ -372,7 +388,7 @@ class ApiClient { /** * Deserialize a JSON string into an object * - * @param object $object object or primitive to be deserialized + * @param object $data object or primitive to be deserialized * @param string $class class name is passed as a string * @return object an instance of $class */ @@ -419,7 +435,7 @@ class ApiClient { /* * return the header 'Accept' based on an array of Accept provided * - * @param array[string] $accept Array of header + * @param string[] $accept Array of header * @return string Accept (e.g. application/json) */ public static function selectHeaderAccept($accept) { diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 704f1c5ebab..2b4f1f27ab7 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -37,16 +37,11 @@ class {{classname}} { private $apiClient; function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user + if ($apiClient == null) { + $apiClient = new ApiClient(); } + + $this->apiClient = $apiClient; } /** @@ -88,28 +83,29 @@ class {{classname}} { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}})); + $_header_accept = ApiClient::selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}})); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}})); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}})); {{#queryParams}}// query params if(${{paramName}} !== null) { - $queryParams['{{baseName}}'] = $this->apiClient->toQueryValue(${{paramName}}); + $queryParams['{{baseName}}'] = ApiClient::toQueryValue(${{paramName}}); }{{/queryParams}} {{#headerParams}}// header params if(${{paramName}} !== null) { - $headerParams['{{baseName}}'] = $this->apiClient->toHeaderValue(${{paramName}}); + $headerParams['{{baseName}}'] = ApiClient::toHeaderValue(${{paramName}}); }{{/headerParams}} {{#pathParams}}// path params if(${{paramName}} !== null) { $resourcePath = str_replace("{" . "{{baseName}}" . "}", - $this->apiClient->toPathValue(${{paramName}}), $resourcePath); + ApiClient::toPathValue(${{paramName}}), + $resourcePath); }{{/pathParams}} {{#formParams}}// form params if (${{paramName}} !== null) { - $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->toFormValue(${{paramName}}); + $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}ApiClient::toFormValue(${{paramName}}); }{{/formParams}} {{#bodyParams}}// body params $_tempBody = null; @@ -138,7 +134,7 @@ class {{classname}} { switch ($e->getCode()) { {{#responses}}{{#dataType}} case {{code}}: - $data = $this->apiClient->deserialize($e->getResponseBody(), '{{dataType}}'); + $data = ApiClient::deserialize($e->getResponseBody(), '{{dataType}}'); $throw = new ApiException("{{message}}", $e->getCode(), $e->getResponseHeaders(), $data); break;{{/dataType}}{{/responses}} } @@ -150,7 +146,7 @@ class {{classname}} { return null; } - $responseObject = $this->apiClient->deserialize($response,'{{returnType}}'); + $responseObject = ApiClient::deserialize($response,'{{returnType}}'); return $responseObject; {{/returnType}} } diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/configuration.mustache index b7a9107e77b..1f0ebb496ab 100644 --- a/modules/swagger-codegen/src/main/resources/php/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/configuration.mustache @@ -17,50 +17,173 @@ namespace {{invokerNamespace}}; -class Configuration { +class ApiConfiguration { + + private static $defaultConfiguration = null; + + /** + * The host (from basePath) + */ + protected $host = '{{basePath}}'; /** * Associate array to store API key(s) */ - public static $apiKey = array(); + protected $apiKeys = array(); /** * Associate array to store API prefix (e.g. Bearer) */ - public static $apiKeyPrefix = array(); + protected $apiKeyPrefixes = array(); /** * Username for HTTP basic authentication */ - public static $username = ''; + protected $username = ''; /** * Password for HTTP basic authentication */ - public static $password = ''; - - /** - * The default instance of ApiClient - */ - public static $apiClient; + protected $password = ''; /** * Debug switch (default set to false) */ - public static $debug = false; + protected $debug = false; /** * Debug file location (log to STDOUT by default) */ - public static $debug_file = 'php://output'; + protected $debugFile = 'php://output'; - /* - * manually initalize ApiClient + /** + * @param string $host + * @return ApiConfiguration */ - public static function init() { - if (self::$apiClient === null) - self::$apiClient = new ApiClient(); + public function setHost($host) { + $this->host = $host; + return $this; } -} + /** + * @return string + */ + public function getHost() { + return $this->host; + } + /** + * @param string $key + * @param string $value + * @return ApiConfiguration + */ + public function setApiKey($key, $value) { + $this->apiKeys[$key] = $value; + return $this; + } + + /** + * @param $key + * @return string + */ + public function getApiKey($key) { + return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null; + } + + /** + * @param string $key + * @param string $value + * @return ApiConfiguration + */ + public function setApiKeyPrefix($key, $value) { + $this->apiKeyPrefixes[$key] = $value; + return $this; + } + + /** + * @param $key + * @return string + */ + public function getApiKeyPrefix($key) { + return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null; + } + + /** + * @param string $username + * @return ApiConfiguration + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * @param string $password + * @return ApiConfiguration + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * @param bool $debug + * @return ApiConfiguration + */ + public function setDebug($debug) { + $this->debug = $debug; + return $this; + } + + /** + * @return bool + */ + public function getDebug() { + return $this->debug; + } + + /** + * @param string $debugFile + * @return ApiConfiguration + */ + public function setDebugFile($debugFile) { + $this->debugFile = $debugFile; + return $this; + } + + /** + * @return string + */ + public function getDebugFile() { + return $this->debugFile; + } + + /** + * @return ApiConfiguration + */ + public static function getDefaultConfiguration() { + if (self::$defaultConfiguration == null) { + return new ApiConfiguration(); + } + + return self::$defaultConfiguration; + } + + public static function setDefaultConfiguration(ApiConfiguration $config) { + self::$defaultConfiguration = $config; + } +} diff --git a/modules/swagger-codegen/src/main/resources/php/model.mustache b/modules/swagger-codegen/src/main/resources/php/model.mustache index 86dafc99d99..fadf38f874b 100644 --- a/modules/swagger-codegen/src/main/resources/php/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php/model.mustache @@ -44,7 +44,7 @@ class {{classname}} implements ArrayAccess { * {{{description}}}{{/description}} * @var {{{datatype}}} */ - public ${{name}}; + protected ${{name}}; {{/vars}} public function __construct(array $data = null) { if ($data != null) { From 99e963709b33f8075f5ce917de8e3eeb2f8bad99 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 08:30:08 -0700 Subject: [PATCH 083/499] renaming configuration --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 2 +- .../php/{configuration.mustache => ApiConfiguration.mustache} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename modules/swagger-codegen/src/main/resources/php/{configuration.mustache => ApiConfiguration.mustache} (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 7fb23157b36..18f8cb8917b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -116,7 +116,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { setNamespacesFromPackages(); prefixPackages(); - supportingFiles.add(new SupportingFile("configuration.mustache", invokerPackage.replace('/', File.separatorChar), "Configuration.php")); + supportingFiles.add(new SupportingFile("ApiConfiguration.mustache", invokerPackage.replace('/', File.separatorChar), "ApiConfiguration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerPackage.replace('/', File.separatorChar), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", invokerPackage.replace('/', File.separatorChar), "ApiException.php")); supportingFiles.add(new SupportingFile("composer.mustache", "", "composer.json")); diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache similarity index 100% rename from modules/swagger-codegen/src/main/resources/php/configuration.mustache rename to modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache From 04be474f56fd019aa7c4022a8d81469f56acca11 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 08:36:49 -0700 Subject: [PATCH 084/499] moving $host back to ApiClient and making ApiClient setters fluent --- .../src/main/resources/php/ApiClient.mustache | 30 ++++++++++++++++++- .../resources/php/ApiConfiguration.mustache | 21 ------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 8a030079fa0..e9e308cbf64 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -31,6 +31,11 @@ class ApiClient { protected $defaultHeaders = array(); + /** + * The host (from basePath) + */ + protected $host = '{{basePath}}'; + /* * @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ @@ -49,7 +54,11 @@ class ApiClient { /** * @param ApiConfiguration $config config for this ApiClient */ - function __construct(ApiConfiguration $config = null) { + function __construct($host = null, ApiConfiguration $config = null) { + if ($host != null) { + $this->host = $host; + } + if ($config == null) { $config = ApiConfiguration::getDefaultConfiguration(); } @@ -69,6 +78,7 @@ class ApiClient { } $this->defaultHeaders[$headerName] = $headerValue; + return $this; } /** @@ -80,6 +90,22 @@ class ApiClient { return $this->defaultHeaders; } + /** + * @param string $host + * @return ApiConfiguration + */ + public function setHost($host) { + $this->host = $host; + return $this; + } + + /** + * @return string + */ + public function getHost() { + return $this->host; + } + /** * delete the default header based on header name * @@ -99,6 +125,7 @@ class ApiClient { throw new \InvalidArgumentException('User-agent must be a string.'); $this->userAgent = $userAgent; + return $this; } /** @@ -120,6 +147,7 @@ class ApiClient { throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); $this->curlTimeout = $seconds; + return $this; } /** diff --git a/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache b/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache index 1f0ebb496ab..764e0eafe89 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache @@ -21,11 +21,6 @@ class ApiConfiguration { private static $defaultConfiguration = null; - /** - * The host (from basePath) - */ - protected $host = '{{basePath}}'; - /** * Associate array to store API key(s) */ @@ -56,22 +51,6 @@ class ApiConfiguration { */ protected $debugFile = 'php://output'; - /** - * @param string $host - * @return ApiConfiguration - */ - public function setHost($host) { - $this->host = $host; - return $this; - } - - /** - * @return string - */ - public function getHost() { - return $this->host; - } - /** * @param string $key * @param string $value From b3a3bdd2e0c3a30809c7c132a03a668ca2e19465 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 09:18:41 -0700 Subject: [PATCH 085/499] add fully-qualified class names to deserialize params --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 4 +++- .../src/main/resources/php/ApiClient.mustache | 6 +----- modules/swagger-codegen/src/main/resources/php/api.mustache | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 18f8cb8917b..7e9bac9c62f 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -8,6 +8,7 @@ import io.swagger.codegen.SupportingFile; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import io.swagger.models.properties.RefProperty; import java.io.File; import java.util.ArrayList; @@ -157,6 +158,8 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { MapProperty mp = (MapProperty) p; Property inner = mp.getAdditionalProperties(); return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + } else if (p instanceof RefProperty) { + return "\\\\" + modelNamespace.replace("\\", "\\\\") + "\\\\" + getSwaggerType(p); } return super.getTypeDeclaration(p); } @@ -256,7 +259,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public Map postProcessSupportingFileData(Map objs) { objs = addNamespaces(super.postProcessSupportingFileData(objs)); - objs = formatImports(objs, "models", "importPath"); return objs; } diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index e9e308cbf64..b91bbf29d37 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -17,10 +17,6 @@ namespace {{invokerNamespace}}; -{{#models}} -use {{importPath}}; -{{/models}} - class ApiClient { public static $PATCH = "PATCH"; @@ -416,7 +412,7 @@ class ApiClient { /** * Deserialize a JSON string into an object * - * @param object $data object or primitive to be deserialized + * @param mixed $data object or primitive to be deserialized * @param string $class class name is passed as a string * @return object an instance of $class */ diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 2b4f1f27ab7..76fe0afab5a 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -22,7 +22,7 @@ namespace {{apiNamespace}}; -use {{invokerNamespace}}\Configuration; +use {{invokerNamespace}}\ApiConfiguration; use {{invokerNamespace}}\ApiClient; use {{invokerNamespace}}\ApiException; From 1519912a1ab460ff0d2fae820b81f01b96a0e3b7 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 09:26:45 -0700 Subject: [PATCH 086/499] cleaning up some php doc --- .../swagger-codegen/src/main/resources/php/api.mustache | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 76fe0afab5a..06f6386b046 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -46,6 +46,7 @@ class {{classname}} { /** * get the API client + * @return ApiClient this API's client */ public function getApiClient() { return $this->apiClient; @@ -53,9 +54,12 @@ class {{classname}} { /** * set the API client + * @param ApiClient $apiClient + * @return {{classname}} */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } {{#operation}} @@ -66,6 +70,7 @@ class {{classname}} { * {{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} {{/allParams}} * @return {{#returnType}}{{#isListContainer}}{{returnBaseType}}[]{{/isListContainer}}{{^isListContainer}}{{{returnType}}}{{/isListContainer}}{{/returnType}}{{^returnType}}void{{/returnType}} + * @throws \{{invokerNamespace}}\ApiException on non-2xx response */ public function {{nickname}}({{#allParams}}${{paramName}}{{#optional}}=null{{/optional}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} From 53bddae904cca40b53552b294e73803f9443e447 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 09:47:28 -0700 Subject: [PATCH 087/499] separate serialization responsibility to ObjectSerializer class --- .../codegen/languages/PhpClientCodegen.java | 1 + .../src/main/resources/php/ApiClient.mustache | 154 +----------------- .../resources/php/ObjectSerializer.mustache | 144 ++++++++++++++++ .../src/main/resources/php/api.mustache | 13 +- 4 files changed, 158 insertions(+), 154 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 7e9bac9c62f..201f7eb0539 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -120,6 +120,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("ApiConfiguration.mustache", invokerPackage.replace('/', File.separatorChar), "ApiConfiguration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerPackage.replace('/', File.separatorChar), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", invokerPackage.replace('/', File.separatorChar), "ApiException.php")); + supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", invokerPackage.replace('/', File.separatorChar), "ObjectSerializer.php")); supportingFiles.add(new SupportingFile("composer.mustache", "", "composer.json")); supportingFiles.add(new SupportingFile("autoload.mustache", "", "autoload.php")); } diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index b91bbf29d37..e697b7305aa 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -50,11 +50,7 @@ class ApiClient { /** * @param ApiConfiguration $config config for this ApiClient */ - function __construct($host = null, ApiConfiguration $config = null) { - if ($host != null) { - $this->host = $host; - } - + function __construct(ApiConfiguration $config = null) { if ($config == null) { $config = ApiConfiguration::getDefaultConfiguration(); } @@ -67,6 +63,7 @@ class ApiClient { * * @param string $headerName header name (e.g. Token) * @param string $headerValue header value (e.g. 1z8wp3) + * @return ApiClient */ public function addDefaultHeader($headerName, $headerValue) { if (!is_string($headerName)) { @@ -115,6 +112,7 @@ class ApiClient { * set the user agent of the api client * * @param string $userAgent the user agent of the api client + * @return ApiClient */ public function setUserAgent($userAgent) { if (!is_string($userAgent)) @@ -137,6 +135,7 @@ class ApiClient { * set the HTTP timeout value * * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + * @return ApiClient */ public function setTimeout($seconds) { if (!is_numeric($seconds) || $seconds < 0) @@ -236,10 +235,10 @@ class ApiClient { $postData = http_build_query($postData); } else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model - $postData = json_encode($this->sanitizeForSerialization($postData)); + $postData = json_encode(ObjectSerializer::sanitizeForSerialization($postData)); } - $url = $this->config->getHost() . $resourcePath; + $url = $this->getHost() . $resourcePath; $curl = curl_init(); // set timeout, if needed @@ -315,147 +314,6 @@ class ApiClient { return $data; } - /** - * Build a JSON POST object - * @param mixed $data the data to serialize - * @return string serialized form of $data - */ - protected function sanitizeForSerialization($data) { - if (is_scalar($data) || null === $data) { - $sanitized = $data; - } else if ($data instanceof \DateTime) { - $sanitized = $data->format(\DateTime::ISO8601); - } else if (is_array($data)) { - foreach ($data as $property => $value) { - $data[$property] = $this->sanitizeForSerialization($value); - } - $sanitized = $data; - } else if (is_object($data)) { - $values = array(); - foreach (array_keys($data::$swaggerTypes) as $property) { - if ($data->$property !== null) { - $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); - } - } - $sanitized = $values; - } else { - $sanitized = (string)$data; - } - - return $sanitized; - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the path, by url-encoding. - * @param string $value a string which will be part of the path - * @return string the serialized object - */ - public static function toPathValue($value) { - return rawurlencode(self::toString($value)); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the query, by imploding comma-separated if it's an object. - * If it's a string, pass through unchanged. It will be url-encoded - * later. - * @param object $object an object to be serialized to a string - * @return string the serialized object - */ - public static function toQueryValue($object) { - if (is_array($object)) { - return implode(',', $object); - } else { - return self::toString($object); - } - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the header. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value a string which will be part of the header - * @return string the header string - */ - public static function toHeaderValue($value) { - return self::toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the http body (form parameter). If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the form parameter - * @return string the form string - */ - public static function toFormValue($value) { - return self::toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the parameter. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the parameter - * @return string the header string - */ - public static function toString($value) { - if ($value instanceof \DateTime) { // datetime in ISO8601 format - return $value->format(\DateTime::ISO8601); - } - else { - return $value; - } - } - - /** - * Deserialize a JSON string into an object - * - * @param mixed $data object or primitive to be deserialized - * @param string $class class name is passed as a string - * @return object an instance of $class - */ - public static function deserialize($data, $class) - { - if (null === $data) { - $deserialized = null; - } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] - $inner = substr($class, 4, -1); - $deserialized = array(); - if(strrpos($inner, ",") !== false) { - $subClass_array = explode(',', $inner, 2); - $subClass = $subClass_array[1]; - foreach ($data as $key => $value) { - $deserialized[$key] = self::deserialize($value, $subClass); - } - } - } elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) { - $subClass = substr($class, 6, -1); - $values = array(); - foreach ($data as $key => $value) { - $values[] = self::deserialize($value, $subClass); - } - $deserialized = $values; - } elseif ($class == 'DateTime') { - $deserialized = new \DateTime($data); - } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { - settype($data, $class); - $deserialized = $data; - } else { - $instance = new $class(); - foreach ($instance::$swaggerTypes as $property => $type) { - $original_property_name = $instance::$attributeMap[$property]; - if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = self::deserialize($data->$original_property_name, $type); - } - } - $deserialized = $instance; - } - - return $deserialized; - } - /* * return the header 'Accept' based on an array of Accept provided * diff --git a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache new file mode 100644 index 00000000000..3a7765a4a82 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache @@ -0,0 +1,144 @@ +format(\DateTime::ISO8601); + } else if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = self::sanitizeForSerialization($value); + } + $sanitized = $data; + } else if (is_object($data)) { + $values = array(); + foreach (array_keys($data::$swaggerTypes) as $property) { + if ($data->$property !== null) { + $values[$data::$attributeMap[$property]] = self::sanitizeForSerialization($data->$property); + } + } + $sanitized = $values; + } else { + $sanitized = (string)$data; + } + + return $sanitized; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * @param string $value a string which will be part of the path + * @return string the serialized object + */ + public static function toPathValue($value) { + return rawurlencode(self::toString($value)); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the query, by imploding comma-separated if it's an object. + * If it's a string, pass through unchanged. It will be url-encoded + * later. + * @param object $object an object to be serialized to a string + * @return string the serialized object + */ + public static function toQueryValue($object) { + if (is_array($object)) { + return implode(',', $object); + } else { + return self::toString($object); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value a string which will be part of the header + * @return string the header string + */ + public static function toHeaderValue($value) { + return self::toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the http body (form parameter). If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the form parameter + * @return string the form string + */ + public static function toFormValue($value) { + return self::toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the parameter + * @return string the header string + */ + public static function toString($value) { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(\DateTime::ISO8601); + } else { + return $value; + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @return object an instance of $class + */ + public static function deserialize($data, $class) { + if (null === $data) { + $deserialized = null; + } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] + $inner = substr($class, 4, -1); + $deserialized = array(); + if(strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = self::deserialize($value, $subClass); + } + } + } elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) { + $subClass = substr($class, 6, -1); + $values = array(); + foreach ($data as $key => $value) { + $values[] = self::deserialize($value, $subClass); + } + $deserialized = $values; + } elseif ($class == 'DateTime') { + $deserialized = new \DateTime($data); + } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { + settype($data, $class); + $deserialized = $data; + } else { + $instance = new $class(); + foreach ($instance::$swaggerTypes as $property => $type) { + $original_property_name = $instance::$attributeMap[$property]; + if (isset($original_property_name) && isset($data->$original_property_name)) { + $instance->$property = self::deserialize($data->$original_property_name, $type); + } + } + $deserialized = $instance; + } + + return $deserialized; + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 06f6386b046..847527ee40c 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -25,6 +25,7 @@ namespace {{apiNamespace}}; use {{invokerNamespace}}\ApiConfiguration; use {{invokerNamespace}}\ApiClient; use {{invokerNamespace}}\ApiException; +use {{invokerNamespace}}\ObjectSerializer; {{#imports}} use {{{import}}}; @@ -96,21 +97,21 @@ class {{classname}} { {{#queryParams}}// query params if(${{paramName}} !== null) { - $queryParams['{{baseName}}'] = ApiClient::toQueryValue(${{paramName}}); + $queryParams['{{baseName}}'] = ObjectSerializer::toQueryValue(${{paramName}}); }{{/queryParams}} {{#headerParams}}// header params if(${{paramName}} !== null) { - $headerParams['{{baseName}}'] = ApiClient::toHeaderValue(${{paramName}}); + $headerParams['{{baseName}}'] = ObjectSerializer::toHeaderValue(${{paramName}}); }{{/headerParams}} {{#pathParams}}// path params if(${{paramName}} !== null) { $resourcePath = str_replace("{" . "{{baseName}}" . "}", - ApiClient::toPathValue(${{paramName}}), + ObjectSerializer::toPathValue(${{paramName}}), $resourcePath); }{{/pathParams}} {{#formParams}}// form params if (${{paramName}} !== null) { - $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}ApiClient::toFormValue(${{paramName}}); + $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}ObjectSerializer::toFormValue(${{paramName}}); }{{/formParams}} {{#bodyParams}}// body params $_tempBody = null; @@ -139,7 +140,7 @@ class {{classname}} { switch ($e->getCode()) { {{#responses}}{{#dataType}} case {{code}}: - $data = ApiClient::deserialize($e->getResponseBody(), '{{dataType}}'); + $data = ObjectSerializer::deserialize($e->getResponseBody(), '{{dataType}}'); $throw = new ApiException("{{message}}", $e->getCode(), $e->getResponseHeaders(), $data); break;{{/dataType}}{{/responses}} } @@ -151,7 +152,7 @@ class {{classname}} { return null; } - $responseObject = ApiClient::deserialize($response,'{{returnType}}'); + $responseObject = ObjectSerializer::deserialize($response,'{{returnType}}'); return $responseObject; {{/returnType}} } From e598384d97e5f3543679a3e7e6a38b2bf052a356 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 10:31:38 -0700 Subject: [PATCH 088/499] move authentication to the API level, so that supporting classes aren't api-specific --- .../src/main/resources/php/ApiClient.mustache | 43 ++++--------------- .../src/main/resources/php/api.mustache | 16 ++++--- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index e697b7305aa..c2a6b369f3c 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -99,6 +99,14 @@ class ApiClient { return $this->host; } + /** + * get the config + * @return ApiConfiguration + */ + public function getConfig() { + return $this->config; + } + /** * delete the default header based on header name * @@ -176,34 +184,6 @@ class ApiClient { return $keyWithPrefix; } - - /** - * update header and query param based on authentication setting - * - * @param array $headerParams header parameters (by ref) - * @param array $queryParams query parameters (by ref) - * @param array $authSettings array of authentication scheme (e.g ['api_key']) - */ - public function updateParamsForAuth(&$headerParams, &$queryParams, $authSettings) - { - if (count($authSettings) == 0) - return; - - // one endpoint can have more than 1 auth settings - foreach($authSettings as $auth) { - // determine which one to use - switch($auth) { - {{#authMethods}} - case '{{name}}': - {{#isApiKey}}{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode($this->config->getUsername().":".$this->config->getPassword());{{/isBasic}} - {{#isOAuth}}//TODO support oauth{{/isOAuth}} - break; - {{/authMethods}} - default: - //TODO show warning about security definition not found - } - } - } /** * @param string $resourcePath path to method endpoint @@ -211,18 +191,13 @@ class ApiClient { * @param array $queryParams parameters to be place in query URL * @param array $postData parameters to be placed in POST body * @param array $headerParams parameters to be place in request header - * @param array $authSettings parameters for authentication * @throws \{{invokerNamespace}}\ApiException on a non 2xx response * @return mixed */ - public function callApi($resourcePath, $method, $queryParams, $postData, - $headerParams, $authSettings) { + public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) { $headers = array(); - # determine authentication setting - $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); - # construct the http header $headerParams = array_merge((array)$this->defaultHeaders, (array)$headerParams); diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 847527ee40c..a014ecbaccc 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -126,15 +126,19 @@ class {{classname}} { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array({{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}); - + {{#authMethods}}{{#isApiKey}} + $apiKey = $this->apiClient->getApiKeyWithPrefix('{{keyParamName}}'); + if (isset($apiKey)) { + {{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $apiKey;{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $apiKey;{{/isKeyInQuery}} + }{{/isApiKey}} + {{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode($this->apiClient->getConfig()->getUsername().":".$this->apiClient->getConfig()->getPassword());{{/isBasic}} + {{#isOAuth}}//TODO support oauth{{/isOAuth}} + {{/authMethods}} // make the API Call try { $response = $this->apiClient->callAPI($resourcePath, $method, $queryParams, $httpBody, - $headerParams, $authSettings); + $headerParams); } catch (ApiException $e) { $throw = $e; @@ -148,7 +152,7 @@ class {{classname}} { throw $throw; } {{#returnType}} - if(!$response) { + if (!$response) { return null; } From 6f11092a57442f5f2a73f155917ebfedcb8e9fd9 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 10:35:57 -0700 Subject: [PATCH 089/499] call setHost using API baspath when no apiclient is provided --- .../swagger-codegen/src/main/resources/php/ApiClient.mustache | 4 ++-- modules/swagger-codegen/src/main/resources/php/api.mustache | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index c2a6b369f3c..996ccbd16d9 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -28,9 +28,9 @@ class ApiClient { protected $defaultHeaders = array(); /** - * The host (from basePath) + * The host */ - protected $host = '{{basePath}}'; + protected $host = 'http://localhost'; /* * @var string timeout (second) of the HTTP request, by default set to 0, no timeout diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index a014ecbaccc..b6f17f528d5 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -39,7 +39,7 @@ class {{classname}} { function __construct($apiClient = null) { if ($apiClient == null) { - $apiClient = new ApiClient(); + $apiClient = (new ApiClient())->setHost('{{basePath}}'); } $this->apiClient = $apiClient; From a664abcf51e1e47bbd7e1d534867490fd264562e Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Mon, 22 Jun 2015 19:17:29 +0100 Subject: [PATCH 090/499] Contributed maven plugin to the swagger-codegen project --- .gitignore | 1 + .../swagger-codegen-maven-plugin/README.md | 41 ++++++ modules/swagger-codegen-maven-plugin/pom.xml | 87 +++++++++++++ .../codegen/plugin/AdditionalParams.java | 16 +++ .../swagger/codegen/plugin/CodeGenMojo.java | 118 ++++++++++++++++++ pom.xml | 1 + 6 files changed, 264 insertions(+) create mode 100644 modules/swagger-codegen-maven-plugin/README.md create mode 100644 modules/swagger-codegen-maven-plugin/pom.xml create mode 100644 modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java create mode 100644 modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java diff --git a/.gitignore b/.gitignore index 24bb9709fc3..a0e39ffd165 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ version.properties lib/* build/* generated-files/* +generated-sources/* generated-code/* *.swp *.swo diff --git a/modules/swagger-codegen-maven-plugin/README.md b/modules/swagger-codegen-maven-plugin/README.md new file mode 100644 index 00000000000..a7eaf852a22 --- /dev/null +++ b/modules/swagger-codegen-maven-plugin/README.md @@ -0,0 +1,41 @@ +swagger-codegen-maven-plugin +============================ + +A Maven plugin to support the [swagger](http://swagger.io) code generation project + +Usage +============================ + +Add to your `build->plugins` section (default phase is `generate-sources` phase) +```xml + + io.swagger + swagger-codegen-maven-plugin + ${project.version} + + + + generate + + + src/main/resources/api.yaml + java + + + + +``` + +Followed by: + +``` +mvn clean compile +``` + +### Configuration parameters + +- `inputSpec` - swagger spec file path +- `language` - target generation language +- `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`) +- `templateDirectory` - directory with mustache templates +- `addCompileSourceRoot` - add the output directory to the project as a source root (`true` by default) diff --git a/modules/swagger-codegen-maven-plugin/pom.xml b/modules/swagger-codegen-maven-plugin/pom.xml new file mode 100644 index 00000000000..7ad4496872c --- /dev/null +++ b/modules/swagger-codegen-maven-plugin/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + + io.swagger + swagger-codegen-project + 2.1.3-SNAPSHOT + ../.. + + swagger-codegen-maven-plugin + swagger-codegen (maven-plugin) + maven-plugin + maven plugin to build modules from swagger codegen + + UTF-8 + + + + org.apache.maven + maven-core + 3.2.5 + + + org.apache.maven + maven-artifact + 3.2.5 + provided + + + org.apache.maven + maven-compat + 3.2.5 + + + org.apache.maven + maven-plugin-api + 3.2.5 + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.4 + + + io.swagger + swagger-codegen + ${project.version} + + + junit + junit + 4.12 + test + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.4 + + true + + + + mojo-descriptor + process-classes + + descriptor + + + + help-goal + + helpmojo + + + + + + + + diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java new file mode 100644 index 00000000000..aa137cbf6c3 --- /dev/null +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java @@ -0,0 +1,16 @@ +package io.swagger.codegen.plugin; + +/** + * User: lanwen + * Date: 24.03.15 + * Time: 14:47 + */ +public final class AdditionalParams { + public static final String TEMPLATE_DIR_PARAM = "templateDir"; + + private AdditionalParams() { + + } + + +} diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java new file mode 100644 index 00000000000..26b6fef1135 --- /dev/null +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -0,0 +1,118 @@ +package io.swagger.codegen.plugin; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import io.swagger.codegen.ClientOptInput; +import io.swagger.codegen.ClientOpts; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.DefaultGenerator; +import io.swagger.models.Swagger; +import io.swagger.parser.SwaggerParser; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.util.ServiceLoader; + +import static io.swagger.codegen.plugin.AdditionalParams.TEMPLATE_DIR_PARAM; + +/** + * Goal which generates client/server code from a swagger json/yaml definition. + */ +@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class CodeGenMojo extends AbstractMojo { + + /** + * Location of the output directory. + */ + @Parameter(name = "output", + property = "swagger.codegen.maven.plugin.output", + defaultValue = "${project.build.directory}/generated-sources/swagger") + private File output; + + /** + * Location of the swagger spec, as URL or file. + */ + @Parameter(name = "inputSpec", required = true) + private String inputSpec; + + /** + * Folder containing the template files. + */ + @Parameter(name = "templateDirectory") + private File templateDirectory; + + /** + * Client language to generate. + */ + @Parameter(name = "language", required = true) + private String language; + + + /** + * Add the output directory to the project as a source root, so that the + * generated java types are compiled and included in the project artifact. + */ + @Parameter(defaultValue = "true") + private boolean addCompileSourceRoot = true; + + /** + * The project being built. + */ + @Parameter(readonly = true, required = true, defaultValue = "${project}") + private MavenProject project; + + @Override + public void execute() throws MojoExecutionException { + Swagger swagger = new SwaggerParser().read(inputSpec); + + CodegenConfig config = forName(language); + config.setOutputDir(output.getAbsolutePath()); + + if (null != templateDirectory) { + config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath()); + } + + ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger); + input.setConfig(config); + new DefaultGenerator().opts(input).generate(); + + if (addCompileSourceRoot) { + project.addCompileSourceRoot(output.toString()); + } + } + + private CodegenConfig forName(String name) { + ServiceLoader loader = ServiceLoader.load(CodegenConfig.class); + for (CodegenConfig config : loader) { + if (config.getName().equals(name)) { + return config; + } + } + + // else try to load directly + try { + return (CodegenConfig) Class.forName(name).newInstance(); + } catch (Exception e) { + throw new RuntimeException("Can't load config class with name ".concat(name), e); + } + } +} diff --git a/pom.xml b/pom.xml index ca707056230..10bd7340167 100644 --- a/pom.xml +++ b/pom.xml @@ -397,6 +397,7 @@ modules/swagger-codegen modules/swagger-codegen-cli + modules/swagger-codegen-maven-plugin modules/swagger-generator From 5de99bafa725b125dc5969d06d9fb93856ba2709 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 11:18:36 -0700 Subject: [PATCH 091/499] fixing package output --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 201f7eb0539..beddbeac729 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -126,7 +126,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { } protected String getSrcDir(String packageName) { - return rootNamespace + "/src/" + packageName; + return "src/" + packageName; } protected void prefixPackages() { From 109b7eeaec3c9ab0c70a1515cc8c58cd501da722 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 11:19:01 -0700 Subject: [PATCH 092/499] adding static setters/getters for models since members are no public --- .../resources/php/ObjectSerializer.mustache | 17 ++++++++++++----- .../src/main/resources/php/model.mustache | 18 ++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache index 3a7765a4a82..fe70c4db653 100644 --- a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache @@ -21,8 +21,9 @@ class ObjectSerializer { } else if (is_object($data)) { $values = array(); foreach (array_keys($data::$swaggerTypes) as $property) { - if ($data->$property !== null) { - $values[$data::$attributeMap[$property]] = self::sanitizeForSerialization($data->$property); + $getter = $data::$getters[$property]; + if ($data->$getter() !== null) { + $values[$data::$attributeMap[$property]] = self::sanitizeForSerialization($data->$getter()); } } $sanitized = $values; @@ -131,9 +132,15 @@ class ObjectSerializer { } else { $instance = new $class(); foreach ($instance::$swaggerTypes as $property => $type) { - $original_property_name = $instance::$attributeMap[$property]; - if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = self::deserialize($data->$original_property_name, $type); + $propertySetter = $instance::$setters[$property]; + + if (!isset($propertySetter) || !isset($data->{$instance::$attributeMap[$property]})) { + continue; + } + + $propertyValue = $data->{$instance::$attributeMap[$property]}; + if (isset($propertyValue)) { + $instance->$propertySetter(self::deserialize($propertyValue, $type)); } } $deserialized = $instance; diff --git a/modules/swagger-codegen/src/main/resources/php/model.mustache b/modules/swagger-codegen/src/main/resources/php/model.mustache index fadf38f874b..0e906b5885c 100644 --- a/modules/swagger-codegen/src/main/resources/php/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php/model.mustache @@ -30,13 +30,23 @@ use \ArrayAccess; class {{classname}} implements ArrayAccess { static $swaggerTypes = array( - {{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}}, - {{/hasMore}}{{/vars}} + {{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} ); static $attributeMap = array( - {{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}}, - {{/hasMore}}{{/vars}} + {{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} + ); + + static $setters = array( + {{#vars}}'{{name}}' => '{{setter}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} + ); + + static $getters = array( + {{#vars}}'{{name}}' => '{{getter}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} ); {{#vars}} From 01d7776fc1a1469ea45bf4a1c2a81032cbf3bfe1 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 11:47:23 -0700 Subject: [PATCH 093/499] don't create a new response object, and keep the old string value in the exception and have the object as ApiException->responseObject --- .../main/resources/php/ApiException.mustache | 28 +++++++++++++++---- .../src/main/resources/php/api.mustache | 6 ++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache index 096979c11cb..4b8d205690c 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache @@ -24,17 +24,22 @@ class ApiException extends Exception { /** * The HTTP body of the server response. */ - protected $response_body; + protected $responseBody; /** * The HTTP header of the server response. */ - protected $response_headers; + protected $responseHeaders; + + /** + * The deserialized response object + */ + protected $responseObject; public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { parent::__construct($message, $code); - $this->response_headers = $responseHeaders; - $this->response_body = $responseBody; + $this->responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; } /** @@ -43,7 +48,7 @@ class ApiException extends Exception { * @return string HTTP response header */ public function getResponseHeaders() { - return $this->response_headers; + return $this->responseHeaders; } /** @@ -52,7 +57,18 @@ class ApiException extends Exception { * @return string HTTP response body */ public function getResponseBody() { - return $this->response_body; + return $this->responseBody; } + /** + * sets the deseralized response object (during deserialization) + * @param mixed $obj + */ + public function setResponseObject($obj) { + $this->responseObject = $obj; + } + + public function getResponseObject() { + return $this->responseObject; + } } diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index b6f17f528d5..3d9ead4bed1 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -140,16 +140,14 @@ class {{classname}} { $queryParams, $httpBody, $headerParams); } catch (ApiException $e) { - $throw = $e; - switch ($e->getCode()) { {{#responses}}{{#dataType}} case {{code}}: $data = ObjectSerializer::deserialize($e->getResponseBody(), '{{dataType}}'); - $throw = new ApiException("{{message}}", $e->getCode(), $e->getResponseHeaders(), $data); + $e->setResponseObject($data); break;{{/dataType}}{{/responses}} } - throw $throw; + throw $e; } {{#returnType}} if (!$response) { From a6331244e15fc09c34aaf16262d667ac9a137ccb Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 12:05:22 -0700 Subject: [PATCH 094/499] move all configuration to ApiConfiguration --- .../src/main/resources/php/ApiClient.mustache | 125 +----------------- .../resources/php/ApiConfiguration.mustache | 109 +++++++++++++++ 2 files changed, 114 insertions(+), 120 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 996ccbd16d9..c29ca1f58e4 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -24,23 +24,6 @@ class ApiClient { public static $GET = "GET"; public static $PUT = "PUT"; public static $DELETE = "DELETE"; - - protected $defaultHeaders = array(); - - /** - * The host - */ - protected $host = 'http://localhost'; - - /* - * @var string timeout (second) of the HTTP request, by default set to 0, no timeout - */ - protected $curlTimeout = 0; - - /* - * @var string user agent of the HTTP request, set to "PHP-Swagger" by default - */ - protected $userAgent = "PHP-Swagger"; /** * @var ApiConfiguration @@ -58,47 +41,6 @@ class ApiClient { $this->config = $config; } - /** - * add default header - * - * @param string $headerName header name (e.g. Token) - * @param string $headerValue header value (e.g. 1z8wp3) - * @return ApiClient - */ - public function addDefaultHeader($headerName, $headerValue) { - if (!is_string($headerName)) { - throw new \InvalidArgumentException('Header name must be a string.'); - } - - $this->defaultHeaders[$headerName] = $headerValue; - return $this; - } - - /** - * get the default header - * - * @return array default header - */ - public function getDefaultHeaders() { - return $this->defaultHeaders; - } - - /** - * @param string $host - * @return ApiConfiguration - */ - public function setHost($host) { - $this->host = $host; - return $this; - } - - /** - * @return string - */ - public function getHost() { - return $this->host; - } - /** * get the config * @return ApiConfiguration @@ -107,62 +49,6 @@ class ApiClient { return $this->config; } - /** - * delete the default header based on header name - * - * @param string $headerName header name (e.g. Token) - */ - public function deleteDefaultHeader($headerName) { - unset($this->defaultHeaders[$headerName]); - } - - /** - * set the user agent of the api client - * - * @param string $userAgent the user agent of the api client - * @return ApiClient - */ - public function setUserAgent($userAgent) { - if (!is_string($userAgent)) - throw new \InvalidArgumentException('User-agent must be a string.'); - - $this->userAgent = $userAgent; - return $this; - } - - /** - * get the user agent of the api client - * - * @return string user agent - */ - public function getUserAgent() { - return $this->userAgent; - } - - /** - * set the HTTP timeout value - * - * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] - * @return ApiClient - */ - public function setTimeout($seconds) { - if (!is_numeric($seconds) || $seconds < 0) - throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); - - $this->curlTimeout = $seconds; - return $this; - } - - /** - * get the HTTP timeout value - * - * @return string HTTP timeout value - */ - public function getTimeout() { - return $this->curlTimeout; - } - - /** * Get API key (with prefix if set) * @param string $apiKey name of apikey @@ -199,7 +85,7 @@ class ApiClient { $headers = array(); # construct the http header - $headerParams = array_merge((array)$this->defaultHeaders, (array)$headerParams); + $headerParams = array_merge((array)$this->config->getDefaultHeaders(), (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -213,12 +99,12 @@ class ApiClient { $postData = json_encode(ObjectSerializer::sanitizeForSerialization($postData)); } - $url = $this->getHost() . $resourcePath; + $url = $this->config->getHost() . $resourcePath; $curl = curl_init(); // set timeout, if needed - if ($this->curlTimeout != 0) { - curl_setopt($curl, CURLOPT_TIMEOUT, $this->curlTimeout); + if ($this->config->getCurlTimeout() != 0) { + curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout()); } // return the result on success, rather than just TRUE curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @@ -247,7 +133,7 @@ class ApiClient { curl_setopt($curl, CURLOPT_URL, $url); // Set user agent - curl_setopt($curl, CURLOPT_USERAGENT, $this->userAgent); + curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent()); // debugging for curl if ($this->config->getDebug()) { @@ -320,6 +206,5 @@ class ApiClient { return implode(',', $content_type); } } - } diff --git a/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache b/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache index 764e0eafe89..4834294901d 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache @@ -41,6 +41,26 @@ class ApiConfiguration { */ protected $password = ''; + /** + * default headers for requests this conf + */ + protected $defaultHeaders = array(); + + /** + * The host + */ + protected $host = 'http://localhost'; + + /* + * @var string timeout (second) of the HTTP request, by default set to 0, no timeout + */ + protected $curlTimeout = 0; + + /* + * @var string user agent of the HTTP request, set to "PHP-Swagger" by default + */ + protected $userAgent = "PHP-Swagger"; + /** * Debug switch (default set to false) */ @@ -119,6 +139,95 @@ class ApiConfiguration { return $this->password; } + /** + * add default header + * + * @param string $headerName header name (e.g. Token) + * @param string $headerValue header value (e.g. 1z8wp3) + * @return ApiClient + */ + public function addDefaultHeader($headerName, $headerValue) { + if (!is_string($headerName)) { + throw new \InvalidArgumentException('Header name must be a string.'); + } + + $this->defaultHeaders[$headerName] = $headerValue; + return $this; + } + + /** + * get the default header + * + * @return array default header + */ + public function getDefaultHeaders() { + return $this->defaultHeaders; + } + + /** + * @param string $host + * @return ApiConfiguration + */ + public function setHost($host) { + $this->host = $host; + return $this; + } + + /** + * @return string + */ + public function getHost() { + return $this->host; + } + + /** + * set the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * @return ApiClient + */ + public function setUserAgent($userAgent) { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * get the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() { + return $this->userAgent; + } + + /** + * set the HTTP timeout value + * + * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + * @return ApiClient + */ + public function setCurlTimeout($seconds) { + if (!is_numeric($seconds) || $seconds < 0) { + throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); + } + + $this->curlTimeout = $seconds; + return $this; + } + + /** + * get the HTTP timeout value + * + * @return string HTTP timeout value + */ + public function getCurlTimeout() { + return $this->curlTimeout; + } + /** * @param bool $debug * @return ApiConfiguration From 5ef50f9f4b27f943e841d04d6958926d9c2e8f48 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 12:07:48 -0700 Subject: [PATCH 095/499] rename ApiConfiguration to ApiClientConfiguration --- .../codegen/languages/PhpClientCodegen.java | 2 +- .../src/main/resources/php/ApiClient.mustache | 10 ++++----- ...stache => ApiClientConfiguration.mustache} | 22 +++++++++---------- .../src/main/resources/php/api.mustache | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) rename modules/swagger-codegen/src/main/resources/php/{ApiConfiguration.mustache => ApiClientConfiguration.mustache} (92%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index beddbeac729..a9909427a0d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -117,7 +117,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { setNamespacesFromPackages(); prefixPackages(); - supportingFiles.add(new SupportingFile("ApiConfiguration.mustache", invokerPackage.replace('/', File.separatorChar), "ApiConfiguration.php")); + supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", invokerPackage.replace('/', File.separatorChar), "ApiClientConfiguration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerPackage.replace('/', File.separatorChar), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", invokerPackage.replace('/', File.separatorChar), "ApiException.php")); supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", invokerPackage.replace('/', File.separatorChar), "ObjectSerializer.php")); diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index c29ca1f58e4..d6133b08584 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -26,16 +26,16 @@ class ApiClient { public static $DELETE = "DELETE"; /** - * @var ApiConfiguration + * @var ApiClientConfiguration */ protected $config; /** - * @param ApiConfiguration $config config for this ApiClient + * @param ApiClientConfiguration $config config for this ApiClient */ - function __construct(ApiConfiguration $config = null) { + function __construct(ApiClientConfiguration $config = null) { if ($config == null) { - $config = ApiConfiguration::getDefaultConfiguration(); + $config = ApiClientConfiguration::getDefaultConfiguration(); } $this->config = $config; @@ -43,7 +43,7 @@ class ApiClient { /** * get the config - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function getConfig() { return $this->config; diff --git a/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache similarity index 92% rename from modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache rename to modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache index 4834294901d..6a674ccfd3f 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiConfiguration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache @@ -17,7 +17,7 @@ namespace {{invokerNamespace}}; -class ApiConfiguration { +class ApiClientConfiguration { private static $defaultConfiguration = null; @@ -74,7 +74,7 @@ class ApiConfiguration { /** * @param string $key * @param string $value - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setApiKey($key, $value) { $this->apiKeys[$key] = $value; @@ -92,7 +92,7 @@ class ApiConfiguration { /** * @param string $key * @param string $value - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setApiKeyPrefix($key, $value) { $this->apiKeyPrefixes[$key] = $value; @@ -109,7 +109,7 @@ class ApiConfiguration { /** * @param string $username - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setUsername($username) { $this->username = $username; @@ -125,7 +125,7 @@ class ApiConfiguration { /** * @param string $password - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setPassword($password) { $this->password = $password; @@ -166,7 +166,7 @@ class ApiConfiguration { /** * @param string $host - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setHost($host) { $this->host = $host; @@ -230,7 +230,7 @@ class ApiConfiguration { /** * @param bool $debug - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setDebug($debug) { $this->debug = $debug; @@ -246,7 +246,7 @@ class ApiConfiguration { /** * @param string $debugFile - * @return ApiConfiguration + * @return ApiClientConfiguration */ public function setDebugFile($debugFile) { $this->debugFile = $debugFile; @@ -261,17 +261,17 @@ class ApiConfiguration { } /** - * @return ApiConfiguration + * @return ApiClientConfiguration */ public static function getDefaultConfiguration() { if (self::$defaultConfiguration == null) { - return new ApiConfiguration(); + return new ApiClientConfiguration(); } return self::$defaultConfiguration; } - public static function setDefaultConfiguration(ApiConfiguration $config) { + public static function setDefaultConfiguration(ApiClientConfiguration $config) { self::$defaultConfiguration = $config; } } diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 3d9ead4bed1..d276d1c652c 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -22,7 +22,7 @@ namespace {{apiNamespace}}; -use {{invokerNamespace}}\ApiConfiguration; +use {{invokerNamespace}}\ApiClientConfiguration; use {{invokerNamespace}}\ApiClient; use {{invokerNamespace}}\ApiException; use {{invokerNamespace}}\ObjectSerializer; From 8e15bd6a85e2a1cc5d04b8ac067d2daa33fbf146 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 12:13:39 -0700 Subject: [PATCH 096/499] call setHost on config --- modules/swagger-codegen/src/main/resources/php/api.mustache | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index d276d1c652c..6fb9fb5dd06 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -39,7 +39,8 @@ class {{classname}} { function __construct($apiClient = null) { if ($apiClient == null) { - $apiClient = (new ApiClient())->setHost('{{basePath}}'); + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('{{basePath}}'); } $this->apiClient = $apiClient; From bd5eb7ace39123389184a103cb404ace51cc5d79 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 12:30:52 -0700 Subject: [PATCH 097/499] update tests --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 2 ++ .../swagger-codegen/src/test/scala/php/PhpModelTest.scala | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index a9909427a0d..5317530a9eb 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -41,6 +41,8 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { apiTemplateFiles.put("api.mustache", ".php"); templateDir = "php"; + setNamespacesFromPackages(); + reservedWords = new HashSet( Arrays.asList( "__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor") diff --git a/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala b/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala index ade8a09e80d..fae3999bbbd 100644 --- a/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala +++ b/modules/swagger-codegen/src/test/scala/php/PhpModelTest.scala @@ -142,7 +142,7 @@ class PhpModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") - vars.get(0).datatype should be("Children") + vars.get(0).datatype should be("\\\\Swagger\\\\Models\\\\Children") vars.get(0).name should be("children") vars.get(0).baseType should be("Children") vars.get(0).required should equal(null) @@ -166,7 +166,7 @@ class PhpModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") vars.get(0).complexType should be("Children") - vars.get(0).datatype should be("array[Children]") + vars.get(0).datatype should be("array[\\\\Swagger\\\\Models\\\\Children]") vars.get(0).name should be("children") vars.get(0).baseType should be("array") vars.get(0).containerType should be("array") @@ -192,7 +192,7 @@ class PhpModelTest extends FlatSpec with Matchers { val vars = cm.vars vars.get(0).baseName should be("children") vars.get(0).complexType should be("Children") - vars.get(0).datatype should be("map[string,Children]") + vars.get(0).datatype should be("map[string,\\\\Swagger\\\\Models\\\\Children]") vars.get(0).name should be("children") vars.get(0).baseType should be("map") vars.get(0).containerType should be("map") From ecddfb7ccf4376b2986c65cab6eca8d7eca206e7 Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Mon, 22 Jun 2015 15:16:45 -0700 Subject: [PATCH 098/499] Renamed QueryParam to Pair class in Java templates. --- .../codegen/languages/JavaClientCodegen.java | 2 +- .../main/resources/Java/ApiClient.mustache | 24 +++++++++---------- .../{QueryParam.mustache => Pair.mustache} | 4 ++-- .../src/main/resources/Java/api.mustache | 4 ++-- .../resources/Java/auth/ApiKeyAuth.mustache | 6 ++--- .../Java/auth/Authentication.mustache | 4 ++-- .../Java/auth/HttpBasicAuth.mustache | 4 ++-- .../main/resources/Java/auth/OAuth.mustache | 4 ++-- .../java/io/swagger/client/ApiClient.java | 24 +++++++++---------- .../client/{QueryParam.java => Pair.java} | 4 ++-- .../java/io/swagger/client/api/PetApi.java | 18 +++++++------- .../java/io/swagger/client/api/StoreApi.java | 10 ++++---- .../java/io/swagger/client/api/UserApi.java | 18 +++++++------- .../io/swagger/client/auth/ApiKeyAuth.java | 6 ++--- .../swagger/client/auth/Authentication.java | 4 ++-- .../io/swagger/client/auth/HttpBasicAuth.java | 4 ++-- .../java/io/swagger/client/auth/OAuth.java | 4 ++-- .../swagger/client/auth/ApiKeyAuthTest.java | 8 +++---- .../client/auth/HttpBasicAuthTest.java | 4 ++-- 19 files changed, 78 insertions(+), 78 deletions(-) rename modules/swagger-codegen/src/main/resources/Java/{QueryParam.mustache => Pair.mustache} (89%) rename samples/client/petstore/java/src/main/java/io/swagger/client/{QueryParam.java => Pair.java} (89%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java index 0f4e8c212ac..2f31cddec6f 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java @@ -116,7 +116,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java")); supportingFiles.add(new SupportingFile("JsonUtil.mustache", invokerFolder, "JsonUtil.java")); supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java")); - supportingFiles.add(new SupportingFile("QueryParam.mustache", invokerFolder, "QueryParam.java")); + supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java")); final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator); supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java")); diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index 59a0ee73281..888f407a412 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -241,10 +241,10 @@ public class ApiClient { } /* - Format to {@code QueryParam} objects. + Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); // preconditions if (name == null || name.isEmpty() || value == null) return params; @@ -255,7 +255,7 @@ public class ApiClient { } if (valueCollection == null) { - params.add(new QueryParam(name, String.valueOf(value))); + params.add(new Pair(name, String.valueOf(value))); return params; } else if (valueCollection.isEmpty()) { return params; @@ -264,10 +264,10 @@ public class ApiClient { collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv if (collectionFormat.equals("csv")) { - params.add(new QueryParam(name, parameterToString(value))); + params.add(new Pair(name, parameterToString(value))); } else if (collectionFormat.equals("multi")) { for (String item : valueCollection) { - params.add(new QueryParam(name, item)); + params.add(new Pair(name, item)); } } else if (collectionFormat.equals("ssv")) { StringBuilder sb = new StringBuilder() ; @@ -275,21 +275,21 @@ public class ApiClient { sb.append(" "); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("tsv")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("\t"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("pipes")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("|"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } return params; @@ -398,7 +398,7 @@ public class ApiClient { * @param authNames The authentications to apply * @return The response body in type of string */ - public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { updateParamsForAuth(authNames, queryParams, headerParams); Client client = getClient(); @@ -406,7 +406,7 @@ public class ApiClient { StringBuilder b = new StringBuilder(); b.append("?"); if (queryParams != null){ - for (QueryParam queryParam : queryParams){ + for (Pair queryParam : queryParams){ if (!queryParam.getName().isEmpty()) { b.append(escapeString(queryParam.getName())); b.append("="); @@ -516,7 +516,7 @@ public class ApiClient { * * @param authNames The authentications to apply */ - private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { + private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { for (String authName : authNames) { Authentication auth = authentications.get(authName); if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); diff --git a/modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache b/modules/swagger-codegen/src/main/resources/Java/Pair.mustache similarity index 89% rename from modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache rename to modules/swagger-codegen/src/main/resources/Java/Pair.mustache index 23b1b26f55c..9805c74903b 100644 --- a/modules/swagger-codegen/src/main/resources/Java/QueryParam.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/Pair.mustache @@ -1,10 +1,10 @@ package {{invokerPackage}}; -public class QueryParam { +public class Pair { private String name = ""; private String value = ""; - public QueryParam(String name, String value) { + public Pair (String name, String value) { setName(name); setValue(value); } diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache index 66dc25d66bf..8d8709da186 100644 --- a/modules/swagger-codegen/src/main/resources/Java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache @@ -3,7 +3,7 @@ package {{package}}; import {{invokerPackage}}.ApiException; import {{invokerPackage}}.ApiClient; import {{invokerPackage}}.Configuration; -import {{invokerPackage}}.QueryParam; +import {{invokerPackage}}.Pair; import {{modelPackage}}.*; @@ -62,7 +62,7 @@ public class {{classname}} { .replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache index 46fa51087b6..aefbe453efd 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache @@ -1,6 +1,6 @@ package {{invokerPackage}}.auth; -import {{invokerPackage}}.QueryParam; +import {{invokerPackage}}.Pair; import java.util.Map; import java.util.Set; @@ -42,7 +42,7 @@ public class ApiKeyAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; @@ -50,7 +50,7 @@ public class ApiKeyAuth implements Authentication { value = apiKey; } if (location == "query") { - queryParams.add(new QueryParam(paramName, value)); + queryParams.add(new Pair(paramName, value)); } else if (location == "header") { headerParams.put(paramName, value); } diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache index 1f39a402b2c..9e0b328915c 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache @@ -1,11 +1,11 @@ package {{invokerPackage}}.auth; -import {{invokerPackage}}.QueryParam; +import {{invokerPackage}}.Pair; import java.util.Map; import java.util.Set; public interface Authentication { /** Apply authentication settings to header and query params. */ - void applyToParams(Set queryParams, Map headerParams); + void applyToParams(Set queryParams, Map headerParams); } diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache index b5bc993f7c4..73c52d96ff1 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache @@ -1,6 +1,6 @@ package {{invokerPackage}}.auth; -import {{invokerPackage}}.QueryParam; +import {{invokerPackage}}.Pair; import java.util.Map; import java.util.Set; @@ -29,7 +29,7 @@ public class HttpBasicAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); try { headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"))); diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache index ab634489eda..4de2fbed905 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache @@ -1,13 +1,13 @@ package {{invokerPackage}}.auth; -import {{invokerPackage}}.QueryParam; +import {{invokerPackage}}.Pair; import java.util.Map; import java.util.Set; public class OAuth implements Authentication { @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { // TODO: support oauth } } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index dd14a1c2454..441e5cc1f3c 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -240,10 +240,10 @@ public class ApiClient { } /* - Format to {@code QueryParam} objects. + Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); // preconditions if (name == null || name.isEmpty() || value == null) return params; @@ -254,7 +254,7 @@ public class ApiClient { } if (valueCollection == null) { - params.add(new QueryParam(name, String.valueOf(value))); + params.add(new Pair(name, String.valueOf(value))); return params; } else if (valueCollection.isEmpty()) { return params; @@ -263,10 +263,10 @@ public class ApiClient { collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv if (collectionFormat.equals("csv")) { - params.add(new QueryParam(name, parameterToString(value))); + params.add(new Pair(name, parameterToString(value))); } else if (collectionFormat.equals("multi")) { for (String item : valueCollection) { - params.add(new QueryParam(name, item)); + params.add(new Pair(name, item)); } } else if (collectionFormat.equals("ssv")) { StringBuilder sb = new StringBuilder() ; @@ -274,21 +274,21 @@ public class ApiClient { sb.append(" "); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("tsv")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("\t"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("pipes")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("|"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } return params; @@ -397,7 +397,7 @@ public class ApiClient { * @param authNames The authentications to apply * @return The response body in type of string */ - public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { updateParamsForAuth(authNames, queryParams, headerParams); Client client = getClient(); @@ -405,7 +405,7 @@ public class ApiClient { StringBuilder b = new StringBuilder(); b.append("?"); if (queryParams != null){ - for (QueryParam queryParam : queryParams){ + for (Pair queryParam : queryParams){ if (!queryParam.getName().isEmpty()) { b.append(escapeString(queryParam.getName())); b.append("="); @@ -515,7 +515,7 @@ public class ApiClient { * * @param authNames The authentications to apply */ - private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { + private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { for (String authName : authNames) { Authentication auth = authentications.get(authName); if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java b/samples/client/petstore/java/src/main/java/io/swagger/client/Pair.java similarity index 89% rename from samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java rename to samples/client/petstore/java/src/main/java/io/swagger/client/Pair.java index 240352e890f..4b7112f6db6 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/QueryParam.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/Pair.java @@ -1,10 +1,10 @@ package io.swagger.client; -public class QueryParam { +public class Pair { private String name = ""; private String value = ""; - public QueryParam(String name, String value) { + public Pair (String name, String value) { setName(name); setValue(value); } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index 3fc9bd267e4..85d87534175 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -3,7 +3,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiClient; import io.swagger.client.Configuration; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import io.swagger.client.model.*; @@ -55,7 +55,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -112,7 +112,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -169,7 +169,7 @@ public class PetApi { String path = "/pet/findByStatus".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -228,7 +228,7 @@ public class PetApi { String path = "/pet/findByTags".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -293,7 +293,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -358,7 +358,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -436,7 +436,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -503,7 +503,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java index f15b7140a5c..a94a57990c3 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java @@ -3,7 +3,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiClient; import io.swagger.client.Configuration; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import io.swagger.client.model.*; @@ -54,7 +54,7 @@ public class StoreApi { String path = "/store/inventory".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -111,7 +111,7 @@ public class StoreApi { String path = "/store/order".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -174,7 +174,7 @@ public class StoreApi { .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -237,7 +237,7 @@ public class StoreApi { .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java index a0c977c7256..4a3a69fe3e4 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java @@ -3,7 +3,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiClient; import io.swagger.client.Configuration; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import io.swagger.client.model.*; @@ -55,7 +55,7 @@ public class UserApi { String path = "/user".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -112,7 +112,7 @@ public class UserApi { String path = "/user/createWithArray".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -169,7 +169,7 @@ public class UserApi { String path = "/user/createWithList".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -227,7 +227,7 @@ public class UserApi { String path = "/user/login".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -287,7 +287,7 @@ public class UserApi { String path = "/user/logout".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -350,7 +350,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -414,7 +414,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -477,7 +477,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java index d72432ce2e9..edd98a16414 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java @@ -1,6 +1,6 @@ package io.swagger.client.auth; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import java.util.Map; import java.util.Set; @@ -42,7 +42,7 @@ public class ApiKeyAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; @@ -50,7 +50,7 @@ public class ApiKeyAuth implements Authentication { value = apiKey; } if (location == "query") { - queryParams.add(new QueryParam(paramName, value)); + queryParams.add(new Pair(paramName, value)); } else if (location == "header") { headerParams.put(paramName, value); } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java index 4f661852f34..32e61103cd7 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java @@ -1,11 +1,11 @@ package io.swagger.client.auth; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import java.util.Map; import java.util.Set; public interface Authentication { /** Apply authentication settings to header and query params. */ - void applyToParams(Set queryParams, Map headerParams); + void applyToParams(Set queryParams, Map headerParams); } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java index 4beaee8b675..0f2428222ac 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java @@ -1,6 +1,6 @@ package io.swagger.client.auth; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import java.util.Map; import java.util.Set; @@ -29,7 +29,7 @@ public class HttpBasicAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); try { headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"))); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java index b754567564f..e0b8f942b39 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java @@ -1,13 +1,13 @@ package io.swagger.client.auth; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import java.util.Map; import java.util.Set; public class OAuth implements Authentication { @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(Set queryParams, Map headerParams) { // TODO: support oauth } } diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java index e99f310f94f..1f0c150cabb 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java @@ -5,7 +5,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import org.junit.*; import static org.junit.Assert.*; @@ -13,7 +13,7 @@ import static org.junit.Assert.*; public class ApiKeyAuthTest { @Test public void testApplyToParamsInQuery() { - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); ApiKeyAuth auth = new ApiKeyAuth("query", "api_key"); @@ -21,7 +21,7 @@ public class ApiKeyAuthTest { auth.applyToParams(queryParams, headerParams); assertEquals(1, queryParams.size()); - for (QueryParam queryParam : queryParams) { + for (Pair queryParam : queryParams) { assertEquals("my-api-key", queryParam.getValue()); } @@ -31,7 +31,7 @@ public class ApiKeyAuthTest { @Test public void testApplyToParamsInHeaderWithPrefix() { - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); ApiKeyAuth auth = new ApiKeyAuth("header", "X-API-TOKEN"); diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java index 5125abce49b..562daa5ba89 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java @@ -5,7 +5,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import org.junit.*; import static org.junit.Assert.*; @@ -20,7 +20,7 @@ public class HttpBasicAuthTest { @Test public void testApplyToParams() { - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); Map headerParams = new HashMap(); auth.setUsername("my-username"); From a1b56c9b83757b61db0fbf5b7d824e34b94550cf Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Mon, 22 Jun 2015 15:28:29 -0700 Subject: [PATCH 099/499] Renamed QueryParam to Pair class in Android templates. --- .../languages/AndroidClientCodegen.java | 4 ++-- .../{QueryParam.mustache => Pair.mustache} | 4 ++-- .../main/resources/android-java/api.mustache | 4 ++-- .../android-java/apiInvoker.mustache | 22 +++++++++---------- .../java/io/swagger/client/ApiInvoker.java | 22 +++++++++---------- .../client/{QueryParam.java => Pair.java} | 4 ++-- .../java/io/swagger/client/api/PetApi.java | 18 +++++++-------- .../java/io/swagger/client/api/StoreApi.java | 10 ++++----- .../java/io/swagger/client/api/UserApi.java | 18 +++++++-------- 9 files changed, 53 insertions(+), 53 deletions(-) rename modules/swagger-codegen/src/main/resources/android-java/{QueryParam.mustache => Pair.mustache} (89%) rename samples/client/petstore/android-java/src/main/java/io/swagger/client/{QueryParam.java => Pair.java} (89%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java index 2d0af4c6c0b..e65736a63f0 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AndroidClientCodegen.java @@ -232,8 +232,8 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java")); supportingFiles.add(new SupportingFile("apiException.mustache", (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java")); - supportingFiles.add(new SupportingFile("QueryParam.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "QueryParam.java")); + supportingFiles.add(new SupportingFile("Pair.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Pair.java")); } public Boolean getUseAndroidMavenGradlePlugin() { diff --git a/modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache b/modules/swagger-codegen/src/main/resources/android-java/Pair.mustache similarity index 89% rename from modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache rename to modules/swagger-codegen/src/main/resources/android-java/Pair.mustache index 23b1b26f55c..5456028a1a0 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/QueryParam.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/Pair.mustache @@ -1,10 +1,10 @@ package {{invokerPackage}}; -public class QueryParam { +public class Pair { private String name = ""; private String value = ""; - public QueryParam(String name, String value) { + public Pair(String name, String value) { setName(name); setValue(value); } diff --git a/modules/swagger-codegen/src/main/resources/android-java/api.mustache b/modules/swagger-codegen/src/main/resources/android-java/api.mustache index 6e34a898ad0..326f4fbac2c 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/api.mustache @@ -2,7 +2,7 @@ package {{package}}; import {{invokerPackage}}.ApiException; import {{invokerPackage}}.ApiInvoker; -import {{invokerPackage}}.QueryParam; +import {{invokerPackage}}.Pair; import {{modelPackage}}.*; @@ -59,7 +59,7 @@ public class {{classname}} { String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params diff --git a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache index d7a9d8b357c..55d85018500 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache @@ -135,10 +135,10 @@ public class ApiInvoker { } /* - Format to {@code QueryParam} objects. + Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); // preconditions if (name == null || name.isEmpty() || value == null) return params; @@ -149,7 +149,7 @@ public class ApiInvoker { } if (valueCollection == null) { - params.add(new QueryParam(name, String.valueOf(value))); + params.add(new Pair(name, String.valueOf(value))); return params; } else if (valueCollection.isEmpty()) { return params; @@ -158,10 +158,10 @@ public class ApiInvoker { collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv if (collectionFormat.equals("csv")) { - params.add(new QueryParam(name, parameterToString(value))); + params.add(new Pair(name, parameterToString(value))); } else if (collectionFormat.equals("multi")) { for (String item : valueCollection) { - params.add(new QueryParam(name, item)); + params.add(new Pair(name, item)); } } else if (collectionFormat.equals("ssv")) { StringBuilder sb = new StringBuilder() ; @@ -169,21 +169,21 @@ public class ApiInvoker { sb.append(" "); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("tsv")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("\t"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("pipes")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("|"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } return params; @@ -241,13 +241,13 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { HttpClient client = getClient(host); StringBuilder b = new StringBuilder(); b.append("?"); if (queryParams != null){ - for (QueryParam queryParam : queryParams){ + for (Pair queryParam : queryParams){ if (!queryParam.getName().isEmpty()) { b.append(escapeString(queryParam.getName())); b.append("="); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java index 58ecbde38c6..f148a6fcbb7 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java @@ -135,10 +135,10 @@ public class ApiInvoker { } /* - Format to {@code QueryParam} objects. + Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + Set params = new HashSet(); // preconditions if (name == null || name.isEmpty() || value == null) return params; @@ -149,7 +149,7 @@ public class ApiInvoker { } if (valueCollection == null) { - params.add(new QueryParam(name, String.valueOf(value))); + params.add(new Pair(name, String.valueOf(value))); return params; } else if (valueCollection.isEmpty()) { return params; @@ -158,10 +158,10 @@ public class ApiInvoker { collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv if (collectionFormat.equals("csv")) { - params.add(new QueryParam(name, parameterToString(value))); + params.add(new Pair(name, parameterToString(value))); } else if (collectionFormat.equals("multi")) { for (String item : valueCollection) { - params.add(new QueryParam(name, item)); + params.add(new Pair(name, item)); } } else if (collectionFormat.equals("ssv")) { StringBuilder sb = new StringBuilder() ; @@ -169,21 +169,21 @@ public class ApiInvoker { sb.append(" "); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("tsv")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("\t"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } else if (collectionFormat.equals("pipes")) { StringBuilder sb = new StringBuilder() ; for (String item : valueCollection) { sb.append("|"); sb.append(item); } - params.add(new QueryParam(name, sb.substring(1))); + params.add(new Pair(name, sb.substring(1))); } return params; @@ -241,13 +241,13 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { HttpClient client = getClient(host); StringBuilder b = new StringBuilder(); b.append("?"); if (queryParams != null){ - for (QueryParam queryParam : queryParams){ + for (Pair queryParam : queryParams){ if (!queryParam.getName().isEmpty()) { b.append(escapeString(queryParam.getName())); b.append("="); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/Pair.java similarity index 89% rename from samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java rename to samples/client/petstore/android-java/src/main/java/io/swagger/client/Pair.java index 240352e890f..2710fb5a99b 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/QueryParam.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/Pair.java @@ -1,10 +1,10 @@ package io.swagger.client; -public class QueryParam { +public class Pair { private String name = ""; private String value = ""; - public QueryParam(String name, String value) { + public Pair(String name, String value) { setName(name); setValue(value); } diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java index db10c57f112..7b792996535 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java @@ -2,7 +2,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiInvoker; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import io.swagger.client.model.*; @@ -53,7 +53,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -107,7 +107,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -161,7 +161,7 @@ public class PetApi { String path = "/pet/findByStatus".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -217,7 +217,7 @@ public class PetApi { String path = "/pet/findByTags".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -278,7 +278,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -339,7 +339,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -409,7 +409,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -472,7 +472,7 @@ public class PetApi { String path = "/pet/{petId}/uploadImage".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java index e8d50c30df7..e038962ac6e 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java @@ -2,7 +2,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiInvoker; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import io.swagger.client.model.*; @@ -52,7 +52,7 @@ public class StoreApi { String path = "/store/inventory".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -106,7 +106,7 @@ public class StoreApi { String path = "/store/order".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -165,7 +165,7 @@ public class StoreApi { String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -224,7 +224,7 @@ public class StoreApi { String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java index d7505874940..3b74f343299 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java @@ -2,7 +2,7 @@ package io.swagger.client.api; import io.swagger.client.ApiException; import io.swagger.client.ApiInvoker; -import io.swagger.client.QueryParam; +import io.swagger.client.Pair; import io.swagger.client.model.*; @@ -53,7 +53,7 @@ public class UserApi { String path = "/user".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -107,7 +107,7 @@ public class UserApi { String path = "/user/createWithArray".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -161,7 +161,7 @@ public class UserApi { String path = "/user/createWithList".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -216,7 +216,7 @@ public class UserApi { String path = "/user/login".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -273,7 +273,7 @@ public class UserApi { String path = "/user/logout".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -332,7 +332,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -392,7 +392,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params @@ -451,7 +451,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + Set queryParams = new HashSet(); // header params Map headerParams = new HashMap(); // form params From 79a5614be9a8fb7928feca37bc8960e6f6dc60dd Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Mon, 22 Jun 2015 15:55:29 -0700 Subject: [PATCH 100/499] Invalid strings will be passed as blank query param. --- .../src/main/resources/Java/ApiClient.mustache | 7 ++++++- .../src/main/resources/android-java/apiInvoker.mustache | 7 ++++++- .../src/main/java/io/swagger/client/ApiInvoker.java | 7 ++++++- .../java/src/main/java/io/swagger/client/ApiClient.java | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index 888f407a412..9392277b52c 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -247,7 +247,12 @@ public class ApiClient { Set params = new HashSet(); // preconditions - if (name == null || name.isEmpty() || value == null) return params; + if (name == null || name.isEmpty()) return params; + + if (value == null) { + params.add(new Pair(name, value)); + return params; + } Collection valueCollection = null; if (value instanceof Collection) { diff --git a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache index 55d85018500..61baf88e8ea 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache @@ -141,7 +141,12 @@ public class ApiInvoker { Set params = new HashSet(); // preconditions - if (name == null || name.isEmpty() || value == null) return params; + if (name == null || name.isEmpty()) return params; + + if (value == null) { + params.add(new Pair(name, value)); + return params; + } Collection valueCollection = null; if (value instanceof Collection) { diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java index f148a6fcbb7..73dc1ddc65b 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java @@ -141,7 +141,12 @@ public class ApiInvoker { Set params = new HashSet(); // preconditions - if (name == null || name.isEmpty() || value == null) return params; + if (name == null || name.isEmpty()) return params; + + if (value == null) { + params.add(new Pair(name, value)); + return params; + } Collection valueCollection = null; if (value instanceof Collection) { diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index 441e5cc1f3c..cd801e0d763 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -246,7 +246,12 @@ public class ApiClient { Set params = new HashSet(); // preconditions - if (name == null || name.isEmpty() || value == null) return params; + if (name == null || name.isEmpty()) return params; + + if (value == null) { + params.add(new Pair(name, value)); + return params; + } Collection valueCollection = null; if (value instanceof Collection) { From 32b50e7c8e0202f9dbefadcee3fdd01ec8fdf516 Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Mon, 22 Jun 2015 17:02:00 -0700 Subject: [PATCH 101/499] Refactored parameterToPairs --- .../main/resources/Java/ApiClient.mustache | 73 ++++++++++--------- .../src/main/resources/Java/api.mustache | 2 +- .../main/resources/android-java/api.mustache | 2 +- .../android-java/apiInvoker.mustache | 73 ++++++++++--------- .../java/io/swagger/client/ApiInvoker.java | 73 ++++++++++--------- .../java/io/swagger/client/api/PetApi.java | 4 +- .../java/io/swagger/client/api/UserApi.java | 4 +- .../java/io/swagger/client/ApiClient.java | 73 ++++++++++--------- .../java/io/swagger/client/api/PetApi.java | 4 +- .../java/io/swagger/client/api/UserApi.java | 4 +- 10 files changed, 158 insertions(+), 154 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index 9392277b52c..bfa33ac0764 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -243,60 +243,61 @@ public class ApiClient { /* Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + public Set parameterToPairs(String collectionFormat, String name, Object value){ Set params = new HashSet(); // preconditions if (name == null || name.isEmpty()) return params; if (value == null) { - params.add(new Pair(name, value)); + params.add(new Pair(name, "")); return params; } - Collection valueCollection = null; + Collection valueCollection = null; if (value instanceof Collection) { - valueCollection = (Collection) value; - } - - if (valueCollection == null) { - params.add(new Pair(name, String.valueOf(value))); - return params; - } else if (valueCollection.isEmpty()) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); return params; } + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv - if (collectionFormat.equals("csv")) { - params.add(new Pair(name, parameterToString(value))); - } else if (collectionFormat.equals("multi")) { - for (String item : valueCollection) { - params.add(new Pair(name, item)); + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); } - } else if (collectionFormat.equals("ssv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append(" "); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("tsv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("\t"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("pipes")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("|"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); + + return params; } + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + return params; } diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache index 8d8709da186..c279e4d223e 100644 --- a/modules/swagger-codegen/src/main/resources/Java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache @@ -67,7 +67,7 @@ public class {{classname}} { Map formParams = new HashMap(); {{#queryParams}} - queryParams.addAll(apiClient.parameterToQueryParams("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); + queryParams.addAll(apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); {{/queryParams}} {{#headerParams}}if ({{paramName}} != null) diff --git a/modules/swagger-codegen/src/main/resources/android-java/api.mustache b/modules/swagger-codegen/src/main/resources/android-java/api.mustache index 326f4fbac2c..5113116deb8 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/api.mustache @@ -66,7 +66,7 @@ public class {{classname}} { Map formParams = new HashMap(); {{#queryParams}} - queryParams.addAll(ApiInvoker.parameterToQueryParams("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); + queryParams.addAll(ApiInvoker.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); {{/queryParams}} {{#headerParams}} diff --git a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache index 61baf88e8ea..c3bc2cd39c9 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache @@ -137,60 +137,61 @@ public class ApiInvoker { /* Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + public static Set parameterToPairs(String collectionFormat, String name, Object value){ Set params = new HashSet(); // preconditions if (name == null || name.isEmpty()) return params; if (value == null) { - params.add(new Pair(name, value)); + params.add(new Pair(name, "")); return params; } - Collection valueCollection = null; + Collection valueCollection = null; if (value instanceof Collection) { - valueCollection = (Collection) value; - } - - if (valueCollection == null) { - params.add(new Pair(name, String.valueOf(value))); - return params; - } else if (valueCollection.isEmpty()) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); return params; } + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv - if (collectionFormat.equals("csv")) { - params.add(new Pair(name, parameterToString(value))); - } else if (collectionFormat.equals("multi")) { - for (String item : valueCollection) { - params.add(new Pair(name, item)); + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); } - } else if (collectionFormat.equals("ssv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append(" "); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("tsv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("\t"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("pipes")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("|"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); + + return params; } + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + return params; } diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java index 73dc1ddc65b..f831a54c14b 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java @@ -137,60 +137,61 @@ public class ApiInvoker { /* Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + public static Set parameterToPairs(String collectionFormat, String name, Object value){ Set params = new HashSet(); // preconditions if (name == null || name.isEmpty()) return params; if (value == null) { - params.add(new Pair(name, value)); + params.add(new Pair(name, "")); return params; } - Collection valueCollection = null; + Collection valueCollection = null; if (value instanceof Collection) { - valueCollection = (Collection) value; - } - - if (valueCollection == null) { - params.add(new Pair(name, String.valueOf(value))); - return params; - } else if (valueCollection.isEmpty()) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); return params; } + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv - if (collectionFormat.equals("csv")) { - params.add(new Pair(name, parameterToString(value))); - } else if (collectionFormat.equals("multi")) { - for (String item : valueCollection) { - params.add(new Pair(name, item)); + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); } - } else if (collectionFormat.equals("ssv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append(" "); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("tsv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("\t"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("pipes")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("|"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); + + return params; } + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + return params; } diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java index 7b792996535..8580512c742 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java @@ -168,7 +168,7 @@ public class PetApi { Map formParams = new HashMap(); - queryParams.addAll(ApiInvoker.parameterToQueryParams("multi", "status", status)); + queryParams.addAll(ApiInvoker.parameterToPairs("multi", "status", status)); @@ -224,7 +224,7 @@ public class PetApi { Map formParams = new HashMap(); - queryParams.addAll(ApiInvoker.parameterToQueryParams("multi", "tags", tags)); + queryParams.addAll(ApiInvoker.parameterToPairs("multi", "tags", tags)); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java index 3b74f343299..f8096cb2a87 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java @@ -223,9 +223,9 @@ public class UserApi { Map formParams = new HashMap(); - queryParams.addAll(ApiInvoker.parameterToQueryParams("", "username", username)); + queryParams.addAll(ApiInvoker.parameterToPairs("", "username", username)); - queryParams.addAll(ApiInvoker.parameterToQueryParams("", "password", password)); + queryParams.addAll(ApiInvoker.parameterToPairs("", "password", password)); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index cd801e0d763..b0258026896 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -242,60 +242,61 @@ public class ApiClient { /* Format to {@code Pair} objects. */ - public Set parameterToQueryParams(String collectionFormat, String name, Object value){ + public Set parameterToPairs(String collectionFormat, String name, Object value){ Set params = new HashSet(); // preconditions if (name == null || name.isEmpty()) return params; if (value == null) { - params.add(new Pair(name, value)); + params.add(new Pair(name, "")); return params; } - Collection valueCollection = null; + Collection valueCollection = null; if (value instanceof Collection) { - valueCollection = (Collection) value; - } - - if (valueCollection == null) { - params.add(new Pair(name, String.valueOf(value))); - return params; - } else if (valueCollection.isEmpty()) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); return params; } + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv - if (collectionFormat.equals("csv")) { - params.add(new Pair(name, parameterToString(value))); - } else if (collectionFormat.equals("multi")) { - for (String item : valueCollection) { - params.add(new Pair(name, item)); + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); } - } else if (collectionFormat.equals("ssv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append(" "); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("tsv")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("\t"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); - } else if (collectionFormat.equals("pipes")) { - StringBuilder sb = new StringBuilder() ; - for (String item : valueCollection) { - sb.append("|"); - sb.append(item); - } - params.add(new Pair(name, sb.substring(1))); + + return params; } + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + return params; } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index 85d87534175..922084ec48f 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -174,7 +174,7 @@ public class PetApi { Map formParams = new HashMap(); - queryParams.addAll(apiClient.parameterToQueryParams("multi", "status", status)); + queryParams.addAll(apiClient.parameterToPairs("multi", "status", status)); @@ -233,7 +233,7 @@ public class PetApi { Map formParams = new HashMap(); - queryParams.addAll(apiClient.parameterToQueryParams("multi", "tags", tags)); + queryParams.addAll(apiClient.parameterToPairs("multi", "tags", tags)); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java index 4a3a69fe3e4..a8e2fa37a85 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java @@ -232,9 +232,9 @@ public class UserApi { Map formParams = new HashMap(); - queryParams.addAll(apiClient.parameterToQueryParams("", "username", username)); + queryParams.addAll(apiClient.parameterToPairs("", "username", username)); - queryParams.addAll(apiClient.parameterToQueryParams("", "password", password)); + queryParams.addAll(apiClient.parameterToPairs("", "password", password)); From 6958db3d3de9fa905be72f3193631ba31e1d74e9 Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Mon, 22 Jun 2015 17:14:18 -0700 Subject: [PATCH 102/499] Refactored Pairs to use List instead of Set. --- .../src/main/resources/Java/ApiClient.mustache | 11 +++++------ .../src/main/resources/Java/api.mustache | 2 +- .../main/resources/Java/auth/ApiKeyAuth.mustache | 4 ++-- .../resources/Java/auth/Authentication.mustache | 4 ++-- .../resources/Java/auth/HttpBasicAuth.mustache | 4 ++-- .../src/main/resources/Java/auth/OAuth.mustache | 4 ++-- .../src/main/resources/android-java/api.mustache | 2 +- .../resources/android-java/apiInvoker.mustache | 9 ++++----- .../main/java/io/swagger/client/ApiInvoker.java | 9 ++++----- .../main/java/io/swagger/client/api/PetApi.java | 16 ++++++++-------- .../java/io/swagger/client/api/StoreApi.java | 8 ++++---- .../main/java/io/swagger/client/api/UserApi.java | 16 ++++++++-------- .../main/java/io/swagger/client/ApiClient.java | 11 +++++------ .../main/java/io/swagger/client/api/PetApi.java | 16 ++++++++-------- .../java/io/swagger/client/api/StoreApi.java | 8 ++++---- .../main/java/io/swagger/client/api/UserApi.java | 16 ++++++++-------- .../java/io/swagger/client/auth/ApiKeyAuth.java | 4 ++-- .../io/swagger/client/auth/Authentication.java | 4 ++-- .../io/swagger/client/auth/HttpBasicAuth.java | 4 ++-- .../main/java/io/swagger/client/auth/OAuth.java | 4 ++-- .../io/swagger/client/auth/ApiKeyAuthTest.java | 8 ++++---- .../swagger/client/auth/HttpBasicAuthTest.java | 6 +++--- 22 files changed, 83 insertions(+), 87 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index bfa33ac0764..d8c48e93b10 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -22,8 +22,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; -import java.util.Set; -import java.util.HashSet; +import java.util.ArrayList; import java.util.Date; import java.util.TimeZone; @@ -243,8 +242,8 @@ public class ApiClient { /* Format to {@code Pair} objects. */ - public Set parameterToPairs(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); // preconditions if (name == null || name.isEmpty()) return params; @@ -404,7 +403,7 @@ public class ApiClient { * @param authNames The authentications to apply * @return The response body in type of string */ - public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + public String invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { updateParamsForAuth(authNames, queryParams, headerParams); Client client = getClient(); @@ -522,7 +521,7 @@ public class ApiClient { * * @param authNames The authentications to apply */ - private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { for (String authName : authNames) { Authentication auth = authentications.get(authName); if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache index c279e4d223e..afb28293cad 100644 --- a/modules/swagger-codegen/src/main/resources/Java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache @@ -62,7 +62,7 @@ public class {{classname}} { .replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache index aefbe453efd..a1824b551ca 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/ApiKeyAuth.mustache @@ -3,7 +3,7 @@ package {{invokerPackage}}.auth; import {{invokerPackage}}.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; public class ApiKeyAuth implements Authentication { private final String location; @@ -42,7 +42,7 @@ public class ApiKeyAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(List queryParams, Map headerParams) { String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache index 9e0b328915c..265c74cb76f 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/Authentication.mustache @@ -3,9 +3,9 @@ package {{invokerPackage}}.auth; import {{invokerPackage}}.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; public interface Authentication { /** Apply authentication settings to header and query params. */ - void applyToParams(Set queryParams, Map headerParams); + void applyToParams(List queryParams, Map headerParams); } diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache index 73c52d96ff1..032ea57d4e8 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/HttpBasicAuth.mustache @@ -3,7 +3,7 @@ package {{invokerPackage}}.auth; import {{invokerPackage}}.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; import java.io.UnsupportedEncodingException; import javax.xml.bind.DatatypeConverter; @@ -29,7 +29,7 @@ public class HttpBasicAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(List queryParams, Map headerParams) { String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); try { headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"))); diff --git a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache index 4de2fbed905..66cf2ac8f0f 100644 --- a/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/auth/OAuth.mustache @@ -3,11 +3,11 @@ package {{invokerPackage}}.auth; import {{invokerPackage}}.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; public class OAuth implements Authentication { @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(List queryParams, Map headerParams) { // TODO: support oauth } } diff --git a/modules/swagger-codegen/src/main/resources/android-java/api.mustache b/modules/swagger-codegen/src/main/resources/android-java/api.mustache index 5113116deb8..9f341301cf0 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/api.mustache @@ -59,7 +59,7 @@ public class {{classname}} { String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params diff --git a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache index c3bc2cd39c9..3aeb9b8505d 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache @@ -23,8 +23,7 @@ import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.List; -import java.util.Set; -import java.util.HashSet; +import java.util.ArrayList; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -137,8 +136,8 @@ public class ApiInvoker { /* Format to {@code Pair} objects. */ - public static Set parameterToPairs(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public static List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); // preconditions if (name == null || name.isEmpty()) return params; @@ -247,7 +246,7 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + public String invokeAPI(String host, String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { HttpClient client = getClient(host); StringBuilder b = new StringBuilder(); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java index f831a54c14b..c55e127cddf 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java @@ -23,8 +23,7 @@ import java.util.Collection; import java.util.Map; import java.util.HashMap; import java.util.List; -import java.util.Set; -import java.util.HashSet; +import java.util.ArrayList; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -137,8 +136,8 @@ public class ApiInvoker { /* Format to {@code Pair} objects. */ - public static Set parameterToPairs(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public static List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); // preconditions if (name == null || name.isEmpty()) return params; @@ -247,7 +246,7 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + public String invokeAPI(String host, String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { HttpClient client = getClient(host); StringBuilder b = new StringBuilder(); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java index 8580512c742..21ee69d089b 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/PetApi.java @@ -53,7 +53,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -107,7 +107,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -161,7 +161,7 @@ public class PetApi { String path = "/pet/findByStatus".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -217,7 +217,7 @@ public class PetApi { String path = "/pet/findByTags".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -278,7 +278,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -339,7 +339,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -409,7 +409,7 @@ public class PetApi { String path = "/pet/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -472,7 +472,7 @@ public class PetApi { String path = "/pet/{petId}/uploadImage".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java index e038962ac6e..49a3ac4aa9a 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/StoreApi.java @@ -52,7 +52,7 @@ public class StoreApi { String path = "/store/inventory".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -106,7 +106,7 @@ public class StoreApi { String path = "/store/order".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -165,7 +165,7 @@ public class StoreApi { String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -224,7 +224,7 @@ public class StoreApi { String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java index f8096cb2a87..a16a745c7f8 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/api/UserApi.java @@ -53,7 +53,7 @@ public class UserApi { String path = "/user".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -107,7 +107,7 @@ public class UserApi { String path = "/user/createWithArray".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -161,7 +161,7 @@ public class UserApi { String path = "/user/createWithList".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -216,7 +216,7 @@ public class UserApi { String path = "/user/login".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -273,7 +273,7 @@ public class UserApi { String path = "/user/logout".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -332,7 +332,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -392,7 +392,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params @@ -451,7 +451,7 @@ public class UserApi { String path = "/user/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); // header params Map headerParams = new HashMap(); // form params diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index b0258026896..4d50ab3ce84 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -22,8 +22,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; -import java.util.Set; -import java.util.HashSet; +import java.util.ArrayList; import java.util.Date; import java.util.TimeZone; @@ -242,8 +241,8 @@ public class ApiClient { /* Format to {@code Pair} objects. */ - public Set parameterToPairs(String collectionFormat, String name, Object value){ - Set params = new HashSet(); + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); // preconditions if (name == null || name.isEmpty()) return params; @@ -403,7 +402,7 @@ public class ApiClient { * @param authNames The authentications to apply * @return The response body in type of string */ - public String invokeAPI(String path, String method, Set queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + public String invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { updateParamsForAuth(authNames, queryParams, headerParams); Client client = getClient(); @@ -521,7 +520,7 @@ public class ApiClient { * * @param authNames The authentications to apply */ - private void updateParamsForAuth(String[] authNames, Set queryParams, Map headerParams) { + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { for (String authName : authNames) { Authentication auth = authentications.get(authName); if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index 922084ec48f..402fc9da953 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -55,7 +55,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -112,7 +112,7 @@ public class PetApi { String path = "/pet".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -169,7 +169,7 @@ public class PetApi { String path = "/pet/findByStatus".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -228,7 +228,7 @@ public class PetApi { String path = "/pet/findByTags".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -293,7 +293,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -358,7 +358,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -436,7 +436,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -503,7 +503,7 @@ public class PetApi { .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java index a94a57990c3..498b6d4a6b8 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java @@ -54,7 +54,7 @@ public class StoreApi { String path = "/store/inventory".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -111,7 +111,7 @@ public class StoreApi { String path = "/store/order".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -174,7 +174,7 @@ public class StoreApi { .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -237,7 +237,7 @@ public class StoreApi { .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java index a8e2fa37a85..3bff204ac02 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java @@ -55,7 +55,7 @@ public class UserApi { String path = "/user".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -112,7 +112,7 @@ public class UserApi { String path = "/user/createWithArray".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -169,7 +169,7 @@ public class UserApi { String path = "/user/createWithList".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -227,7 +227,7 @@ public class UserApi { String path = "/user/login".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -287,7 +287,7 @@ public class UserApi { String path = "/user/logout".replaceAll("\\{format\\}","json"); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -350,7 +350,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -414,7 +414,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); @@ -477,7 +477,7 @@ public class UserApi { .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); Map formParams = new HashMap(); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java index edd98a16414..0e5ca9c7c53 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/ApiKeyAuth.java @@ -3,7 +3,7 @@ package io.swagger.client.auth; import io.swagger.client.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; public class ApiKeyAuth implements Authentication { private final String location; @@ -42,7 +42,7 @@ public class ApiKeyAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(List queryParams, Map headerParams) { String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java index 32e61103cd7..98b1a6900b9 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/Authentication.java @@ -3,9 +3,9 @@ package io.swagger.client.auth; import io.swagger.client.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; public interface Authentication { /** Apply authentication settings to header and query params. */ - void applyToParams(Set queryParams, Map headerParams); + void applyToParams(List queryParams, Map headerParams); } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java index 0f2428222ac..980b24311be 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/HttpBasicAuth.java @@ -3,7 +3,7 @@ package io.swagger.client.auth; import io.swagger.client.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; import java.io.UnsupportedEncodingException; import javax.xml.bind.DatatypeConverter; @@ -29,7 +29,7 @@ public class HttpBasicAuth implements Authentication { } @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(List queryParams, Map headerParams) { String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); try { headerParams.put("Authorization", "Basic " + DatatypeConverter.printBase64Binary(str.getBytes("UTF-8"))); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java index e0b8f942b39..39fba5498c0 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/auth/OAuth.java @@ -3,11 +3,11 @@ package io.swagger.client.auth; import io.swagger.client.Pair; import java.util.Map; -import java.util.Set; +import java.util.List; public class OAuth implements Authentication { @Override - public void applyToParams(Set queryParams, Map headerParams) { + public void applyToParams(List queryParams, Map headerParams) { // TODO: support oauth } } diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java index 1f0c150cabb..5bdb4fb78fb 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/ApiKeyAuthTest.java @@ -1,9 +1,9 @@ package io.swagger.client.auth; import java.util.HashMap; -import java.util.HashSet; +import java.util.ArrayList; import java.util.Map; -import java.util.Set; +import java.util.List; import io.swagger.client.Pair; import org.junit.*; @@ -13,7 +13,7 @@ import static org.junit.Assert.*; public class ApiKeyAuthTest { @Test public void testApplyToParamsInQuery() { - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); ApiKeyAuth auth = new ApiKeyAuth("query", "api_key"); @@ -31,7 +31,7 @@ public class ApiKeyAuthTest { @Test public void testApplyToParamsInHeaderWithPrefix() { - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); ApiKeyAuth auth = new ApiKeyAuth("header", "X-API-TOKEN"); diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java index 562daa5ba89..52c5497ba83 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/auth/HttpBasicAuthTest.java @@ -1,9 +1,9 @@ package io.swagger.client.auth; import java.util.HashMap; -import java.util.HashSet; +import java.util.ArrayList; import java.util.Map; -import java.util.Set; +import java.util.List; import io.swagger.client.Pair; import org.junit.*; @@ -20,7 +20,7 @@ public class HttpBasicAuthTest { @Test public void testApplyToParams() { - Set queryParams = new HashSet(); + List queryParams = new ArrayList(); Map headerParams = new HashMap(); auth.setUsername("my-username"); From 229ea9362760ce23d26f2891a29d70b68614c70f Mon Sep 17 00:00:00 2001 From: xhh Date: Sat, 20 Jun 2015 12:16:53 +0800 Subject: [PATCH 103/499] Add debugging switch to Ruby generator --- .../src/main/resources/ruby/swagger.mustache | 6 +---- .../ruby/swagger/configuration.mustache | 12 +++++++++- .../resources/ruby/swagger/request.mustache | 23 ++++++++++++------- samples/client/petstore/ruby/README.md | 4 +++- .../ruby/lib/swagger_client/swagger.rb | 6 +---- .../swagger_client/swagger/configuration.rb | 12 +++++++++- .../lib/swagger_client/swagger/request.rb | 23 ++++++++++++------- 7 files changed, 57 insertions(+), 29 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index 239e3cfac26..21c4e8cd04e 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -1,6 +1,3 @@ -require 'logger' -require 'json' - module {{moduleName}} module Swagger class << self @@ -25,8 +22,7 @@ module {{moduleName}} def configure yield(configuration) if block_given? - # Configure logger. Default to use Rails - self.logger ||= configuration.logger || (defined?(Rails) ? Rails.logger : Logger.new(STDOUT)) + self.logger = configuration.logger # remove :// from scheme configuration.scheme.sub!(/:\/\//, '') diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index e9a8af9c162..485bcb3cf81 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -1,7 +1,11 @@ +require 'logger' + module {{moduleName}} module Swagger class Configuration - attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, + :scheme, :host, :base_path, :user_agent, :debug, :logger, :inject_format, + :force_ending_format, :camelize_params, :user_agent, :verify_ssl # Defaults go in here.. def initialize @@ -23,6 +27,12 @@ module {{moduleName}} # Note: do NOT set it to false in production code, otherwise you would # face multiple types of cryptographic attacks @verify_ssl = true + + # whether to enable debugging + @debug = false + + # configure logger, default to logger of Rails (if in Rails) or STDOUT + @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT) end end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 99b58d58be8..70eb319ed95 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -125,12 +125,17 @@ module {{moduleName}} data.each do |key, value| data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter end - data elsif @body # http body is JSON - @body.is_a?(String) ? @body : @body.to_json + data = @body.is_a?(String) ? @body : @body.to_json else - nil + data = nil end + + if Swagger.configuration.debug + Swagger.logger.debug "HTTP request body param ~BEGIN~\n#{data}\n~END~\n" + end + + data end # Construct a query string from the query-string-type params @@ -159,13 +164,10 @@ module {{moduleName}} end def make - #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 + :headers => self.headers.stringify_keys, + :verbose => Swagger.configuration.debug } response = case self.http_method.to_sym when :get,:GET @@ -198,6 +200,11 @@ module {{moduleName}} request_options.merge(:body => self.outgoing_body) ) end + + if Swagger.configuration.debug + Swagger.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" + end + Response.new(response) end diff --git a/samples/client/petstore/ruby/README.md b/samples/client/petstore/ruby/README.md index 2a15c1661cc..06ba93a5abc 100644 --- a/samples/client/petstore/ruby/README.md +++ b/samples/client/petstore/ruby/README.md @@ -43,9 +43,11 @@ ruby -Ilib script.rb require 'swagger_client' SwaggerClient::Swagger.configure do |config| - config.api_key = 'special-key' + config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' + # enable debugging (default is false) + config.debug = true end ``` diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index 477ec89ba81..e6c1ca51096 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -1,6 +1,3 @@ -require 'logger' -require 'json' - module SwaggerClient module Swagger class << self @@ -25,8 +22,7 @@ module SwaggerClient def configure yield(configuration) if block_given? - # Configure logger. Default to use Rails - self.logger ||= configuration.logger || (defined?(Rails) ? Rails.logger : Logger.new(STDOUT)) + self.logger = configuration.logger # remove :// from scheme configuration.scheme.sub!(/:\/\//, '') diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index a2d4fe0e291..b4d8b33d90d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -1,7 +1,11 @@ +require 'logger' + module SwaggerClient module Swagger class Configuration - attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, + :scheme, :host, :base_path, :user_agent, :debug, :logger, :inject_format, + :force_ending_format, :camelize_params, :user_agent, :verify_ssl # Defaults go in here.. def initialize @@ -23,6 +27,12 @@ module SwaggerClient # Note: do NOT set it to false in production code, otherwise you would # face multiple types of cryptographic attacks @verify_ssl = true + + # whether to enable debugging + @debug = false + + # configure logger, default to logger of Rails (if in Rails) or STDOUT + @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT) end end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index 4cd5d84b0b9..2e669df60cb 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -124,12 +124,17 @@ module SwaggerClient data.each do |key, value| data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter end - data elsif @body # http body is JSON - @body.is_a?(String) ? @body : @body.to_json + data = @body.is_a?(String) ? @body : @body.to_json else - nil + data = nil end + + if Swagger.configuration.debug + Swagger.logger.debug "HTTP request body param ~BEGIN~\n#{data}\n~END~\n" + end + + data end # Construct a query string from the query-string-type params @@ -158,13 +163,10 @@ module SwaggerClient end def make - #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 + :headers => self.headers.stringify_keys, + :verbose => Swagger.configuration.debug } response = case self.http_method.to_sym when :get,:GET @@ -197,6 +199,11 @@ module SwaggerClient request_options.merge(:body => self.outgoing_body) ) end + + if Swagger.configuration.debug + Swagger.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" + end + Response.new(response) end From da14c9e6927ec78006e5c40c161f88a9706816f3 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 19:09:32 -0700 Subject: [PATCH 104/499] changing to invokerPackage --- .../src/main/resources/php/ApiClientConfiguration.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache index 84b901f84e9..491f5a45dd8 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace {{invokerNamespace}}; +namespace {{invokerPackage}}; class ApiClientConfiguration { From 3b6a3b4a38aba47e7bf9a3d7a8f2e80753c15d02 Mon Sep 17 00:00:00 2001 From: xhh Date: Sat, 20 Jun 2015 12:52:33 +0800 Subject: [PATCH 105/499] Add logging for API call entry and result --- .../src/main/resources/ruby/api.mustache | 12 +++- .../ruby/lib/swagger_client/api/pet_api.rb | 67 ++++++++++++++++--- .../ruby/lib/swagger_client/api/store_api.rb | 35 ++++++++-- .../ruby/lib/swagger_client/api/user_api.rb | 66 +++++++++++++++--- 4 files changed, 159 insertions(+), 21 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index 531f8710e69..af87882fbe1 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -14,6 +14,9 @@ module {{moduleName}} {{#allParams}}{{^required}} # @option opts [{{{dataType}}}] :{{paramName}} {{description}} {{/required}}{{/allParams}} # @return [{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}nil{{/returnType}}] def self.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: {{classname}}#{{nickname}} ..." + end {{#allParams}}{{#required}} # verify the required parameter '{{paramName}}' is set raise "Missing the required parameter '{{paramName}}' when calling {{nickname}}" if {{{paramName}}}.nil? @@ -52,7 +55,14 @@ module {{moduleName}} auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('{{{returnType}}}'){{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + result = response.deserialize('{{{returnType}}}') + if Swagger.configuration.debug + Swagger.logger.debug "API called: {{classname}}#{{nickname}}. Result: #{result.inspect}" + end + result{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: {{classname}}#{{nickname}}" + end nil{{/returnType}} end {{/operation}} diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 4a421faef86..8ec023a6f77 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -11,6 +11,9 @@ module SwaggerClient # @option opts [Pet] :body Pet object that needs to be added to the store # @return [nil] def self.update_pet(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#update_pet ..." + end # resource path @@ -38,7 +41,10 @@ module SwaggerClient auth_names = ['petstore_auth'] - Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:PUT, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#update_pet" + end nil end @@ -48,6 +54,9 @@ module SwaggerClient # @option opts [Pet] :body Pet object that needs to be added to the store # @return [nil] def self.add_pet(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#add_pet ..." + end # resource path @@ -75,7 +84,10 @@ module SwaggerClient auth_names = ['petstore_auth'] - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#add_pet" + end nil end @@ -85,6 +97,9 @@ module SwaggerClient # @option opts [Array] :status Status values that need to be considered for filter # @return [Array] def self.find_pets_by_status(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#find_pets_by_status ..." + end # resource path @@ -114,7 +129,11 @@ module SwaggerClient auth_names = ['petstore_auth'] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('Array') + result = response.deserialize('Array') + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#find_pets_by_status. Result: #{result.inspect}" + end + result end # Finds Pets by tags @@ -123,6 +142,9 @@ module SwaggerClient # @option opts [Array] :tags Tags to filter by # @return [Array] def self.find_pets_by_tags(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#find_pets_by_tags ..." + end # resource path @@ -152,7 +174,11 @@ module SwaggerClient auth_names = ['petstore_auth'] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('Array') + result = response.deserialize('Array') + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#find_pets_by_tags. Result: #{result.inspect}" + end + result end # Find pet by ID @@ -161,6 +187,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [Pet] def self.get_pet_by_id(pet_id, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#get_pet_by_id ..." + end # verify the required parameter 'pet_id' is set raise "Missing the required parameter 'pet_id' when calling get_pet_by_id" if pet_id.nil? @@ -192,7 +221,11 @@ module SwaggerClient auth_names = ['api_key', 'petstore_auth'] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('Pet') + result = response.deserialize('Pet') + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#get_pet_by_id. Result: #{result.inspect}" + end + result end # Updates a pet in the store with form data @@ -203,6 +236,9 @@ module SwaggerClient # @option opts [String] :status Updated status of the pet # @return [nil] def self.update_pet_with_form(pet_id, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#update_pet_with_form ..." + end # verify the required parameter 'pet_id' is set raise "Missing the required parameter 'pet_id' when calling update_pet_with_form" if pet_id.nil? @@ -235,7 +271,10 @@ module SwaggerClient auth_names = ['petstore_auth'] - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#update_pet_with_form" + end nil end @@ -246,6 +285,9 @@ module SwaggerClient # @option opts [String] :api_key # @return [nil] def self.delete_pet(pet_id, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#delete_pet ..." + end # verify the required parameter 'pet_id' is set raise "Missing the required parameter 'pet_id' when calling delete_pet" if pet_id.nil? @@ -277,7 +319,10 @@ module SwaggerClient auth_names = ['petstore_auth'] - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:DELETE, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#delete_pet" + end nil end @@ -289,6 +334,9 @@ module SwaggerClient # @option opts [file] :file file to upload # @return [nil] def self.upload_file(pet_id, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: PetApi#upload_file ..." + end # verify the required parameter 'pet_id' is set raise "Missing the required parameter 'pet_id' when calling upload_file" if pet_id.nil? @@ -321,7 +369,10 @@ module SwaggerClient auth_names = ['petstore_auth'] - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: PetApi#upload_file" + end nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb index a97f981f878..7581c4d36d6 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb @@ -10,6 +10,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [Hash] def self.get_inventory(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: StoreApi#get_inventory ..." + end # resource path @@ -38,7 +41,11 @@ module SwaggerClient auth_names = ['api_key'] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('Hash') + result = response.deserialize('Hash') + if Swagger.configuration.debug + Swagger.logger.debug "API called: StoreApi#get_inventory. Result: #{result.inspect}" + end + result end # Place an order for a pet @@ -47,6 +54,9 @@ module SwaggerClient # @option opts [Order] :body order placed for purchasing the pet # @return [Order] def self.place_order(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: StoreApi#place_order ..." + end # resource path @@ -75,7 +85,11 @@ module SwaggerClient auth_names = [] response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('Order') + result = response.deserialize('Order') + if Swagger.configuration.debug + Swagger.logger.debug "API called: StoreApi#place_order. Result: #{result.inspect}" + end + result end # Find purchase order by ID @@ -84,6 +98,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [Order] def self.get_order_by_id(order_id, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: StoreApi#get_order_by_id ..." + end # verify the required parameter 'order_id' is set raise "Missing the required parameter 'order_id' when calling get_order_by_id" if order_id.nil? @@ -115,7 +132,11 @@ module SwaggerClient auth_names = [] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('Order') + result = response.deserialize('Order') + if Swagger.configuration.debug + Swagger.logger.debug "API called: StoreApi#get_order_by_id. Result: #{result.inspect}" + end + result end # Delete purchase order by ID @@ -124,6 +145,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [nil] def self.delete_order(order_id, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: StoreApi#delete_order ..." + end # verify the required parameter 'order_id' is set raise "Missing the required parameter 'order_id' when calling delete_order" if order_id.nil? @@ -154,7 +178,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:DELETE, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: StoreApi#delete_order" + end nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb index 8337a8b9dd0..48407491fba 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb @@ -11,6 +11,9 @@ module SwaggerClient # @option opts [User] :body Created user object # @return [nil] def self.create_user(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#create_user ..." + end # resource path @@ -38,7 +41,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#create_user" + end nil end @@ -48,6 +54,9 @@ module SwaggerClient # @option opts [Array] :body List of user object # @return [nil] def self.create_users_with_array_input(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#create_users_with_array_input ..." + end # resource path @@ -75,7 +84,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#create_users_with_array_input" + end nil end @@ -85,6 +97,9 @@ module SwaggerClient # @option opts [Array] :body List of user object # @return [nil] def self.create_users_with_list_input(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#create_users_with_list_input ..." + end # resource path @@ -112,7 +127,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#create_users_with_list_input" + end nil end @@ -123,6 +141,9 @@ module SwaggerClient # @option opts [String] :password The password for login in clear text # @return [String] def self.login_user(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#login_user ..." + end # resource path @@ -153,7 +174,11 @@ module SwaggerClient auth_names = [] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('String') + result = response.deserialize('String') + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#login_user. Result: #{result.inspect}" + end + result end # Logs out current logged in user session @@ -161,6 +186,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [nil] def self.logout_user(opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#logout_user ..." + end # resource path @@ -188,7 +216,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:GET, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#logout_user" + end nil end @@ -198,6 +229,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [User] def self.get_user_by_name(username, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#get_user_by_name ..." + end # verify the required parameter 'username' is set raise "Missing the required parameter 'username' when calling get_user_by_name" if username.nil? @@ -229,7 +263,11 @@ module SwaggerClient auth_names = [] response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make - response.deserialize('User') + result = response.deserialize('User') + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#get_user_by_name. Result: #{result.inspect}" + end + result end # Updated user @@ -239,6 +277,9 @@ module SwaggerClient # @option opts [User] :body Updated user object # @return [nil] def self.update_user(username, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#update_user ..." + end # verify the required parameter 'username' is set raise "Missing the required parameter 'username' when calling update_user" if username.nil? @@ -269,7 +310,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:PUT, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#update_user" + end nil end @@ -279,6 +323,9 @@ module SwaggerClient # @param [Hash] opts the optional parameters # @return [nil] def self.delete_user(username, opts = {}) + if Swagger.configuration.debug + Swagger.logger.debug "Calling API: UserApi#delete_user ..." + end # verify the required parameter 'username' is set raise "Missing the required parameter 'username' when calling delete_user" if username.nil? @@ -309,7 +356,10 @@ module SwaggerClient auth_names = [] - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + Swagger::Request.new(:DELETE, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + if Swagger.configuration.debug + Swagger.logger.debug "API called: UserApi#delete_user" + end nil end end From 4fe979a8c0e564cd8eebb123612488562fe29e2f Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 19:26:26 -0700 Subject: [PATCH 106/499] code compiles and *should* work, but need to re-organize for separate client/api-specific class namespaces --- .../codegen/languages/PhpClientCodegen.java | 155 +++++++----------- .../src/main/resources/php/ApiClient.mustache | 4 +- .../resources/php/ObjectSerializer.mustache | 2 +- .../src/main/resources/php/api.mustache | 6 +- 4 files changed, 63 insertions(+), 104 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index c362ce8da3b..88e7725578c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -24,18 +24,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { protected String groupId = "swagger"; protected String artifactId = "swagger-client"; protected String artifactVersion = null; - protected String rootNamespace; - protected String invokerNamespace; - protected String modelNamespace; - protected String apiNamespace; public PhpClientCodegen() { super(); - rootNamespace = "Swagger"; - invokerPackage = "Client"; - modelPackage = "Models"; - apiPackage = "Api"; outputFolder = "generated-code/php"; modelTemplateFiles.put("model.mustache", ".php"); apiTemplateFiles.put("api.mustache", ".php"); @@ -95,7 +87,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("object", "object"); typeMapping.put("DateTime", "\\DateTime"); - cliOptions.add(new CliOption("rootNamespace", "root namespace from which other namespaces derive")); cliOptions.add(new CliOption("invokerPackage", "namespace for core, non-api-specific classes")); } @@ -138,20 +129,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.setInvokerPackage((String) additionalProperties.get("invokerPackage")); } - if (additionalProperties.containsKey("rootNamespace")) { - this.setRootNamespace((String) additionalProperties.get("rootNamespace")); - } - - prefixPackages(); - - // theirs - supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); - supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, "lib"), "Configuration.php")); - supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); - supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); - supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); - - // mine supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, "lib"), "ApiClientConfiguration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); @@ -160,15 +137,15 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); } - protected String getSrcDir(String packageName) { - return "src/" + packageName; - } - - protected void prefixPackages() { - setApiPackage(getSrcDir(apiPackage)); - setInvokerPackage(getSrcDir(invokerPackage)); - setModelPackage(getSrcDir(modelPackage)); - } +// protected String getSrcDir(String packageName) { +// return "src/" + packageName; +// } +// +// protected void prefixPackages() { +// setApiPackage(getSrcDir(apiPackage)); +// setInvokerPackage(getSrcDir(invokerPackage)); +// setModelPackage(getSrcDir(modelPackage)); +// } @Override public String escapeReservedWord(String name) { @@ -238,10 +215,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.invokerPackage = invokerPackage; } - public void setRootNamespace(String rootNamespace) { - this.rootNamespace = rootNamespace; - } - @Override public String toVarName(String name) { // parameter name starting with number won't compile @@ -279,64 +252,54 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return toModelName(name); } - public String toNamespace(String packageName) { - return rootNamespace + "\\" + packageName.replace('/', '\\').replace('.', '\\'); - } - - protected void setNamespacesFromPackages() { - invokerNamespace = toNamespace(invokerPackage); - apiNamespace = toNamespace(apiPackage); - modelNamespace = toNamespace(modelPackage); - } - - @Override - public Map postProcessModels(Map objs) { - return addNamespaces(super.postProcessModels(objs)); - } - - @Override - public Map postProcessOperations(Map objs) { - objs = addNamespaces(super.postProcessOperations(objs)); - objs = formatImports(objs, "imports", "import"); - - return objs; - } - - @Override - public Map postProcessSupportingFileData(Map objs) { - objs = addNamespaces(super.postProcessSupportingFileData(objs)); - - return objs; - } - - protected Map addNamespaces(Map objs) { - objs.put("rootNamespace", rootNamespace); - objs.put("invokerNamespace", invokerNamespace); - objs.put("apiNamespace", apiNamespace); - objs.put("modelNamespace", modelNamespace); - - return objs; - } - - protected Map formatImports(Map objs, String objsKey, String importKey) { - if (objs.containsKey(objsKey)) { - String modelName; - List> newImportList = new ArrayList>(); - - for (Map importMap : (List>) objs.get(objsKey)) { - modelName = ((String) importMap.get(importKey)).replace(modelPackage + ".", ""); - - if (reservedWords.contains(modelName)) { - continue; - } - - importMap.put(importKey, modelNamespace + "\\" + modelName); - newImportList.add(importMap); - } - - objs.put(objsKey, newImportList); - } - - return objs; - } +// @Override +// public Map postProcessModels(Map objs) { +// return addNamespaces(super.postProcessModels(objs)); +// } +// +// @Override +// public Map postProcessOperations(Map objs) { +// objs = addNamespaces(super.postProcessOperations(objs)); +// objs = formatImports(objs, "imports", "import"); +// +// return objs; +// } +// +// @Override +// public Map postProcessSupportingFileData(Map objs) { +// objs = addNamespaces(super.postProcessSupportingFileData(objs)); +// +// return objs; +// } +// +// protected Map addNamespaces(Map objs) { +// objs.put("rootNamespace", rootNamespace); +// objs.put("invokerNamespace", invokerNamespace); +// objs.put("apiNamespace", apiNamespace); +// objs.put("modelNamespace", modelNamespace); +// +// return objs; +// } +// +// protected Map formatImports(Map objs, String objsKey, String importKey) { +// if (objs.containsKey(objsKey)) { +// String modelName; +// List> newImportList = new ArrayList>(); +// +// for (Map importMap : (List>) objs.get(objsKey)) { +// modelName = ((String) importMap.get(importKey)).replace(modelPackage + ".", ""); +// +// if (reservedWords.contains(modelName)) { +// continue; +// } +// +// importMap.put(importKey, modelNamespace + "\\" + modelName); +// newImportList.add(importMap); +// } +// +// objs.put(objsKey, newImportList); +// } +// +// return objs; +// } } diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index b22c4e86a21..15726db05ea 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -15,7 +15,7 @@ * limitations under the License. */ -namespace {{invokerNamespace}}; +namespace {{invokerPackage}}; class ApiClient { @@ -77,7 +77,7 @@ class ApiClient { * @param array $queryParams parameters to be place in query URL * @param array $postData parameters to be placed in POST body * @param array $headerParams parameters to be place in request header - * @throws \{{invokerNamespace}}\ApiException on a non 2xx response + * @throws \{{invokerPackage}}\ApiException on a non 2xx response * @return mixed */ public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) { diff --git a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache index 79e7c8b356e..4880a8106d0 100644 --- a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache @@ -1,5 +1,5 @@ Date: Mon, 22 Jun 2015 19:34:03 -0700 Subject: [PATCH 107/499] make packagePath configureable, and remove unused code --- .../codegen/languages/PhpClientCodegen.java | 73 +++---------------- 1 file changed, 11 insertions(+), 62 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 88e7725578c..54ae637d9a9 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -23,6 +23,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { protected String invokerPackage = "Swagger\\Client"; protected String groupId = "swagger"; protected String artifactId = "swagger-client"; + protected String packagePath = "SwaggerClient-php"; protected String artifactVersion = null; public PhpClientCodegen() { @@ -88,10 +89,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("DateTime", "\\DateTime"); cliOptions.add(new CliOption("invokerPackage", "namespace for core, non-api-specific classes")); + cliOptions.add(new CliOption("packagePath", "main package name for classes")); } public String getPackagePath() { - return "SwaggerClient-php"; + return packagePath; } public String toPackagePath(String packageName, String basePath) { @@ -129,6 +131,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.setInvokerPackage((String) additionalProperties.get("invokerPackage")); } + if (additionalProperties.containsKey("packagePath")) { + this.setPackagePath((String) additionalProperties.get("packagePath")); + } + supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, "lib"), "ApiClientConfiguration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); @@ -137,16 +143,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); } -// protected String getSrcDir(String packageName) { -// return "src/" + packageName; -// } -// -// protected void prefixPackages() { -// setApiPackage(getSrcDir(apiPackage)); -// setInvokerPackage(getSrcDir(invokerPackage)); -// setModelPackage(getSrcDir(modelPackage)); -// } - @Override public String escapeReservedWord(String name) { return "_" + name; @@ -215,6 +211,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.invokerPackage = invokerPackage; } + public void setPackagePath(String packagePath) { + this.packagePath = packagePath; + } + @Override public String toVarName(String name) { // parameter name starting with number won't compile @@ -251,55 +251,4 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { // should be the same as the model name return toModelName(name); } - -// @Override -// public Map postProcessModels(Map objs) { -// return addNamespaces(super.postProcessModels(objs)); -// } -// -// @Override -// public Map postProcessOperations(Map objs) { -// objs = addNamespaces(super.postProcessOperations(objs)); -// objs = formatImports(objs, "imports", "import"); -// -// return objs; -// } -// -// @Override -// public Map postProcessSupportingFileData(Map objs) { -// objs = addNamespaces(super.postProcessSupportingFileData(objs)); -// -// return objs; -// } -// -// protected Map addNamespaces(Map objs) { -// objs.put("rootNamespace", rootNamespace); -// objs.put("invokerNamespace", invokerNamespace); -// objs.put("apiNamespace", apiNamespace); -// objs.put("modelNamespace", modelNamespace); -// -// return objs; -// } -// -// protected Map formatImports(Map objs, String objsKey, String importKey) { -// if (objs.containsKey(objsKey)) { -// String modelName; -// List> newImportList = new ArrayList>(); -// -// for (Map importMap : (List>) objs.get(objsKey)) { -// modelName = ((String) importMap.get(importKey)).replace(modelPackage + ".", ""); -// -// if (reservedWords.contains(modelName)) { -// continue; -// } -// -// importMap.put(importKey, modelNamespace + "\\" + modelName); -// newImportList.add(importMap); -// } -// -// objs.put(objsKey, newImportList); -// } -// -// return objs; -// } } From 02c41ac574a4cbd853b83862296abfe477c0c319 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Mon, 22 Jun 2015 20:00:28 -0700 Subject: [PATCH 108/499] fix for #900, invalid param name for java client --- .../codegen/languages/JavaClientCodegen.java | 4 +++ .../src/test/scala/Java/JavaModelTest.scala | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java index fcec455e9b3..effcddc6834 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java @@ -144,6 +144,10 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { // replace - with _ e.g. created-at => created_at name = name.replaceAll("-", "_"); + if("_".equals(name)) { + name = "_u"; + } + // if it's all uppper case, do nothing if (name.matches("^[A-Z_]*$")) { return name; diff --git a/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala b/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala index fc819f1f195..0df82fce377 100644 --- a/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala +++ b/modules/swagger-codegen/src/test/scala/Java/JavaModelTest.scala @@ -3,6 +3,7 @@ package Java import io.swagger.codegen.languages.JavaClientCodegen import io.swagger.models._ import io.swagger.models.properties._ +import io.swagger.util.Json import org.junit.runner.RunWith import org.scalatest.{FlatSpec, Matchers} import org.scalatest.junit.JUnitRunner @@ -344,3 +345,32 @@ class JavaModelTest extends FlatSpec with Matchers { cm.classname should be("WithDots") } } + + +@RunWith(classOf[JUnitRunner]) +class JavaModelTest2 extends FlatSpec with Matchers { + it should "translate an invalid param name" in { + val model = new ModelImpl() + .description("a model with a 2nd char upper-case property names") + .property("_", new StringProperty()) + + val codegen = new JavaClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be("sample") + cm.classname should be("Sample") + cm.vars.size should be(1) + + val vars = cm.vars + Json.prettyPrint(vars.get(0)) + vars.get(0).baseName should be("_") + vars.get(0).getter should be("getU") + vars.get(0).setter should be("setU") + vars.get(0).datatype should be("String") + vars.get(0).name should be("u") + vars.get(0).defaultValue should be("null") + vars.get(0).baseType should be("String") + vars.get(0).hasMore should equal(null) + vars.get(0).isNotContainer should equal(true) + } +} From d5d148365630604177043da54bc18973339af1f2 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 20:14:54 -0700 Subject: [PATCH 109/499] properly account for custom and non-custom settings for modelPackage and apiPackage --- .../codegen/languages/PhpClientCodegen.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 54ae637d9a9..72fba6c54ce 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -33,8 +33,8 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { modelTemplateFiles.put("model.mustache", ".php"); apiTemplateFiles.put("api.mustache", ".php"); templateDir = "php"; - apiPackage = invokerPackage + "\\Api"; - modelPackage = invokerPackage + "\\Model"; + apiPackage = "Api"; + modelPackage = "Model"; reservedWords = new HashSet( Arrays.asList( @@ -88,7 +88,6 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("object", "object"); typeMapping.put("DateTime", "\\DateTime"); - cliOptions.add(new CliOption("invokerPackage", "namespace for core, non-api-specific classes")); cliOptions.add(new CliOption("packagePath", "main package name for classes")); } @@ -127,14 +126,22 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { public void processOpts() { super.processOpts(); - if (additionalProperties.containsKey("invokerPackage")) { - this.setInvokerPackage((String) additionalProperties.get("invokerPackage")); - } - if (additionalProperties.containsKey("packagePath")) { this.setPackagePath((String) additionalProperties.get("packagePath")); } + if (additionalProperties.containsKey("modelPackage")) { + this.setModelPackage(invokerPackage + "\\" + additionalProperties.get("modelPackage")); + } + + if (additionalProperties.containsKey("apiPackage")) { + this.setApiPackage(invokerPackage + "\\" + additionalProperties.get("apiPackage")); + } + + additionalProperties.replace("modelPackage", modelPackage); + additionalProperties.replace("apiPackage", apiPackage); + additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); + supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, "lib"), "ApiClientConfiguration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); From b4d6fd3ba39d02b72d6d5cccc010108bb9bb1f22 Mon Sep 17 00:00:00 2001 From: Raghav sidhanti Date: Mon, 22 Jun 2015 20:16:35 -0700 Subject: [PATCH 110/499] Returning when query param value is null. --- .../src/main/resources/Java/ApiClient.mustache | 7 +------ .../src/main/resources/android-java/apiInvoker.mustache | 7 +------ .../src/main/java/io/swagger/client/ApiInvoker.java | 7 +------ .../src/main/java/io/swagger/client/model/Pet.java | 2 +- .../java/src/main/java/io/swagger/client/ApiClient.java | 7 +------ .../java/src/main/java/io/swagger/client/api/PetApi.java | 2 +- .../java/src/main/java/io/swagger/client/model/Pet.java | 2 +- 7 files changed, 7 insertions(+), 27 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index d8c48e93b10..e87819e6944 100644 --- a/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -246,12 +246,7 @@ public class ApiClient { List params = new ArrayList(); // preconditions - if (name == null || name.isEmpty()) return params; - - if (value == null) { - params.add(new Pair(name, "")); - return params; - } + if (name == null || name.isEmpty() || value == null) return params; Collection valueCollection = null; if (value instanceof Collection) { diff --git a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache index 3aeb9b8505d..5aabd2458e8 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/apiInvoker.mustache @@ -140,12 +140,7 @@ public class ApiInvoker { List params = new ArrayList(); // preconditions - if (name == null || name.isEmpty()) return params; - - if (value == null) { - params.add(new Pair(name, "")); - return params; - } + if (name == null || name.isEmpty() || value == null) return params; Collection valueCollection = null; if (value instanceof Collection) { diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java index c55e127cddf..0ccc3713958 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/ApiInvoker.java @@ -140,12 +140,7 @@ public class ApiInvoker { List params = new ArrayList(); // preconditions - if (name == null || name.isEmpty()) return params; - - if (value == null) { - params.add(new Pair(name, "")); - return params; - } + if (name == null || name.isEmpty() || value == null) return params; Collection valueCollection = null; if (value instanceof Collection) { diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java index 90a840e6e42..26219b16a45 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import io.swagger.client.model.Tag; import java.util.*; +import io.swagger.client.model.Tag; import io.swagger.annotations.*; import com.google.gson.annotations.SerializedName; diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index 4d50ab3ce84..9659ce3ba5f 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -245,12 +245,7 @@ public class ApiClient { List params = new ArrayList(); // preconditions - if (name == null || name.isEmpty()) return params; - - if (value == null) { - params.add(new Pair(name, "")); - return params; - } + if (name == null || name.isEmpty() || value == null) return params; Collection valueCollection = null; if (value instanceof Collection) { diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index 402fc9da953..609fb66af2b 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -323,7 +323,7 @@ public class PetApi { } try { - String[] authNames = new String[] { "api_key", "petstore_auth" }; + String[] authNames = new String[] { "petstore_auth", "api_key" }; String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); if(response != null){ return (Pet) apiClient.deserialize(response, "", Pet.class); diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java index cf7ace02309..ddd0e1038c0 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import io.swagger.client.model.Tag; import java.util.*; +import io.swagger.client.model.Tag; import io.swagger.annotations.*; import com.fasterxml.jackson.annotation.JsonProperty; From 7be35bb02eecb73d8488dc4d16871cd8bbba2707 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 26 May 2015 10:59:55 +0900 Subject: [PATCH 111/499] Change method name to avoid name collision --- .../src/main/resources/swift/APIs.mustache | 2 +- .../main/resources/swift/Extensions.mustache | 29 ++++++++++++++----- .../src/main/resources/swift/Models.mustache | 2 +- .../src/main/resources/swift/api.mustache | 2 +- .../src/main/resources/swift/model.mustache | 6 ++-- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache index aa39ccfcbdd..d9fcb84c125 100644 --- a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache @@ -15,7 +15,7 @@ class {{projectName}}API { class APIBase { func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? { - let encoded: AnyObject? = encodable?.encode() + let encoded: AnyObject? = encodable?.encodeToJSON() if encoded! is [AnyObject] { var dictionary = [String:AnyObject]() diff --git a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache index c937db23fe3..a06ebae7026 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache @@ -8,41 +8,41 @@ import Alamofire import PromiseKit extension Bool: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension Float: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension Int: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension Double: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension String: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } private func encodeIfPossible(object: T) -> AnyObject { if object is JSONEncodable { - return (object as! JSONEncodable).encode() + return (object as! JSONEncodable).encodeToJSON() } else { return object as! AnyObject } } extension Array: JSONEncodable { - func encode() -> AnyObject { + func encodeToJSON() -> AnyObject { return self.map(encodeIfPossible) } } extension Dictionary: JSONEncodable { - func encode() -> AnyObject { + func encodeToJSON() -> AnyObject { var dictionary = [NSObject:AnyObject]() for (key, value) in self { dictionary[key as! NSObject] = encodeIfPossible(value) @@ -50,3 +50,16 @@ extension Dictionary: JSONEncodable { return dictionary } } + + +private let dateFormatter: NSDateFormatter = { + let dateFormatter = NSDateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd" + return dateFormatter +}() + +extension NSDate: JSONEncodable { + func encodeToJSON() -> AnyObject { + return dateFormatter.stringFromDate(self) + } +} diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index 37c497ddcb9..587b710326b 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -7,7 +7,7 @@ import Foundation protocol JSONEncodable { - func encode() -> AnyObject + func encodeToJSON() -> AnyObject } class Response { diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index e24bdae6773..8c40c3f5be7 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -35,7 +35,7 @@ extension {{projectName}}API { path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{^required}}?{{/required}}.encode() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index a964882c97c..06f10146cf6 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -22,12 +22,12 @@ class {{classname}}: JSONEncodable { {{/vars}} // MARK: JSONEncodable - func encode() -> AnyObject { + func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encode(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encode(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } From d08acf72984669cd9adfd70ae0e620a9439ec327 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 12:25:46 +0900 Subject: [PATCH 112/499] Add a dateTime formatter candidate --- .../src/main/resources/swift/Models.mustache | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index 587b710326b..31c055b54dc 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -97,17 +97,24 @@ class Decoders { static private func initialize() { dispatch_once(&once) { - let dateTimeFormatter = NSDateFormatter() - dateTimeFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" - let dateFormatter = NSDateFormatter() - dateFormatter.dateFormat = "yyyy-MM-dd" + let formatters = [ + "yyyy-MM-dd", + "yyyy-MM-dd'T'HH:mm:ssZZZZZ", + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ].map { (format: String) -> NSDateFormatter in + let formatter = NSDateFormatter() + formatter.dateFormat = format + return formatter + } // Decoder for NSDate Decoders.addDecoder(clazz: NSDate.self) { (source: AnyObject) -> NSDate in let sourceString = source as! String - if count(sourceString) == 10 { - return dateFormatter.dateFromString(sourceString)! + for formatter in formatters { + if let date = formatter.dateFromString(sourceString) { + return date + } } - return dateTimeFormatter.dateFromString(sourceString)! + fatalError("formatter failed to parse \(sourceString)") } {{#models}}{{#model}} // Decoder for {{{classname}}} From a7c91d610f60c1554edde152b76073c3dc07d251 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 12:26:01 +0900 Subject: [PATCH 113/499] Add error response body to NSError --- .../src/main/resources/swift/AlamofireImplementations.mustache | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index 244d816332c..37edceea13c 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -45,7 +45,8 @@ class AlamofireRequestBuilder: RequestBuilder { } if res!.statusCode >= 400 { //TODO: Add error entity - let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: [:]) + let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] + let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) defer.reject(error) return } From 495e528eecd6df3e1cce3322cbc3f4cb0b46e43c Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 12:30:58 +0900 Subject: [PATCH 114/499] Add generated code --- samples/client/petstore/swift/Cartfile | 2 + .../Classes/Swaggers/APIHelper.swift | 21 ++ .../Classes/Swaggers/APIs.swift | 66 +++++ .../Classes/Swaggers/APIs/PetAPI.swift | 225 ++++++++++++++++++ .../Classes/Swaggers/APIs/StoreAPI.swift | 114 +++++++++ .../Classes/Swaggers/APIs/UserAPI.swift | 206 ++++++++++++++++ .../Swaggers/AlamofireImplementations.swift | 80 +++++++ .../Classes/Swaggers/Extensions.swift | 65 +++++ .../Classes/Swaggers/Models.swift | 185 ++++++++++++++ .../Classes/Swaggers/Models/Category.swift | 25 ++ .../Classes/Swaggers/Models/Order.swift | 40 ++++ .../Classes/Swaggers/Models/Pet.swift | 40 ++++ .../Classes/Swaggers/Models/Tag.swift | 25 ++ .../Classes/Swaggers/Models/User.swift | 38 +++ 14 files changed, 1132 insertions(+) create mode 100644 samples/client/petstore/swift/Cartfile create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift diff --git a/samples/client/petstore/swift/Cartfile b/samples/client/petstore/swift/Cartfile new file mode 100644 index 00000000000..af74617bcf2 --- /dev/null +++ b/samples/client/petstore/swift/Cartfile @@ -0,0 +1,2 @@ +github "Alamofire/Alamofire" >= 1.2 +github "mxcl/PromiseKit" >=1.5.3 diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift new file mode 100644 index 00000000000..418f1c8512b --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift @@ -0,0 +1,21 @@ +// APIHelper.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +class APIHelper { + static func rejectNil(source: [String:AnyObject?]) -> [String:AnyObject]? { + var destination = [String:AnyObject]() + for (key, nillableValue) in source { + if let value: AnyObject = nillableValue { + destination[key] = value + } + } + + if destination.isEmpty { + return nil + } + return destination + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift new file mode 100644 index 00000000000..75138ff689a --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift @@ -0,0 +1,66 @@ +// APIs.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation +import PromiseKit + +class PetstoreClientAPI { + static let basePath = "http://petstore.swagger.io/v2" + static var credential: NSURLCredential? + static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() +} + +class APIBase { + func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? { + let encoded: AnyObject? = encodable?.encodeToJSON() + + if encoded! is [AnyObject] { + var dictionary = [String:AnyObject]() + for (index, item) in enumerate(encoded as! [AnyObject]) { + dictionary["\(index)"] = item + } + return dictionary + } else { + return encoded as? [String:AnyObject] + } + } +} + +class RequestBuilder { + var credential: NSURLCredential? + var headers: [String:String] = [:] + let parameters: [String:AnyObject]? + let isBody: Bool + let method: String + let URLString: String + + required init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool) { + self.method = method + self.URLString = URLString + self.parameters = parameters + self.isBody = isBody + } + + func execute() -> Promise> { fatalError("Not implemented") } + + func addHeader(#name: String, value: String) -> Self { + if !value.isEmpty { + headers[name] = value + } + return self + } + + func addCredential() -> Self { + self.credential = PetstoreClientAPI.credential + return self + } +} + +protocol RequestBuilderFactory { + func getBuilder() -> RequestBuilder.Type +} + + diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift new file mode 100644 index 00000000000..48e5f439159 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -0,0 +1,225 @@ +// +// PetAPI.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension PetstoreClientAPI { + + class PetAPI: APIBase { + + /** + + Update an existing pet + + - PUT /pet + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@5fd7e9cb] + + :param: body (body) Pet object that needs to be added to the store + + :returns: Promise> + */ + func updatePet(#body: Pet?) -> RequestBuilder { + let path = "/pet" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "PUT", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Add a new pet to the store + + - POST /pet + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@58363f95] + + :param: body (body) Pet object that needs to be added to the store + + :returns: Promise> + */ + func addPet(#body: Pet?) -> RequestBuilder { + let path = "/pet" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Finds Pets by status + + - GET /pet/findByStatus + - Multiple status values can be provided with comma seperated strings + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@51887c71] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + + :param: status (query) Status values that need to be considered for filter + + :returns: Promise> + */ + func findPetsByStatus(#status: [String]?) -> RequestBuilder<[Pet]> { + let path = "/pet/findByStatus" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "status": status + ] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder<[Pet]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: false) + } + + /** + + Finds Pets by tags + + - GET /pet/findByTags + - Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4ede45aa] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + + :param: tags (query) Tags to filter by + + :returns: Promise> + */ + func findPetsByTags(#tags: [String]?) -> RequestBuilder<[Pet]> { + let path = "/pet/findByTags" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "tags": tags + ] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder<[Pet]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: false) + } + + /** + + Find pet by ID + + - GET /pet/{petId} + - Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] + - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + + :param: petId (path) ID of pet that needs to be fetched + + :returns: Promise> + */ + func getPetById(#petId: Int) -> RequestBuilder { + var path = "/pet/{petId}" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Updates a pet in the store with form data + + - POST /pet/{petId} + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@795525a1] + + :param: petId (path) ID of pet that needs to be updated + :param: name (form) Updated name of the pet + :param: status (form) Updated status of the pet + + :returns: Promise> + */ + func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { + var path = "/pet/{petId}" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Deletes a pet + + - DELETE /pet/{petId} + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4519ab42] + + :param: petId (path) Pet id to delete + + :returns: Promise> + */ + func deletePet(#petId: Int) -> RequestBuilder { + var path = "/pet/{petId}" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "DELETE", URLString: url, parameters: parameters, isBody: true) + } + + /** + + uploads an image + + - POST /pet/{petId}/uploadImage + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@183a9d7f] + + :param: petId (path) ID of pet to update + :param: additionalMetadata (form) Additional data to pass to server + :param: file (form) file to upload + + :returns: Promise> + */ + func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + var path = "/pet/{petId}/uploadImage" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift new file mode 100644 index 00000000000..8ffedbdb39b --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -0,0 +1,114 @@ +// +// StoreAPI.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension PetstoreClientAPI { + + class StoreAPI: APIBase { + + /** + + Returns pet inventories by status + + - GET /store/inventory + - Returns a map of status codes to quantities + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@303a0946] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] + + :returns: Promise> + */ + func getInventory() -> RequestBuilder<[String:Int]> { + let path = "/store/inventory" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder<[String:Int]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Place an order for a pet + + - POST /store/order + - + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] + + :param: body (body) order placed for purchasing the pet + + :returns: Promise> + */ + func placeOrder(#body: Order?) -> RequestBuilder { + let path = "/store/order" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Find purchase order by ID + + - GET /store/order/{orderId} + - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] + + :param: orderId (path) ID of pet that needs to be fetched + + :returns: Promise> + */ + func getOrderById(#orderId: String) -> RequestBuilder { + var path = "/store/order/{orderId}" + path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Delete purchase order by ID + + - DELETE /store/order/{orderId} + - For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + + :param: orderId (path) ID of the order that needs to be deleted + + :returns: Promise> + */ + func deleteOrder(#orderId: String) -> RequestBuilder { + var path = "/store/order/{orderId}" + path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "DELETE", URLString: url, parameters: parameters, isBody: true) + } + + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift new file mode 100644 index 00000000000..aed405c7bb0 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -0,0 +1,206 @@ +// +// UserAPI.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension PetstoreClientAPI { + + class UserAPI: APIBase { + + /** + + Create user + + - POST /user + - This can only be done by the logged in user. + + :param: body (body) Created user object + + :returns: Promise> + */ + func createUser(#body: User?) -> RequestBuilder { + let path = "/user" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Creates list of users with given input array + + - POST /user/createWithArray + - + + :param: body (body) List of user object + + :returns: Promise> + */ + func createUsersWithArrayInput(#body: [User]?) -> RequestBuilder { + let path = "/user/createWithArray" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Creates list of users with given input array + + - POST /user/createWithList + - + + :param: body (body) List of user object + + :returns: Promise> + */ + func createUsersWithListInput(#body: [User]?) -> RequestBuilder { + let path = "/user/createWithList" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Logs user into the system + + - GET /user/login + - + - examples: [{example="aeiou", contentType=application/json}, {example=string, contentType=application/xml}] + - examples: [{example="aeiou", contentType=application/json}, {example=string, contentType=application/xml}] + + :param: username (query) The user name for login + :param: password (query) The password for login in clear text + + :returns: Promise> + */ + func loginUser(#username: String?, password: String?) -> RequestBuilder { + let path = "/user/login" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "username": username, + "password": password + ] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: false) + } + + /** + + Logs out current logged in user session + + - GET /user/logout + - + + :returns: Promise> + */ + func logoutUser() -> RequestBuilder { + let path = "/user/logout" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Get user by user name + + - GET /user/{username} + - + - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + + :param: username (path) The name that needs to be fetched. Use user1 for testing. + + :returns: Promise> + */ + func getUserByName(#username: String) -> RequestBuilder { + var path = "/user/{username}" + path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Updated user + + - PUT /user/{username} + - This can only be done by the logged in user. + + :param: username (path) name that need to be deleted + :param: body (body) Updated user object + + :returns: Promise> + */ + func updateUser(#username: String, body: User?) -> RequestBuilder { + var path = "/user/{username}" + path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "PUT", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Delete user + + - DELETE /user/{username} + - This can only be done by the logged in user. + + :param: username (path) The name that needs to be deleted + + :returns: Promise> + */ + func deleteUser(#username: String) -> RequestBuilder { + var path = "/user/{username}" + path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "DELETE", URLString: url, parameters: parameters, isBody: true) + } + + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift new file mode 100644 index 00000000000..37edceea13c --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift @@ -0,0 +1,80 @@ +// AlamofireImplementations.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +class AlamofireRequestBuilderFactory: RequestBuilderFactory { + func getBuilder() -> RequestBuilder.Type { + return AlamofireRequestBuilder.self + } +} + +// Store manager to retain its reference +private var managerStore: [String: Alamofire.Manager] = [:] + +class AlamofireRequestBuilder: RequestBuilder { + required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool) { + super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) + } + + override func execute() -> Promise> { + let managerId = NSUUID().UUIDString + // Create a new manager for each request to customize its request header + let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() + configuration.HTTPAdditionalHeaders = buildHeaders() + let manager = Alamofire.Manager(configuration: configuration) + managerStore[managerId] = manager + + let encoding = isBody ? Alamofire.ParameterEncoding.JSON : Alamofire.ParameterEncoding.URL + let request = manager.request(Alamofire.Method(rawValue: method)!, URLString, parameters: parameters, encoding: encoding) + if let credential = self.credential { + request.authenticate(usingCredential: credential) + } + + let defer = Promise>.defer() + request.responseJSON(options: .AllowFragments) { (req, res, json, error) in + managerStore.removeValueForKey(managerId) + + if let error = error { + defer.reject(error) + return + } + if res!.statusCode >= 400 { + //TODO: Add error entity + let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] + let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) + defer.reject(error) + return + } + + if () is T { + let response = Response(response: res!, body: () as! T) + defer.fulfill(response) + return + } + if let json: AnyObject = json { + let body = Decoders.decode(clazz: T.self, source: json) + let response = Response(response: res!, body: body) + defer.fulfill(response) + return + } + + defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + } + return defer.promise + } + + private func buildHeaders() -> [String: AnyObject] { + var httpHeaders = Manager.defaultHTTPHeaders + for (key, value) in self.headers { + httpHeaders[key] = value + } + return httpHeaders + } +} + + diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift new file mode 100644 index 00000000000..a06ebae7026 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift @@ -0,0 +1,65 @@ +// Extensions.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension Bool: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Float: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Int: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Double: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension String: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +private func encodeIfPossible(object: T) -> AnyObject { + if object is JSONEncodable { + return (object as! JSONEncodable).encodeToJSON() + } else { + return object as! AnyObject + } +} + +extension Array: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.map(encodeIfPossible) + } +} + +extension Dictionary: JSONEncodable { + func encodeToJSON() -> AnyObject { + var dictionary = [NSObject:AnyObject]() + for (key, value) in self { + dictionary[key as! NSObject] = encodeIfPossible(value) + } + return dictionary + } +} + + +private let dateFormatter: NSDateFormatter = { + let dateFormatter = NSDateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd" + return dateFormatter +}() + +extension NSDate: JSONEncodable { + func encodeToJSON() -> AnyObject { + return dateFormatter.stringFromDate(self) + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift new file mode 100644 index 00000000000..54e38e75bfe --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift @@ -0,0 +1,185 @@ +// Models.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + +protocol JSONEncodable { + func encodeToJSON() -> AnyObject +} + +class Response { + let statusCode: Int + let header: [String: String] + let body: T + + init(statusCode: Int, header: [String: String], body: T) { + self.statusCode = statusCode + self.header = header + self.body = body + } + + convenience init(response: NSHTTPURLResponse, body: T) { + let rawHeader = response.allHeaderFields + var header = [String:String]() + for (key, value) in rawHeader { + header[key as! String] = value as? String + } + self.init(statusCode: response.statusCode, header: header, body: body) + } +} + +private var once = dispatch_once_t() +class Decoders { + static private var decoders = Dictionary AnyObject)>() + + static func addDecoder(#clazz: T.Type, decoder: ((AnyObject) -> T)) { + let key = "\(T.self)" + decoders[key] = { decoder($0) as! AnyObject } + } + + static func decode(#clazz: [T].Type, source: AnyObject) -> [T] { + let array = source as! [AnyObject] + return array.map { Decoders.decode(clazz: T.self, source: $0) } + } + + static func decode(#clazz: [Key:T].Type, source: AnyObject) -> [Key:T] { + let sourceDictinoary = source as! [Key: AnyObject] + var dictionary = [Key:T]() + for (key, value) in sourceDictinoary { + dictionary[key] = Decoders.decode(clazz: T.self, source: value) + } + return dictionary + } + + static func decode(#clazz: T.Type, source: AnyObject) -> T { + initialize() + if source is T { + return source as! T + } + + let key = "\(T.self)" + if let decoder = decoders[key] { + return decoder(source) as! T + } else { + fatalError("Source \(source) is not convertible to type \(clazz): Maybe swagger file is insufficient") + } + } + + static func decodeOptional(#clazz: T.Type, source: AnyObject?) -> T? { + if source is NSNull { + return nil + } + return source.map { (source: AnyObject) -> T in + Decoders.decode(clazz: clazz, source: source) + } + } + + static func decodeOptional(#clazz: [T].Type, source: AnyObject?) -> [T]? { + if source is NSNull { + return nil + } + return source.map { (someSource: AnyObject) -> [T] in + Decoders.decode(clazz: clazz, source: someSource) + } + } + + static func decodeOptional(#clazz: [Key:T].Type, source: AnyObject?) -> [Key:T]? { + if source is NSNull { + return nil + } + return source.map { (someSource: AnyObject) -> [Key:T] in + Decoders.decode(clazz: clazz, source: someSource) + } + } + + static private func initialize() { + dispatch_once(&once) { + let formatters = [ + "yyyy-MM-dd", + "yyyy-MM-dd'T'HH:mm:ssZZZZZ", + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ].map { (format: String) -> NSDateFormatter in + let formatter = NSDateFormatter() + formatter.dateFormat = format + return formatter + } + // Decoder for NSDate + Decoders.addDecoder(clazz: NSDate.self) { (source: AnyObject) -> NSDate in + let sourceString = source as! String + for formatter in formatters { + if let date = formatter.dateFromString(sourceString) { + return date + } + } + fatalError("formatter failed to parse \(sourceString)") + } + + // Decoder for User + Decoders.addDecoder(clazz: User.self) { (source: AnyObject) -> User in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = User() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.username = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["username"]) + instance.firstName = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["firstName"]) + instance.lastName = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["lastName"]) + instance.email = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["email"]) + instance.password = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["password"]) + instance.phone = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["phone"]) + instance.userStatus = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["userStatus"]) + return instance + } + + + // Decoder for Category + Decoders.addDecoder(clazz: Category.self) { (source: AnyObject) -> Category in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Category() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.name = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["name"]) + return instance + } + + + // Decoder for Pet + Decoders.addDecoder(clazz: Pet.self) { (source: AnyObject) -> Pet in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Pet() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.category = Decoders.decodeOptional(clazz: Category.self, source: sourceDictionary["category"]) + instance.name = Decoders.decode(clazz: String.self, source: sourceDictionary["name"]!) + instance.photoUrls = Decoders.decode(clazz: Array.self, source: sourceDictionary["photoUrls"]!) + instance.tags = Decoders.decodeOptional(clazz: Array.self, source: sourceDictionary["tags"]) + instance.status = (sourceDictionary["status"] as? String).map { Pet.Status(rawValue: $0)! } + return instance + } + + + // Decoder for Tag + Decoders.addDecoder(clazz: Tag.self) { (source: AnyObject) -> Tag in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Tag() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.name = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["name"]) + return instance + } + + + // Decoder for Order + Decoders.addDecoder(clazz: Order.self) { (source: AnyObject) -> Order in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Order() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.petId = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["petId"]) + instance.quantity = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["quantity"]) + instance.shipDate = Decoders.decodeOptional(clazz: NSDate.self, source: sourceDictionary["shipDate"]) + instance.status = (sourceDictionary["status"] as? String).map { Order.Status(rawValue: $0)! } + instance.complete = Decoders.decodeOptional(clazz: Bool.self, source: sourceDictionary["complete"]) + return instance + } + + } + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift new file mode 100644 index 00000000000..eab3e7b9e01 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift @@ -0,0 +1,25 @@ +// +// Category.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Category: JSONEncodable { + + var id: Int? + var name: String? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["name"] = self.name + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift new file mode 100644 index 00000000000..11884502bc1 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift @@ -0,0 +1,40 @@ +// +// Order.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Order: JSONEncodable { + + enum Status: String { + case Placed = "placed" + case Approved = "approved" + case Delivered = "delivered" + } + + var id: Int? + var petId: Int? + var quantity: Int? + var shipDate: NSDate? + /** Order Status */ + var status: Status? + var complete: Bool? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["petId"] = self.petId + nillableDictionary["quantity"] = self.quantity + nillableDictionary["shipDate"] = self.shipDate?.encodeToJSON() + nillableDictionary["status"] = self.status?.rawValue + nillableDictionary["complete"] = self.complete + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift new file mode 100644 index 00000000000..ff66ea2ea43 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift @@ -0,0 +1,40 @@ +// +// Pet.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Pet: JSONEncodable { + + enum Status: String { + case Available = "available" + case Pending = "pending" + case Sold = "sold" + } + + var id: Int? + var category: Category? + var name: String! + var photoUrls: [String]! + var tags: [Tag]? + /** pet status in the store */ + var status: Status? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["category"] = self.category?.encodeToJSON() + nillableDictionary["name"] = self.name + nillableDictionary["photoUrls"] = self.photoUrls.encodeToJSON() + nillableDictionary["tags"] = self.tags?.encodeToJSON() + nillableDictionary["status"] = self.status?.rawValue + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift new file mode 100644 index 00000000000..2951506a0dc --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift @@ -0,0 +1,25 @@ +// +// Tag.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Tag: JSONEncodable { + + var id: Int? + var name: String? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["name"] = self.name + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift new file mode 100644 index 00000000000..f2461238dc7 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift @@ -0,0 +1,38 @@ +// +// User.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class User: JSONEncodable { + + var id: Int? + var username: String? + var firstName: String? + var lastName: String? + var email: String? + var password: String? + var phone: String? + /** User Status */ + var userStatus: Int? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["username"] = self.username + nillableDictionary["firstName"] = self.firstName + nillableDictionary["lastName"] = self.lastName + nillableDictionary["email"] = self.email + nillableDictionary["password"] = self.password + nillableDictionary["phone"] = self.phone + nillableDictionary["userStatus"] = self.userStatus + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} From db01ec801f73a5c2caf6f85b6e79ef45f4c26baf Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:01:57 +0900 Subject: [PATCH 115/499] Add suppressRequired functionality --- .../codegen/languages/SwiftGenerator.java | 256 ++++++++++++++++++ .../src/main/resources/swift/Models.mustache | 4 +- .../src/main/resources/swift/api.mustache | 4 +- .../src/main/resources/swift/model.mustache | 10 +- 4 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java new file mode 100644 index 00000000000..697bdefef8f --- /dev/null +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java @@ -0,0 +1,256 @@ +package com.wordnik.swagger.codegen.languages; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.Model; +import com.wordnik.swagger.models.Operation; +import com.wordnik.swagger.models.parameters.HeaderParameter; +import com.wordnik.swagger.models.parameters.Parameter; +import com.wordnik.swagger.models.properties.*; +import org.apache.commons.lang.StringUtils; + +import javax.annotation.Nullable; +import java.util.*; +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { + private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); + protected String sourceFolder = "Classes/Swaggers"; + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "swift"; + } + + public String getHelp() { + return "Generates a swift client library."; + } + + public SwiftGenerator() { + super(); + outputFolder = "generated-code/swift"; + modelTemplateFiles.put("model.mustache", ".swift"); + apiTemplateFiles.put("api.mustache", ".swift"); + templateDir = "swift"; + apiPackage = "/APIs"; + modelPackage = "/Models"; + + // Inject application name + String appName = System.getProperty("appName"); + if (appName == null) { + appName = "SwaggerClient"; + } + additionalProperties.put("projectName", appName); + + // Inject base url override + String basePathOverride = System.getProperty("basePathOverride"); + if (basePathOverride != null) { + additionalProperties.put("basePathOverride", basePathOverride); + } + + // Make all the variable optional + String suppressRequired = System.getProperty("suppressRequired"); + if (suppressRequired != null) { + additionalProperties.put("suppressRequired", suppressRequired); + } + + sourceFolder = appName + "/" + sourceFolder; + + supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); + supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); + supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift")); + supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift")); + supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); + supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "Int", + "Float", + "Double", + "Bool", + "Void", + "String", + "Character") + ); + defaultIncludes = new HashSet( + Arrays.asList( + "NSDate", + "Array", + "Dictionary", + "Set", + "Any", + "Empty", + "AnyObject") + ); + reservedWords = new HashSet( + Arrays.asList( + "class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue", + "false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else", + "self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if", + "true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol", + "switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional", + "struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol", + "required", "right", "set", "Type", "unowned", "weak") + ); + + typeMapping = new HashMap(); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Dictionary"); + typeMapping.put("date", "NSDate"); + typeMapping.put("Date", "NSDate"); + typeMapping.put("DateTime", "NSDate"); + typeMapping.put("boolean", "Bool"); + typeMapping.put("string", "String"); + typeMapping.put("char", "Character"); + typeMapping.put("short", "Int"); + typeMapping.put("int", "Int"); + typeMapping.put("long", "Int"); + typeMapping.put("integer", "Int"); + typeMapping.put("Integer", "Int"); + typeMapping.put("float", "Float"); + typeMapping.put("number", "Double"); + typeMapping.put("double", "Double"); + typeMapping.put("object", "AnyObject"); + typeMapping.put("file", "NSData"); + + importMapping = new HashMap(); + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; // add an underscore to the name + } + + @Override + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return "[" + getTypeDeclaration(inner) + "]"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return "[String:" + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) + return toModelName(type); + } else + type = swaggerType; + return toModelName(type); + } + + @Override + public String toDefaultValue(Property p) { + // nil + return null; + } + + @Override + public String toInstantiationType(Property p) { + if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return "[String:" + inner + "]"; + } else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return "[" + inner + "]"; + } + return null; + } + + @Override + public CodegenProperty fromProperty(String name, Property p) { + CodegenProperty codegenProperty = super.fromProperty(name, p); + if (codegenProperty.isEnum) { + List> swiftEnums = new ArrayList>(); + List values = (List) codegenProperty.allowableValues.get("values"); + for (String value : values) { + Map map = new HashMap(); + map.put("enum", StringUtils.capitalize(value)); + map.put("raw", value); + swiftEnums.add(map); + } + codegenProperty.allowableValues.put("values", swiftEnums); + codegenProperty.datatypeWithEnum = + StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); + } + return codegenProperty; + } + + @Override + public String toApiName(String name) { + if(name.length() == 0) + return "DefaultAPI"; + return initialCaps(name) + "API"; + } + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { + path = normalizePath(path); + List parameters = operation.getParameters(); + parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { + @Override + public boolean apply(@Nullable Parameter parameter) { + return !(parameter instanceof HeaderParameter); + } + })); + operation.setParameters(parameters); + return super.fromOperation(path, httpMethod, operation, definitions); + } + + private static String normalizePath(String path) { + StringBuilder builder = new StringBuilder(); + + int cursor = 0; + Matcher matcher = PATH_PARAM_PATTERN.matcher(path); + boolean found = matcher.find(); + while (found) { + String stringBeforeMatch = path.substring(cursor, matcher.start()); + builder.append(stringBeforeMatch); + + String group = matcher.group().substring(1, matcher.group().length() - 1); + group = camelize(group, true); + builder + .append("{") + .append(group) + .append("}"); + + cursor = matcher.end(); + found = matcher.find(); + } + + String stringAfterMatch = path.substring(cursor); + builder.append(stringAfterMatch); + + return builder.toString(); + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index 31c055b54dc..a62c2f2c9b8 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#required}}!{{/required}} {{/isEnum}}{{^isEnum}} - instance.{{name}} = Decoders.decode{{^required}}Optional{{/required}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#required}}!{{/required}}){{/isEnum}}{{/vars}} + instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}} {{/isEnum}}{{^isEnum}} + instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}}){{/isEnum}}{{/vars}} return instance }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index 8c40c3f5be7..abfea5e10fb 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -30,12 +30,12 @@ extension {{projectName}}API { :returns: Promise> {{description}} */ - func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { + func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 06f10146cf6..6de26a5a1a9 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable { } {{/isEnum}}{{/vars}} {{#vars}}{{#isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatype}}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} + {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ + {{/description}}var {{name}}: {{{datatype}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/vars}} // MARK: JSONEncodable func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } From c9a9b0ad2b5d3aeb597e37f9d0d020fd306973fb Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:02:29 +0900 Subject: [PATCH 116/499] Refine authMethods description --- modules/swagger-codegen/src/main/resources/swift/api.mustache | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index abfea5e10fb..e458e6d7bca 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -21,7 +21,9 @@ extension {{projectName}}API { - {{{notes}}}{{/notes}}{{#subresourceOperation}} - subresourceOperation: {{subresourceOperation}}{{/subresourceOperation}}{{#defaultResponse}} - defaultResponse: {{defaultResponse}}{{/defaultResponse}}{{#authMethods}} - - authMethods: {{authMethods}}{{/authMethods}}{{#responseHeaders}} + - {{#isBasic}}BASIC{{/isBasic}}{{#isOAuth}}OAuth{{/isOAuth}}{{#isApiKey}}API Key{{/isApiKey}}: + - type: {{type}}{{#keyParamName}} {{keyParamName}} {{#isKeyInQuery}}(QUERY){{/isKeyInQuery}}{{#isKeyInHeaer}}(HEADER){{/isKeyInHeaer}}{{/keyParamName}} + - name: {{name}}{{/authMethods}}{{#responseHeaders}} - responseHeaders: {{responseHeaders}}{{/responseHeaders}}{{#examples}} - examples: {{{examples}}}{{/examples}}{{#externalDocs}} - externalDocs: {{externalDocs}}{{/externalDocs}}{{#hasParams}} From ff88f7175d9cad4f45719dac9670bf8a055f6e43 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:08:08 +0900 Subject: [PATCH 117/499] Update models --- .../Classes/Swaggers/APIs/PetAPI.swift | 36 ++++++++++++++----- .../Classes/Swaggers/APIs/StoreAPI.swift | 16 +++++---- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index 48e5f439159..efd14dfaaea 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -18,7 +18,9 @@ extension PetstoreClientAPI { - PUT /pet - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@5fd7e9cb] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: body (body) Pet object that needs to be added to the store @@ -41,7 +43,9 @@ extension PetstoreClientAPI { - POST /pet - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@58363f95] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: body (body) Pet object that needs to be added to the store @@ -64,7 +68,9 @@ extension PetstoreClientAPI { - GET /pet/findByStatus - Multiple status values can be provided with comma seperated strings - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@51887c71] + - OAuth: + - type: oauth2 + - name: petstore_auth - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] @@ -92,7 +98,9 @@ extension PetstoreClientAPI { - GET /pet/findByTags - Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4ede45aa] + - OAuth: + - type: oauth2 + - name: petstore_auth - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] @@ -120,8 +128,12 @@ extension PetstoreClientAPI { - GET /pet/{petId} - Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] + - API Key: + - type: apiKey api_key + - name: api_key + - OAuth: + - type: oauth2 + - name: petstore_auth - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] @@ -148,7 +160,9 @@ extension PetstoreClientAPI { - POST /pet/{petId} - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@795525a1] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: petId (path) ID of pet that needs to be updated :param: name (form) Updated name of the pet @@ -175,7 +189,9 @@ extension PetstoreClientAPI { - DELETE /pet/{petId} - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4519ab42] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: petId (path) Pet id to delete @@ -200,7 +216,9 @@ extension PetstoreClientAPI { - POST /pet/{petId}/uploadImage - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@183a9d7f] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: petId (path) ID of pet to update :param: additionalMetadata (form) Additional data to pass to server diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index 8ffedbdb39b..033fe10abea 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -18,9 +18,11 @@ extension PetstoreClientAPI { - GET /store/inventory - Returns a map of status codes to quantities - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@303a0946] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] + - API Key: + - type: apiKey api_key + - name: api_key + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] :returns: Promise> */ @@ -42,8 +44,8 @@ extension PetstoreClientAPI { - POST /store/order - - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -66,8 +68,8 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched From e0109afc60aae68995a21d071191828ce73c59c7 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:23:54 +0900 Subject: [PATCH 118/499] Fix typo --- .../src/main/resources/swift/Models.mustache | 4 ++-- .../swagger-codegen/src/main/resources/swift/api.mustache | 4 ++-- .../swagger-codegen/src/main/resources/swift/model.mustache | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index a62c2f2c9b8..b2f72e483ad 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}} {{/isEnum}}{{^isEnum}} - instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}}){{/isEnum}}{{/vars}} + instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}} {{/isEnum}}{{^isEnum}} + instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}}){{/isEnum}}{{/vars}} return instance }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index e458e6d7bca..fc009c63f2a 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -32,12 +32,12 @@ extension {{projectName}}API { :returns: Promise> {{description}} */ - func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { + func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 6de26a5a1a9..2302a6f44a5 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -25,9 +25,9 @@ class {{classname}}: JSONEncodable { func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} - nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } From 9e47042122eab0e3c39cedf3c1800091109c3c44 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:24:08 +0900 Subject: [PATCH 119/499] Update models --- .../Classes/Swaggers/APIs/PetAPI.swift | 8 ++++---- .../Classes/Swaggers/APIs/StoreAPI.swift | 16 ++++++++-------- .../Classes/Swaggers/APIs/UserAPI.swift | 6 +++--- .../PetstoreClient/Classes/Swaggers/Models.swift | 4 ++-- .../Classes/Swaggers/Models/Pet.swift | 6 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index efd14dfaaea..b136a04f8d2 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -141,7 +141,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func getPetById(#petId: Int) -> RequestBuilder { + func getPetById(#petId: Int?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -170,7 +170,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { + func updatePetWithForm(#petId: String?, name: String?, status: String?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -197,7 +197,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deletePet(#petId: Int) -> RequestBuilder { + func deletePet(#petId: Int?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -226,7 +226,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + func uploadFile(#petId: Int?, additionalMetadata: String?, file: NSData?) -> RequestBuilder { var path = "/pet/{petId}/uploadImage" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index 033fe10abea..ed0c5a87889 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -21,8 +21,8 @@ extension PetstoreClientAPI { - API Key: - type: apiKey api_key - name: api_key - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] :returns: Promise> */ @@ -44,8 +44,8 @@ extension PetstoreClientAPI { - POST /store/order - - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -68,14 +68,14 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getOrderById(#orderId: String) -> RequestBuilder { + func getOrderById(#orderId: String?) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -99,7 +99,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteOrder(#orderId: String) -> RequestBuilder { + func deleteOrder(#orderId: String?) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift index aed405c7bb0..812d823459d 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -141,7 +141,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func getUserByName(#username: String) -> RequestBuilder { + func getUserByName(#username: String?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -166,7 +166,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updateUser(#username: String, body: User?) -> RequestBuilder { + func updateUser(#username: String?, body: User?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -189,7 +189,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteUser(#username: String) -> RequestBuilder { + func deleteUser(#username: String?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift index 54e38e75bfe..d8ef5b109c2 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift @@ -149,8 +149,8 @@ class Decoders { var instance = Pet() instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) instance.category = Decoders.decodeOptional(clazz: Category.self, source: sourceDictionary["category"]) - instance.name = Decoders.decode(clazz: String.self, source: sourceDictionary["name"]!) - instance.photoUrls = Decoders.decode(clazz: Array.self, source: sourceDictionary["photoUrls"]!) + instance.name = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["name"]) + instance.photoUrls = Decoders.decodeOptional(clazz: Array.self, source: sourceDictionary["photoUrls"]) instance.tags = Decoders.decodeOptional(clazz: Array.self, source: sourceDictionary["tags"]) instance.status = (sourceDictionary["status"] as? String).map { Pet.Status(rawValue: $0)! } return instance diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift index ff66ea2ea43..0baac38a285 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift @@ -18,8 +18,8 @@ class Pet: JSONEncodable { var id: Int? var category: Category? - var name: String! - var photoUrls: [String]! + var name: String? + var photoUrls: [String]? var tags: [Tag]? /** pet status in the store */ var status: Status? @@ -31,7 +31,7 @@ class Pet: JSONEncodable { nillableDictionary["id"] = self.id nillableDictionary["category"] = self.category?.encodeToJSON() nillableDictionary["name"] = self.name - nillableDictionary["photoUrls"] = self.photoUrls.encodeToJSON() + nillableDictionary["photoUrls"] = self.photoUrls?.encodeToJSON() nillableDictionary["tags"] = self.tags?.encodeToJSON() nillableDictionary["status"] = self.status?.rawValue let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] From 8540ac71c8562959ab1b2cb71d1d50f0e97a2104 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:04:22 +0900 Subject: [PATCH 120/499] Update swift code generation script --- bin/swift-petstore.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/swift-petstore.sh b/bin/swift-petstore.sh index ce6a7e702f0..4436ed8774d 100755 --- a/bin/swift-petstore.sh +++ b/bin/swift-petstore.sh @@ -28,4 +28,4 @@ fi export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift" -java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags +java -DsuppressRequired=true -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags From 24465d2df493b501845e191f1b0dca74449b9a94 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:04:45 +0900 Subject: [PATCH 121/499] Change model naming --- .../wordnik/swagger/codegen/languages/SwiftGenerator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java index 697bdefef8f..f67834c5540 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java @@ -127,7 +127,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { @Override public String escapeReservedWord(String name) { - return "_" + name; // add an underscore to the name + return "Swagger" + name; // add an underscore to the name } @Override @@ -202,6 +202,9 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { codegenProperty.allowableValues.put("values", swiftEnums); codegenProperty.datatypeWithEnum = StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); + if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { + codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); + } } return codegenProperty; } From bcab55e3efc07feeaafb301d681937b873ea07a0 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:05:02 +0900 Subject: [PATCH 122/499] Tighten parameter requirement --- modules/swagger-codegen/src/main/resources/swift/api.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index fc009c63f2a..3caec601879 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -32,12 +32,12 @@ extension {{projectName}}API { :returns: Promise> {{description}} */ - func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { + func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} From febaa340e3cadea6f5689589dd7c207cef8bdbd9 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:05:32 +0900 Subject: [PATCH 123/499] Treat object as String (temporary measure) --- .../com/wordnik/swagger/codegen/languages/SwiftGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java index f67834c5540..4f2bb6fa24b 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java @@ -119,7 +119,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { typeMapping.put("float", "Float"); typeMapping.put("number", "Double"); typeMapping.put("double", "Double"); - typeMapping.put("object", "AnyObject"); + typeMapping.put("object", "String"); typeMapping.put("file", "NSData"); importMapping = new HashMap(); From fa3a9a9d61a880a9dbf8589edf1dd40b81093c69 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 23 Jun 2015 10:22:05 +0900 Subject: [PATCH 124/499] Change class package --- .../codegen/languages/SwiftGenerator.java | 259 ---------- .../codegen/languages/SwiftGenerator.java | 442 +++++++++--------- 2 files changed, 219 insertions(+), 482 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java deleted file mode 100644 index 4f2bb6fa24b..00000000000 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.wordnik.swagger.codegen.languages; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.wordnik.swagger.codegen.*; -import com.wordnik.swagger.models.Model; -import com.wordnik.swagger.models.Operation; -import com.wordnik.swagger.models.parameters.HeaderParameter; -import com.wordnik.swagger.models.parameters.Parameter; -import com.wordnik.swagger.models.properties.*; -import org.apache.commons.lang.StringUtils; - -import javax.annotation.Nullable; -import java.util.*; -import java.io.File; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { - private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); - protected String sourceFolder = "Classes/Swaggers"; - - public CodegenType getTag() { - return CodegenType.CLIENT; - } - - public String getName() { - return "swift"; - } - - public String getHelp() { - return "Generates a swift client library."; - } - - public SwiftGenerator() { - super(); - outputFolder = "generated-code/swift"; - modelTemplateFiles.put("model.mustache", ".swift"); - apiTemplateFiles.put("api.mustache", ".swift"); - templateDir = "swift"; - apiPackage = "/APIs"; - modelPackage = "/Models"; - - // Inject application name - String appName = System.getProperty("appName"); - if (appName == null) { - appName = "SwaggerClient"; - } - additionalProperties.put("projectName", appName); - - // Inject base url override - String basePathOverride = System.getProperty("basePathOverride"); - if (basePathOverride != null) { - additionalProperties.put("basePathOverride", basePathOverride); - } - - // Make all the variable optional - String suppressRequired = System.getProperty("suppressRequired"); - if (suppressRequired != null) { - additionalProperties.put("suppressRequired", suppressRequired); - } - - sourceFolder = appName + "/" + sourceFolder; - - supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); - supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); - supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift")); - supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift")); - supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); - supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - - languageSpecificPrimitives = new HashSet( - Arrays.asList( - "Int", - "Float", - "Double", - "Bool", - "Void", - "String", - "Character") - ); - defaultIncludes = new HashSet( - Arrays.asList( - "NSDate", - "Array", - "Dictionary", - "Set", - "Any", - "Empty", - "AnyObject") - ); - reservedWords = new HashSet( - Arrays.asList( - "class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue", - "false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else", - "self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if", - "true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol", - "switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional", - "struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol", - "required", "right", "set", "Type", "unowned", "weak") - ); - - typeMapping = new HashMap(); - typeMapping.put("array", "Array"); - typeMapping.put("List", "Array"); - typeMapping.put("map", "Dictionary"); - typeMapping.put("date", "NSDate"); - typeMapping.put("Date", "NSDate"); - typeMapping.put("DateTime", "NSDate"); - typeMapping.put("boolean", "Bool"); - typeMapping.put("string", "String"); - typeMapping.put("char", "Character"); - typeMapping.put("short", "Int"); - typeMapping.put("int", "Int"); - typeMapping.put("long", "Int"); - typeMapping.put("integer", "Int"); - typeMapping.put("Integer", "Int"); - typeMapping.put("float", "Float"); - typeMapping.put("number", "Double"); - typeMapping.put("double", "Double"); - typeMapping.put("object", "String"); - typeMapping.put("file", "NSData"); - - importMapping = new HashMap(); - } - - @Override - public String escapeReservedWord(String name) { - return "Swagger" + name; // add an underscore to the name - } - - @Override - public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); - } - - @Override - public String apiFileFolder() { - return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); - } - - @Override - public String getTypeDeclaration(Property p) { - if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - Property inner = ap.getItems(); - return "[" + getTypeDeclaration(inner) + "]"; - } else if (p instanceof MapProperty) { - MapProperty mp = (MapProperty) p; - Property inner = mp.getAdditionalProperties(); - return "[String:" + getTypeDeclaration(inner) + "]"; - } - return super.getTypeDeclaration(p); - } - - @Override - public String getSwaggerType(Property p) { - String swaggerType = super.getSwaggerType(p); - String type = null; - if (typeMapping.containsKey(swaggerType)) { - type = typeMapping.get(swaggerType); - if (languageSpecificPrimitives.contains(type)) - return toModelName(type); - } else - type = swaggerType; - return toModelName(type); - } - - @Override - public String toDefaultValue(Property p) { - // nil - return null; - } - - @Override - public String toInstantiationType(Property p) { - if (p instanceof MapProperty) { - MapProperty ap = (MapProperty) p; - String inner = getSwaggerType(ap.getAdditionalProperties()); - return "[String:" + inner + "]"; - } else if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - String inner = getSwaggerType(ap.getItems()); - return "[" + inner + "]"; - } - return null; - } - - @Override - public CodegenProperty fromProperty(String name, Property p) { - CodegenProperty codegenProperty = super.fromProperty(name, p); - if (codegenProperty.isEnum) { - List> swiftEnums = new ArrayList>(); - List values = (List) codegenProperty.allowableValues.get("values"); - for (String value : values) { - Map map = new HashMap(); - map.put("enum", StringUtils.capitalize(value)); - map.put("raw", value); - swiftEnums.add(map); - } - codegenProperty.allowableValues.put("values", swiftEnums); - codegenProperty.datatypeWithEnum = - StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); - if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { - codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); - } - } - return codegenProperty; - } - - @Override - public String toApiName(String name) { - if(name.length() == 0) - return "DefaultAPI"; - return initialCaps(name) + "API"; - } - - @Override - public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { - path = normalizePath(path); - List parameters = operation.getParameters(); - parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { - @Override - public boolean apply(@Nullable Parameter parameter) { - return !(parameter instanceof HeaderParameter); - } - })); - operation.setParameters(parameters); - return super.fromOperation(path, httpMethod, operation, definitions); - } - - private static String normalizePath(String path) { - StringBuilder builder = new StringBuilder(); - - int cursor = 0; - Matcher matcher = PATH_PARAM_PATTERN.matcher(path); - boolean found = matcher.find(); - while (found) { - String stringBeforeMatch = path.substring(cursor, matcher.start()); - builder.append(stringBeforeMatch); - - String group = matcher.group().substring(1, matcher.group().length() - 1); - group = camelize(group, true); - builder - .append("{") - .append(group) - .append("}"); - - cursor = matcher.end(); - found = matcher.find(); - } - - String stringAfterMatch = path.substring(cursor); - builder.append(stringAfterMatch); - - return builder.toString(); - } -} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java index 2b384f36a7d..15ca6dc1556 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java @@ -3,12 +3,7 @@ package io.swagger.codegen.languages; import com.google.common.base.Predicate; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; -import io.swagger.codegen.CodegenConfig; -import io.swagger.codegen.CodegenOperation; -import io.swagger.codegen.CodegenProperty; -import io.swagger.codegen.CodegenType; -import io.swagger.codegen.DefaultCodegen; -import io.swagger.codegen.SupportingFile; +import io.swagger.codegen.*; import io.swagger.models.Model; import io.swagger.models.Operation; import io.swagger.models.parameters.HeaderParameter; @@ -19,247 +14,248 @@ import io.swagger.models.properties.Property; import org.apache.commons.lang.StringUtils; import javax.annotation.Nullable; +import java.util.*; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { - private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); - protected String sourceFolder = "Classes/Swaggers"; + private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); + protected String sourceFolder = "Classes/Swaggers"; - public SwiftGenerator() { - super(); - outputFolder = "generated-code/swift"; - modelTemplateFiles.put("model.mustache", ".swift"); - apiTemplateFiles.put("api.mustache", ".swift"); - templateDir = "swift"; - apiPackage = "/APIs"; - modelPackage = "/Models"; + public CodegenType getTag() { + return CodegenType.CLIENT; + } - // Inject application name - String appName = System.getProperty("appName"); - if (appName == null) { - appName = "SwaggerClient"; - } - additionalProperties.put("projectName", appName); + public String getName() { + return "swift"; + } - // Inject base url override - String basePathOverride = System.getProperty("basePathOverride"); - if (basePathOverride != null) { - additionalProperties.put("basePathOverride", basePathOverride); - } + public String getHelp() { + return "Generates a swift client library."; + } - sourceFolder = appName + "/" + sourceFolder; + public SwiftGenerator() { + super(); + outputFolder = "generated-code/swift"; + modelTemplateFiles.put("model.mustache", ".swift"); + apiTemplateFiles.put("api.mustache", ".swift"); + templateDir = "swift"; + apiPackage = "/APIs"; + modelPackage = "/Models"; - supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); - supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); - supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift")); - supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift")); - supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); - supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); + // Inject application name + String appName = System.getProperty("appName"); + if (appName == null) { + appName = "SwaggerClient"; + } + additionalProperties.put("projectName", appName); - languageSpecificPrimitives = new HashSet( - Arrays.asList( - "Int", - "Float", - "Double", - "Bool", - "Void", - "String", - "Character") - ); - defaultIncludes = new HashSet( - Arrays.asList( - "NSDate", - "Array", - "Dictionary", - "Set", - "Any", - "Empty", - "AnyObject") - ); - reservedWords = new HashSet( - Arrays.asList( - "class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue", - "false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else", - "self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if", - "true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol", - "switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional", - "struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol", - "required", "right", "set", "Type", "unowned", "weak") - ); - - typeMapping = new HashMap(); - typeMapping.put("array", "Array"); - typeMapping.put("List", "Array"); - typeMapping.put("map", "Dictionary"); - typeMapping.put("date", "NSDate"); - typeMapping.put("Date", "NSDate"); - typeMapping.put("DateTime", "NSDate"); - typeMapping.put("boolean", "Bool"); - typeMapping.put("string", "String"); - typeMapping.put("char", "Character"); - typeMapping.put("short", "Int"); - typeMapping.put("int", "Int"); - typeMapping.put("long", "Int"); - typeMapping.put("integer", "Int"); - typeMapping.put("Integer", "Int"); - typeMapping.put("float", "Float"); - typeMapping.put("number", "Double"); - typeMapping.put("double", "Double"); - typeMapping.put("object", "AnyObject"); - typeMapping.put("file", "NSData"); - - importMapping = new HashMap(); + // Inject base url override + String basePathOverride = System.getProperty("basePathOverride"); + if (basePathOverride != null) { + additionalProperties.put("basePathOverride", basePathOverride); } - private static String normalizePath(String path) { - StringBuilder builder = new StringBuilder(); - - int cursor = 0; - Matcher matcher = PATH_PARAM_PATTERN.matcher(path); - boolean found = matcher.find(); - while (found) { - String stringBeforeMatch = path.substring(cursor, matcher.start()); - builder.append(stringBeforeMatch); - - String group = matcher.group().substring(1, matcher.group().length() - 1); - group = camelize(group, true); - builder - .append("{") - .append(group) - .append("}"); - - cursor = matcher.end(); - found = matcher.find(); - } - - String stringAfterMatch = path.substring(cursor); - builder.append(stringAfterMatch); - - return builder.toString(); + // Make all the variable optional + String suppressRequired = System.getProperty("suppressRequired"); + if (suppressRequired != null) { + additionalProperties.put("suppressRequired", suppressRequired); } - public CodegenType getTag() { - return CodegenType.CLIENT; - } + sourceFolder = appName + "/" + sourceFolder; - public String getName() { - return "swift"; - } + supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); + supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); + supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift")); + supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift")); + supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); + supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - public String getHelp() { - return "Generates a swift client library."; - } + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "Int", + "Float", + "Double", + "Bool", + "Void", + "String", + "Character") + ); + defaultIncludes = new HashSet( + Arrays.asList( + "NSDate", + "Array", + "Dictionary", + "Set", + "Any", + "Empty", + "AnyObject") + ); + reservedWords = new HashSet( + Arrays.asList( + "class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue", + "false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else", + "self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if", + "true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol", + "switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional", + "struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol", + "required", "right", "set", "Type", "unowned", "weak") + ); - @Override - public String escapeReservedWord(String name) { - return "_" + name; // add an underscore to the name - } + typeMapping = new HashMap(); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Dictionary"); + typeMapping.put("date", "NSDate"); + typeMapping.put("Date", "NSDate"); + typeMapping.put("DateTime", "NSDate"); + typeMapping.put("boolean", "Bool"); + typeMapping.put("string", "String"); + typeMapping.put("char", "Character"); + typeMapping.put("short", "Int"); + typeMapping.put("int", "Int"); + typeMapping.put("long", "Int"); + typeMapping.put("integer", "Int"); + typeMapping.put("Integer", "Int"); + typeMapping.put("float", "Float"); + typeMapping.put("number", "Double"); + typeMapping.put("double", "Double"); + typeMapping.put("object", "String"); + typeMapping.put("file", "NSData"); - @Override - public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); - } + importMapping = new HashMap(); + } - @Override - public String apiFileFolder() { - return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); - } + @Override + public String escapeReservedWord(String name) { + return "Swagger" + name; // add an underscore to the name + } - @Override - public String getTypeDeclaration(Property p) { - if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - Property inner = ap.getItems(); - return "[" + getTypeDeclaration(inner) + "]"; - } else if (p instanceof MapProperty) { - MapProperty mp = (MapProperty) p; - Property inner = mp.getAdditionalProperties(); - return "[String:" + getTypeDeclaration(inner) + "]"; - } - return super.getTypeDeclaration(p); - } + @Override + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); + } - @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; - } + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return "[" + getTypeDeclaration(inner) + "]"; + } else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return "[String:" + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) return toModelName(type); + } else + type = swaggerType; + return toModelName(type); + } + + @Override + public String toDefaultValue(Property p) { + // nil + return null; + } + + @Override + public String toInstantiationType(Property p) { + if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return "[String:" + inner + "]"; + } else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return "[" + inner + "]"; + } + return null; + } + + @Override + public CodegenProperty fromProperty(String name, Property p) { + CodegenProperty codegenProperty = super.fromProperty(name, p); + if (codegenProperty.isEnum) { + List> swiftEnums = new ArrayList>(); + List values = (List) codegenProperty.allowableValues.get("values"); + for (String value : values) { + Map map = new HashMap(); + map.put("enum", StringUtils.capitalize(value)); + map.put("raw", value); + swiftEnums.add(map); + } + codegenProperty.allowableValues.put("values", swiftEnums); + codegenProperty.datatypeWithEnum = + StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); + if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { + codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); + } + } + return codegenProperty; + } + + @Override + public String toApiName(String name) { + if(name.length() == 0) + return "DefaultAPI"; + return initialCaps(name) + "API"; + } + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { + path = normalizePath(path); + List parameters = operation.getParameters(); + parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { + @Override + public boolean apply(@Nullable Parameter parameter) { + return !(parameter instanceof HeaderParameter); + } + })); + operation.setParameters(parameters); + return super.fromOperation(path, httpMethod, operation, definitions); + } + + private static String normalizePath(String path) { + StringBuilder builder = new StringBuilder(); + + int cursor = 0; + Matcher matcher = PATH_PARAM_PATTERN.matcher(path); + boolean found = matcher.find(); + while (found) { + String stringBeforeMatch = path.substring(cursor, matcher.start()); + builder.append(stringBeforeMatch); + + String group = matcher.group().substring(1, matcher.group().length() - 1); + group = camelize(group, true); + builder + .append("{") + .append(group) + .append("}"); + + cursor = matcher.end(); + found = matcher.find(); } - @Override - public String toDefaultValue(Property p) { - // nil - return null; - } + String stringAfterMatch = path.substring(cursor); + builder.append(stringAfterMatch); - @Override - public String toInstantiationType(Property p) { - if (p instanceof MapProperty) { - MapProperty ap = (MapProperty) p; - String inner = getSwaggerType(ap.getAdditionalProperties()); - return "[String:" + inner + "]"; - } else if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - String inner = getSwaggerType(ap.getItems()); - return "[" + inner + "]"; - } - return null; - } - - @Override - public CodegenProperty fromProperty(String name, Property p) { - CodegenProperty codegenProperty = super.fromProperty(name, p); - if (codegenProperty.isEnum) { - List> swiftEnums = new ArrayList>(); - List values = (List) codegenProperty.allowableValues.get("values"); - for (String value : values) { - Map map = new HashMap(); - map.put("enum", StringUtils.capitalize(value)); - map.put("raw", value); - swiftEnums.add(map); - } - codegenProperty.allowableValues.put("values", swiftEnums); - codegenProperty.datatypeWithEnum = - StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); - } - return codegenProperty; - } - - @Override - public String toApiName(String name) { - if (name.length() == 0) { - return "DefaultAPI"; - } - return initialCaps(name) + "API"; - } - - @Override - public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { - path = normalizePath(path); - List parameters = operation.getParameters(); - parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { - @Override - public boolean apply(@Nullable Parameter parameter) { - return !(parameter instanceof HeaderParameter); - } - })); - operation.setParameters(parameters); - return super.fromOperation(path, httpMethod, operation, definitions); - } + return builder.toString(); + } } \ No newline at end of file From 79e31a5761860edaa860b2f359340d2032ac35e3 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 23 Jun 2015 11:59:49 +0900 Subject: [PATCH 125/499] Add a workaround against void forcibly being converted to string --- .../main/resources/swift/AlamofireImplementations.mustache | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index 37edceea13c..edc7a51a169 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -61,6 +61,12 @@ class AlamofireRequestBuilder: RequestBuilder { let response = Response(response: res!, body: body) defer.fulfill(response) return + } else if "" is T { + // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release + // https://github.com/swagger-api/swagger-parser/pull/34 + let response = Response(response: res!, body: "" as! T) + defer.fulfill(response) + return } defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) From c93b0dd3b80e9bd735e3c831f8dddbfc2a5020fa Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 20:24:19 -0700 Subject: [PATCH 126/499] make srcBasePath configureable --- .../codegen/languages/PhpClientCodegen.java | 24 ++++++++++++++----- .../src/main/resources/php/autoload.mustache | 4 ++-- .../src/main/resources/php/composer.mustache | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 72fba6c54ce..71b0d67d215 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -25,6 +25,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { protected String artifactId = "swagger-client"; protected String packagePath = "SwaggerClient-php"; protected String artifactVersion = null; + protected String srcBasePath = "lib"; public PhpClientCodegen() { super(); @@ -44,6 +45,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { additionalProperties.put("invokerPackage", invokerPackage); additionalProperties.put("modelPackage", modelPackage); additionalProperties.put("apiPackage", apiPackage); + additionalProperties.put("srcBasePath", srcBasePath); additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); additionalProperties.put("groupId", groupId); additionalProperties.put("artifactId", artifactId); @@ -89,6 +91,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("DateTime", "\\DateTime"); cliOptions.add(new CliOption("packagePath", "main package name for classes")); + cliOptions.add(new CliOption("srcBasePath", "directory directory under packagePath to serve as source root")); } public String getPackagePath() { @@ -130,6 +133,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.setPackagePath((String) additionalProperties.get("packagePath")); } + if (additionalProperties.containsKey("srcBasePath")) { + this.setSrcBasePath((String) additionalProperties.get("srcBasePath")); + } + if (additionalProperties.containsKey("modelPackage")) { this.setModelPackage(invokerPackage + "\\" + additionalProperties.get("modelPackage")); } @@ -138,14 +145,15 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.setApiPackage(invokerPackage + "\\" + additionalProperties.get("apiPackage")); } + additionalProperties.replace("srcBasePath", srcBasePath); additionalProperties.replace("modelPackage", modelPackage); additionalProperties.replace("apiPackage", apiPackage); additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); - supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, "lib"), "ApiClientConfiguration.php")); - supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); - supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); - supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, "lib"), "ObjectSerializer.php")); + supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClientConfiguration.php")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClient.php")); + supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiException.php")); + supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php")); supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); } @@ -157,11 +165,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return (outputFolder + "/" + toPackagePath(apiPackage(), "lib")); + return (outputFolder + "/" + toPackagePath(apiPackage(), srcBasePath)); } public String modelFileFolder() { - return (outputFolder + "/" + toPackagePath(modelPackage(), "lib")); + return (outputFolder + "/" + toPackagePath(modelPackage(), srcBasePath)); } @Override @@ -222,6 +230,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.packagePath = packagePath; } + public void setSrcBasePath(String srcBasePath) { + this.srcBasePath = srcBasePath; + } + @Override public String toVarName(String name) { // parameter name starting with number won't compile diff --git a/modules/swagger-codegen/src/main/resources/php/autoload.mustache b/modules/swagger-codegen/src/main/resources/php/autoload.mustache index 4f56a6e20c0..04be6e11992 100644 --- a/modules/swagger-codegen/src/main/resources/php/autoload.mustache +++ b/modules/swagger-codegen/src/main/resources/php/autoload.mustache @@ -4,7 +4,7 @@ * * After registering this autoload function with SPL, the following line * would cause the function to attempt to load the \{{invokerPackage}}\Baz\Qux class - * from /path/to/project/lib/Baz/Qux.php: + * from /path/to/project/{{srcBasePath}}/Baz/Qux.php: * * new \{{invokerPackage}}\Baz\Qux; * @@ -17,7 +17,7 @@ spl_autoload_register(function ($class) { $prefix = '{{escapedInvokerPackage}}\\'; // base directory for the namespace prefix - $base_dir = __DIR__ . '/lib/'; + $base_dir = __DIR__ . '/{{srcBasePath}}/'; // does the class use the namespace prefix? $len = strlen($prefix); diff --git a/modules/swagger-codegen/src/main/resources/php/composer.mustache b/modules/swagger-codegen/src/main/resources/php/composer.mustache index f4e38c84f73..d36267617c4 100644 --- a/modules/swagger-codegen/src/main/resources/php/composer.mustache +++ b/modules/swagger-codegen/src/main/resources/php/composer.mustache @@ -28,6 +28,6 @@ "squizlabs/php_codesniffer": "~2.0" }, "autoload": { - "psr-4": { "{{escapedInvokerPackage}}\\" : "lib/" } + "psr-4": { "{{escapedInvokerPackage}}\\" : "{{srcBasePath}}/" } } } From 8e0142338ecf63ff1cc84f635d8edb296e650aee Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 20:36:57 -0700 Subject: [PATCH 127/499] removing unused imports --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 71b0d67d215..7a67a6c3b34 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -11,13 +11,9 @@ import io.swagger.models.properties.Property; import io.swagger.models.properties.RefProperty; import java.io.File; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { protected String invokerPackage = "Swagger\\Client"; From 5a9e9550ca9a5701a222ca89f229082efa9c60de Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 20:43:00 -0700 Subject: [PATCH 128/499] fixing php-doc --- .../swagger-codegen/src/main/resources/php/ApiClient.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 15726db05ea..e96961975d8 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -194,7 +194,7 @@ class ApiClient { /* * return the content type based on an array of content-type provided * - * @param array[string] content_type_array Array fo content-type + * @param string[] content_type_array Array fo content-type * @return string Content-Type (e.g. application/json) */ public static function selectHeaderContentType($content_type) { From 46ec934a9c065a3d4146f958d6cd171f72565002 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 20:49:12 -0700 Subject: [PATCH 129/499] java7 doesn't have replace, but put operates as such, so switch to that --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 7a67a6c3b34..9967980c53a 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -141,9 +141,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { this.setApiPackage(invokerPackage + "\\" + additionalProperties.get("apiPackage")); } - additionalProperties.replace("srcBasePath", srcBasePath); - additionalProperties.replace("modelPackage", modelPackage); - additionalProperties.replace("apiPackage", apiPackage); + additionalProperties.put("srcBasePath", srcBasePath); + additionalProperties.put("modelPackage", modelPackage); + additionalProperties.put("apiPackage", apiPackage); additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClientConfiguration.php")); From 6623e120cd22d6f490b8003ca3fe5488e0c0063b Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 20:53:59 -0700 Subject: [PATCH 130/499] renaming to Configuration --- .../codegen/languages/PhpClientCodegen.java | 2 +- .../src/main/resources/php/ApiClient.mustache | 10 +- .../php/ApiClientConfiguration.mustache | 257 ------------------ .../src/main/resources/php/api.mustache | 2 +- .../main/resources/php/configuration.mustache | 232 +++++++++++++++- 5 files changed, 225 insertions(+), 278 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 9967980c53a..550aa151f23 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -146,7 +146,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { additionalProperties.put("apiPackage", apiPackage); additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); - supportingFiles.add(new SupportingFile("ApiClientConfiguration.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClientConfiguration.php")); + supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, srcBasePath), "Configuration.php")); supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClient.php")); supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiException.php")); supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php")); diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index e96961975d8..488857c3a00 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -26,16 +26,16 @@ class ApiClient { public static $DELETE = "DELETE"; /** - * @var ApiClientConfiguration + * @var Configuration */ protected $config; /** - * @param ApiClientConfiguration $config config for this ApiClient + * @param Configuration $config config for this ApiClient */ - function __construct(ApiClientConfiguration $config = null) { + function __construct(Configuration $config = null) { if ($config == null) { - $config = ApiClientConfiguration::getDefaultConfiguration(); + $config = Configuration::getDefaultConfiguration(); } $this->config = $config; @@ -43,7 +43,7 @@ class ApiClient { /** * get the config - * @return ApiClientConfiguration + * @return Configuration */ public function getConfig() { return $this->config; diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache deleted file mode 100644 index 491f5a45dd8..00000000000 --- a/modules/swagger-codegen/src/main/resources/php/ApiClientConfiguration.mustache +++ /dev/null @@ -1,257 +0,0 @@ -apiKeys[$key] = $value; - return $this; - } - - /** - * @param $key - * @return string - */ - public function getApiKey($key) { - return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null; - } - - /** - * @param string $key - * @param string $value - * @return ApiClientConfiguration - */ - public function setApiKeyPrefix($key, $value) { - $this->apiKeyPrefixes[$key] = $value; - return $this; - } - - /** - * @param $key - * @return string - */ - public function getApiKeyPrefix($key) { - return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null; - } - - /** - * @param string $username - * @return ApiClientConfiguration - */ - public function setUsername($username) { - $this->username = $username; - return $this; - } - - /** - * @return string - */ - public function getUsername() { - return $this->username; - } - - /** - * @param string $password - * @return ApiClientConfiguration - */ - public function setPassword($password) { - $this->password = $password; - return $this; - } - - /** - * @return string - */ - public function getPassword() { - return $this->password; - } - - /** - * add default header - * - * @param string $headerName header name (e.g. Token) - * @param string $headerValue header value (e.g. 1z8wp3) - * @return ApiClient - */ - public function addDefaultHeader($headerName, $headerValue) { - if (!is_string($headerName)) { - throw new \InvalidArgumentException('Header name must be a string.'); - } - - $this->defaultHeaders[$headerName] = $headerValue; - return $this; - } - - /** - * get the default header - * - * @return array default header - */ - public function getDefaultHeaders() { - return $this->defaultHeaders; - } - - /** - * @param string $host - * @return ApiClientConfiguration - */ - public function setHost($host) { - $this->host = $host; - return $this; - } - - /** - * @return string - */ - public function getHost() { - return $this->host; - } - - /** - * set the user agent of the api client - * - * @param string $userAgent the user agent of the api client - * @return ApiClient - */ - public function setUserAgent($userAgent) { - if (!is_string($userAgent)) { - throw new \InvalidArgumentException('User-agent must be a string.'); - } - - $this->userAgent = $userAgent; - return $this; - } - - /** - * get the user agent of the api client - * - * @return string user agent - */ - public function getUserAgent() { - return $this->userAgent; - } - - /** - * set the HTTP timeout value - * - * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] - * @return ApiClient - */ - public function setCurlTimeout($seconds) { - if (!is_numeric($seconds) || $seconds < 0) { - throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); - } - - $this->curlTimeout = $seconds; - return $this; - } - - /** - * get the HTTP timeout value - * - * @return string HTTP timeout value - */ - public function getCurlTimeout() { - return $this->curlTimeout; - } - - /** - * @param bool $debug - * @return ApiClientConfiguration - */ - public function setDebug($debug) { - $this->debug = $debug; - return $this; - } - - /** - * @return bool - */ - public function getDebug() { - return $this->debug; - } - - /** - * @param string $debugFile - * @return ApiClientConfiguration - */ - public function setDebugFile($debugFile) { - $this->debugFile = $debugFile; - return $this; - } - - /** - * @return string - */ - public function getDebugFile() { - return $this->debugFile; - } - - /** - * @return ApiClientConfiguration - */ - public static function getDefaultConfiguration() { - if (self::$defaultConfiguration == null) { - return new ApiClientConfiguration(); - } - - return self::$defaultConfiguration; - } - - public static function setDefaultConfiguration(ApiClientConfiguration $config) { - self::$defaultConfiguration = $config; - } -} diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index c9d21ca81b1..23f8f494aef 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -22,7 +22,7 @@ namespace {{apiPackage}}; -use \{{invokerPackage}}\ApiClientConfiguration; +use \{{invokerPackage}}\Configuration; use \{{invokerPackage}}\ApiClient; use \{{invokerPackage}}\ApiException; use \{{invokerPackage}}\ObjectSerializer; diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/configuration.mustache index 030910ffca7..a0cae318c2d 100644 --- a/modules/swagger-codegen/src/main/resources/php/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/configuration.mustache @@ -17,37 +17,241 @@ namespace {{invokerPackage}}; -use \{{invokerPackage}}\ApiClient; - class Configuration { + private static $defaultConfiguration = null; + /** @var string[] Associate array to store API key(s) */ - public static $apiKey = array(); + protected $apiKeys = array(); /** string[] Associate array to store API prefix (e.g. Bearer) */ - public static $apiKeyPrefix = array(); + protected $apiKeyPrefixes = array(); /** @var string Username for HTTP basic authentication */ - public static $username = ''; + protected $username = ''; /** @var string Password for HTTP basic authentication */ - public static $password = ''; + protected $password = ''; /** @var \{{invokerPackage}}\ApiClient The default instance of ApiClient */ - public static $apiClient; + protected $defaultHeaders = array(); + + /** @var string The host */ + protected $host = 'http://localhost'; + + /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ + protected $curlTimeout = 0; + + /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ + protected $userAgent = "PHP-Swagger"; /** @var bool Debug switch (default set to false) */ - public static $debug = false; + protected $debug = false; /** @var string Debug file location (log to STDOUT by default) */ - public static $debug_file = 'php://output'; + protected $debugFile = 'php://output'; - /* - * manually initalize ApiClient + /** + * @param string $key + * @param string $value + * @return Configuration */ - public static function init() { - if (self::$apiClient === null) - self::$apiClient = new ApiClient(); + public function setApiKey($key, $value) { + $this->apiKeys[$key] = $value; + return $this; } + /** + * @param $key + * @return string + */ + public function getApiKey($key) { + return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null; + } + + /** + * @param string $key + * @param string $value + * @return Configuration + */ + public function setApiKeyPrefix($key, $value) { + $this->apiKeyPrefixes[$key] = $value; + return $this; + } + + /** + * @param $key + * @return string + */ + public function getApiKeyPrefix($key) { + return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null; + } + + /** + * @param string $username + * @return Configuration + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * @param string $password + * @return Configuration + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * add default header + * + * @param string $headerName header name (e.g. Token) + * @param string $headerValue header value (e.g. 1z8wp3) + * @return ApiClient + */ + public function addDefaultHeader($headerName, $headerValue) { + if (!is_string($headerName)) { + throw new \InvalidArgumentException('Header name must be a string.'); + } + + $this->defaultHeaders[$headerName] = $headerValue; + return $this; + } + + /** + * get the default header + * + * @return array default header + */ + public function getDefaultHeaders() { + return $this->defaultHeaders; + } + + /** + * @param string $host + * @return Configuration + */ + public function setHost($host) { + $this->host = $host; + return $this; + } + + /** + * @return string + */ + public function getHost() { + return $this->host; + } + + /** + * set the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * @return ApiClient + */ + public function setUserAgent($userAgent) { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * get the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() { + return $this->userAgent; + } + + /** + * set the HTTP timeout value + * + * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + * @return ApiClient + */ + public function setCurlTimeout($seconds) { + if (!is_numeric($seconds) || $seconds < 0) { + throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); + } + + $this->curlTimeout = $seconds; + return $this; + } + + /** + * get the HTTP timeout value + * + * @return string HTTP timeout value + */ + public function getCurlTimeout() { + return $this->curlTimeout; + } + + /** + * @param bool $debug + * @return Configuration + */ + public function setDebug($debug) { + $this->debug = $debug; + return $this; + } + + /** + * @return bool + */ + public function getDebug() { + return $this->debug; + } + + /** + * @param string $debugFile + * @return Configuration + */ + public function setDebugFile($debugFile) { + $this->debugFile = $debugFile; + return $this; + } + + /** + * @return string + */ + public function getDebugFile() { + return $this->debugFile; + } + + /** + * @return Configuration + */ + public static function getDefaultConfiguration() { + if (self::$defaultConfiguration == null) { + return new Configuration(); + } + + return self::$defaultConfiguration; + } + + public static function setDefaultConfiguration(Configuration $config) { + self::$defaultConfiguration = $config; + } } From 60b0ffeb0eeb93b47bc82372f2d3204bcd5b5110 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 21:06:22 -0700 Subject: [PATCH 131/499] don't prepend the invokerPackage - an artifact from an earlier implementation --- .../io/swagger/codegen/languages/PhpClientCodegen.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 550aa151f23..20e8d20c5ed 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -30,8 +30,8 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { modelTemplateFiles.put("model.mustache", ".php"); apiTemplateFiles.put("api.mustache", ".php"); templateDir = "php"; - apiPackage = "Api"; - modelPackage = "Model"; + apiPackage = invokerPackage + "\\Api"; + modelPackage = invokerPackage + "\\Model"; reservedWords = new HashSet( Arrays.asList( @@ -134,11 +134,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { } if (additionalProperties.containsKey("modelPackage")) { - this.setModelPackage(invokerPackage + "\\" + additionalProperties.get("modelPackage")); + this.setModelPackage((String) additionalProperties.get("modelPackage")); } if (additionalProperties.containsKey("apiPackage")) { - this.setApiPackage(invokerPackage + "\\" + additionalProperties.get("apiPackage")); + this.setApiPackage((String) additionalProperties.get("apiPackage")); } additionalProperties.put("srcBasePath", srcBasePath); From 2fced0f6342a4594c2f8a000cef9f266a2e68d66 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 21:12:13 -0700 Subject: [PATCH 132/499] Revert "Updates to csharp model template to support inheritance" This reverts commit 5f1df9e093eaf7b584c98879b4e05dcf1ac8c58f. --- .../src/main/resources/csharp/model.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/csharp/model.mustache b/modules/swagger-codegen/src/main/resources/csharp/model.mustache index 111c98993a2..ce0e62de192 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/model.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/model.mustache @@ -13,7 +13,7 @@ namespace {{package}} { /// {{description}} /// [DataContract] - public class {{classname}}{{#parent}} : {{{parent}}}{{/parent}} { + public class {{classname}} { {{#vars}} {{#description}}/* {{{description}}} */{{/description}} [DataMember(Name="{{baseName}}", EmitDefaultValue=false)] @@ -39,11 +39,11 @@ namespace {{package}} { /// Get the JSON string presentation of the object /// /// JSON string presentation of the object - public {{#parent}} new {{/parent}}string ToJson() { + public string ToJson() { return JsonConvert.SerializeObject(this, Formatting.Indented); } } {{/model}} {{/models}} -} \ No newline at end of file +} From c91a1b963bb8548f807ecbfe8b22c1e27f8f9a8a Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Mon, 22 Jun 2015 21:33:44 -0700 Subject: [PATCH 133/499] change serializer to be instanced, rather than static methods --- .../src/main/resources/php/ApiClient.mustache | 18 ++++++++--- .../resources/php/ObjectSerializer.mustache | 32 +++++++++---------- .../src/main/resources/php/api.mustache | 12 +++---- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 488857c3a00..2862a0e0538 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -25,11 +25,12 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; + /** @var ObjectSerializer */ + protected $serializer; + /** * @param Configuration $config config for this ApiClient */ @@ -39,6 +40,7 @@ class ApiClient { } $this->config = $config; + $this->serializer = new ObjectSerializer(); } /** @@ -49,6 +51,14 @@ class ApiClient { return $this->config; } + /** + * get the serializer + * @return ObjectSerializer + */ + public function getSerializer() { + return $this->serializer; + } + /** * Get API key (with prefix if set) * @param string $apiKey name of apikey @@ -96,7 +106,7 @@ class ApiClient { $postData = http_build_query($postData); } else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model - $postData = json_encode(ObjectSerializer::sanitizeForSerialization($postData)); + $postData = json_encode($this->serializer->sanitizeForSerialization($postData)); } $url = $this->config->getHost() . $resourcePath; diff --git a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache index 4880a8106d0..56a61e97c91 100644 --- a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache @@ -8,14 +8,14 @@ class ObjectSerializer { * @param mixed $data the data to serialize * @return string serialized form of $data */ - public static function sanitizeForSerialization($data) { + public function sanitizeForSerialization($data) { if (is_scalar($data) || null === $data) { $sanitized = $data; } else if ($data instanceof \DateTime) { $sanitized = $data->format(\DateTime::ISO8601); } else if (is_array($data)) { foreach ($data as $property => $value) { - $data[$property] = self::sanitizeForSerialization($value); + $data[$property] = $this->sanitizeForSerialization($value); } $sanitized = $data; } else if (is_object($data)) { @@ -23,7 +23,7 @@ class ObjectSerializer { foreach (array_keys($data::$swaggerTypes) as $property) { $getter = $data::$getters[$property]; if ($data->$getter() !== null) { - $values[$data::$attributeMap[$property]] = self::sanitizeForSerialization($data->$getter()); + $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$getter()); } } $sanitized = $values; @@ -40,8 +40,8 @@ class ObjectSerializer { * @param string $value a string which will be part of the path * @return string the serialized object */ - public static function toPathValue($value) { - return rawurlencode(self::toString($value)); + public function toPathValue($value) { + return rawurlencode($this->toString($value)); } /** @@ -52,11 +52,11 @@ class ObjectSerializer { * @param object $object an object to be serialized to a string * @return string the serialized object */ - public static function toQueryValue($object) { + public function toQueryValue($object) { if (is_array($object)) { return implode(',', $object); } else { - return self::toString($object); + return $this->toString($object); } } @@ -67,8 +67,8 @@ class ObjectSerializer { * @param string $value a string which will be part of the header * @return string the header string */ - public static function toHeaderValue($value) { - return self::toString($value); + public function toHeaderValue($value) { + return $this->toString($value); } /** @@ -78,8 +78,8 @@ class ObjectSerializer { * @param string $value the value of the form parameter * @return string the form string */ - public static function toFormValue($value) { - return self::toString($value); + public function toFormValue($value) { + return $this->toString($value); } /** @@ -89,7 +89,7 @@ class ObjectSerializer { * @param string $value the value of the parameter * @return string the header string */ - public static function toString($value) { + public function toString($value) { if ($value instanceof \DateTime) { // datetime in ISO8601 format return $value->format(\DateTime::ISO8601); } else { @@ -104,7 +104,7 @@ class ObjectSerializer { * @param string $class class name is passed as a string * @return object an instance of $class */ - public static function deserialize($data, $class) { + public function deserialize($data, $class) { if (null === $data) { $deserialized = null; } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] @@ -114,14 +114,14 @@ class ObjectSerializer { $subClass_array = explode(',', $inner, 2); $subClass = $subClass_array[1]; foreach ($data as $key => $value) { - $deserialized[$key] = self::deserialize($value, $subClass); + $deserialized[$key] = $this->deserialize($value, $subClass); } } } elseif (strcasecmp(substr($class, -2),'[]') == 0) { $subClass = substr($class, 0, -2); $values = array(); foreach ($data as $key => $value) { - $values[] = self::deserialize($value, $subClass); + $values[] = $this->deserialize($value, $subClass); } $deserialized = $values; } elseif ($class == 'DateTime') { @@ -140,7 +140,7 @@ class ObjectSerializer { $propertyValue = $data->{$instance::$attributeMap[$property]}; if (isset($propertyValue)) { - $instance->$propertySetter(self::deserialize($propertyValue, $type)); + $instance->$propertySetter($this->deserialize($propertyValue, $type)); } } $deserialized = $instance; diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 23f8f494aef..cd483ffa881 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -95,21 +95,21 @@ class {{classname}} { {{#queryParams}}// query params if(${{paramName}} !== null) { - $queryParams['{{baseName}}'] = ObjectSerializer::toQueryValue(${{paramName}}); + $queryParams['{{baseName}}'] = $this->apiClient->getSerializer()->toQueryValue(${{paramName}}); }{{/queryParams}} {{#headerParams}}// header params if(${{paramName}} !== null) { - $headerParams['{{baseName}}'] = ObjectSerializer::toHeaderValue(${{paramName}}); + $headerParams['{{baseName}}'] = $this->apiClient->getSerializer()->toHeaderValue(${{paramName}}); }{{/headerParams}} {{#pathParams}}// path params if(${{paramName}} !== null) { $resourcePath = str_replace("{" . "{{baseName}}" . "}", - ObjectSerializer::toPathValue(${{paramName}}), + $this->apiClient->getSerializer()->toPathValue(${{paramName}}), $resourcePath); }{{/pathParams}} {{#formParams}}// form params if (${{paramName}} !== null) { - $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}ObjectSerializer::toFormValue(${{paramName}}); + $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->getSerializer()->toFormValue(${{paramName}}); }{{/formParams}} {{#bodyParams}}// body params $_tempBody = null; @@ -140,7 +140,7 @@ class {{classname}} { } catch (ApiException $e) { switch ($e->getCode()) { {{#responses}}{{#dataType}} case {{code}}: - $data = ObjectSerializer::deserialize($e->getResponseBody(), '{{dataType}}'); + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '{{dataType}}'); $e->setResponseObject($data); break;{{/dataType}}{{/responses}} } @@ -152,7 +152,7 @@ class {{classname}} { return null; } - $responseObject = ObjectSerializer::deserialize($response,'{{returnType}}'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'{{returnType}}'); return $responseObject; {{/returnType}} } From 46869df631312f8308d8233d92151bb5a4ad60b2 Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 23 Jun 2015 15:02:40 +0800 Subject: [PATCH 134/499] Make HTTP response accessible by storing the last response so that users are able to retrieve, for example, rate-limit headers from the response --- .../src/main/resources/ruby/swagger.mustache | 2 +- .../resources/ruby/swagger/request.mustache | 21 ++++++++++++------- .../resources/ruby/swagger/response.mustache | 15 ++++++------- .../ruby/lib/swagger_client/swagger.rb | 2 +- .../lib/swagger_client/swagger/request.rb | 21 ++++++++++++------- .../lib/swagger_client/swagger/response.rb | 15 ++++++------- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index 21c4e8cd04e..f07bdec9c50 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -1,7 +1,7 @@ module {{moduleName}} module Swagger class << self - attr_accessor :logger + attr_accessor :logger, :last_response # A Swagger configuration object. Must act like a hash and return sensible # values for all Swagger configuration options. See Swagger::Configuration. diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 70eb319ed95..ef2103766e4 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -5,7 +5,7 @@ module {{moduleName}} require 'addressable/uri' require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names + attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names, :response # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host @@ -169,7 +169,7 @@ module {{moduleName}} :headers => self.headers.stringify_keys, :verbose => Swagger.configuration.debug } - response = case self.http_method.to_sym + raw = case self.http_method.to_sym when :get,:GET Typhoeus::Request.get( self.url, @@ -201,15 +201,22 @@ module {{moduleName}} ) end + @response = Response.new(raw) + if Swagger.configuration.debug - Swagger.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" + Swagger.logger.debug "HTTP response body ~BEGIN~\n#{@response.body}\n~END~\n" end - Response.new(response) - end + # record as last response + Swagger.last_response = @response - def response - self.make + unless @response.success? + fail ApiError.new(:code => @response.code, + :response_headers => @response.headers, + :response_body => @response.body), + @response.status_message + end + @response end def response_code_pretty diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index b621110935a..d712aa29540 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -8,23 +8,24 @@ module {{moduleName}} def initialize(raw) self.raw = raw - - unless raw.success? - fail ApiError.new(:code => code, - :response_headers => headers, - :response_body => body), - raw.status_message - end end def code raw.code end + def status_message + raw.status_message + end + def body raw.body end + def success? + raw.success? + end + # Deserialize the raw response body to the given return type. # # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index e6c1ca51096..285d92ae2c7 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -1,7 +1,7 @@ module SwaggerClient module Swagger class << self - attr_accessor :logger + attr_accessor :logger, :last_response # A Swagger configuration object. Must act like a hash and return sensible # values for all Swagger configuration options. See Swagger::Configuration. diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index 2e669df60cb..4cc88016500 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -5,7 +5,7 @@ module SwaggerClient require 'addressable/uri' require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names + attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names, :response # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host @@ -168,7 +168,7 @@ module SwaggerClient :headers => self.headers.stringify_keys, :verbose => Swagger.configuration.debug } - response = case self.http_method.to_sym + raw = case self.http_method.to_sym when :get,:GET Typhoeus::Request.get( self.url, @@ -200,15 +200,22 @@ module SwaggerClient ) end + @response = Response.new(raw) + if Swagger.configuration.debug - Swagger.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" + Swagger.logger.debug "HTTP response body ~BEGIN~\n#{@response.body}\n~END~\n" end - Response.new(response) - end + # record as last response + Swagger.last_response = @response - def response - self.make + unless @response.success? + fail ApiError.new(:code => @response.code, + :response_headers => @response.headers, + :response_body => @response.body), + @response.status_message + end + @response end def response_code_pretty diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index f560006de6d..61d899e1f3b 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -8,23 +8,24 @@ module SwaggerClient def initialize(raw) self.raw = raw - - unless raw.success? - fail ApiError.new(:code => code, - :response_headers => headers, - :response_body => body), - raw.status_message - end end def code raw.code end + def status_message + raw.status_message + end + def body raw.body end + def success? + raw.success? + end + # Deserialize the raw response body to the given return type. # # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" From aec4af1b8824cdb8b63d65760fd5dd87b86f1732 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 23 Jun 2015 16:10:21 +0900 Subject: [PATCH 135/499] Replace slash with File.separator --- .../swagger/codegen/languages/SwiftGenerator.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java index 15ca6dc1556..96f0666df52 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java @@ -21,7 +21,7 @@ import java.util.regex.Pattern; public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); - protected String sourceFolder = "Classes/Swaggers"; + protected String sourceFolder = "Classes" + File.separator + "Swaggers"; public CodegenType getTag() { return CodegenType.CLIENT; @@ -37,12 +37,12 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { public SwiftGenerator() { super(); - outputFolder = "generated-code/swift"; + outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); apiTemplateFiles.put("api.mustache", ".swift"); templateDir = "swift"; - apiPackage = "/APIs"; - modelPackage = "/Models"; + apiPackage = File.separator + "APIs"; + modelPackage = File.separator + "Models"; // Inject application name String appName = System.getProperty("appName"); @@ -63,7 +63,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { additionalProperties.put("suppressRequired", suppressRequired); } - sourceFolder = appName + "/" + sourceFolder; + sourceFolder = appName + File.separator + sourceFolder; supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); @@ -134,12 +134,12 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { @Override public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); + return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar); } @Override public String apiFileFolder() { - return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); + return outputFolder + File.separator + sourceFolder + apiPackage().replace('.', File.separatorChar); } @Override From 19ee56592e0cde1c79d0b8d15bad7c6fd45c0ba9 Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 23 Jun 2015 17:23:22 +0800 Subject: [PATCH 136/499] Allow customizing SSL CA certificate by adding a `ssl_ca_cert` configuration option --- .../main/resources/ruby/swagger/configuration.mustache | 8 ++++++++ .../src/main/resources/ruby/swagger/request.mustache | 1 + .../ruby/lib/swagger_client/swagger/configuration.rb | 8 ++++++++ .../petstore/ruby/lib/swagger_client/swagger/request.rb | 1 + 4 files changed, 18 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index 485bcb3cf81..5ed22afb151 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -7,6 +7,14 @@ module {{moduleName}} :scheme, :host, :base_path, :user_agent, :debug, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + # Set this to customize the certificate file to verify the peer. + # + # @return [String] the path to the certificate file + # + # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code: + # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 + attr_accessor :ssl_ca_cert + # Defaults go in here.. def initialize @format = 'json' diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index ef2103766e4..c05167c7fdc 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -166,6 +166,7 @@ module {{moduleName}} def make request_options = { :ssl_verifypeer => Swagger.configuration.verify_ssl, + :cainfo => Swagger.configuration.ssl_ca_cert, :headers => self.headers.stringify_keys, :verbose => Swagger.configuration.debug } diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index b4d8b33d90d..9ed1673eff1 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -7,6 +7,14 @@ module SwaggerClient :scheme, :host, :base_path, :user_agent, :debug, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + # Set this to customize the certificate file to verify the peer. + # + # @return [String] the path to the certificate file + # + # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code: + # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 + attr_accessor :ssl_ca_cert + # Defaults go in here.. def initialize @format = 'json' diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index 4cc88016500..df0987b0d22 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -165,6 +165,7 @@ module SwaggerClient def make request_options = { :ssl_verifypeer => Swagger.configuration.verify_ssl, + :cainfo => Swagger.configuration.ssl_ca_cert, :headers => self.headers.stringify_keys, :verbose => Swagger.configuration.debug } From c45af23946779a88444dab5a9795a19a41accbe5 Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Tue, 23 Jun 2015 12:05:43 +0200 Subject: [PATCH 137/499] Fixed headerParams and paramName --- .../src/main/resources/TypeScript-Angular/api.mustache | 8 ++++---- .../src/main/resources/TypeScript-node/api.mustache | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache index 1095667b245..1bc4a8a02a1 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache @@ -22,13 +22,13 @@ module {{package}} { } } {{#operation}} - public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}, {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> { + public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}} {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> { var path = this.basePath + '{{path}}'; {{#pathParams}} path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}})); {{/pathParams}} var queryParameters: any = {}; - var headers: any = {}; + var headerParams: any = {}; {{#allParams}}{{#required}} // verify required parameter '{{paramName}}' is set if (!{{paramName}}) { @@ -43,10 +43,10 @@ module {{package}} { method: '{{httpMethod}}', url: path, json: true, - {{#bodyParam}}data: body, + {{#bodyParam}}data: {{paramName}}, {{/bodyParam}} params: queryParameters, - headers: headers + headers: headerParams }; if (extraHttpRequestParams) { diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache index 156ad63f72d..eb569cdc928 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache @@ -24,7 +24,7 @@ export class {{classname}} { {{/pathParams}} var queryParameters: any = {}; - var headers: any = {}; + var headerParams: any = {}; {{#allParams}}{{#required}} // verify required parameter '{{paramName}}' is set @@ -48,7 +48,7 @@ export class {{classname}} { qs: queryParameters, uri: path, json: true, - {{#bodyParam}}body: body, + {{#bodyParam}}body: {{paramName}}, {{/bodyParam}} auth: { username: this.username, password: this.password From 550493ba848a9de97a55ac093522f1d3929a686a Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 23 Jun 2015 21:20:12 +0800 Subject: [PATCH 138/499] fix php separator --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 6 +++--- .../petstore/php/SwaggerClient-php/lib/Api/PetApi.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 0690163f137..9ed02361dff 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -23,7 +23,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { public PhpClientCodegen() { super(); - outputFolder = "generated-code/php"; + outputFolder = "generated-code" + File.separator + "php"; modelTemplateFiles.put("model.mustache", ".php"); apiTemplateFiles.put("api.mustache", ".php"); templateDir = "php"; @@ -127,11 +127,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return (outputFolder + "/" + toPackagePath(apiPackage(), "lib")); + return (outputFolder + File.separator + toPackagePath(apiPackage(), "lib")); } public String modelFileFolder() { - return (outputFolder + "/" + toPackagePath(modelPackage(), "lib")); + return (outputFolder + File.separator + toPackagePath(modelPackage(), "lib")); } @Override diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php index f4f6ea8538a..7fe7b70312e 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php @@ -516,7 +516,7 @@ class PetApi { $formParams['additionalMetadata'] = $this->apiClient->toFormValue($additional_metadata); }// form params if ($file !== null) { - $formParams['file'] = '@' . $this->apiClient->toFormValue($file); + $formParams['file'] = '@'.$this->apiClient->toFormValue($file); } From 13d350be2e37c2d6fc0c04236d7f5961870240c6 Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 23 Jun 2015 21:23:48 +0800 Subject: [PATCH 139/499] Fix warnings and upgrade jersey for Scala client * Upgrade jersey to latest version (from 1.7 to 1.19) * Replace getClientResponseStatus() with getStatusInfo() * Fix the following maven warnings and model import warnings [WARNING] 'build.plugins.plugin.version' for org.codehaus.mojo:build-helper-maven-plugin is missing. @ line 72, column 15 [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [WARNING] Expected all dependencies to require Scala version: 2.10.4 [WARNING] com.fasterxml.jackson.module:jackson-module-scala_2.10:2.4.2 requires scala version: 2.10.4 [WARNING] org.scala-lang:scala-reflect:2.10.4 requires scala version: 2.10.4 [WARNING] io.swagger:swagger-scala-client:1.0.0 requires scala version: 2.10.4 [WARNING] org.scalatest:scalatest_2.10:2.1.3 requires scala version: 2.10.3 [WARNING] Multiple versions of scala libraries detected! [WARNING] /Users/xhh/projects/swagger-codegen/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Pet.scala:3: warning: imported `Category' is permanently hidden by definition of object Category in package model --- .../codegen/languages/ScalaClientCodegen.java | 16 ++++++++++++++++ .../src/main/resources/scala/apiInvoker.mustache | 7 +++---- .../src/main/resources/scala/pom.mustache | 7 +++++-- samples/client/petstore/scala/pom.xml | 7 +++++-- .../scala/io/swagger/client/ApiInvoker.scala | 7 +++---- .../main/scala/io/swagger/client/model/Pet.scala | 2 -- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java index d8c143aad1d..6ad296a0210 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java @@ -20,6 +20,9 @@ import java.io.File; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig { protected String invokerPackage = "io.swagger.client"; @@ -214,4 +217,17 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig return camelize(operationId, true); } + @Override + public Map postProcessModels(Map objs) { + // remove model imports to avoid warnings for importing class in the same package in Scala + List> imports = (List>) objs.get("imports"); + final String prefix = modelPackage() + "."; + Iterator> iterator = imports.iterator(); + while (iterator.hasNext()) { + String _import = iterator.next().get("import"); + if (_import.startsWith(prefix)) iterator.remove(); + } + return objs; + } + } diff --git a/modules/swagger-codegen/src/main/resources/scala/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/scala/apiInvoker.mustache index f432c2dc59e..9c2e9c073cd 100644 --- a/modules/swagger-codegen/src/main/resources/scala/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/scala/apiInvoker.mustache @@ -141,7 +141,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper, } case _ => null } - response.getClientResponseStatus().getStatusCode() match { + response.getStatusInfo().getStatusCode() match { case 204 => "" case code: Int if (Range(200, 299).contains(code)) => { response.hasEntity() match { @@ -155,7 +155,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper, case false => "no data" } throw new ApiException( - response.getClientResponseStatus().getStatusCode(), + response.getStatusInfo().getStatusCode(), entity) } } @@ -172,7 +172,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper, } } } - + def newClient(host: String): Client = asyncHttpClient match { case true => { import org.sonatype.spice.jersey.client.ahc.config.DefaultAhcConfig @@ -200,4 +200,3 @@ object ApiInvoker extends ApiInvoker(mapper = ScalaJsonUtil.getJsonMapper, authPreemptive = {{authPreemptive}}) class ApiException(val code: Int, msg: String) extends RuntimeException(msg) - diff --git a/modules/swagger-codegen/src/main/resources/scala/pom.mustache b/modules/swagger-codegen/src/main/resources/scala/pom.mustache index 2d8a1257eb4..c6fe4a1f356 100644 --- a/modules/swagger-codegen/src/main/resources/scala/pom.mustache +++ b/modules/swagger-codegen/src/main/resources/scala/pom.mustache @@ -72,6 +72,7 @@ org.codehaus.mojo build-helper-maven-plugin + 1.9.1 add_sources @@ -208,7 +209,7 @@ 2.10.4 1.2 2.2 - 1.7 + 1.19 1.5.0 1.0.5 1.0.0 @@ -216,6 +217,8 @@ 4.8.1 3.1.5 - 2.1.3 + 2.2.4 + + UTF-8 diff --git a/samples/client/petstore/scala/pom.xml b/samples/client/petstore/scala/pom.xml index 7e56a41c890..9f39f4e45ce 100644 --- a/samples/client/petstore/scala/pom.xml +++ b/samples/client/petstore/scala/pom.xml @@ -72,6 +72,7 @@ org.codehaus.mojo build-helper-maven-plugin + 1.9.1 add_sources @@ -208,7 +209,7 @@ 2.10.4 1.2 2.2 - 1.7 + 1.19 1.5.0 1.0.5 1.0.0 @@ -216,6 +217,8 @@ 4.8.1 3.1.5 - 2.1.3 + 2.2.4 + + UTF-8 diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/ApiInvoker.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/ApiInvoker.scala index 91ab98471e9..1f9d3c012d5 100644 --- a/samples/client/petstore/scala/src/main/scala/io/swagger/client/ApiInvoker.scala +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/ApiInvoker.scala @@ -141,7 +141,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper, } case _ => null } - response.getClientResponseStatus().getStatusCode() match { + response.getStatusInfo().getStatusCode() match { case 204 => "" case code: Int if (Range(200, 299).contains(code)) => { response.hasEntity() match { @@ -155,7 +155,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper, case false => "no data" } throw new ApiException( - response.getClientResponseStatus().getStatusCode(), + response.getStatusInfo().getStatusCode(), entity) } } @@ -172,7 +172,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper, } } } - + def newClient(host: String): Client = asyncHttpClient match { case true => { import org.sonatype.spice.jersey.client.ahc.config.DefaultAhcConfig @@ -200,4 +200,3 @@ object ApiInvoker extends ApiInvoker(mapper = ScalaJsonUtil.getJsonMapper, authPreemptive = false) class ApiException(val code: Int, msg: String) extends RuntimeException(msg) - diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Pet.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Pet.scala index 430f6a3659c..30dc8750976 100644 --- a/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Pet.scala +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Pet.scala @@ -1,7 +1,5 @@ package io.swagger.client.model -import io.swagger.client.model.Category -import io.swagger.client.model.Tag From 2fce2e410937a89cb35ac910a15dd1422d601171 Mon Sep 17 00:00:00 2001 From: Martin Hardorf Date: Tue, 23 Jun 2015 15:37:07 +0200 Subject: [PATCH 140/499] Removed wrong hasMore from Angular TypeScript mustache --- .../src/main/resources/TypeScript-Angular/api.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache index 1bc4a8a02a1..88f7f9ff15a 100644 --- a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache @@ -22,7 +22,7 @@ module {{package}} { } } {{#operation}} - public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}} {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> { + public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}, {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> { var path = this.basePath + '{{path}}'; {{#pathParams}} path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}})); From 2979d938292fb5add41b98f520f05778755a713b Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 23 Jun 2015 21:47:10 +0800 Subject: [PATCH 141/499] use replace instead of replaceAll --- .../io/swagger/codegen/languages/PhpClientCodegen.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 9ed02361dff..57fb52137e1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -101,11 +101,12 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return (getPackagePath() + File.separatorChar + basePath // Replace period, backslash, forward slash with file separator in package name - + packageName.replaceAll("[\\.\\\\/]", File.separator) + + packageName.replace("\\", File.separator). + replace(".", File.separator).replace("/", File.separator) // Trim prefix file separators from package path .replaceAll("^" + File.separator, "")) - // Trim trailing file separators from the overall path - .replaceAll(File.separator + "$", ""); + // Trim trailing file separators from the overall path + .replaceAll(File.separator + "$", ""); } public CodegenType getTag() { From 351833a923dc5a21e3c4f8fba50b7e008c908ec3 Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 23 Jun 2015 21:52:00 +0800 Subject: [PATCH 142/499] test fix --- .../java/io/swagger/codegen/languages/PhpClientCodegen.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 57fb52137e1..e504a888f8a 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -102,11 +102,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return (getPackagePath() + File.separatorChar + basePath // Replace period, backslash, forward slash with file separator in package name + packageName.replace("\\", File.separator). - replace(".", File.separator).replace("/", File.separator) + replace(".", File.separator).replace("/", File.separator)); // Trim prefix file separators from package path - .replaceAll("^" + File.separator, "")) + //.replaceAll("^" + File.separator, "")) // Trim trailing file separators from the overall path - .replaceAll(File.separator + "$", ""); + //.replaceAll(File.separator + "$", ""); } public CodegenType getTag() { From d18426c69a85500f71bc5b0b7d1e62162aeefbfd Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 23 Jun 2015 22:30:43 +0800 Subject: [PATCH 143/499] fix reg expression --- .../codegen/languages/PhpClientCodegen.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index e504a888f8a..7f92a06fe76 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -99,14 +99,20 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar; } + String regFirstPathSeparator; + if ("/".equals(File.separator)) { // for mac, linux + regFirstPathSeparator = "^/"; + } else { // for windows + regFirstPathSeparator = "^\\"; + } + return (getPackagePath() + File.separatorChar + basePath // Replace period, backslash, forward slash with file separator in package name - + packageName.replace("\\", File.separator). - replace(".", File.separator).replace("/", File.separator)); + + packageName.replaceAll("[\\.\\\\/]", File.separator) // Trim prefix file separators from package path - //.replaceAll("^" + File.separator, "")) + .replaceAll(regFirstPathSeparator, "")) // Trim trailing file separators from the overall path - //.replaceAll(File.separator + "$", ""); + .replaceAll(File.separator + "$", ""); } public CodegenType getTag() { From d83036ccdfacd31aa7c2eefab66333b4bbf79c73 Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 23 Jun 2015 22:36:57 +0800 Subject: [PATCH 144/499] fix regular expression --- .../swagger/codegen/languages/PhpClientCodegen.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 7f92a06fe76..5bf8400577d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -103,7 +103,14 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { if ("/".equals(File.separator)) { // for mac, linux regFirstPathSeparator = "^/"; } else { // for windows - regFirstPathSeparator = "^\\"; + regFirstPathSeparator = "^\\\\"; + } + + String regLastPathSeparator; + if ("/".equals(File.separator)) { // for mac, linux + regLastPathSeparator = "/$"; + } else { // for windows + regLastPathSeparator = "\\\\$"; } return (getPackagePath() + File.separatorChar + basePath @@ -112,7 +119,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { // Trim prefix file separators from package path .replaceAll(regFirstPathSeparator, "")) // Trim trailing file separators from the overall path - .replaceAll(File.separator + "$", ""); + .replaceAll(regLastPathSeparator+ "$", ""); } public CodegenType getTag() { From 1b4c71c28039ead9f656f4afe22b70d635470ffe Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Tue, 23 Jun 2015 09:27:34 -0700 Subject: [PATCH 145/499] re-adding Configuration->deleteDefaultHeader --- .../src/main/resources/php/configuration.mustache | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/configuration.mustache index a0cae318c2d..b85ad289418 100644 --- a/modules/swagger-codegen/src/main/resources/php/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/configuration.mustache @@ -144,6 +144,15 @@ class Configuration { return $this->defaultHeaders; } + /** + * delete a default header + * @param string $headerName the header to delete + * @return Configuration + */ + public function deleteDefaultHeader($headerName) { + unset($this->defaultHeaders[$headerName]); + } + /** * @param string $host * @return Configuration From efd5b806be552c973594fb95622d1114922d02b2 Mon Sep 17 00:00:00 2001 From: nmonterroso Date: Tue, 23 Jun 2015 09:27:52 -0700 Subject: [PATCH 146/499] updating php generated samples and updating tests --- .../php/SwaggerClient-php/lib/Api/PetApi.php | 310 +++++++++++------ .../SwaggerClient-php/lib/Api/StoreApi.php | 174 ++++++---- .../php/SwaggerClient-php/lib/Api/UserApi.php | 256 ++++++++------ .../php/SwaggerClient-php/lib/ApiClient.php | 327 +++--------------- .../SwaggerClient-php/lib/ApiException.php | 28 +- .../SwaggerClient-php/lib/Configuration.php | 241 ++++++++++++- .../SwaggerClient-php/lib/Model/Category.php | 60 +++- .../php/SwaggerClient-php/lib/Model/Order.php | 156 ++++++++- .../php/SwaggerClient-php/lib/Model/Pet.php | 156 ++++++++- .../php/SwaggerClient-php/lib/Model/Tag.php | 60 +++- .../php/SwaggerClient-php/lib/Model/User.php | 204 ++++++++++- .../lib/ObjectSerializer.php | 151 ++++++++ .../SwaggerClient-php/tests/PetApiTest.php | 104 +++--- .../SwaggerClient-php/tests/StoreApiTest.php | 7 +- .../SwaggerClient-php/tests/UserApiTest.php | 7 +- 15 files changed, 1549 insertions(+), 692 deletions(-) create mode 100644 samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php index f4f6ea8538a..e6d8fcd2c8c 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php @@ -22,30 +22,28 @@ namespace Swagger\Client\Api; -use \Swagger\Client\ApiClient; use \Swagger\Client\Configuration; +use \Swagger\Client\ApiClient; +use \Swagger\Client\ApiException; +use \Swagger\Client\ObjectSerializer; class PetApi { - /** - * @param \Swagger\Client\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \Swagger\Client\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \Swagger\Client\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('http://petstore.swagger.io/v2'); + } + + $this->apiClient = $apiClient; + } + /** * @return \Swagger\Client\ApiClient get the API client */ @@ -54,10 +52,12 @@ class PetApi { } /** - * @param \Swagger\Client $apiClient set the API client + * @param \Swagger\Client\ApiClient $apiClient set the API client + * @return PetApi */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } @@ -68,6 +68,7 @@ class PetApi { * * @param \Swagger\Client\Model\Pet $body Pet object that needs to be added to the store (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function updatePet($body) { @@ -80,11 +81,11 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/json','application/xml')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('application/json','application/xml')); @@ -103,14 +104,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -121,6 +129,7 @@ class PetApi { * * @param \Swagger\Client\Model\Pet $body Pet object that needs to be added to the store (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function addPet($body) { @@ -133,11 +142,11 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/json','application/xml')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('application/json','application/xml')); @@ -156,14 +165,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -174,6 +190,7 @@ class PetApi { * * @param string[] $status Status values that need to be considered for filter (required) * @return \Swagger\Client\Model\Pet[] + * @throws \Swagger\Client\ApiException on non-2xx response */ public function findPetsByStatus($status) { @@ -186,15 +203,15 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // query params if($status !== null) { - $queryParams['status'] = $this->apiClient->toQueryValue($status); + $queryParams['status'] = $this->apiClient->getSerializer()->toQueryValue($status); } @@ -208,20 +225,33 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Pet[]'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet[]'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Pet[]'); return $responseObject; + } /** @@ -231,6 +261,7 @@ class PetApi { * * @param string[] $tags Tags to filter by (required) * @return \Swagger\Client\Model\Pet[] + * @throws \Swagger\Client\ApiException on non-2xx response */ public function findPetsByTags($tags) { @@ -243,15 +274,15 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // query params if($tags !== null) { - $queryParams['tags'] = $this->apiClient->toQueryValue($tags); + $queryParams['tags'] = $this->apiClient->getSerializer()->toQueryValue($tags); } @@ -265,20 +296,33 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Pet[]'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet[]'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Pet[]'); return $responseObject; + } /** @@ -288,6 +332,7 @@ class PetApi { * * @param int $pet_id ID of pet that needs to be fetched (required) * @return \Swagger\Client\Model\Pet + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getPetById($pet_id) { @@ -305,18 +350,19 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } @@ -328,20 +374,40 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('api_key', 'petstore_auth'); - + + + //TODO support oauth + + $apiKey = $this->apiClient->getApiKeyWithPrefix('api_key'); + if (isset($apiKey)) { + $headerParams['api_key'] = $apiKey; + } + + + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Pet'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Pet'); return $responseObject; + } /** @@ -353,6 +419,7 @@ class PetApi { * @param string $name Updated name of the pet (required) * @param string $status Updated status of the pet (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function updatePetWithForm($pet_id, $name, $status) { @@ -370,25 +437,26 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/x-www-form-urlencoded')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('application/x-www-form-urlencoded')); // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } // form params if ($name !== null) { - $formParams['name'] = $this->apiClient->toFormValue($name); + $formParams['name'] = $this->apiClient->getSerializer()->toFormValue($name); }// form params if ($status !== null) { - $formParams['status'] = $this->apiClient->toFormValue($status); + $formParams['status'] = $this->apiClient->getSerializer()->toFormValue($status); } @@ -399,14 +467,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -418,6 +493,7 @@ class PetApi { * @param string $api_key (required) * @param int $pet_id Pet id to delete (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function deletePet($api_key, $pet_id) { @@ -435,21 +511,22 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // header params if($api_key !== null) { - $headerParams['api_key'] = $this->apiClient->toHeaderValue($api_key); + $headerParams['api_key'] = $this->apiClient->getSerializer()->toHeaderValue($api_key); } // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } @@ -461,14 +538,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -481,6 +565,7 @@ class PetApi { * @param string $additional_metadata Additional data to pass to server (required) * @param string $file file to upload (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function uploadFile($pet_id, $additional_metadata, $file) { @@ -498,25 +583,26 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('multipart/form-data')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('multipart/form-data')); // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } // form params if ($additional_metadata !== null) { - $formParams['additionalMetadata'] = $this->apiClient->toFormValue($additional_metadata); + $formParams['additionalMetadata'] = $this->apiClient->getSerializer()->toFormValue($additional_metadata); }// form params if ($file !== null) { - $formParams['file'] = '@' . $this->apiClient->toFormValue($file); + $formParams['file'] = '@' . $this->apiClient->getSerializer()->toFormValue($file); } @@ -527,16 +613,22 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } - } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php index 07a922aab0a..237ba3f1acf 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php @@ -22,30 +22,28 @@ namespace Swagger\Client\Api; -use \Swagger\Client\ApiClient; use \Swagger\Client\Configuration; +use \Swagger\Client\ApiClient; +use \Swagger\Client\ApiException; +use \Swagger\Client\ObjectSerializer; class StoreApi { - /** - * @param \Swagger\Client\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \Swagger\Client\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \Swagger\Client\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('http://petstore.swagger.io/v2'); + } + + $this->apiClient = $apiClient; + } + /** * @return \Swagger\Client\ApiClient get the API client */ @@ -54,10 +52,12 @@ class StoreApi { } /** - * @param \Swagger\Client $apiClient set the API client + * @param \Swagger\Client\ApiClient $apiClient set the API client + * @return StoreApi */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } @@ -67,6 +67,7 @@ class StoreApi { * Returns pet inventories by status * * @return map[string,int] + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getInventory() { @@ -79,11 +80,11 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -98,20 +99,37 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('api_key'); - + + $apiKey = $this->apiClient->getApiKeyWithPrefix('api_key'); + if (isset($apiKey)) { + $headerParams['api_key'] = $apiKey; + } + + + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), 'map[string,int]'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'map[string,int]'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'map[string,int]'); return $responseObject; + } /** @@ -121,6 +139,7 @@ class StoreApi { * * @param \Swagger\Client\Model\Order $body order placed for purchasing the pet (required) * @return \Swagger\Client\Model\Order + * @throws \Swagger\Client\ApiException on non-2xx response */ public function placeOrder($body) { @@ -133,11 +152,11 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -156,20 +175,30 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Order'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Order'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Order'); return $responseObject; + } /** @@ -179,6 +208,7 @@ class StoreApi { * * @param string $order_id ID of pet that needs to be fetched (required) * @return \Swagger\Client\Model\Order + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getOrderById($order_id) { @@ -196,18 +226,19 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($order_id !== null) { $resourcePath = str_replace("{" . "orderId" . "}", - $this->apiClient->toPathValue($order_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($order_id), + $resourcePath); } @@ -219,20 +250,30 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Order'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Order'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Order'); return $responseObject; + } /** @@ -242,6 +283,7 @@ class StoreApi { * * @param string $order_id ID of the order that needs to be deleted (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function deleteOrder($order_id) { @@ -259,18 +301,19 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($order_id !== null) { $resourcePath = str_replace("{" . "orderId" . "}", - $this->apiClient->toPathValue($order_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($order_id), + $resourcePath); } @@ -282,16 +325,19 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } - } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php index f4d35a3a7a0..1d0765bbb81 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php @@ -22,30 +22,28 @@ namespace Swagger\Client\Api; -use \Swagger\Client\ApiClient; use \Swagger\Client\Configuration; +use \Swagger\Client\ApiClient; +use \Swagger\Client\ApiException; +use \Swagger\Client\ObjectSerializer; class UserApi { - /** - * @param \Swagger\Client\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \Swagger\Client\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \Swagger\Client\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('http://petstore.swagger.io/v2'); + } + + $this->apiClient = $apiClient; + } + /** * @return \Swagger\Client\ApiClient get the API client */ @@ -54,10 +52,12 @@ class UserApi { } /** - * @param \Swagger\Client $apiClient set the API client + * @param \Swagger\Client\ApiClient $apiClient set the API client + * @return UserApi */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } @@ -68,6 +68,7 @@ class UserApi { * * @param \Swagger\Client\Model\User $body Created user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function createUser($body) { @@ -80,11 +81,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -103,14 +104,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -121,6 +126,7 @@ class UserApi { * * @param \Swagger\Client\Model\User[] $body List of user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function createUsersWithArrayInput($body) { @@ -133,11 +139,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -156,14 +162,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -174,6 +184,7 @@ class UserApi { * * @param \Swagger\Client\Model\User[] $body List of user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function createUsersWithListInput($body) { @@ -186,11 +197,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -209,14 +220,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -228,6 +243,7 @@ class UserApi { * @param string $username The user name for login (required) * @param string $password The password for login in clear text (required) * @return string + * @throws \Swagger\Client\ApiException on non-2xx response */ public function loginUser($username, $password) { @@ -240,18 +256,18 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // query params if($username !== null) { - $queryParams['username'] = $this->apiClient->toQueryValue($username); + $queryParams['username'] = $this->apiClient->getSerializer()->toQueryValue($username); }// query params if($password !== null) { - $queryParams['password'] = $this->apiClient->toQueryValue($password); + $queryParams['password'] = $this->apiClient->getSerializer()->toQueryValue($password); } @@ -265,20 +281,30 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), 'string'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'string'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'string'); return $responseObject; + } /** @@ -287,6 +313,7 @@ class UserApi { * Logs out current logged in user session * * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function logoutUser() { @@ -299,11 +326,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -318,14 +345,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -336,6 +367,7 @@ class UserApi { * * @param string $username The name that needs to be fetched. Use user1 for testing. (required) * @return \Swagger\Client\Model\User + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getUserByName($username) { @@ -353,18 +385,19 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($username !== null) { $resourcePath = str_replace("{" . "username" . "}", - $this->apiClient->toPathValue($username), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($username), + $resourcePath); } @@ -376,20 +409,30 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\User'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\User'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\User'); return $responseObject; + } /** @@ -400,6 +443,7 @@ class UserApi { * @param string $username name that need to be deleted (required) * @param \Swagger\Client\Model\User $body Updated user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function updateUser($username, $body) { @@ -417,18 +461,19 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($username !== null) { $resourcePath = str_replace("{" . "username" . "}", - $this->apiClient->toPathValue($username), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($username), + $resourcePath); } // body params @@ -444,14 +489,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -462,6 +511,7 @@ class UserApi { * * @param string $username The name that needs to be deleted (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function deleteUser($username) { @@ -479,18 +529,19 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($username !== null) { $resourcePath = str_replace("{" . "username" . "}", - $this->apiClient->toPathValue($username), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($username), + $resourcePath); } @@ -502,16 +553,19 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } - } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php index bb5229fb170..66204f0c4f3 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php @@ -25,146 +25,60 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - /** @var string[] Array of default headers where the key is the header name and the value is the header value */ - private $default_header = array(); + /** @var Configuration */ + protected $config; - /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ - protected $curl_timeout = 0; - - /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ - protected $user_agent = "PHP-Swagger"; + /** @var ObjectSerializer */ + protected $serializer; /** - * @param string $host Base url of the API server (optional) + * @param Configuration $config config for this ApiClient */ - function __construct($host = null) { - if ($host === null) { - $this->host = 'http://petstore.swagger.io/v2'; - } else { - $this->host = $host; + function __construct(Configuration $config = null) { + if ($config == null) { + $config = Configuration::getDefaultConfiguration(); } + + $this->config = $config; + $this->serializer = new ObjectSerializer(); } /** - * add default header - * - * @param string $header_name header name (e.g. Token) - * @param string $header_value header value (e.g. 1z8wp3) + * get the config + * @return Configuration */ - public function addDefaultHeader($header_name, $header_value) { - if (!is_string($header_name)) - throw new \InvalidArgumentException('Header name must be a string.'); - - $this->default_header[$header_name] = $header_value; + public function getConfig() { + return $this->config; } /** - * get the default header - * - * @return array default header + * get the serializer + * @return ObjectSerializer */ - public function getDefaultHeader() { - return $this->default_header; + public function getSerializer() { + return $this->serializer; } - /** - * delete the default header based on header name - * - * @param string $header_name header name (e.g. Token) - */ - public function deleteDefaultHeader($header_name) { - unset($this->default_header[$header_name]); - } - - /** - * set the user agent of the api client - * - * @param string $user_agent the user agent of the api client - */ - public function setUserAgent($user_agent) { - if (!is_string($user_agent)) - throw new \InvalidArgumentException('User-agent must be a string.'); - - $this->user_agent= $user_agent; - } - - /** - * get the user agent of the api client - * - * @return string user agent - */ - public function getUserAgent($user_agent) { - return $this->user_agent; - } - - /** - * set the HTTP timeout value - * - * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] - */ - public function setTimeout($seconds) { - if (!is_numeric($seconds) || $seconds < 0) - throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); - - $this->curl_timeout = $seconds; - } - - /** - * get the HTTP timeout value - * - * @return string HTTP timeout value - */ - public function getTimeout() { - return $this->curl_timeout; - } - - /** * Get API key (with prefix if set) - * @param string key name + * @param string $apiKey name of apikey * @return string API key with the prefix */ public function getApiKeyWithPrefix($apiKey) { - if (isset(Configuration::$apiKeyPrefix[$apiKey])) { - return Configuration::$apiKeyPrefix[$apiKey]." ".Configuration::$apiKey[$apiKey]; - } else if (isset(Configuration::$apiKey[$apiKey])) { - return Configuration::$apiKey[$apiKey]; + $prefix = $this->config->getApiKeyPrefix($apiKey); + $apiKey = $this->config->getApiKey($apiKey); + + if (!isset($apiKey)) { + return null; + } + + if (isset($prefix)) { + $keyWithPrefix = $prefix." ".$apiKey; } else { - return; + $keyWithPrefix = $apiKey; } - } - /** - * update hearder and query param based on authentication setting - * - * @param array $headerParams header parameters (by ref) - * @param array $queryParams query parameters (by ref) - * @param array $authSettings array of authentication scheme (e.g ['api_key']) - */ - public function updateParamsForAuth(&$headerParams, &$queryParams, $authSettings) - { - if (count($authSettings) == 0) - return; - - // one endpoint can have more than 1 auth settings - foreach($authSettings as $auth) { - // determine which one to use - switch($auth) { - - case 'api_key': - $headerParams['api_key'] = $this->getApiKeyWithPrefix('api_key'); - - break; - - case 'petstore_auth': - - //TODO support oauth - break; - - default: - //TODO show warning about security definition not found - } - } + return $keyWithPrefix; } /** @@ -173,18 +87,15 @@ class ApiClient { * @param array $queryParams parameters to be place in query URL * @param array $postData parameters to be placed in POST body * @param array $headerParams parameters to be place in request header + * @throws \Swagger\Client\ApiException on a non 2xx response * @return mixed */ - public function callApi($resourcePath, $method, $queryParams, $postData, - $headerParams, $authSettings) { + public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) { $headers = array(); - # determine authentication setting - $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); - # construct the http header - $headerParams = array_merge((array)$this->default_header, (array)$headerParams); + $headerParams = array_merge((array)$this->config->getDefaultHeaders(), (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -195,15 +106,15 @@ class ApiClient { $postData = http_build_query($postData); } else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model - $postData = json_encode($this->sanitizeForSerialization($postData)); + $postData = json_encode($this->serializer->sanitizeForSerialization($postData)); } - $url = $this->host . $resourcePath; + $url = $this->config->getHost() . $resourcePath; $curl = curl_init(); // set timeout, if needed - if ($this->curl_timeout != 0) { - curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_timeout); + if ($this->config->getCurlTimeout() != 0) { + curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout()); } // return the result on success, rather than just TRUE curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @@ -232,14 +143,14 @@ class ApiClient { curl_setopt($curl, CURLOPT_URL, $url); // Set user agent - curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent()); // debugging for curl - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile()); curl_setopt($curl, CURLOPT_VERBOSE, 1); - curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a')); + curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a')); } else { curl_setopt($curl, CURLOPT_VERBOSE, 0); } @@ -255,8 +166,8 @@ class ApiClient { $response_info = curl_getinfo($curl); // debug HTTP response body - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile()); } // Handle the response @@ -274,153 +185,13 @@ class ApiClient { return $data; } - /** - * Build a JSON POST object - */ - protected function sanitizeForSerialization($data) - { - if (is_scalar($data) || null === $data) { - $sanitized = $data; - } else if ($data instanceof \DateTime) { - $sanitized = $data->format(\DateTime::ISO8601); - } else if (is_array($data)) { - foreach ($data as $property => $value) { - $data[$property] = $this->sanitizeForSerialization($value); - } - $sanitized = $data; - } else if (is_object($data)) { - $values = array(); - foreach (array_keys($data::$swaggerTypes) as $property) { - if ($data->$property !== null) { - $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); - } - } - $sanitized = $values; - } else { - $sanitized = (string)$data; - } - - return $sanitized; - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the path, by url-encoding. - * @param string $value a string which will be part of the path - * @return string the serialized object - */ - public function toPathValue($value) { - return rawurlencode($this->toString($value)); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the query, by imploding comma-separated if it's an object. - * If it's a string, pass through unchanged. It will be url-encoded - * later. - * @param object $object an object to be serialized to a string - * @return string the serialized object - */ - public function toQueryValue($object) { - if (is_array($object)) { - return implode(',', $object); - } else { - return $this->toString($object); - } - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the header. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value a string which will be part of the header - * @return string the header string - */ - public function toHeaderValue($value) { - return $this->toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the http body (form parameter). If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the form parameter - * @return string the form string - */ - public function toFormValue($value) { - return $this->toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the parameter. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the parameter - * @return string the header string - */ - public function toString($value) { - if ($value instanceof \DateTime) { // datetime in ISO8601 format - return $value->format(\DateTime::ISO8601); - } - else { - return $value; - } - } - - /** - * Deserialize a JSON string into an object - * - * @param object $object object or primitive to be deserialized - * @param string $class class name is passed as a string - * @return object an instance of $class - */ - public function deserialize($data, $class) - { - if (null === $data) { - $deserialized = null; - } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] - $inner = substr($class, 4, -1); - $deserialized = array(); - if(strrpos($inner, ",") !== false) { - $subClass_array = explode(',', $inner, 2); - $subClass = $subClass_array[1]; - foreach ($data as $key => $value) { - $deserialized[$key] = $this->deserialize($value, $subClass); - } - } - } elseif (strcasecmp(substr($class, -2),'[]') == 0) { - $subClass = substr($class, 0, -2); - $values = array(); - foreach ($data as $key => $value) { - $values[] = $this->deserialize($value, $subClass); - } - $deserialized = $values; - } elseif ($class == 'DateTime') { - $deserialized = new \DateTime($data); - } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { - settype($data, $class); - $deserialized = $data; - } else { - $instance = new $class(); - foreach ($instance::$swaggerTypes as $property => $type) { - $original_property_name = $instance::$attributeMap[$property]; - if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = $this->deserialize($data->$original_property_name, $type); - } - } - $deserialized = $instance; - } - - return $deserialized; - } - /* * return the header 'Accept' based on an array of Accept provided * - * @param array[string] $accept Array of header + * @param string[] $accept Array of header * @return string Accept (e.g. application/json) */ - public function selectHeaderAccept($accept) { + public static function selectHeaderAccept($accept) { if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) { return NULL; } elseif (preg_grep("/application\/json/i", $accept)) { @@ -433,10 +204,10 @@ class ApiClient { /* * return the content type based on an array of content-type provided * - * @param array[string] content_type_array Array fo content-type + * @param string[] content_type_array Array fo content-type * @return string Content-Type (e.g. application/json) */ - public function selectHeaderContentType($content_type) { + public static function selectHeaderContentType($content_type) { if (count($content_type) === 0 or (count($content_type) === 1 and $content_type[0] === '')) { return 'application/json'; } elseif (preg_grep("/application\/json/i", $content_type)) { @@ -445,6 +216,4 @@ class ApiClient { return implode(',', $content_type); } } - } - diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php index 5f3b1812261..51774137aed 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php @@ -22,15 +22,20 @@ use \Exception; class ApiException extends Exception { /** @var string The HTTP body of the server response. */ - protected $response_body; + protected $responseBody; /** @var string[] The HTTP header of the server response. */ - protected $response_headers; + protected $responseHeaders; + + /** + * The deserialized response object + */ + protected $responseObject; public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { parent::__construct($message, $code); - $this->response_headers = $responseHeaders; - $this->response_body = $responseBody; + $this->responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; } /** @@ -39,7 +44,7 @@ class ApiException extends Exception { * @return string HTTP response header */ public function getResponseHeaders() { - return $this->response_headers; + return $this->responseHeaders; } /** @@ -48,7 +53,18 @@ class ApiException extends Exception { * @return string HTTP response body */ public function getResponseBody() { - return $this->response_body; + return $this->responseBody; } + /** + * sets the deseralized response object (during deserialization) + * @param mixed $obj + */ + public function setResponseObject($obj) { + $this->responseObject = $obj; + } + + public function getResponseObject() { + return $this->responseObject; + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php index e6381781bb0..a407fe4dd49 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php @@ -17,37 +17,250 @@ namespace Swagger\Client; -use \Swagger\Client\ApiClient; - class Configuration { + private static $defaultConfiguration = null; + /** @var string[] Associate array to store API key(s) */ - public static $apiKey = array(); + protected $apiKeys = array(); /** string[] Associate array to store API prefix (e.g. Bearer) */ - public static $apiKeyPrefix = array(); + protected $apiKeyPrefixes = array(); /** @var string Username for HTTP basic authentication */ - public static $username = ''; + protected $username = ''; /** @var string Password for HTTP basic authentication */ - public static $password = ''; + protected $password = ''; /** @var \Swagger\Client\ApiClient The default instance of ApiClient */ - public static $apiClient; + protected $defaultHeaders = array(); + + /** @var string The host */ + protected $host = 'http://localhost'; + + /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ + protected $curlTimeout = 0; + + /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ + protected $userAgent = "PHP-Swagger"; /** @var bool Debug switch (default set to false) */ - public static $debug = false; + protected $debug = false; /** @var string Debug file location (log to STDOUT by default) */ - public static $debug_file = 'php://output'; + protected $debugFile = 'php://output'; - /* - * manually initalize ApiClient + /** + * @param string $key + * @param string $value + * @return Configuration */ - public static function init() { - if (self::$apiClient === null) - self::$apiClient = new ApiClient(); + public function setApiKey($key, $value) { + $this->apiKeys[$key] = $value; + return $this; } + /** + * @param $key + * @return string + */ + public function getApiKey($key) { + return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null; + } + + /** + * @param string $key + * @param string $value + * @return Configuration + */ + public function setApiKeyPrefix($key, $value) { + $this->apiKeyPrefixes[$key] = $value; + return $this; + } + + /** + * @param $key + * @return string + */ + public function getApiKeyPrefix($key) { + return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null; + } + + /** + * @param string $username + * @return Configuration + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * @param string $password + * @return Configuration + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * add default header + * + * @param string $headerName header name (e.g. Token) + * @param string $headerValue header value (e.g. 1z8wp3) + * @return ApiClient + */ + public function addDefaultHeader($headerName, $headerValue) { + if (!is_string($headerName)) { + throw new \InvalidArgumentException('Header name must be a string.'); + } + + $this->defaultHeaders[$headerName] = $headerValue; + return $this; + } + + /** + * get the default header + * + * @return array default header + */ + public function getDefaultHeaders() { + return $this->defaultHeaders; + } + + /** + * delete a default header + * @param string $headerName the header to delete + * @return Configuration + */ + public function deleteDefaultHeader($headerName) { + unset($this->defaultHeaders[$headerName]); + } + + /** + * @param string $host + * @return Configuration + */ + public function setHost($host) { + $this->host = $host; + return $this; + } + + /** + * @return string + */ + public function getHost() { + return $this->host; + } + + /** + * set the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * @return ApiClient + */ + public function setUserAgent($userAgent) { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * get the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() { + return $this->userAgent; + } + + /** + * set the HTTP timeout value + * + * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + * @return ApiClient + */ + public function setCurlTimeout($seconds) { + if (!is_numeric($seconds) || $seconds < 0) { + throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); + } + + $this->curlTimeout = $seconds; + return $this; + } + + /** + * get the HTTP timeout value + * + * @return string HTTP timeout value + */ + public function getCurlTimeout() { + return $this->curlTimeout; + } + + /** + * @param bool $debug + * @return Configuration + */ + public function setDebug($debug) { + $this->debug = $debug; + return $this; + } + + /** + * @return bool + */ + public function getDebug() { + return $this->debug; + } + + /** + * @param string $debugFile + * @return Configuration + */ + public function setDebugFile($debugFile) { + $this->debugFile = $debugFile; + return $this; + } + + /** + * @return string + */ + public function getDebugFile() { + return $this->debugFile; + } + + /** + * @return Configuration + */ + public static function getDefaultConfiguration() { + if (self::$defaultConfiguration == null) { + return new Configuration(); + } + + return self::$defaultConfiguration; + } + + public static function setDefaultConfiguration(Configuration $config) { + self::$defaultConfiguration = $config; + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php index 750a8fee5df..75aaf2eeead 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php @@ -38,21 +38,69 @@ class Category implements ArrayAccess { 'id' => 'id', 'name' => 'name' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'name' => 'setName' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'name' => 'getName' + ); + /** @var int $id */ - public $id; + protected $id; /** @var string $name */ - public $name; + protected $name; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->name = $data["name"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->name = @$data["name"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get name + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * set name + * @param string $name + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php index 64552afb763..c7a433c3d8c 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php @@ -46,37 +46,165 @@ class Order implements ArrayAccess { 'status' => 'status', 'complete' => 'complete' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'pet_id' => 'setPetId', + 'quantity' => 'setQuantity', + 'ship_date' => 'setShipDate', + 'status' => 'setStatus', + 'complete' => 'setComplete' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'pet_id' => 'getPetId', + 'quantity' => 'getQuantity', + 'ship_date' => 'getShipDate', + 'status' => 'getStatus', + 'complete' => 'getComplete' + ); + /** @var int $id */ - public $id; + protected $id; /** @var int $pet_id */ - public $pet_id; + protected $pet_id; /** @var int $quantity */ - public $quantity; + protected $quantity; /** @var \DateTime $ship_date */ - public $ship_date; + protected $ship_date; /** @var string $status Order Status */ - public $status; + protected $status; /** @var bool $complete */ - public $complete; + protected $complete; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->pet_id = $data["pet_id"]; + $this->quantity = $data["quantity"]; + $this->ship_date = $data["ship_date"]; + $this->status = $data["status"]; + $this->complete = $data["complete"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->pet_id = @$data["pet_id"]; - $this->quantity = @$data["quantity"]; - $this->ship_date = @$data["ship_date"]; - $this->status = @$data["status"]; - $this->complete = @$data["complete"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get pet_id + * @return int + */ + public function getPetId() { + return $this->pet_id; + } + + /** + * set pet_id + * @param int $pet_id + * @return $this + */ + public function setPetId($pet_id) { + $this->pet_id = $pet_id; + return $this; + } + + /** + * get quantity + * @return int + */ + public function getQuantity() { + return $this->quantity; + } + + /** + * set quantity + * @param int $quantity + * @return $this + */ + public function setQuantity($quantity) { + $this->quantity = $quantity; + return $this; + } + + /** + * get ship_date + * @return \DateTime + */ + public function getShipDate() { + return $this->ship_date; + } + + /** + * set ship_date + * @param \DateTime $ship_date + * @return $this + */ + public function setShipDate($ship_date) { + $this->ship_date = $ship_date; + return $this; + } + + /** + * get status + * @return string + */ + public function getStatus() { + return $this->status; + } + + /** + * set status + * @param string $status + * @return $this + */ + public function setStatus($status) { + $this->status = $status; + return $this; + } + + /** + * get complete + * @return bool + */ + public function getComplete() { + return $this->complete; + } + + /** + * set complete + * @param bool $complete + * @return $this + */ + public function setComplete($complete) { + $this->complete = $complete; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php index ef2a4c76a0d..cbe27e1fce9 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php @@ -46,37 +46,165 @@ class Pet implements ArrayAccess { 'tags' => 'tags', 'status' => 'status' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'category' => 'setCategory', + 'name' => 'setName', + 'photo_urls' => 'setPhotoUrls', + 'tags' => 'setTags', + 'status' => 'setStatus' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'category' => 'getCategory', + 'name' => 'getName', + 'photo_urls' => 'getPhotoUrls', + 'tags' => 'getTags', + 'status' => 'getStatus' + ); + /** @var int $id */ - public $id; + protected $id; /** @var \Swagger\Client\Model\Category $category */ - public $category; + protected $category; /** @var string $name */ - public $name; + protected $name; /** @var string[] $photo_urls */ - public $photo_urls; + protected $photo_urls; /** @var \Swagger\Client\Model\Tag[] $tags */ - public $tags; + protected $tags; /** @var string $status pet status in the store */ - public $status; + protected $status; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->category = $data["category"]; + $this->name = $data["name"]; + $this->photo_urls = $data["photo_urls"]; + $this->tags = $data["tags"]; + $this->status = $data["status"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->category = @$data["category"]; - $this->name = @$data["name"]; - $this->photo_urls = @$data["photo_urls"]; - $this->tags = @$data["tags"]; - $this->status = @$data["status"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get category + * @return \Swagger\Client\Model\Category + */ + public function getCategory() { + return $this->category; + } + + /** + * set category + * @param \Swagger\Client\Model\Category $category + * @return $this + */ + public function setCategory($category) { + $this->category = $category; + return $this; + } + + /** + * get name + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * set name + * @param string $name + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + + /** + * get photo_urls + * @return string[] + */ + public function getPhotoUrls() { + return $this->photo_urls; + } + + /** + * set photo_urls + * @param string[] $photo_urls + * @return $this + */ + public function setPhotoUrls($photo_urls) { + $this->photo_urls = $photo_urls; + return $this; + } + + /** + * get tags + * @return \Swagger\Client\Model\Tag[] + */ + public function getTags() { + return $this->tags; + } + + /** + * set tags + * @param \Swagger\Client\Model\Tag[] $tags + * @return $this + */ + public function setTags($tags) { + $this->tags = $tags; + return $this; + } + + /** + * get status + * @return string + */ + public function getStatus() { + return $this->status; + } + + /** + * set status + * @param string $status + * @return $this + */ + public function setStatus($status) { + $this->status = $status; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php index 5959cb20a6a..3fd785f001b 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php @@ -38,21 +38,69 @@ class Tag implements ArrayAccess { 'id' => 'id', 'name' => 'name' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'name' => 'setName' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'name' => 'getName' + ); + /** @var int $id */ - public $id; + protected $id; /** @var string $name */ - public $name; + protected $name; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->name = $data["name"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->name = @$data["name"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get name + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * set name + * @param string $name + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php index 1bfb7f332db..2bb31056bde 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php @@ -50,45 +50,213 @@ class User implements ArrayAccess { 'phone' => 'phone', 'user_status' => 'userStatus' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'username' => 'setUsername', + 'first_name' => 'setFirstName', + 'last_name' => 'setLastName', + 'email' => 'setEmail', + 'password' => 'setPassword', + 'phone' => 'setPhone', + 'user_status' => 'setUserStatus' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'username' => 'getUsername', + 'first_name' => 'getFirstName', + 'last_name' => 'getLastName', + 'email' => 'getEmail', + 'password' => 'getPassword', + 'phone' => 'getPhone', + 'user_status' => 'getUserStatus' + ); + /** @var int $id */ - public $id; + protected $id; /** @var string $username */ - public $username; + protected $username; /** @var string $first_name */ - public $first_name; + protected $first_name; /** @var string $last_name */ - public $last_name; + protected $last_name; /** @var string $email */ - public $email; + protected $email; /** @var string $password */ - public $password; + protected $password; /** @var string $phone */ - public $phone; + protected $phone; /** @var int $user_status User Status */ - public $user_status; + protected $user_status; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->username = $data["username"]; + $this->first_name = $data["first_name"]; + $this->last_name = $data["last_name"]; + $this->email = $data["email"]; + $this->password = $data["password"]; + $this->phone = $data["phone"]; + $this->user_status = $data["user_status"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->username = @$data["username"]; - $this->first_name = @$data["first_name"]; - $this->last_name = @$data["last_name"]; - $this->email = @$data["email"]; - $this->password = @$data["password"]; - $this->phone = @$data["phone"]; - $this->user_status = @$data["user_status"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get username + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * set username + * @param string $username + * @return $this + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * get first_name + * @return string + */ + public function getFirstName() { + return $this->first_name; + } + + /** + * set first_name + * @param string $first_name + * @return $this + */ + public function setFirstName($first_name) { + $this->first_name = $first_name; + return $this; + } + + /** + * get last_name + * @return string + */ + public function getLastName() { + return $this->last_name; + } + + /** + * set last_name + * @param string $last_name + * @return $this + */ + public function setLastName($last_name) { + $this->last_name = $last_name; + return $this; + } + + /** + * get email + * @return string + */ + public function getEmail() { + return $this->email; + } + + /** + * set email + * @param string $email + * @return $this + */ + public function setEmail($email) { + $this->email = $email; + return $this; + } + + /** + * get password + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * set password + * @param string $password + * @return $this + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * get phone + * @return string + */ + public function getPhone() { + return $this->phone; + } + + /** + * set phone + * @param string $phone + * @return $this + */ + public function setPhone($phone) { + $this->phone = $phone; + return $this; + } + + /** + * get user_status + * @return int + */ + public function getUserStatus() { + return $this->user_status; + } + + /** + * set user_status + * @param int $user_status + * @return $this + */ + public function setUserStatus($user_status) { + $this->user_status = $user_status; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php b/samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php new file mode 100644 index 00000000000..802a49bc01a --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php @@ -0,0 +1,151 @@ +format(\DateTime::ISO8601); + } else if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = $this->sanitizeForSerialization($value); + } + $sanitized = $data; + } else if (is_object($data)) { + $values = array(); + foreach (array_keys($data::$swaggerTypes) as $property) { + $getter = $data::$getters[$property]; + if ($data->$getter() !== null) { + $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$getter()); + } + } + $sanitized = $values; + } else { + $sanitized = (string)$data; + } + + return $sanitized; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * @param string $value a string which will be part of the path + * @return string the serialized object + */ + public function toPathValue($value) { + return rawurlencode($this->toString($value)); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the query, by imploding comma-separated if it's an object. + * If it's a string, pass through unchanged. It will be url-encoded + * later. + * @param object $object an object to be serialized to a string + * @return string the serialized object + */ + public function toQueryValue($object) { + if (is_array($object)) { + return implode(',', $object); + } else { + return $this->toString($object); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value a string which will be part of the header + * @return string the header string + */ + public function toHeaderValue($value) { + return $this->toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the http body (form parameter). If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the form parameter + * @return string the form string + */ + public function toFormValue($value) { + return $this->toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the parameter + * @return string the header string + */ + public function toString($value) { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(\DateTime::ISO8601); + } else { + return $value; + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @return object an instance of $class + */ + public function deserialize($data, $class) { + if (null === $data) { + $deserialized = null; + } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] + $inner = substr($class, 4, -1); + $deserialized = array(); + if(strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = $this->deserialize($value, $subClass); + } + } + } elseif (strcasecmp(substr($class, -2),'[]') == 0) { + $subClass = substr($class, 0, -2); + $values = array(); + foreach ($data as $key => $value) { + $values[] = $this->deserialize($value, $subClass); + } + $deserialized = $values; + } elseif ($class == 'DateTime') { + $deserialized = new \DateTime($data); + } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { + settype($data, $class); + $deserialized = $data; + } else { + $instance = new $class(); + foreach ($instance::$swaggerTypes as $property => $type) { + $propertySetter = $instance::$setters[$property]; + + if (!isset($propertySetter) || !isset($data->{$instance::$attributeMap[$property]})) { + continue; + } + + $propertyValue = $data->{$instance::$attributeMap[$property]}; + if (isset($propertyValue)) { + $instance->$propertySetter($this->deserialize($propertyValue, $type)); + } + } + $deserialized = $instance; + } + + return $deserialized; + } +} \ No newline at end of file diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index 131a79dba92..3ac28772291 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -22,19 +22,19 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // new pet $new_pet_id = 10005; $new_pet = new Swagger\Client\Model\Pet; - $new_pet->id = $new_pet_id; - $new_pet->name = "PHP Unit Test"; + $new_pet->setId($new_pet_id); + $new_pet->setName("PHP Unit Test"); // new tag $tag= new Swagger\Client\Model\Tag; - $tag->id = $new_pet_id; // use the same id as pet - $tag->name = "test php tag"; + $tag->setId($new_pet_id); // use the same id as pet + $tag->setName("test php tag"); // new category $category = new Swagger\Client\Model\Category; - $category->id = $new_pet_id; // use the same id as pet - $category->name = "test php category"; + $category->setId($new_pet_id); // use the same id as pet + $category->setName("test php category"); - $new_pet->tags = array($tag); - $new_pet->category = $category; + $new_pet->setTags(array($tag)); + $new_pet->setCategory($category); $pet_api = new Swagger\Client\Api\PetAPI(); // add a new pet (model) @@ -56,65 +56,53 @@ class PetApiTest extends \PHPUnit_Framework_TestCase $this->assertSame('application/yaml,application/xml', $api_client->selectHeaderContentType(array('application/yaml','application/xml'))); // test addDefaultHeader and getDefaultHeader - $api_client->addDefaultHeader('test1', 'value1'); - $api_client->addDefaultHeader('test2', 200); - $defaultHeader = $api_client->getDefaultHeader(); + $api_client->getConfig()->addDefaultHeader('test1', 'value1'); + $api_client->getConfig()->addDefaultHeader('test2', 200); + $defaultHeader = $api_client->getConfig()->getDefaultHeaders(); $this->assertSame('value1', $defaultHeader['test1']); $this->assertSame(200, $defaultHeader['test2']); // test deleteDefaultHeader - $api_client->deleteDefaultHeader('test2'); - $defaultHeader = $api_client->getDefaultHeader(); + $api_client->getConfig()->deleteDefaultHeader('test2'); + $defaultHeader = $api_client->getConfig()->getDefaultHeaders(); $this->assertFalse(isset($defaultHeader['test2'])); - $pet_api = new Swagger\Client\Api\PetAPI(); $pet_api2 = new Swagger\Client\Api\PetAPI(); $apiClient3 = new Swagger\Client\ApiClient(); - $apiClient3->setUserAgent = 'api client 3'; + $apiClient3->getConfig()->setUserAgent('api client 3'); $apiClient4 = new Swagger\Client\ApiClient(); - $apiClient4->setUserAgent = 'api client 4'; + $apiClient4->getConfig()->setUserAgent('api client 4'); $pet_api3 = new Swagger\Client\Api\PetAPI($apiClient3); - // same default api client - $this->assertSame($pet_api->getApiClient(), $pet_api2->getApiClient()); - // confirm using the default api client in the Configuration - $this->assertSame($pet_api->getApiClient(), Swagger\Client\Configuration::$apiClient); // 2 different api clients are not the same $this->assertNotEquals($apiClient3, $apiClient4); - // customized pet api not using the default (configuration) api client - $this->assertNotEquals($pet_api3->getApiClient(), Swagger\Client\Configuration::$apiClient); // customied pet api not using the old pet api's api client $this->assertNotEquals($pet_api2->getApiClient(), $pet_api3->getApiClient()); - - // both pet api and pet api2 share the same api client and confirm using timeout value - $pet_api->getApiClient()->setTimeout(999); - $this->assertSame(999, $pet_api2->getApiClient()->getTimeout()); - } // test getPetById with a Pet object (id 10005) public function testGetPetById() { // initialize the API client without host - $api_client = new Swagger\Client\ApiClient(); - Swagger\Client\Configuration::$apiKey['api_key'] = '111222333444555'; $pet_id = 10005; // ID of pet that needs to be fetched - $pet_api = new Swagger\Client\Api\PetAPI($api_client); + $pet_api = new Swagger\Client\Api\PetAPI(); + $pet_api->getApiClient()->getConfig()->setApiKey('api_key', '111222333444555'); // return Pet (model) $response = $pet_api->getPetById($pet_id); - $this->assertSame($response->id, $pet_id); - $this->assertSame($response->name, 'PHP Unit Test'); - $this->assertSame($response->category->id, $pet_id); - $this->assertSame($response->category->name, 'test php category'); - $this->assertSame($response->tags[0]->id, $pet_id); - $this->assertSame($response->tags[0]->name, 'test php tag'); + $this->assertSame($response->getId(), $pet_id); + $this->assertSame($response->getName(), 'PHP Unit Test'); + $this->assertSame($response->getCategory()->getId(), $pet_id); + $this->assertSame($response->getCategory()->getName(), 'test php category'); + $this->assertSame($response->getTags()[0]->getId(), $pet_id); + $this->assertSame($response->getTags()[0]->getName(), 'test php tag'); } // test getPetByStatus and verify by the "id" of the response public function testFindPetByStatus() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_api = new Swagger\Client\Api\PetAPI($api_client); // return Pet (model) $response = $pet_api->findPetsByStatus("available"); @@ -133,30 +121,32 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUpdatePet() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_id = 10001; // ID of pet that needs to be fetched $pet_api = new Swagger\Client\Api\PetAPI($api_client); // create updated pet object $updated_pet = new Swagger\Client\Model\Pet; - $updated_pet->id = $pet_id; - $updated_pet->name = 'updatePet'; // new name - $updated_pet->status = 'pending'; // new status + $updated_pet->setId($pet_id); + $updated_pet->setName('updatePet'); // new name + $updated_pet->setStatus('pending'); // new status // update Pet (model/json) $update_response = $pet_api->updatePet($updated_pet); // return nothing (void) $this->assertSame($update_response, NULL); // verify updated Pet $response = $pet_api->getPetById($pet_id); - $this->assertSame($response->id, $pet_id); - $this->assertSame($response->status, 'pending'); - $this->assertSame($response->name, 'updatePet'); + $this->assertSame($response->getId(), $pet_id); + $this->assertSame($response->getStatus(), 'pending'); + $this->assertSame($response->getName(), 'updatePet'); } // test updatePet and verify by the "id" of the response public function testUpdatePetWithForm() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_id = 10001; // ID of pet that needs to be fetched $pet_api = new Swagger\Client\Api\PetAPI($api_client); // update Pet (form) @@ -164,20 +154,21 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // return nothing (void) $this->assertSame($update_response, NULL); $response = $pet_api->getPetById($pet_id); - $this->assertSame($response->id, $pet_id); - $this->assertSame($response->name, 'update pet with form'); - $this->assertSame($response->status, 'sold'); + $this->assertSame($response->getId(), $pet_id); + $this->assertSame($response->getName(), 'update pet with form'); + $this->assertSame($response->getStatus(), 'sold'); } // test addPet and verify by the "id" and "name" of the response public function testAddPet() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $new_pet_id = 10001; $new_pet = new Swagger\Client\Model\Pet; - $new_pet->id = $new_pet_id; - $new_pet->name = "PHP Unit Test"; + $new_pet->setId($new_pet_id); + $new_pet->setName("PHP Unit Test"); $pet_api = new Swagger\Client\Api\PetAPI($api_client); // add a new pet (model) $add_response = $pet_api->addPet($new_pet); @@ -185,15 +176,16 @@ class PetApiTest extends \PHPUnit_Framework_TestCase $this->assertSame($add_response, NULL); // verify added Pet $response = $pet_api->getPetById($new_pet_id); - $this->assertSame($response->id, $new_pet_id); - $this->assertSame($response->name, 'PHP Unit Test'); + $this->assertSame($response->getId(), $new_pet_id); + $this->assertSame($response->getName(), 'PHP Unit Test'); } // test upload file public function testUploadFile() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_api = new Swagger\Client\Api\PetAPI($api_client); // upload file $pet_id = 10001; @@ -206,7 +198,9 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testGetInventory() { // initialize the API client - $api_client = new Swagger\Client\APIClient('http://petstore.swagger.io/v2'); + $config = new Swagger\Client\Configuration(); + $config->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\APIClient($config); $store_api = new Swagger\Client\Api\StoreAPI($api_client); // get inventory $get_response = $store_api->getInventory(); diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php index a92149fbaf3..05bd873c993 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php @@ -1,6 +1,6 @@ setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); + $store_api = new Swagger\Client\Api\StoreAPI($api_client); // get inventory $get_response = $store_api->getInventory(); diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php index 181e8a1249e..3efce8b08ba 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php @@ -1,6 +1,6 @@ setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); + $user_api = new Swagger\Client\Api\UserApi($api_client); // login $response = $user_api->loginUser("xxxxx", "yyyyyyyy"); From ce6ec20feff944fd7dece44cb2c788e84a863c64 Mon Sep 17 00:00:00 2001 From: Ole Lensmar Date: Wed, 24 Jun 2015 00:11:13 +0200 Subject: [PATCH 147/499] added config parameters for all default parameters and a configOptions map for language specific parameters --- .../codegen/plugin/AdditionalParams.java | 8 ++- .../swagger/codegen/plugin/CodeGenMojo.java | 67 ++++++++++++++++++- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java index aa137cbf6c3..62fb530f0f0 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java @@ -7,10 +7,12 @@ package io.swagger.codegen.plugin; */ public final class AdditionalParams { public static final String TEMPLATE_DIR_PARAM = "templateDir"; + public static final String MODEL_PACKAGE_PARAM = "modelPackage"; + public static final String API_PACKAGE_PARAM = "apiPackage"; + public static final String INVOKER_PACKAGE_PARAM = "invokerPackage"; + public static final String SOURCE_FOLDER_PARAM = "sourceFolder"; + public static final String IMPL_FOLDER_PARAM = "implFolder"; private AdditionalParams() { - } - - } diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java index 26b6fef1135..e136ebf43aa 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -16,6 +16,7 @@ package io.swagger.codegen.plugin; * limitations under the License. */ +import io.swagger.codegen.CliOption; import io.swagger.codegen.ClientOptInput; import io.swagger.codegen.ClientOpts; import io.swagger.codegen.CodegenConfig; @@ -30,16 +31,16 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import java.io.File; +import java.util.Map; import java.util.ServiceLoader; -import static io.swagger.codegen.plugin.AdditionalParams.TEMPLATE_DIR_PARAM; +import static io.swagger.codegen.plugin.AdditionalParams.*; /** * Goal which generates client/server code from a swagger json/yaml definition. */ @Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES) public class CodeGenMojo extends AbstractMojo { - /** * Location of the output directory. */ @@ -60,12 +61,47 @@ public class CodeGenMojo extends AbstractMojo { @Parameter(name = "templateDirectory") private File templateDirectory; + /** + * Folder containing the template files. + */ + @Parameter(name = "modelPackage") + private String modelPackage; + + /** + * Folder containing the template files. + */ + @Parameter(name = "apiPackage") + private String apiPackage; + + /** + * Folder containing the template files. + */ + @Parameter(name = "invokerPackage") + private String invokerPackage; + + /** + * Folder containing the template files. + */ + @Parameter(name = "implFolder") + private String implFolder; + + /** + * Folder containing the template files. + */ + @Parameter(name = "sourceFolder") + private File sourceFolder; + /** * Client language to generate. */ @Parameter(name = "language", required = true) private String language; + /** + * A map of language-specific properties as passed with the -c option to the command line + */ + @Parameter(name ="configOptions") + private Map configOptions; /** * Add the output directory to the project as a source root, so that the @@ -90,8 +126,33 @@ public class CodeGenMojo extends AbstractMojo { if (null != templateDirectory) { config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath()); } + if (null != modelPackage) { + config.additionalProperties().put(MODEL_PACKAGE_PARAM, modelPackage ); + } + if (null != apiPackage) { + config.additionalProperties().put(API_PACKAGE_PARAM, apiPackage); + } + if (null != invokerPackage) { + config.additionalProperties().put(INVOKER_PACKAGE_PARAM, invokerPackage); + } + if (null != sourceFolder) { + config.additionalProperties().put(SOURCE_FOLDER_PARAM, sourceFolder.getAbsolutePath()); + } + if (null != implFolder) { + config.additionalProperties().put(IMPL_FOLDER_PARAM, implFolder); + } - ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger); + ClientOpts clientOpts = new ClientOpts(); + if( configOptions != null ){ + for (CliOption langCliOption : config.cliOptions()) { + if (configOptions.containsKey(langCliOption.getOpt())) { + config.additionalProperties().put(langCliOption.getOpt(), + configOptions.get(langCliOption.getOpt())); + } + } + } + + ClientOptInput input = new ClientOptInput().opts(clientOpts).swagger(swagger); input.setConfig(config); new DefaultGenerator().opts(input).generate(); From 50dd196d4224bdb72c668f02e825cddd909ee317 Mon Sep 17 00:00:00 2001 From: Ole Lensmar Date: Wed, 24 Jun 2015 00:12:50 +0200 Subject: [PATCH 148/499] fixed code formatting and imports --- modules/swagger-codegen-maven-plugin/pom.xml | 2 +- .../java/io/swagger/codegen/plugin/CodeGenMojo.java | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/swagger-codegen-maven-plugin/pom.xml b/modules/swagger-codegen-maven-plugin/pom.xml index 7ad4496872c..08c1ffef2ad 100644 --- a/modules/swagger-codegen-maven-plugin/pom.xml +++ b/modules/swagger-codegen-maven-plugin/pom.xml @@ -17,7 +17,7 @@ UTF-8 - + org.apache.maven maven-core 3.2.5 diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java index e136ebf43aa..58eadc62523 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -34,7 +34,12 @@ import java.io.File; import java.util.Map; import java.util.ServiceLoader; -import static io.swagger.codegen.plugin.AdditionalParams.*; +import static io.swagger.codegen.plugin.AdditionalParams.API_PACKAGE_PARAM; +import static io.swagger.codegen.plugin.AdditionalParams.IMPL_FOLDER_PARAM; +import static io.swagger.codegen.plugin.AdditionalParams.INVOKER_PACKAGE_PARAM; +import static io.swagger.codegen.plugin.AdditionalParams.MODEL_PACKAGE_PARAM; +import static io.swagger.codegen.plugin.AdditionalParams.SOURCE_FOLDER_PARAM; +import static io.swagger.codegen.plugin.AdditionalParams.TEMPLATE_DIR_PARAM; /** * Goal which generates client/server code from a swagger json/yaml definition. @@ -100,7 +105,7 @@ public class CodeGenMojo extends AbstractMojo { /** * A map of language-specific properties as passed with the -c option to the command line */ - @Parameter(name ="configOptions") + @Parameter(name = "configOptions") private Map configOptions; /** @@ -127,7 +132,7 @@ public class CodeGenMojo extends AbstractMojo { config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath()); } if (null != modelPackage) { - config.additionalProperties().put(MODEL_PACKAGE_PARAM, modelPackage ); + config.additionalProperties().put(MODEL_PACKAGE_PARAM, modelPackage); } if (null != apiPackage) { config.additionalProperties().put(API_PACKAGE_PARAM, apiPackage); @@ -143,7 +148,7 @@ public class CodeGenMojo extends AbstractMojo { } ClientOpts clientOpts = new ClientOpts(); - if( configOptions != null ){ + if (configOptions != null) { for (CliOption langCliOption : config.cliOptions()) { if (configOptions.containsKey(langCliOption.getOpt())) { config.additionalProperties().put(langCliOption.getOpt(), From 1b1f860c828973a26eecbc2c9d5ff37c3e147eb5 Mon Sep 17 00:00:00 2001 From: Gabriel Radu <1342gr@gmail.com> Date: Wed, 24 Jun 2015 03:07:22 +0100 Subject: [PATCH 149/499] Add a `pathPrefix` key to the `operations` key --- .../src/main/java/io/swagger/codegen/DefaultGenerator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index 0ad05b0762b..481ca924d98 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -393,6 +393,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { Map operations = new HashMap(); Map objs = new HashMap(); objs.put("classname", config.toApiName(tag)); + objs.put("pathPrefix", config.toApiVarName(tag)); // check for operationId uniqueness Set opIds = new HashSet(); From 8e6c0f96fba7f1796f7b9251767560216d4371a8 Mon Sep 17 00:00:00 2001 From: Ole Lensmar Date: Wed, 24 Jun 2015 07:31:10 +0200 Subject: [PATCH 150/499] updated documentation and removed java-specific parameters from general configuration --- .../swagger-codegen-maven-plugin/README.md | 16 ++++++++++- .../codegen/plugin/AdditionalParams.java | 2 -- .../swagger/codegen/plugin/CodeGenMojo.java | 28 +++---------------- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/modules/swagger-codegen-maven-plugin/README.md b/modules/swagger-codegen-maven-plugin/README.md index a7eaf852a22..372b2c90adf 100644 --- a/modules/swagger-codegen-maven-plugin/README.md +++ b/modules/swagger-codegen-maven-plugin/README.md @@ -20,6 +20,9 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase) src/main/resources/api.yaml java + + src/gen/java/main + @@ -32,10 +35,21 @@ Followed by: mvn clean compile ``` -### Configuration parameters +### General Configuration parameters - `inputSpec` - swagger spec file path - `language` - target generation language - `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`) - `templateDirectory` - directory with mustache templates - `addCompileSourceRoot` - add the output directory to the project as a source root (`true` by default) +- `modelPackage` - the package to use for generated model objects/classes +- `apiPackage` - the package to use for generated api objects/classes +- `invokerPackage` - the package to use for the generated invoker objects +- `configOptions` - a map of language-specific parameters (see below) + +### Java-specific parameters (under configOptions) + +- `sourceFolder` - the folder to use for generated sources under the output folder +- `groupId` - groupId in generated pom.xml +- `artifactId` - artifactId in generated pom.xml +- `artifactVersion` - artifact version in generated pom.xml diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java index 62fb530f0f0..f3678e783e0 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/AdditionalParams.java @@ -10,8 +10,6 @@ public final class AdditionalParams { public static final String MODEL_PACKAGE_PARAM = "modelPackage"; public static final String API_PACKAGE_PARAM = "apiPackage"; public static final String INVOKER_PACKAGE_PARAM = "invokerPackage"; - public static final String SOURCE_FOLDER_PARAM = "sourceFolder"; - public static final String IMPL_FOLDER_PARAM = "implFolder"; private AdditionalParams() { } diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java index 58eadc62523..32ea914fa64 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -35,10 +35,8 @@ import java.util.Map; import java.util.ServiceLoader; import static io.swagger.codegen.plugin.AdditionalParams.API_PACKAGE_PARAM; -import static io.swagger.codegen.plugin.AdditionalParams.IMPL_FOLDER_PARAM; import static io.swagger.codegen.plugin.AdditionalParams.INVOKER_PACKAGE_PARAM; import static io.swagger.codegen.plugin.AdditionalParams.MODEL_PACKAGE_PARAM; -import static io.swagger.codegen.plugin.AdditionalParams.SOURCE_FOLDER_PARAM; import static io.swagger.codegen.plugin.AdditionalParams.TEMPLATE_DIR_PARAM; /** @@ -67,35 +65,23 @@ public class CodeGenMojo extends AbstractMojo { private File templateDirectory; /** - * Folder containing the template files. + * The package to use for generated model objects/classes */ @Parameter(name = "modelPackage") private String modelPackage; /** - * Folder containing the template files. + * The package to use for generated api objects/classes */ @Parameter(name = "apiPackage") private String apiPackage; /** - * Folder containing the template files. + * The package to use for the generated invoker objects */ @Parameter(name = "invokerPackage") private String invokerPackage; - /** - * Folder containing the template files. - */ - @Parameter(name = "implFolder") - private String implFolder; - - /** - * Folder containing the template files. - */ - @Parameter(name = "sourceFolder") - private File sourceFolder; - /** * Client language to generate. */ @@ -103,7 +89,7 @@ public class CodeGenMojo extends AbstractMojo { private String language; /** - * A map of language-specific properties as passed with the -c option to the command line + * A map of language-specific parameters as passed with the -c option to the command line */ @Parameter(name = "configOptions") private Map configOptions; @@ -140,12 +126,6 @@ public class CodeGenMojo extends AbstractMojo { if (null != invokerPackage) { config.additionalProperties().put(INVOKER_PACKAGE_PARAM, invokerPackage); } - if (null != sourceFolder) { - config.additionalProperties().put(SOURCE_FOLDER_PARAM, sourceFolder.getAbsolutePath()); - } - if (null != implFolder) { - config.additionalProperties().put(IMPL_FOLDER_PARAM, implFolder); - } ClientOpts clientOpts = new ClientOpts(); if (configOptions != null) { From 6aac24398a3538e664fd56fc5d96b95e5f1ae29d Mon Sep 17 00:00:00 2001 From: wing328 Date: Wed, 24 Jun 2015 14:34:05 +0800 Subject: [PATCH 151/499] update model to support inheritance (#879) --- .../src/main/resources/csharp/model.mustache | 8 ++++---- .../csharp/src/main/csharp/io/swagger/Model/Category.cs | 2 -- .../csharp/src/main/csharp/io/swagger/Model/Order.cs | 2 -- .../csharp/src/main/csharp/io/swagger/Model/Pet.cs | 2 -- .../csharp/src/main/csharp/io/swagger/Model/Tag.cs | 2 -- .../csharp/src/main/csharp/io/swagger/Model/User.cs | 2 -- 6 files changed, 4 insertions(+), 14 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/csharp/model.mustache b/modules/swagger-codegen/src/main/resources/csharp/model.mustache index 0d86e0e2b99..c0fac63b385 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/model.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/model.mustache @@ -13,7 +13,7 @@ namespace {{packageName}}.Model { /// {{description}} /// [DataContract] - public class {{classname}} { + public class {{classname}}{{#parent}} : {{{parent}}}{{/parent}} { {{#vars}} {{#description}}/* {{{description}}} */{{/description}} [DataMember(Name="{{baseName}}", EmitDefaultValue=false)] @@ -39,11 +39,11 @@ namespace {{packageName}}.Model { /// Get the JSON string presentation of the object /// /// JSON string presentation of the object - public string ToJson() { + public {{#parent}} new {{/parent}}string ToJson() { return JsonConvert.SerializeObject(this, Formatting.Indented); } } - {{/model}} - {{/models}} +{{/model}} +{{/models}} } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs index 74121762af9..4a410e8220d 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs @@ -49,6 +49,4 @@ namespace IO.Swagger.Model { } } - - } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs index 7451619050c..9e7e706f77e 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs @@ -77,6 +77,4 @@ namespace IO.Swagger.Model { } } - - } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs index 0bfba35b1e3..49e6d582f5e 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs @@ -77,6 +77,4 @@ namespace IO.Swagger.Model { } } - - } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs index 53901491a47..47c87ae9ef1 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs @@ -49,6 +49,4 @@ namespace IO.Swagger.Model { } } - - } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs index e58d0296a06..f2c3db54608 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs @@ -91,6 +91,4 @@ namespace IO.Swagger.Model { } } - - } From 621e3e7b1a42ea91037629b41d35f1d8a0b909ad Mon Sep 17 00:00:00 2001 From: xhh Date: Wed, 24 Jun 2015 15:57:01 +0800 Subject: [PATCH 152/499] Add comments for some configuration options --- .../ruby/swagger/configuration.mustache | 61 +++++++++++++++---- .../swagger_client/swagger/configuration.rb | 61 +++++++++++++++---- 2 files changed, 98 insertions(+), 24 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index 5ed22afb151..1c7cb52c50f 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -3,18 +3,63 @@ require 'logger' module {{moduleName}} module Swagger class Configuration - attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, - :scheme, :host, :base_path, :user_agent, :debug, :logger, :inject_format, - :force_ending_format, :camelize_params, :user_agent, :verify_ssl + attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format, :camelize_params + + # Defines the username used with HTTP basic authentication. + # + # @return [String] + attr_accessor :username + + # Defines the password used with HTTP basic authentication. + # + # @return [String] + attr_accessor :password + + # Defines API keys used with API Key authentications. + # + # @return [Hash] key: parameter name, value: parameter value (API key) + # + # @example parameter name is "api_key", API key is "xxx" (e.g. "api_key=xxx" in query string) + # config.api_key['api_key'] = 'xxx' + attr_accessor :api_key + + # Defines API key prefixes used with API Key authentications. + # + # @return [Hash] key: parameter name, value: API key prefix + # + # @example parameter name is "Authorization", API key prefix is "Token" (e.g. "Authorization: Token xxx" in headers) + # config.api_key_prefix['api_key'] = 'Token' + attr_accessor :api_key_prefix + + # Set this to false to skip verifying SSL certificate when calling API from https server. + # Default to true. + # + # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks. + # + # @return [true, false] + attr_accessor :verify_ssl # Set this to customize the certificate file to verify the peer. # # @return [String] the path to the certificate file # # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code: - # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 + # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 attr_accessor :ssl_ca_cert + # Set this to enable/disable debugging. When enabled (set to true), HTTP request/response + # details will be logged with `logger.debug` (see the `logger` attribute). + # Default to false. + # + # @return [true, false] + attr_accessor :debug + + # Defines the logger used for debugging. + # Default to `Rails.logger` (when in Rails) or logging to STDOUT. + # + # @return [#debug] + attr_accessor :logger + # Defaults go in here.. def initialize @format = 'json' @@ -26,20 +71,12 @@ module {{moduleName}} @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 - # whether to enable debugging @debug = false - - # configure logger, default to logger of Rails (if in Rails) or STDOUT @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT) end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index 9ed1673eff1..50fe6a0bcc0 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -3,18 +3,63 @@ require 'logger' module SwaggerClient module Swagger class Configuration - attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, - :scheme, :host, :base_path, :user_agent, :debug, :logger, :inject_format, - :force_ending_format, :camelize_params, :user_agent, :verify_ssl + attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format, :camelize_params + + # Defines the username used with HTTP basic authentication. + # + # @return [String] + attr_accessor :username + + # Defines the password used with HTTP basic authentication. + # + # @return [String] + attr_accessor :password + + # Defines API keys used with API Key authentications. + # + # @return [Hash] key: parameter name, value: parameter value (API key) + # + # @example parameter name is "api_key", API key is "xxx" (e.g. "api_key=xxx" in query string) + # config.api_key['api_key'] = 'xxx' + attr_accessor :api_key + + # Defines API key prefixes used with API Key authentications. + # + # @return [Hash] key: parameter name, value: API key prefix + # + # @example parameter name is "Authorization", API key prefix is "Token" (e.g. "Authorization: Token xxx" in headers) + # config.api_key_prefix['api_key'] = 'Token' + attr_accessor :api_key_prefix + + # Set this to false to skip verifying SSL certificate when calling API from https server. + # Default to true. + # + # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks. + # + # @return [true, false] + attr_accessor :verify_ssl # Set this to customize the certificate file to verify the peer. # # @return [String] the path to the certificate file # # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code: - # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 + # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 attr_accessor :ssl_ca_cert + # Set this to enable/disable debugging. When enabled (set to true), HTTP request/response + # details will be logged with `logger.debug` (see the `logger` attribute). + # Default to false. + # + # @return [true, false] + attr_accessor :debug + + # Defines the logger used for debugging. + # Default to `Rails.logger` (when in Rails) or logging to STDOUT. + # + # @return [#debug] + attr_accessor :logger + # Defaults go in here.. def initialize @format = 'json' @@ -26,20 +71,12 @@ module SwaggerClient @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 - # whether to enable debugging @debug = false - - # configure logger, default to logger of Rails (if in Rails) or STDOUT @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT) end end From 644231b91518e428410f5033cac66a07e3902e5e Mon Sep 17 00:00:00 2001 From: Julian Bez Date: Wed, 24 Jun 2015 16:32:49 +0200 Subject: [PATCH 153/499] Change optional to required --- modules/swagger-codegen/src/main/resources/php/api.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 3ed7f18c579..394460ce46f 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -67,10 +67,10 @@ class {{classname}} { * * {{{summary}}} * -{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} +{{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} */ - public function {{nickname}}({{#allParams}}${{paramName}}{{#optional}}=null{{/optional}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { + public function {{nickname}}({{#allParams}}${{paramName}}{{#required}}=null{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} // verify the required parameter '{{paramName}}' is set if (${{paramName}} === null) { From 8ce3823698f3c0fd797983082c0da438c3c8caca Mon Sep 17 00:00:00 2001 From: Julian Bez Date: Wed, 24 Jun 2015 16:34:32 +0200 Subject: [PATCH 154/499] Change to not required --- modules/swagger-codegen/src/main/resources/php/api.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 394460ce46f..0eb1b0cd54a 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -70,7 +70,7 @@ class {{classname}} { {{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} */ - public function {{nickname}}({{#allParams}}${{paramName}}{{#required}}=null{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { + public function {{nickname}}({{#allParams}}${{paramName}}{{^required}}=null{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} // verify the required parameter '{{paramName}}' is set if (${{paramName}} === null) { From 1af23fb75124705456c877f617200bd9e656a7d3 Mon Sep 17 00:00:00 2001 From: Raghav Sidhanti Date: Wed, 24 Jun 2015 11:55:03 -0700 Subject: [PATCH 155/499] Unit tests for Android and Java parameterToPairs method --- .../io/swagger/client/ApiInvokerTest.java | 91 +++++++++++++++++++ .../java/io/swagger/client/ApiClientTest.java | 83 ++++++++++++++++- 2 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 samples/client/petstore/android-java/src/test/java/io/swagger/client/ApiInvokerTest.java diff --git a/samples/client/petstore/android-java/src/test/java/io/swagger/client/ApiInvokerTest.java b/samples/client/petstore/android-java/src/test/java/io/swagger/client/ApiInvokerTest.java new file mode 100644 index 00000000000..3e4b114012c --- /dev/null +++ b/samples/client/petstore/android-java/src/test/java/io/swagger/client/ApiInvokerTest.java @@ -0,0 +1,91 @@ +package io.swagger.client; + +import org.junit.*; +import static org.junit.Assert.*; + +import java.util.*; + + +public class ApiInvokerTest { + + @Test + public void testParameterToPairsWhenNameIsInvalid() throws Exception { + List pairs_a = ApiInvoker.parameterToPairs("csv", null, new Integer(1)); + List pairs_b = ApiInvoker.parameterToPairs("csv", "", new Integer(1)); + + assertTrue(pairs_a.isEmpty()); + assertTrue(pairs_b.isEmpty()); + } + + @Test + public void testParameterToPairsWhenValueIsNull() throws Exception { + List pairs = ApiInvoker.parameterToPairs("csv", "param-a", null); + + assertTrue(pairs.isEmpty()); + } + + @Test + public void testParameterToPairsWhenValueIsEmptyStrings() throws Exception { + + // single empty string + List pairs = ApiInvoker.parameterToPairs("csv", "param-a", " "); + assertEquals(1, pairs.size()); + + // list of empty strings + List strs = new ArrayList(); + strs.add(" "); + strs.add(" "); + strs.add(" "); + + List concatStrings = ApiInvoker.parameterToPairs("csv", "param-a", strs); + + assertEquals(1, concatStrings.size()); + assertFalse(concatStrings.get(0).getValue().isEmpty()); // should contain some delimiters + } + + @Test + public void testParameterToPairsWhenValueIsNotCollection() throws Exception { + String name = "param-a"; + Integer value = 1; + + List pairs = ApiInvoker.parameterToPairs("csv", name, value); + + assertEquals(1, pairs.size()); + assertEquals(value, Integer.valueOf(pairs.get(0).getValue())); + } + + @Test + public void testParameterToPairsWhenValueIsCollection() throws Exception { + Map collectionFormatMap = new HashMap(); + collectionFormatMap.put("csv", ","); + collectionFormatMap.put("tsv", "\t"); + collectionFormatMap.put("ssv", " "); + collectionFormatMap.put("pipes", "\\|"); + collectionFormatMap.put("", ","); // no format, must default to csv + collectionFormatMap.put("unknown", ","); // all other formats, must default to csv + + String name = "param-a"; + + List values = new ArrayList(); + values.add("value-a"); + values.add(123); + values.add(new Date()); + + // check for multi separately + List multiPairs = ApiInvoker.parameterToPairs("multi", name, values); + assertEquals(values.size(), multiPairs.size()); + + // all other formats + for (String collectionFormat : collectionFormatMap.keySet()) { + List pairs = ApiInvoker.parameterToPairs(collectionFormat, name, values); + + assertEquals(1, pairs.size()); + + String delimiter = collectionFormatMap.get(collectionFormat); + String[] pairValueSplit = pairs.get(0).getValue().split(delimiter); + + // must equal input values + assertEquals(values.size(), pairValueSplit.length); + } + } +} diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/ApiClientTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/ApiClientTest.java index 8a560d2d7bc..802c0cae3b9 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/client/ApiClientTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/ApiClientTest.java @@ -2,7 +2,7 @@ package io.swagger.client; import io.swagger.client.auth.*; -import java.util.Map; +import java.util.*; import org.junit.*; import static org.junit.Assert.*; @@ -109,4 +109,85 @@ public class ApiClientTest { auth.setApiKey(null); auth.setApiKeyPrefix(null); } + + @Test + public void testParameterToPairsWhenNameIsInvalid() throws Exception { + List pairs_a = apiClient.parameterToPairs("csv", null, new Integer(1)); + List pairs_b = apiClient.parameterToPairs("csv", "", new Integer(1)); + + assertTrue(pairs_a.isEmpty()); + assertTrue(pairs_b.isEmpty()); + } + + @Test + public void testParameterToPairsWhenValueIsNull() throws Exception { + List pairs = apiClient.parameterToPairs("csv", "param-a", null); + + assertTrue(pairs.isEmpty()); + } + + @Test + public void testParameterToPairsWhenValueIsEmptyStrings() throws Exception { + + // single empty string + List pairs = apiClient.parameterToPairs("csv", "param-a", " "); + assertEquals(1, pairs.size()); + + // list of empty strings + List strs = new ArrayList(); + strs.add(" "); + strs.add(" "); + strs.add(" "); + + List concatStrings = apiClient.parameterToPairs("csv", "param-a", strs); + + assertEquals(1, concatStrings.size()); + assertFalse(concatStrings.get(0).getValue().isEmpty()); // should contain some delimiters + } + + @Test + public void testParameterToPairsWhenValueIsNotCollection() throws Exception { + String name = "param-a"; + Integer value = 1; + + List pairs = apiClient.parameterToPairs("csv", name, value); + + assertEquals(1, pairs.size()); + assertEquals(value, Integer.valueOf(pairs.get(0).getValue())); + } + + @Test + public void testParameterToPairsWhenValueIsCollection() throws Exception { + Map collectionFormatMap = new HashMap(); + collectionFormatMap.put("csv", ","); + collectionFormatMap.put("tsv", "\t"); + collectionFormatMap.put("ssv", " "); + collectionFormatMap.put("pipes", "\\|"); + collectionFormatMap.put("", ","); // no format, must default to csv + collectionFormatMap.put("unknown", ","); // all other formats, must default to csv + + String name = "param-a"; + + List values = new ArrayList(); + values.add("value-a"); + values.add(123); + values.add(new Date()); + + // check for multi separately + List multiPairs = apiClient.parameterToPairs("multi", name, values); + assertEquals(values.size(), multiPairs.size()); + + // all other formats + for (String collectionFormat : collectionFormatMap.keySet()) { + List pairs = apiClient.parameterToPairs(collectionFormat, name, values); + + assertEquals(1, pairs.size()); + + String delimiter = collectionFormatMap.get(collectionFormat); + String[] pairValueSplit = pairs.get(0).getValue().split(delimiter); + + // must equal input values + assertEquals(values.size(), pairValueSplit.length); + } + } } From f3a0f464f792e04694c606c9303f813101471752 Mon Sep 17 00:00:00 2001 From: xhh Date: Thu, 25 Jun 2015 15:35:48 +0800 Subject: [PATCH 156/499] Support file downloading in Ruby generator --- .../codegen/languages/RubyClientCodegen.java | 1 + .../resources/ruby/swagger/response.mustache | 23 ++++++++++++++++++- .../ruby/lib/swagger_client/api/pet_api.rb | 2 +- .../lib/swagger_client/swagger/response.rb | 23 ++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index c3c78710682..3e1929b7485 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -61,6 +61,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("List", "Array"); typeMapping.put("map", "Hash"); typeMapping.put("object", "Object"); + typeMapping.put("file", "File"); // remove modelPackage and apiPackage added by default cliOptions.clear(); diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index b621110935a..14e276ddf5d 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -3,6 +3,7 @@ module {{moduleName}} class Response require 'json' require 'date' + require 'tempfile' attr_accessor :raw @@ -31,8 +32,11 @@ module {{moduleName}} def deserialize(return_type) return nil if body.blank? + # handle file downloading - save response body into a tmp file and return the File instance + return download_file if return_type == 'File' + # ensuring a default content type - content_type = raw.headers_hash['Content-Type'] || 'application/json' + content_type = raw.headers['Content-Type'] || 'application/json' unless content_type.start_with?('application/json') fail "Content-Type is not supported: #{content_type}" @@ -82,6 +86,23 @@ module {{moduleName}} end end + # Save response body into a file in tmp folder, using the filename from the + # "Content-Disposition" header if provided, otherwise a random filename. + def download_file + tmp_file = Tempfile.new '' + content_disposition = raw.headers['Content-Disposition'] + if content_disposition + filename = content_disposition[/filename="([^"]+)"/, 1] + path = File.join File.dirname(tmp_file), filename + else + path = tmp_file.path + end + # close and delete temp file + tmp_file.close! + File.open(path, 'w') { |file| file.write(raw.body) } + return File.new(path) + end + # `headers_hash` is a Typhoeus-specific extension of Hash, # so simplify it back into a regular old Hash. def headers diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 4a421faef86..f20f89bc584 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -286,7 +286,7 @@ module SwaggerClient # @param pet_id ID of pet to update # @param [Hash] opts the optional parameters # @option opts [String] :additional_metadata Additional data to pass to server - # @option opts [file] :file file to upload + # @option opts [File] :file file to upload # @return [nil] def self.upload_file(pet_id, opts = {}) diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index f560006de6d..e9c8e3805a0 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -3,6 +3,7 @@ module SwaggerClient class Response require 'json' require 'date' + require 'tempfile' attr_accessor :raw @@ -31,8 +32,11 @@ module SwaggerClient def deserialize(return_type) return nil if body.blank? + # handle file downloading - save response body into a tmp file and return the File instance + return download_file if return_type == 'File' + # ensuring a default content type - content_type = raw.headers_hash['Content-Type'] || 'application/json' + content_type = raw.headers['Content-Type'] || 'application/json' unless content_type.start_with?('application/json') fail "Content-Type is not supported: #{content_type}" @@ -82,6 +86,23 @@ module SwaggerClient end end + # Save response body into a file in tmp folder, using the filename from the + # "Content-Disposition" header if provided, otherwise a random filename. + def download_file + tmp_file = Tempfile.new '' + content_disposition = raw.headers['Content-Disposition'] + if content_disposition + filename = content_disposition[/filename="([^"]+)"/, 1] + path = File.join File.dirname(tmp_file), filename + else + path = tmp_file.path + end + # close and delete temp file + tmp_file.close! + File.open(path, 'w') { |file| file.write(raw.body) } + return File.new(path) + end + # `headers_hash` is a Typhoeus-specific extension of Hash, # so simplify it back into a regular old Hash. def headers From ceafbcc97f36e31b4986a38ca10aaac4edd0405d Mon Sep 17 00:00:00 2001 From: xhh Date: Thu, 25 Jun 2015 16:07:02 +0800 Subject: [PATCH 157/499] Add config option for file downloading folder. Log about file downloading --- .../resources/ruby/swagger/configuration.mustache | 7 +++++++ .../src/main/resources/ruby/swagger/response.mustache | 11 ++++++++--- .../src/main/resources/ruby/swagger_client.mustache | 3 ++- samples/client/petstore/ruby/lib/swagger_client.rb | 3 ++- .../ruby/lib/swagger_client/swagger/configuration.rb | 7 +++++++ .../ruby/lib/swagger_client/swagger/response.rb | 11 ++++++++--- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index e9a8af9c162..9400bdce6b7 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -3,6 +3,13 @@ module {{moduleName}} class Configuration attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + # Defines the temporary folder to store downloaded files + # (for API endpoints that have file response). + # Default to use `Tempfile`. + # + # @return [String] + attr_accessor :temp_folder_path + # Defaults go in here.. def initialize @format = 'json' diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index 14e276ddf5d..076f93e104f 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -86,10 +86,13 @@ module {{moduleName}} end end - # Save response body into a file in tmp folder, using the filename from the - # "Content-Disposition" header if provided, otherwise a random filename. + # Save response body into a file in (the defined) temporary folder, using the filename + # from the "Content-Disposition" header if provided, otherwise a random filename. + # + # @see Configuration#temp_folder_path + # @return [File] the file downloaded def download_file - tmp_file = Tempfile.new '' + tmp_file = Tempfile.new '', Swagger.configuration.temp_folder_path content_disposition = raw.headers['Content-Disposition'] if content_disposition filename = content_disposition[/filename="([^"]+)"/, 1] @@ -99,7 +102,9 @@ module {{moduleName}} end # close and delete temp file tmp_file.close! + File.open(path, 'w') { |file| file.write(raw.body) } + Swagger.logger.info "File written to #{path}. Please move the file to a proper folder for further processing and delete the temp afterwards" return File.new(path) end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache index 0be00aaec95..5bf57a642dd 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache @@ -22,5 +22,6 @@ require '{{importPath}}' module {{moduleName}} # Initialize the default configuration - Swagger.configuration ||= Swagger::Configuration.new + Swagger.configuration = Swagger::Configuration.new + Swagger.configure { |config| } end diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 42380927f82..eff88be2ebd 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -22,5 +22,6 @@ require 'swagger_client/api/store_api' module SwaggerClient # Initialize the default configuration - Swagger.configuration ||= Swagger::Configuration.new + Swagger.configuration = Swagger::Configuration.new + Swagger.configure { |config| } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index a2d4fe0e291..0b7836d989c 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -3,6 +3,13 @@ module SwaggerClient class Configuration attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + # Defines the temporary folder to store downloaded files + # (for API endpoints that have file response). + # Default to use `Tempfile`. + # + # @return [String] + attr_accessor :temp_folder_path + # Defaults go in here.. def initialize @format = 'json' diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index e9c8e3805a0..adabfa21397 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -86,10 +86,13 @@ module SwaggerClient end end - # Save response body into a file in tmp folder, using the filename from the - # "Content-Disposition" header if provided, otherwise a random filename. + # Save response body into a file in (the defined) temporary folder, using the filename + # from the "Content-Disposition" header if provided, otherwise a random filename. + # + # @see Configuration#temp_folder_path + # @return [File] the file downloaded def download_file - tmp_file = Tempfile.new '' + tmp_file = Tempfile.new '', Swagger.configuration.temp_folder_path content_disposition = raw.headers['Content-Disposition'] if content_disposition filename = content_disposition[/filename="([^"]+)"/, 1] @@ -99,7 +102,9 @@ module SwaggerClient end # close and delete temp file tmp_file.close! + File.open(path, 'w') { |file| file.write(raw.body) } + Swagger.logger.info "File written to #{path}. Please move the file to a proper folder for further processing and delete the temp afterwards" return File.new(path) end From e6e1db206407ee4cba3cd00e3414846d3c771c9c Mon Sep 17 00:00:00 2001 From: xhh Date: Thu, 25 Jun 2015 16:26:04 +0800 Subject: [PATCH 158/499] Support looser format when detecting filename --- .../src/main/resources/ruby/swagger/response.mustache | 2 +- .../client/petstore/ruby/lib/swagger_client/swagger/response.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index 076f93e104f..6e898255b87 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -95,7 +95,7 @@ module {{moduleName}} tmp_file = Tempfile.new '', Swagger.configuration.temp_folder_path content_disposition = raw.headers['Content-Disposition'] if content_disposition - filename = content_disposition[/filename="([^"]+)"/, 1] + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] path = File.join File.dirname(tmp_file), filename else path = tmp_file.path diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index adabfa21397..045d200d205 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -95,7 +95,7 @@ module SwaggerClient tmp_file = Tempfile.new '', Swagger.configuration.temp_folder_path content_disposition = raw.headers['Content-Disposition'] if content_disposition - filename = content_disposition[/filename="([^"]+)"/, 1] + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] path = File.join File.dirname(tmp_file), filename else path = tmp_file.path From 8cce7ac053aa6956ffbf75a183189c644bd6430d Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 25 Jun 2015 22:40:14 +0800 Subject: [PATCH 159/499] fix optional for python, python3 --- .../src/main/resources/python/api.mustache | 2 +- .../src/main/resources/python3/api.mustache | 2 +- .../SwaggerPetstore/apis/pet_api.py | 18 +++++++++--------- .../SwaggerPetstore/apis/store_api.py | 2 +- .../SwaggerPetstore/apis/user_api.py | 12 ++++++------ .../client/petstore/python3/client/pet_api.py | 18 +++++++++--------- .../petstore/python3/client/store_api.py | 2 +- .../client/petstore/python3/client/user_api.py | 12 ++++++------ 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index 867014d5e12..3fb62cb75ea 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -47,7 +47,7 @@ class {{classname}}(object): {{{summary}}} {{{notes}}} - {{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}} + {{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} :return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}} """ diff --git a/modules/swagger-codegen/src/main/resources/python3/api.mustache b/modules/swagger-codegen/src/main/resources/python3/api.mustache index 015158bccec..2ff659b11b5 100644 --- a/modules/swagger-codegen/src/main/resources/python3/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python3/api.mustache @@ -36,7 +36,7 @@ class {{classname}}(object): {{{notes}}} Args: - {{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} + {{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} Returns: {{returnType}} diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py index 5f5c2fe81fa..7f022930869 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py @@ -46,7 +46,7 @@ class PetApi(object): Update an existing pet - :param Pet body: Pet object that needs to be added to the store + :param Pet body: Pet object that needs to be added to the store (optional) :return: None """ @@ -97,7 +97,7 @@ class PetApi(object): Add a new pet to the store - :param Pet body: Pet object that needs to be added to the store + :param Pet body: Pet object that needs to be added to the store (optional) :return: None """ @@ -148,7 +148,7 @@ class PetApi(object): Finds Pets by status Multiple status values can be provided with comma seperated strings - :param list[str] status: Status values that need to be considered for filter + :param list[str] status: Status values that need to be considered for filter (optional) :return: list[Pet] """ @@ -201,7 +201,7 @@ class PetApi(object): Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - :param list[str] tags: Tags to filter by + :param list[str] tags: Tags to filter by (optional) :return: list[Pet] """ @@ -312,8 +312,8 @@ class PetApi(object): :param str pet_id: ID of pet that needs to be updated (required) - :param str name: Updated name of the pet - :param str status: Updated status of the pet + :param str name: Updated name of the pet (optional) + :param str status: Updated status of the pet (optional) :return: None """ @@ -374,7 +374,7 @@ class PetApi(object): Deletes a pet - :param str api_key: + :param str api_key: (optional) :param int pet_id: Pet id to delete (required) :return: None @@ -434,8 +434,8 @@ class PetApi(object): :param int pet_id: ID of pet to update (required) - :param str additional_metadata: Additional data to pass to server - :param File file: file to upload + :param str additional_metadata: Additional data to pass to server (optional) + :param File file: file to upload (optional) :return: None """ diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py index 1e024cfbb5b..f017df791d9 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py @@ -95,7 +95,7 @@ class StoreApi(object): Place an order for a pet - :param Order body: order placed for purchasing the pet + :param Order body: order placed for purchasing the pet (optional) :return: Order """ diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py index 84a40b06579..177c5e3a565 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py @@ -46,7 +46,7 @@ class UserApi(object): Create user This can only be done by the logged in user. - :param User body: Created user object + :param User body: Created user object (optional) :return: None """ @@ -97,7 +97,7 @@ class UserApi(object): Creates list of users with given input array - :param list[User] body: List of user object + :param list[User] body: List of user object (optional) :return: None """ @@ -148,7 +148,7 @@ class UserApi(object): Creates list of users with given input array - :param list[User] body: List of user object + :param list[User] body: List of user object (optional) :return: None """ @@ -199,8 +199,8 @@ class UserApi(object): Logs user into the system - :param str username: The user name for login - :param str password: The password for login in clear text + :param str username: The user name for login (optional) + :param str password: The password for login in clear text (optional) :return: str """ @@ -361,7 +361,7 @@ class UserApi(object): This can only be done by the logged in user. :param str username: name that need to be deleted (required) - :param User body: Updated user object + :param User body: Updated user object (optional) :return: None """ diff --git a/samples/client/petstore/python3/client/pet_api.py b/samples/client/petstore/python3/client/pet_api.py index 9293a89d2b0..cebab131778 100644 --- a/samples/client/petstore/python3/client/pet_api.py +++ b/samples/client/petstore/python3/client/pet_api.py @@ -35,7 +35,7 @@ class PetApi(object): Args: - body, Pet: Pet object that needs to be added to the store (required) + body, Pet: Pet object that needs to be added to the store (optional) Returns: @@ -77,7 +77,7 @@ class PetApi(object): Args: - body, Pet: Pet object that needs to be added to the store (required) + body, Pet: Pet object that needs to be added to the store (optional) Returns: @@ -119,7 +119,7 @@ class PetApi(object): Multiple status values can be provided with comma seperated strings Args: - status, list[str]: Status values that need to be considered for filter (required) + status, list[str]: Status values that need to be considered for filter (optional) Returns: list[Pet] @@ -170,7 +170,7 @@ class PetApi(object): Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. Args: - tags, list[str]: Tags to filter by (required) + tags, list[str]: Tags to filter by (optional) Returns: list[Pet] @@ -275,8 +275,8 @@ class PetApi(object): Args: pet_id, str: ID of pet that needs to be updated (required) - name, str: Updated name of the pet (required) - status, str: Updated status of the pet (required) + name, str: Updated name of the pet (optional) + status, str: Updated status of the pet (optional) Returns: @@ -323,7 +323,7 @@ class PetApi(object): Args: - api_key, str: (required) + api_key, str: (optional) pet_id, int: Pet id to delete (required) @@ -375,8 +375,8 @@ class PetApi(object): Args: pet_id, int: ID of pet to update (required) - additional_metadata, str: Additional data to pass to server (required) - file, file: file to upload (required) + additional_metadata, str: Additional data to pass to server (optional) + file, file: file to upload (optional) Returns: diff --git a/samples/client/petstore/python3/client/store_api.py b/samples/client/petstore/python3/client/store_api.py index 8002b473f8a..802e116f1ff 100644 --- a/samples/client/petstore/python3/client/store_api.py +++ b/samples/client/petstore/python3/client/store_api.py @@ -82,7 +82,7 @@ class StoreApi(object): Args: - body, Order: order placed for purchasing the pet (required) + body, Order: order placed for purchasing the pet (optional) Returns: Order diff --git a/samples/client/petstore/python3/client/user_api.py b/samples/client/petstore/python3/client/user_api.py index c4c3c2ede52..54813ca2ddd 100644 --- a/samples/client/petstore/python3/client/user_api.py +++ b/samples/client/petstore/python3/client/user_api.py @@ -35,7 +35,7 @@ class UserApi(object): This can only be done by the logged in user. Args: - body, User: Created user object (required) + body, User: Created user object (optional) Returns: @@ -77,7 +77,7 @@ class UserApi(object): Args: - body, list[User]: List of user object (required) + body, list[User]: List of user object (optional) Returns: @@ -119,7 +119,7 @@ class UserApi(object): Args: - body, list[User]: List of user object (required) + body, list[User]: List of user object (optional) Returns: @@ -161,8 +161,8 @@ class UserApi(object): Args: - username, str: The user name for login (required) - password, str: The password for login in clear text (required) + username, str: The user name for login (optional) + password, str: The password for login in clear text (optional) Returns: str @@ -311,7 +311,7 @@ class UserApi(object): Args: username, str: name that need to be deleted (required) - body, User: Updated user object (required) + body, User: Updated user object (optional) Returns: From 18ac6e8aae520aa2ba451a567b29b4ddc9662ab4 Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 25 Jun 2015 23:10:25 +0800 Subject: [PATCH 160/499] fix perl and asyncscala optional tab --- .../main/resources/asyncscala/api.mustache | 11 +- .../src/main/resources/perl/api.mustache | 2 +- samples/client/petstore/async-scala/build.sbt | 12 +- .../io/swagger/client/SwaggerClient.scala | 28 +- .../scala/io/swagger/client/api/PetApi.scala | 360 +++++++++--------- .../io/swagger/client/api/StoreApi.scala | 171 ++++----- .../scala/io/swagger/client/api/UserApi.scala | 351 ++++++++--------- .../io/swagger/client/model/Category.scala | 12 +- .../scala/io/swagger/client/model/Order.scala | 20 +- .../scala/io/swagger/client/model/Pet.scala | 20 +- .../scala/io/swagger/client/model/Tag.scala | 12 +- .../scala/io/swagger/client/model/User.scala | 24 +- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 18 +- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 2 +- .../perl/lib/WWW/SwaggerClient/UserApi.pm | 12 +- 15 files changed, 526 insertions(+), 529 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache b/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache index cd12ae18806..49b7c089704 100644 --- a/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache +++ b/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache @@ -11,10 +11,9 @@ import collection.mutable class {{classname}}(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { {{#operation}} - def {{nickname}}({{#allParams}}{{#optional}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}}, - {{/hasMore}} - {{/optional}}{{^optional}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}}, - {{/hasMore}}{{/optional}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = { + def {{nickname}}({{#allParams}}{{^required}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}},{{/hasMore}} + {{/required}}{{#required}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}}, + {{/hasMore}}{{/required}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = { // create path and map variables val path = (addFmt("{{path}}"){{#pathParams}} replaceAll ("\\{" + "{{baseName}}" + "\\}",{{paramName}}.toString){{/pathParams}}) @@ -27,8 +26,8 @@ class {{classname}}(client: TransportClient, config: SwaggerConfig) extends ApiC val paramCount = (Set[Any]({{/requiredParamCount}}{{#requiredParams}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) - null).size if (paramCount != {{requiredParamCount}}) sys.error("missing required params"){{/requiredParamCount}} - {{#queryParams}}{{#optional}}if({{paramName}} != null) {{paramName}}.foreach { v => queryParams += "{{baseName}}" -> v.toString }{{/optional}}{{^optional}} - if({{paramName}} != null) queryParams += "{{baseName}}" -> {{paramName}}.toString{{/optional}}{{/queryParams}} + {{#queryParams}}{{^required}}if({{paramName}} != null) {{paramName}}.foreach { v => queryParams += "{{baseName}}" -> v.toString }{{/required}}{{#required}} + if({{paramName}} != null) queryParams += "{{baseName}}" -> {{paramName}}.toString{{/required}}{{/queryParams}} {{#headerParams}}headerParams += "{{baseName}}" -> {{paramName}}.toString{{/headerParams}} diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index 93848cf5af8..e69e4e3066f 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -54,7 +54,7 @@ sub new { # # {{{summary}}} # -{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} +{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} # sub {{nickname}} { diff --git a/samples/client/petstore/async-scala/build.sbt b/samples/client/petstore/async-scala/build.sbt index 1d7306d541d..b02498c74e8 100644 --- a/samples/client/petstore/async-scala/build.sbt +++ b/samples/client/petstore/async-scala/build.sbt @@ -3,10 +3,10 @@ organization := "" name := "-client" libraryDependencies ++= Seq( -"com.wordnik" %% "swagger-async-httpclient" % "0.3.5", -"joda-time" % "joda-time" % "2.3", -"org.joda" % "joda-convert" % "1.3.1", -"ch.qos.logback" % "logback-classic" % "1.0.13" % "provided", -"org.scalatest" %% "scalatest" % "2.2.1" % "test", -"junit" % "junit" % "4.11" % "test" + "io.swagger" %% "swagger-async-httpclient" % "0.3.5", + "joda-time" % "joda-time" % "2.3", + "org.joda" % "joda-convert" % "1.3.1", + "ch.qos.logback" % "logback-classic" % "1.0.13" % "provided", + "org.scalatest" %% "scalatest" % "2.2.1" % "test", + "junit" % "junit" % "4.11" % "test" ) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala index 92262387823..9d0c05187a9 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala @@ -7,21 +7,21 @@ import io.swagger.client._ import java.io.Closeable class SwaggerClient(config: SwaggerConfig) extends Closeable { -val locator = config.locator -val name = config.name + val locator = config.locator + val name = config.name -private[this] val client = transportClient + private[this] val client = transportClient -protected def transportClient: TransportClient = new RestClient(config) + protected def transportClient: TransportClient = new RestClient(config) + + val user = new UserApi(client, config) + + val pet = new PetApi(client, config) + + val store = new StoreApi(client, config) + - val user = new UserApi(client, config) - - val pet = new PetApi(client, config) - - val store = new StoreApi(client, config) - - -def close() { -client.close() -} + def close() { + client.close() + } } \ No newline at end of file diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala index 5138049a22a..4b6a2b155d9 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala @@ -7,187 +7,191 @@ import scala.concurrent.{ Future, Await } import scala.concurrent.duration._ import collection.mutable - class PetApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { +class PetApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { - - def updatePet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet")) + + def updatePet(body: Option[Pet] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet")) - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def addPet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def findPetsByStatus(status: List[String] = available)(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { - // create path and map variables - val path = (addFmt("/pet/findByStatus")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - if(status != null) queryParams += "status" -> status.toString - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def findPetsByTags(tags: List[String])(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { - // create path and map variables - val path = (addFmt("/pet/findByTags")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - if(tags != null) queryParams += "tags" -> tags.toString - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = { - // create path and map variables - val path = (addFmt("/pet/{petId}") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def updatePetWithForm(petId: String, - name: String, - status: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet/{petId}") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def deletePet(apiKey: String, - petId: Long)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet/{petId}") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - headerParams += "api_key" -> apiKey.toString - - val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def uploadFile(petId: Long, - additionalMetadata: String, - file: File)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet/{petId}/uploadImage") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) } + } + + + def addPet(body: Option[Pet] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def findPetsByStatus(status: Option[List[String]] = Some(available) + )(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { + // create path and map variables + val path = (addFmt("/pet/findByStatus")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + if(status != null) status.foreach { v => queryParams += "status" -> v.toString } + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def findPetsByTags(tags: Option[List[String]] = None + )(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { + // create path and map variables + val path = (addFmt("/pet/findByTags")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + if(tags != null) tags.foreach { v => queryParams += "tags" -> v.toString } + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def updatePetWithForm(petId: String, + name: Option[String] = None, + status: Option[String] = None + )(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def deletePet(apiKey: Option[String] = None, + petId: Long)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + headerParams += "api_key" -> apiKey.toString + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def uploadFile(petId: Long, + additionalMetadata: Option[String] = None, + file: Option[File] = None + )(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}/uploadImage") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + +} diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala index c98675739de..c7a18efbf14 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala @@ -6,94 +6,95 @@ import scala.concurrent.{ Future, Await } import scala.concurrent.duration._ import collection.mutable - class StoreApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { +class StoreApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { - - def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = { - // create path and map variables - val path = (addFmt("/store/inventory")) + + def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = { + // create path and map variables + val path = (addFmt("/store/inventory")) - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def placeOrder(body: Order)(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = { - // create path and map variables - val path = (addFmt("/store/order")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def getOrderById(orderId: String)(implicit reader: ClientResponseReader[Order]): Future[Order] = { - // create path and map variables - val path = (addFmt("/store/order/{orderId}") - replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/store/order/{orderId}") - replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) } + } + + + def placeOrder(body: Option[Order] = None + )(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = { + // create path and map variables + val path = (addFmt("/store/order")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def getOrderById(orderId: String)(implicit reader: ClientResponseReader[Order]): Future[Order] = { + // create path and map variables + val path = (addFmt("/store/order/{orderId}") + replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/store/order/{orderId}") + replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + +} diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala index 3b8ba3cdc2e..766e4d22312 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala @@ -6,183 +6,186 @@ import scala.concurrent.{ Future, Await } import scala.concurrent.duration._ import collection.mutable - class UserApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { +class UserApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { - - def createUser(body: User)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user")) + + def createUser(body: Option[User] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user")) - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def createUsersWithArrayInput(body: List[User])(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/createWithArray")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def createUsersWithListInput(body: List[User])(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/createWithList")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def loginUser(username: String, - password: String)(implicit reader: ClientResponseReader[String]): Future[String] = { - // create path and map variables - val path = (addFmt("/user/login")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - if(username != null) queryParams += "username" -> username.toString - if(password != null) queryParams += "password" -> password.toString - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def logoutUser()(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/logout")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def getUserByName(username: String)(implicit reader: ClientResponseReader[User]): Future[User] = { - // create path and map variables - val path = (addFmt("/user/{username}") - replaceAll ("\\{" + "username" + "\\}",username.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def updateUser(username: String, - body: User)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/{username}") - replaceAll ("\\{" + "username" + "\\}",username.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def deleteUser(username: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/{username}") - replaceAll ("\\{" + "username" + "\\}",username.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) } + } + + + def createUsersWithArrayInput(body: Option[List[User]] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/createWithArray")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def createUsersWithListInput(body: Option[List[User]] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/createWithList")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def loginUser(username: Option[String] = None, + password: Option[String] = None + )(implicit reader: ClientResponseReader[String]): Future[String] = { + // create path and map variables + val path = (addFmt("/user/login")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + if(username != null) username.foreach { v => queryParams += "username" -> v.toString }if(password != null) password.foreach { v => queryParams += "password" -> v.toString } + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def logoutUser()(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/logout")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def getUserByName(username: String)(implicit reader: ClientResponseReader[User]): Future[User] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def updateUser(username: String, + body: Option[User] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def deleteUser(username: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + +} diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala index a19b846e875..1b410e7c59e 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala @@ -3,10 +3,8 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Category ( - id: Long, - name: String - - ) - +case class Category ( + id: Long, + name: String + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala index 4e847e74b27..f7a10a44965 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala @@ -3,14 +3,12 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Order ( - id: Long, - petId: Long, - quantity: Integer, - shipDate: DateTime, - status: String, // Order Status - complete: Boolean - - ) - +case class Order ( + id: Long, + petId: Long, + quantity: Integer, + shipDate: DateTime, + status: String, // Order Status + complete: Boolean + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala index d7da69df9ee..7e76c72914b 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala @@ -3,14 +3,12 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Pet ( - id: Long, - category: Category, - name: String, - photoUrls: List[String], - tags: List[Tag], - status: String // pet status in the store - - ) - +case class Pet ( + id: Long, + category: Category, + name: String, + photoUrls: List[String], + tags: List[Tag], + status: String // pet status in the store + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala index aa2a883063f..9dfe60d36f8 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala @@ -3,10 +3,8 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Tag ( - id: Long, - name: String - - ) - +case class Tag ( + id: Long, + name: String + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala index 692ec715347..598adae451a 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala @@ -3,16 +3,14 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class User ( - id: Long, - username: String, - firstName: String, - lastName: String, - email: String, - password: String, - phone: String, - userStatus: Integer // User Status - - ) - +case class User ( + id: Long, + username: String, + firstName: String, + lastName: String, + email: String, + password: String, + phone: String, + userStatus: Integer // User Status + +) diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 7fe640aaea4..bf085889e79 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -52,7 +52,7 @@ sub new { # # Update an existing pet # -# @param Pet $body Pet object that needs to be added to the store (required) +# @param Pet $body Pet object that needs to be added to the store (optional) # @return void # sub update_pet { @@ -102,7 +102,7 @@ sub update_pet { # # Add a new pet to the store # -# @param Pet $body Pet object that needs to be added to the store (required) +# @param Pet $body Pet object that needs to be added to the store (optional) # @return void # sub add_pet { @@ -152,7 +152,7 @@ sub add_pet { # # Finds Pets by status # -# @param ARRAY[string] $status Status values that need to be considered for filter (required) +# @param ARRAY[string] $status Status values that need to be considered for filter (optional) # @return ARRAY[Pet] # sub find_pets_by_status { @@ -205,7 +205,7 @@ sub find_pets_by_status { # # Finds Pets by tags # -# @param ARRAY[string] $tags Tags to filter by (required) +# @param ARRAY[string] $tags Tags to filter by (optional) # @return ARRAY[Pet] # sub find_pets_by_tags { @@ -319,8 +319,8 @@ sub get_pet_by_id { # Updates a pet in the store with form data # # @param string $pet_id ID of pet that needs to be updated (required) -# @param string $name Updated name of the pet (required) -# @param string $status Updated status of the pet (required) +# @param string $name Updated name of the pet (optional) +# @param string $status Updated status of the pet (optional) # @return void # sub update_pet_with_form { @@ -387,7 +387,7 @@ sub update_pet_with_form { # # Deletes a pet # -# @param string $api_key (required) +# @param string $api_key (optional) # @param int $pet_id Pet id to delete (required) # @return void # @@ -449,8 +449,8 @@ sub delete_pet { # uploads an image # # @param int $pet_id ID of pet to update (required) -# @param string $additional_metadata Additional data to pass to server (required) -# @param file $file file to upload (required) +# @param string $additional_metadata Additional data to pass to server (optional) +# @param file $file file to upload (optional) # @return void # sub upload_file { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index 6072f61518c..a2ac9010e77 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -101,7 +101,7 @@ sub get_inventory { # # Place an order for a pet # -# @param Order $body order placed for purchasing the pet (required) +# @param Order $body order placed for purchasing the pet (optional) # @return Order # sub place_order { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index f588f1bb410..4c6e293aaaa 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -52,7 +52,7 @@ sub new { # # Create user # -# @param User $body Created user object (required) +# @param User $body Created user object (optional) # @return void # sub create_user { @@ -102,7 +102,7 @@ sub create_user { # # Creates list of users with given input array # -# @param ARRAY[User] $body List of user object (required) +# @param ARRAY[User] $body List of user object (optional) # @return void # sub create_users_with_array_input { @@ -152,7 +152,7 @@ sub create_users_with_array_input { # # Creates list of users with given input array # -# @param ARRAY[User] $body List of user object (required) +# @param ARRAY[User] $body List of user object (optional) # @return void # sub create_users_with_list_input { @@ -202,8 +202,8 @@ sub create_users_with_list_input { # # Logs user into the system # -# @param string $username The user name for login (required) -# @param string $password The password for login in clear text (required) +# @param string $username The user name for login (optional) +# @param string $password The password for login in clear text (optional) # @return string # sub login_user { @@ -366,7 +366,7 @@ sub get_user_by_name { # Updated user # # @param string $username name that need to be deleted (required) -# @param User $body Updated user object (required) +# @param User $body Updated user object (optional) # @return void # sub update_user { From 9d739a44cd8daab709dc68ab4ac6d9837e5f4315 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 25 Jun 2015 21:47:00 +0800 Subject: [PATCH 161/499] update python test case --- .../python/SwaggerPetstore-python/tests/test_store_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py index 740e2bdc8ad..933a44f237d 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_store_api.py @@ -28,4 +28,3 @@ class StoreApiTests(unittest.TestCase): data = self.store_api.get_inventory() self.assertIsNotNone(data) self.assertTrue(isinstance(data, dict)) - self.assertItemsEqual(data.keys(), ['available', 'string', 'sold', 'pending', 'confused', 'active', 'na']) From 07d5365c5cb3ae2005ffa00eb2e8e6786da38509 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Thu, 25 Jun 2015 10:17:28 -0700 Subject: [PATCH 162/499] merged from #902, rebuilt client --- .../codegen/languages/PhpClientCodegen.java | 64 +++- .../src/main/resources/php/ApiClient.mustache | 322 +++-------------- .../main/resources/php/ApiException.mustache | 28 +- .../resources/php/ObjectSerializer.mustache | 151 ++++++++ .../src/main/resources/php/api.mustache | 92 +++-- .../src/main/resources/php/autoload.mustache | 4 +- .../src/main/resources/php/composer.mustache | 2 +- .../main/resources/php/configuration.mustache | 241 ++++++++++++- .../src/main/resources/php/model.mustache | 42 ++- .../php/SwaggerClient-php/lib/Api/PetApi.php | 310 +++++++++++------ .../SwaggerClient-php/lib/Api/StoreApi.php | 174 ++++++---- .../php/SwaggerClient-php/lib/Api/UserApi.php | 256 ++++++++------ .../php/SwaggerClient-php/lib/ApiClient.php | 327 +++--------------- .../SwaggerClient-php/lib/ApiException.php | 28 +- .../SwaggerClient-php/lib/Configuration.php | 241 ++++++++++++- .../SwaggerClient-php/lib/Model/Category.php | 60 +++- .../php/SwaggerClient-php/lib/Model/Order.php | 156 ++++++++- .../php/SwaggerClient-php/lib/Model/Pet.php | 156 ++++++++- .../php/SwaggerClient-php/lib/Model/Tag.php | 60 +++- .../php/SwaggerClient-php/lib/Model/User.php | 204 ++++++++++- .../lib/ObjectSerializer.php | 151 ++++++++ .../SwaggerClient-php/tests/PetApiTest.php | 104 +++--- .../SwaggerClient-php/tests/StoreApiTest.php | 7 +- .../SwaggerClient-php/tests/UserApiTest.php | 7 +- 24 files changed, 2145 insertions(+), 1042 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache create mode 100644 samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java index 5bf8400577d..e2ddba4bf34 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PhpClientCodegen.java @@ -1,5 +1,6 @@ package io.swagger.codegen.languages; +import io.swagger.codegen.CliOption; import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenType; import io.swagger.codegen.DefaultCodegen; @@ -18,7 +19,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { protected String invokerPackage = "Swagger\\Client"; protected String groupId = "swagger"; protected String artifactId = "swagger-client"; + protected String packagePath = "SwaggerClient-php"; protected String artifactVersion = null; + protected String srcBasePath = "lib"; public PhpClientCodegen() { super(); @@ -38,6 +41,7 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { additionalProperties.put("invokerPackage", invokerPackage); additionalProperties.put("modelPackage", modelPackage); additionalProperties.put("apiPackage", apiPackage); + additionalProperties.put("srcBasePath", srcBasePath); additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); additionalProperties.put("groupId", groupId); additionalProperties.put("artifactId", artifactId); @@ -81,16 +85,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("list", "array"); typeMapping.put("object", "object"); typeMapping.put("DateTime", "\\DateTime"); - - supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); - supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, "lib"), "Configuration.php")); - supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, "lib"), "ApiClient.php")); - supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, "lib"), "ApiException.php")); - supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); + + cliOptions.add(new CliOption("packagePath", "main package name for classes")); + cliOptions.add(new CliOption("srcBasePath", "directory directory under packagePath to serve as source root")); } public String getPackagePath() { - return "SwaggerClient-php"; + return packagePath; } public String toPackagePath(String packageName, String basePath) { @@ -134,6 +135,39 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return "Generates a PHP client library."; } + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey("packagePath")) { + this.setPackagePath((String) additionalProperties.get("packagePath")); + } + + if (additionalProperties.containsKey("srcBasePath")) { + this.setSrcBasePath((String) additionalProperties.get("srcBasePath")); + } + + if (additionalProperties.containsKey("modelPackage")) { + this.setModelPackage((String) additionalProperties.get("modelPackage")); + } + + if (additionalProperties.containsKey("apiPackage")) { + this.setApiPackage((String) additionalProperties.get("apiPackage")); + } + + additionalProperties.put("srcBasePath", srcBasePath); + additionalProperties.put("modelPackage", modelPackage); + additionalProperties.put("apiPackage", apiPackage); + additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); + + supportingFiles.add(new SupportingFile("configuration.mustache", toPackagePath(invokerPackage, srcBasePath), "Configuration.php")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClient.php")); + supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiException.php")); + supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php")); + supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); + supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); + } + @Override public String escapeReservedWord(String name) { return "_" + name; @@ -141,11 +175,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return (outputFolder + File.separator + toPackagePath(apiPackage(), "lib")); + return (outputFolder + "/" + toPackagePath(apiPackage(), srcBasePath)); } public String modelFileFolder() { - return (outputFolder + File.separator + toPackagePath(modelPackage(), "lib")); + return (outputFolder + "/" + toPackagePath(modelPackage(), srcBasePath)); } @Override @@ -198,6 +232,17 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { return "null"; } + public void setInvokerPackage(String invokerPackage) { + this.invokerPackage = invokerPackage; + } + + public void setPackagePath(String packagePath) { + this.packagePath = packagePath; + } + + public void setSrcBasePath(String srcBasePath) { + this.srcBasePath = srcBasePath; + } @Override public String toVarName(String name) { @@ -235,5 +280,4 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { // should be the same as the model name return toModelName(name); } - } diff --git a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache index 9badb4dbb37..2862a0e0538 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiClient.mustache @@ -25,141 +25,60 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - /** @var string[] Array of default headers where the key is the header name and the value is the header value */ - private $default_header = array(); + /** @var Configuration */ + protected $config; - /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ - protected $curl_timeout = 0; - - /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ - protected $user_agent = "PHP-Swagger"; + /** @var ObjectSerializer */ + protected $serializer; /** - * @param string $host Base url of the API server (optional) + * @param Configuration $config config for this ApiClient */ - function __construct($host = null) { - if ($host === null) { - $this->host = '{{basePath}}'; - } else { - $this->host = $host; + function __construct(Configuration $config = null) { + if ($config == null) { + $config = Configuration::getDefaultConfiguration(); } + + $this->config = $config; + $this->serializer = new ObjectSerializer(); } /** - * add default header - * - * @param string $header_name header name (e.g. Token) - * @param string $header_value header value (e.g. 1z8wp3) + * get the config + * @return Configuration */ - public function addDefaultHeader($header_name, $header_value) { - if (!is_string($header_name)) - throw new \InvalidArgumentException('Header name must be a string.'); - - $this->default_header[$header_name] = $header_value; + public function getConfig() { + return $this->config; } /** - * get the default header - * - * @return array default header + * get the serializer + * @return ObjectSerializer */ - public function getDefaultHeader() { - return $this->default_header; + public function getSerializer() { + return $this->serializer; } - /** - * delete the default header based on header name - * - * @param string $header_name header name (e.g. Token) - */ - public function deleteDefaultHeader($header_name) { - unset($this->default_header[$header_name]); - } - - /** - * set the user agent of the api client - * - * @param string $user_agent the user agent of the api client - */ - public function setUserAgent($user_agent) { - if (!is_string($user_agent)) - throw new \InvalidArgumentException('User-agent must be a string.'); - - $this->user_agent= $user_agent; - } - - /** - * get the user agent of the api client - * - * @return string user agent - */ - public function getUserAgent($user_agent) { - return $this->user_agent; - } - - /** - * set the HTTP timeout value - * - * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] - */ - public function setTimeout($seconds) { - if (!is_numeric($seconds) || $seconds < 0) - throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); - - $this->curl_timeout = $seconds; - } - - /** - * get the HTTP timeout value - * - * @return string HTTP timeout value - */ - public function getTimeout() { - return $this->curl_timeout; - } - - /** * Get API key (with prefix if set) - * @param string key name + * @param string $apiKey name of apikey * @return string API key with the prefix */ public function getApiKeyWithPrefix($apiKey) { - if (isset(Configuration::$apiKeyPrefix[$apiKey])) { - return Configuration::$apiKeyPrefix[$apiKey]." ".Configuration::$apiKey[$apiKey]; - } else if (isset(Configuration::$apiKey[$apiKey])) { - return Configuration::$apiKey[$apiKey]; + $prefix = $this->config->getApiKeyPrefix($apiKey); + $apiKey = $this->config->getApiKey($apiKey); + + if (!isset($apiKey)) { + return null; + } + + if (isset($prefix)) { + $keyWithPrefix = $prefix." ".$apiKey; } else { - return; + $keyWithPrefix = $apiKey; } - } - /** - * update hearder and query param based on authentication setting - * - * @param array $headerParams header parameters (by ref) - * @param array $queryParams query parameters (by ref) - * @param array $authSettings array of authentication scheme (e.g ['api_key']) - */ - public function updateParamsForAuth(&$headerParams, &$queryParams, $authSettings) - { - if (count($authSettings) == 0) - return; - - // one endpoint can have more than 1 auth settings - foreach($authSettings as $auth) { - // determine which one to use - switch($auth) { - {{#authMethods}} - case '{{name}}': - {{#isApiKey}}{{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $this->getApiKeyWithPrefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode(Configuration::$username.":".Configuration::$password);{{/isBasic}} - {{#isOAuth}}//TODO support oauth{{/isOAuth}} - break; - {{/authMethods}} - default: - //TODO show warning about security definition not found - } - } + return $keyWithPrefix; } /** @@ -168,18 +87,15 @@ class ApiClient { * @param array $queryParams parameters to be place in query URL * @param array $postData parameters to be placed in POST body * @param array $headerParams parameters to be place in request header + * @throws \{{invokerPackage}}\ApiException on a non 2xx response * @return mixed */ - public function callApi($resourcePath, $method, $queryParams, $postData, - $headerParams, $authSettings) { + public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) { $headers = array(); - # determine authentication setting - $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); - # construct the http header - $headerParams = array_merge((array)$this->default_header, (array)$headerParams); + $headerParams = array_merge((array)$this->config->getDefaultHeaders(), (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -190,15 +106,15 @@ class ApiClient { $postData = http_build_query($postData); } else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model - $postData = json_encode($this->sanitizeForSerialization($postData)); + $postData = json_encode($this->serializer->sanitizeForSerialization($postData)); } - $url = $this->host . $resourcePath; + $url = $this->config->getHost() . $resourcePath; $curl = curl_init(); // set timeout, if needed - if ($this->curl_timeout != 0) { - curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_timeout); + if ($this->config->getCurlTimeout() != 0) { + curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout()); } // return the result on success, rather than just TRUE curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @@ -227,14 +143,14 @@ class ApiClient { curl_setopt($curl, CURLOPT_URL, $url); // Set user agent - curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent()); // debugging for curl - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile()); curl_setopt($curl, CURLOPT_VERBOSE, 1); - curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a')); + curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a')); } else { curl_setopt($curl, CURLOPT_VERBOSE, 0); } @@ -250,8 +166,8 @@ class ApiClient { $response_info = curl_getinfo($curl); // debug HTTP response body - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile()); } // Handle the response @@ -269,153 +185,13 @@ class ApiClient { return $data; } - /** - * Build a JSON POST object - */ - protected function sanitizeForSerialization($data) - { - if (is_scalar($data) || null === $data) { - $sanitized = $data; - } else if ($data instanceof \DateTime) { - $sanitized = $data->format(\DateTime::ISO8601); - } else if (is_array($data)) { - foreach ($data as $property => $value) { - $data[$property] = $this->sanitizeForSerialization($value); - } - $sanitized = $data; - } else if (is_object($data)) { - $values = array(); - foreach (array_keys($data::$swaggerTypes) as $property) { - if ($data->$property !== null) { - $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); - } - } - $sanitized = $values; - } else { - $sanitized = (string)$data; - } - - return $sanitized; - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the path, by url-encoding. - * @param string $value a string which will be part of the path - * @return string the serialized object - */ - public function toPathValue($value) { - return rawurlencode($this->toString($value)); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the query, by imploding comma-separated if it's an object. - * If it's a string, pass through unchanged. It will be url-encoded - * later. - * @param object $object an object to be serialized to a string - * @return string the serialized object - */ - public function toQueryValue($object) { - if (is_array($object)) { - return implode(',', $object); - } else { - return $this->toString($object); - } - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the header. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value a string which will be part of the header - * @return string the header string - */ - public function toHeaderValue($value) { - return $this->toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the http body (form parameter). If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the form parameter - * @return string the form string - */ - public function toFormValue($value) { - return $this->toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the parameter. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the parameter - * @return string the header string - */ - public function toString($value) { - if ($value instanceof \DateTime) { // datetime in ISO8601 format - return $value->format(\DateTime::ISO8601); - } - else { - return $value; - } - } - - /** - * Deserialize a JSON string into an object - * - * @param object $object object or primitive to be deserialized - * @param string $class class name is passed as a string - * @return object an instance of $class - */ - public function deserialize($data, $class) - { - if (null === $data) { - $deserialized = null; - } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] - $inner = substr($class, 4, -1); - $deserialized = array(); - if(strrpos($inner, ",") !== false) { - $subClass_array = explode(',', $inner, 2); - $subClass = $subClass_array[1]; - foreach ($data as $key => $value) { - $deserialized[$key] = $this->deserialize($value, $subClass); - } - } - } elseif (strcasecmp(substr($class, -2),'[]') == 0) { - $subClass = substr($class, 0, -2); - $values = array(); - foreach ($data as $key => $value) { - $values[] = $this->deserialize($value, $subClass); - } - $deserialized = $values; - } elseif ($class == 'DateTime') { - $deserialized = new \DateTime($data); - } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { - settype($data, $class); - $deserialized = $data; - } else { - $instance = new $class(); - foreach ($instance::$swaggerTypes as $property => $type) { - $original_property_name = $instance::$attributeMap[$property]; - if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = $this->deserialize($data->$original_property_name, $type); - } - } - $deserialized = $instance; - } - - return $deserialized; - } - /* * return the header 'Accept' based on an array of Accept provided * - * @param array[string] $accept Array of header + * @param string[] $accept Array of header * @return string Accept (e.g. application/json) */ - public function selectHeaderAccept($accept) { + public static function selectHeaderAccept($accept) { if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) { return NULL; } elseif (preg_grep("/application\/json/i", $accept)) { @@ -428,10 +204,10 @@ class ApiClient { /* * return the content type based on an array of content-type provided * - * @param array[string] content_type_array Array fo content-type + * @param string[] content_type_array Array fo content-type * @return string Content-Type (e.g. application/json) */ - public function selectHeaderContentType($content_type) { + public static function selectHeaderContentType($content_type) { if (count($content_type) === 0 or (count($content_type) === 1 and $content_type[0] === '')) { return 'application/json'; } elseif (preg_grep("/application\/json/i", $content_type)) { @@ -440,6 +216,4 @@ class ApiClient { return implode(',', $content_type); } } - } - diff --git a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache index a835d579d32..6d5415f798d 100644 --- a/modules/swagger-codegen/src/main/resources/php/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache @@ -22,15 +22,20 @@ use \Exception; class ApiException extends Exception { /** @var string The HTTP body of the server response. */ - protected $response_body; + protected $responseBody; /** @var string[] The HTTP header of the server response. */ - protected $response_headers; + protected $responseHeaders; + + /** + * The deserialized response object + */ + protected $responseObject; public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { parent::__construct($message, $code); - $this->response_headers = $responseHeaders; - $this->response_body = $responseBody; + $this->responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; } /** @@ -39,7 +44,7 @@ class ApiException extends Exception { * @return string HTTP response header */ public function getResponseHeaders() { - return $this->response_headers; + return $this->responseHeaders; } /** @@ -48,7 +53,18 @@ class ApiException extends Exception { * @return string HTTP response body */ public function getResponseBody() { - return $this->response_body; + return $this->responseBody; } + /** + * sets the deseralized response object (during deserialization) + * @param mixed $obj + */ + public function setResponseObject($obj) { + $this->responseObject = $obj; + } + + public function getResponseObject() { + return $this->responseObject; + } } diff --git a/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache new file mode 100644 index 00000000000..56a61e97c91 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php/ObjectSerializer.mustache @@ -0,0 +1,151 @@ +format(\DateTime::ISO8601); + } else if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = $this->sanitizeForSerialization($value); + } + $sanitized = $data; + } else if (is_object($data)) { + $values = array(); + foreach (array_keys($data::$swaggerTypes) as $property) { + $getter = $data::$getters[$property]; + if ($data->$getter() !== null) { + $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$getter()); + } + } + $sanitized = $values; + } else { + $sanitized = (string)$data; + } + + return $sanitized; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * @param string $value a string which will be part of the path + * @return string the serialized object + */ + public function toPathValue($value) { + return rawurlencode($this->toString($value)); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the query, by imploding comma-separated if it's an object. + * If it's a string, pass through unchanged. It will be url-encoded + * later. + * @param object $object an object to be serialized to a string + * @return string the serialized object + */ + public function toQueryValue($object) { + if (is_array($object)) { + return implode(',', $object); + } else { + return $this->toString($object); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value a string which will be part of the header + * @return string the header string + */ + public function toHeaderValue($value) { + return $this->toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the http body (form parameter). If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the form parameter + * @return string the form string + */ + public function toFormValue($value) { + return $this->toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the parameter + * @return string the header string + */ + public function toString($value) { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(\DateTime::ISO8601); + } else { + return $value; + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @return object an instance of $class + */ + public function deserialize($data, $class) { + if (null === $data) { + $deserialized = null; + } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] + $inner = substr($class, 4, -1); + $deserialized = array(); + if(strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = $this->deserialize($value, $subClass); + } + } + } elseif (strcasecmp(substr($class, -2),'[]') == 0) { + $subClass = substr($class, 0, -2); + $values = array(); + foreach ($data as $key => $value) { + $values[] = $this->deserialize($value, $subClass); + } + $deserialized = $values; + } elseif ($class == 'DateTime') { + $deserialized = new \DateTime($data); + } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { + settype($data, $class); + $deserialized = $data; + } else { + $instance = new $class(); + foreach ($instance::$swaggerTypes as $property => $type) { + $propertySetter = $instance::$setters[$property]; + + if (!isset($propertySetter) || !isset($data->{$instance::$attributeMap[$property]})) { + continue; + } + + $propertyValue = $data->{$instance::$attributeMap[$property]}; + if (isset($propertyValue)) { + $instance->$propertySetter($this->deserialize($propertyValue, $type)); + } + } + $deserialized = $instance; + } + + return $deserialized; + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 3ed7f18c579..cd483ffa881 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -22,31 +22,29 @@ namespace {{apiPackage}}; -use \{{invokerPackage}}\ApiClient; use \{{invokerPackage}}\Configuration; +use \{{invokerPackage}}\ApiClient; +use \{{invokerPackage}}\ApiException; +use \{{invokerPackage}}\ObjectSerializer; {{#operations}} class {{classname}} { - /** - * @param \{{invokerPackage}}\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \{{invokerPackage}}\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \{{invokerPackage}}\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('{{basePath}}'); + } + + $this->apiClient = $apiClient; + } + /** * @return \{{invokerPackage}}\ApiClient get the API client */ @@ -55,10 +53,12 @@ class {{classname}} { } /** - * @param \{{invokerPackage}} $apiClient set the API client + * @param \{{invokerPackage}}\ApiClient $apiClient set the API client + * @return {{classname}} */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } {{#operation}} @@ -69,6 +69,7 @@ class {{classname}} { * {{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} {{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} + * @throws \{{invokerPackage}}\ApiException on non-2xx response */ public function {{nickname}}({{#allParams}}${{paramName}}{{#optional}}=null{{/optional}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} @@ -86,28 +87,29 @@ class {{classname}} { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}})); + $_header_accept = ApiClient::selectHeaderAccept(array({{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}})); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}})); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array({{#consumes}}'{{mediaType}}'{{#hasMore}},{{/hasMore}}{{/consumes}})); {{#queryParams}}// query params if(${{paramName}} !== null) { - $queryParams['{{baseName}}'] = $this->apiClient->toQueryValue(${{paramName}}); + $queryParams['{{baseName}}'] = $this->apiClient->getSerializer()->toQueryValue(${{paramName}}); }{{/queryParams}} {{#headerParams}}// header params if(${{paramName}} !== null) { - $headerParams['{{baseName}}'] = $this->apiClient->toHeaderValue(${{paramName}}); + $headerParams['{{baseName}}'] = $this->apiClient->getSerializer()->toHeaderValue(${{paramName}}); }{{/headerParams}} {{#pathParams}}// path params if(${{paramName}} !== null) { $resourcePath = str_replace("{" . "{{baseName}}" . "}", - $this->apiClient->toPathValue(${{paramName}}), $resourcePath); + $this->apiClient->getSerializer()->toPathValue(${{paramName}}), + $resourcePath); }{{/pathParams}} {{#formParams}}// form params if (${{paramName}} !== null) { - $formParams['{{baseName}}'] = {{#isFile}}'@'.{{/isFile}}$this->apiClient->toFormValue(${{paramName}}); + $formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->getSerializer()->toFormValue(${{paramName}}); }{{/formParams}} {{#bodyParams}}// body params $_tempBody = null; @@ -122,22 +124,38 @@ class {{classname}} { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array({{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}); - + {{#authMethods}}{{#isApiKey}} + $apiKey = $this->apiClient->getApiKeyWithPrefix('{{keyParamName}}'); + if (isset($apiKey)) { + {{#isKeyInHeader}}$headerParams['{{keyParamName}}'] = $apiKey;{{/isKeyInHeader}}{{#isKeyInQuery}}$queryParams['{{keyParamName}}'] = $apiKey;{{/isKeyInQuery}} + }{{/isApiKey}} + {{#isBasic}}$headerParams['Authorization'] = 'Basic '.base64_encode($this->apiClient->getConfig()->getUsername().":".$this->apiClient->getConfig()->getPassword());{{/isBasic}} + {{#isOAuth}}//TODO support oauth{{/isOAuth}} + {{/authMethods}} // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - {{#returnType}}if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { {{#responses}}{{#dataType}} + case {{code}}: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '{{dataType}}'); + $e->setResponseObject($data); + break;{{/dataType}}{{/responses}} + } + + throw $e; + } + {{#returnType}} + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'{{returnType}}'); - return $responseObject;{{/returnType}} + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'{{returnType}}'); + return $responseObject; + {{/returnType}} } {{/operation}} -{{newline}} -{{/operations}} } +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/php/autoload.mustache b/modules/swagger-codegen/src/main/resources/php/autoload.mustache index 4f56a6e20c0..04be6e11992 100644 --- a/modules/swagger-codegen/src/main/resources/php/autoload.mustache +++ b/modules/swagger-codegen/src/main/resources/php/autoload.mustache @@ -4,7 +4,7 @@ * * After registering this autoload function with SPL, the following line * would cause the function to attempt to load the \{{invokerPackage}}\Baz\Qux class - * from /path/to/project/lib/Baz/Qux.php: + * from /path/to/project/{{srcBasePath}}/Baz/Qux.php: * * new \{{invokerPackage}}\Baz\Qux; * @@ -17,7 +17,7 @@ spl_autoload_register(function ($class) { $prefix = '{{escapedInvokerPackage}}\\'; // base directory for the namespace prefix - $base_dir = __DIR__ . '/lib/'; + $base_dir = __DIR__ . '/{{srcBasePath}}/'; // does the class use the namespace prefix? $len = strlen($prefix); diff --git a/modules/swagger-codegen/src/main/resources/php/composer.mustache b/modules/swagger-codegen/src/main/resources/php/composer.mustache index f4e38c84f73..d36267617c4 100644 --- a/modules/swagger-codegen/src/main/resources/php/composer.mustache +++ b/modules/swagger-codegen/src/main/resources/php/composer.mustache @@ -28,6 +28,6 @@ "squizlabs/php_codesniffer": "~2.0" }, "autoload": { - "psr-4": { "{{escapedInvokerPackage}}\\" : "lib/" } + "psr-4": { "{{escapedInvokerPackage}}\\" : "{{srcBasePath}}/" } } } diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/configuration.mustache index 030910ffca7..b85ad289418 100644 --- a/modules/swagger-codegen/src/main/resources/php/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/configuration.mustache @@ -17,37 +17,250 @@ namespace {{invokerPackage}}; -use \{{invokerPackage}}\ApiClient; - class Configuration { + private static $defaultConfiguration = null; + /** @var string[] Associate array to store API key(s) */ - public static $apiKey = array(); + protected $apiKeys = array(); /** string[] Associate array to store API prefix (e.g. Bearer) */ - public static $apiKeyPrefix = array(); + protected $apiKeyPrefixes = array(); /** @var string Username for HTTP basic authentication */ - public static $username = ''; + protected $username = ''; /** @var string Password for HTTP basic authentication */ - public static $password = ''; + protected $password = ''; /** @var \{{invokerPackage}}\ApiClient The default instance of ApiClient */ - public static $apiClient; + protected $defaultHeaders = array(); + + /** @var string The host */ + protected $host = 'http://localhost'; + + /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ + protected $curlTimeout = 0; + + /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ + protected $userAgent = "PHP-Swagger"; /** @var bool Debug switch (default set to false) */ - public static $debug = false; + protected $debug = false; /** @var string Debug file location (log to STDOUT by default) */ - public static $debug_file = 'php://output'; + protected $debugFile = 'php://output'; - /* - * manually initalize ApiClient + /** + * @param string $key + * @param string $value + * @return Configuration */ - public static function init() { - if (self::$apiClient === null) - self::$apiClient = new ApiClient(); + public function setApiKey($key, $value) { + $this->apiKeys[$key] = $value; + return $this; } + /** + * @param $key + * @return string + */ + public function getApiKey($key) { + return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null; + } + + /** + * @param string $key + * @param string $value + * @return Configuration + */ + public function setApiKeyPrefix($key, $value) { + $this->apiKeyPrefixes[$key] = $value; + return $this; + } + + /** + * @param $key + * @return string + */ + public function getApiKeyPrefix($key) { + return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null; + } + + /** + * @param string $username + * @return Configuration + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * @param string $password + * @return Configuration + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * add default header + * + * @param string $headerName header name (e.g. Token) + * @param string $headerValue header value (e.g. 1z8wp3) + * @return ApiClient + */ + public function addDefaultHeader($headerName, $headerValue) { + if (!is_string($headerName)) { + throw new \InvalidArgumentException('Header name must be a string.'); + } + + $this->defaultHeaders[$headerName] = $headerValue; + return $this; + } + + /** + * get the default header + * + * @return array default header + */ + public function getDefaultHeaders() { + return $this->defaultHeaders; + } + + /** + * delete a default header + * @param string $headerName the header to delete + * @return Configuration + */ + public function deleteDefaultHeader($headerName) { + unset($this->defaultHeaders[$headerName]); + } + + /** + * @param string $host + * @return Configuration + */ + public function setHost($host) { + $this->host = $host; + return $this; + } + + /** + * @return string + */ + public function getHost() { + return $this->host; + } + + /** + * set the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * @return ApiClient + */ + public function setUserAgent($userAgent) { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * get the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() { + return $this->userAgent; + } + + /** + * set the HTTP timeout value + * + * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + * @return ApiClient + */ + public function setCurlTimeout($seconds) { + if (!is_numeric($seconds) || $seconds < 0) { + throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); + } + + $this->curlTimeout = $seconds; + return $this; + } + + /** + * get the HTTP timeout value + * + * @return string HTTP timeout value + */ + public function getCurlTimeout() { + return $this->curlTimeout; + } + + /** + * @param bool $debug + * @return Configuration + */ + public function setDebug($debug) { + $this->debug = $debug; + return $this; + } + + /** + * @return bool + */ + public function getDebug() { + return $this->debug; + } + + /** + * @param string $debugFile + * @return Configuration + */ + public function setDebugFile($debugFile) { + $this->debugFile = $debugFile; + return $this; + } + + /** + * @return string + */ + public function getDebugFile() { + return $this->debugFile; + } + + /** + * @return Configuration + */ + public static function getDefaultConfiguration() { + if (self::$defaultConfiguration == null) { + return new Configuration(); + } + + return self::$defaultConfiguration; + } + + public static function setDefaultConfiguration(Configuration $config) { + self::$defaultConfiguration = $config; + } } diff --git a/modules/swagger-codegen/src/main/resources/php/model.mustache b/modules/swagger-codegen/src/main/resources/php/model.mustache index cc2d57197ab..35795bf8c0b 100644 --- a/modules/swagger-codegen/src/main/resources/php/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php/model.mustache @@ -40,18 +40,48 @@ class {{classname}} implements ArrayAccess { {{#vars}}'{{name}}' => '{{baseName}}'{{#hasMore}}, {{/hasMore}}{{/vars}} ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + {{#vars}}'{{name}}' => '{{setter}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + {{#vars}}'{{name}}' => '{{getter}}'{{#hasMore}}, + {{/hasMore}}{{/vars}} + ); + {{#vars}} /** @var {{datatype}} ${{name}} {{#description}}{{{description}}} {{/description}}*/ - public ${{name}}; + protected ${{name}}; {{/vars}} - /** - * @param mixed[] Array of parameters to initialize the object with - */ public function __construct(array $data = null) { - {{#vars}}$this->{{name}} = @$data["{{name}}"];{{#hasMore}} - {{/hasMore}}{{/vars}} + if ($data != null) { + {{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}} + {{/hasMore}}{{/vars}} + } + } + {{#vars}} + /** + * get {{name}} + * @return {{datatype}} + */ + public function {{getter}}() { + return $this->{{name}}; } + /** + * set {{name}} + * @param {{datatype}} ${{name}} + * @return $this + */ + public function {{setter}}(${{name}}) { + $this->{{name}} = ${{name}}; + return $this; + } + {{/vars}} public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php index 7fe7b70312e..ed5cb6b6110 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/PetApi.php @@ -22,30 +22,28 @@ namespace Swagger\Client\Api; -use \Swagger\Client\ApiClient; use \Swagger\Client\Configuration; +use \Swagger\Client\ApiClient; +use \Swagger\Client\ApiException; +use \Swagger\Client\ObjectSerializer; class PetApi { - /** - * @param \Swagger\Client\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \Swagger\Client\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \Swagger\Client\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('http://petstore.swagger.io/v2'); + } + + $this->apiClient = $apiClient; + } + /** * @return \Swagger\Client\ApiClient get the API client */ @@ -54,10 +52,12 @@ class PetApi { } /** - * @param \Swagger\Client $apiClient set the API client + * @param \Swagger\Client\ApiClient $apiClient set the API client + * @return PetApi */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } @@ -68,6 +68,7 @@ class PetApi { * * @param \Swagger\Client\Model\Pet $body Pet object that needs to be added to the store (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function updatePet($body) { @@ -80,11 +81,11 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/json','application/xml')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('application/json','application/xml')); @@ -103,14 +104,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -121,6 +129,7 @@ class PetApi { * * @param \Swagger\Client\Model\Pet $body Pet object that needs to be added to the store (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function addPet($body) { @@ -133,11 +142,11 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/json','application/xml')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('application/json','application/xml')); @@ -156,14 +165,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -174,6 +190,7 @@ class PetApi { * * @param string[] $status Status values that need to be considered for filter (required) * @return \Swagger\Client\Model\Pet[] + * @throws \Swagger\Client\ApiException on non-2xx response */ public function findPetsByStatus($status) { @@ -186,15 +203,15 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // query params if($status !== null) { - $queryParams['status'] = $this->apiClient->toQueryValue($status); + $queryParams['status'] = $this->apiClient->getSerializer()->toQueryValue($status); } @@ -208,20 +225,33 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Pet[]'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet[]'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Pet[]'); return $responseObject; + } /** @@ -231,6 +261,7 @@ class PetApi { * * @param string[] $tags Tags to filter by (required) * @return \Swagger\Client\Model\Pet[] + * @throws \Swagger\Client\ApiException on non-2xx response */ public function findPetsByTags($tags) { @@ -243,15 +274,15 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // query params if($tags !== null) { - $queryParams['tags'] = $this->apiClient->toQueryValue($tags); + $queryParams['tags'] = $this->apiClient->getSerializer()->toQueryValue($tags); } @@ -265,20 +296,33 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Pet[]'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet[]'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Pet[]'); return $responseObject; + } /** @@ -288,6 +332,7 @@ class PetApi { * * @param int $pet_id ID of pet that needs to be fetched (required) * @return \Swagger\Client\Model\Pet + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getPetById($pet_id) { @@ -305,18 +350,19 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } @@ -328,20 +374,40 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('api_key', 'petstore_auth'); - + + $apiKey = $this->apiClient->getApiKeyWithPrefix('api_key'); + if (isset($apiKey)) { + $headerParams['api_key'] = $apiKey; + } + + + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Pet'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Pet'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Pet'); return $responseObject; + } /** @@ -353,6 +419,7 @@ class PetApi { * @param string $name Updated name of the pet (required) * @param string $status Updated status of the pet (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function updatePetWithForm($pet_id, $name, $status) { @@ -370,25 +437,26 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('application/x-www-form-urlencoded')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('application/x-www-form-urlencoded')); // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } // form params if ($name !== null) { - $formParams['name'] = $this->apiClient->toFormValue($name); + $formParams['name'] = $this->apiClient->getSerializer()->toFormValue($name); }// form params if ($status !== null) { - $formParams['status'] = $this->apiClient->toFormValue($status); + $formParams['status'] = $this->apiClient->getSerializer()->toFormValue($status); } @@ -399,14 +467,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -418,6 +493,7 @@ class PetApi { * @param string $api_key (required) * @param int $pet_id Pet id to delete (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function deletePet($api_key, $pet_id) { @@ -435,21 +511,22 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // header params if($api_key !== null) { - $headerParams['api_key'] = $this->apiClient->toHeaderValue($api_key); + $headerParams['api_key'] = $this->apiClient->getSerializer()->toHeaderValue($api_key); } // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } @@ -461,14 +538,21 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -481,6 +565,7 @@ class PetApi { * @param string $additional_metadata Additional data to pass to server (required) * @param string $file file to upload (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function uploadFile($pet_id, $additional_metadata, $file) { @@ -498,25 +583,26 @@ class PetApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array('multipart/form-data')); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array('multipart/form-data')); // path params if($pet_id !== null) { $resourcePath = str_replace("{" . "petId" . "}", - $this->apiClient->toPathValue($pet_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($pet_id), + $resourcePath); } // form params if ($additional_metadata !== null) { - $formParams['additionalMetadata'] = $this->apiClient->toFormValue($additional_metadata); + $formParams['additionalMetadata'] = $this->apiClient->getSerializer()->toFormValue($additional_metadata); }// form params if ($file !== null) { - $formParams['file'] = '@'.$this->apiClient->toFormValue($file); + $formParams['file'] = '@' . $this->apiClient->getSerializer()->toFormValue($file); } @@ -527,16 +613,22 @@ class PetApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('petstore_auth'); - + + + //TODO support oauth + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } - } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php index 07a922aab0a..237ba3f1acf 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/StoreApi.php @@ -22,30 +22,28 @@ namespace Swagger\Client\Api; -use \Swagger\Client\ApiClient; use \Swagger\Client\Configuration; +use \Swagger\Client\ApiClient; +use \Swagger\Client\ApiException; +use \Swagger\Client\ObjectSerializer; class StoreApi { - /** - * @param \Swagger\Client\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \Swagger\Client\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \Swagger\Client\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('http://petstore.swagger.io/v2'); + } + + $this->apiClient = $apiClient; + } + /** * @return \Swagger\Client\ApiClient get the API client */ @@ -54,10 +52,12 @@ class StoreApi { } /** - * @param \Swagger\Client $apiClient set the API client + * @param \Swagger\Client\ApiClient $apiClient set the API client + * @return StoreApi */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } @@ -67,6 +67,7 @@ class StoreApi { * Returns pet inventories by status * * @return map[string,int] + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getInventory() { @@ -79,11 +80,11 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -98,20 +99,37 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array('api_key'); - + + $apiKey = $this->apiClient->getApiKeyWithPrefix('api_key'); + if (isset($apiKey)) { + $headerParams['api_key'] = $apiKey; + } + + + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), 'map[string,int]'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'map[string,int]'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'map[string,int]'); return $responseObject; + } /** @@ -121,6 +139,7 @@ class StoreApi { * * @param \Swagger\Client\Model\Order $body order placed for purchasing the pet (required) * @return \Swagger\Client\Model\Order + * @throws \Swagger\Client\ApiException on non-2xx response */ public function placeOrder($body) { @@ -133,11 +152,11 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -156,20 +175,30 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Order'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Order'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Order'); return $responseObject; + } /** @@ -179,6 +208,7 @@ class StoreApi { * * @param string $order_id ID of pet that needs to be fetched (required) * @return \Swagger\Client\Model\Order + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getOrderById($order_id) { @@ -196,18 +226,19 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($order_id !== null) { $resourcePath = str_replace("{" . "orderId" . "}", - $this->apiClient->toPathValue($order_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($order_id), + $resourcePath); } @@ -219,20 +250,30 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\Order'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\Order'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\Order'); return $responseObject; + } /** @@ -242,6 +283,7 @@ class StoreApi { * * @param string $order_id ID of the order that needs to be deleted (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function deleteOrder($order_id) { @@ -259,18 +301,19 @@ class StoreApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($order_id !== null) { $resourcePath = str_replace("{" . "orderId" . "}", - $this->apiClient->toPathValue($order_id), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($order_id), + $resourcePath); } @@ -282,16 +325,19 @@ class StoreApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } - } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php index f4d35a3a7a0..1d0765bbb81 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Api/UserApi.php @@ -22,30 +22,28 @@ namespace Swagger\Client\Api; -use \Swagger\Client\ApiClient; use \Swagger\Client\Configuration; +use \Swagger\Client\ApiClient; +use \Swagger\Client\ApiException; +use \Swagger\Client\ObjectSerializer; class UserApi { - /** - * @param \Swagger\Client\ApiClient|null $apiClient The api client to use. Defaults to getting it from Configuration - */ - function __construct($apiClient = null) { - if (null === $apiClient) { - if (Configuration::$apiClient === null) { - Configuration::$apiClient = new ApiClient(); // create a new API client if not present - $this->apiClient = Configuration::$apiClient; - } - else - $this->apiClient = Configuration::$apiClient; // use the default one - } else { - $this->apiClient = $apiClient; // use the one provided by the user - } - } - /** @var \Swagger\Client\ApiClient instance of the ApiClient */ private $apiClient; + /** + * @param \Swagger\Client\ApiClient|null $apiClient The api client to use + */ + function __construct($apiClient = null) { + if ($apiClient == null) { + $apiClient = new ApiClient(); + $apiClient->getConfig()->setHost('http://petstore.swagger.io/v2'); + } + + $this->apiClient = $apiClient; + } + /** * @return \Swagger\Client\ApiClient get the API client */ @@ -54,10 +52,12 @@ class UserApi { } /** - * @param \Swagger\Client $apiClient set the API client + * @param \Swagger\Client\ApiClient $apiClient set the API client + * @return UserApi */ - public function setApiClient($apiClient) { + public function setApiClient(ApiClient $apiClient) { $this->apiClient = $apiClient; + return $this; } @@ -68,6 +68,7 @@ class UserApi { * * @param \Swagger\Client\Model\User $body Created user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function createUser($body) { @@ -80,11 +81,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -103,14 +104,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -121,6 +126,7 @@ class UserApi { * * @param \Swagger\Client\Model\User[] $body List of user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function createUsersWithArrayInput($body) { @@ -133,11 +139,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -156,14 +162,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -174,6 +184,7 @@ class UserApi { * * @param \Swagger\Client\Model\User[] $body List of user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function createUsersWithListInput($body) { @@ -186,11 +197,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -209,14 +220,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -228,6 +243,7 @@ class UserApi { * @param string $username The user name for login (required) * @param string $password The password for login in clear text (required) * @return string + * @throws \Swagger\Client\ApiException on non-2xx response */ public function loginUser($username, $password) { @@ -240,18 +256,18 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // query params if($username !== null) { - $queryParams['username'] = $this->apiClient->toQueryValue($username); + $queryParams['username'] = $this->apiClient->getSerializer()->toQueryValue($username); }// query params if($password !== null) { - $queryParams['password'] = $this->apiClient->toQueryValue($password); + $queryParams['password'] = $this->apiClient->getSerializer()->toQueryValue($password); } @@ -265,20 +281,30 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), 'string'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'string'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'string'); return $responseObject; + } /** @@ -287,6 +313,7 @@ class UserApi { * Logs out current logged in user session * * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function logoutUser() { @@ -299,11 +326,11 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); @@ -318,14 +345,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -336,6 +367,7 @@ class UserApi { * * @param string $username The name that needs to be fetched. Use user1 for testing. (required) * @return \Swagger\Client\Model\User + * @throws \Swagger\Client\ApiException on non-2xx response */ public function getUserByName($username) { @@ -353,18 +385,19 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($username !== null) { $resourcePath = str_replace("{" . "username" . "}", - $this->apiClient->toPathValue($username), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($username), + $resourcePath); } @@ -376,20 +409,30 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); - if(! $response) { + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = $this->apiClient->getSerializer()->deserialize($e->getResponseBody(), '\Swagger\Client\Model\User'); + $e->setResponseObject($data); + break; + } + + throw $e; + } + + if (!$response) { return null; } - $responseObject = $this->apiClient->deserialize($response,'\Swagger\Client\Model\User'); + $responseObject = $this->apiClient->getSerializer()->deserialize($response,'\Swagger\Client\Model\User'); return $responseObject; + } /** @@ -400,6 +443,7 @@ class UserApi { * @param string $username name that need to be deleted (required) * @param \Swagger\Client\Model\User $body Updated user object (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function updateUser($username, $body) { @@ -417,18 +461,19 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($username !== null) { $resourcePath = str_replace("{" . "username" . "}", - $this->apiClient->toPathValue($username), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($username), + $resourcePath); } // body params @@ -444,14 +489,18 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } @@ -462,6 +511,7 @@ class UserApi { * * @param string $username The name that needs to be deleted (required) * @return void + * @throws \Swagger\Client\ApiException on non-2xx response */ public function deleteUser($username) { @@ -479,18 +529,19 @@ class UserApi { $queryParams = array(); $headerParams = array(); $formParams = array(); - $_header_accept = $this->apiClient->selectHeaderAccept(array('application/json', 'application/xml')); + $_header_accept = ApiClient::selectHeaderAccept(array('application/json', 'application/xml')); if (!is_null($_header_accept)) { $headerParams['Accept'] = $_header_accept; } - $headerParams['Content-Type'] = $this->apiClient->selectHeaderContentType(array()); + $headerParams['Content-Type'] = ApiClient::selectHeaderContentType(array()); // path params if($username !== null) { $resourcePath = str_replace("{" . "username" . "}", - $this->apiClient->toPathValue($username), $resourcePath); + $this->apiClient->getSerializer()->toPathValue($username), + $resourcePath); } @@ -502,16 +553,19 @@ class UserApi { // for HTTP post (form) $httpBody = $formParams; } - - // authentication setting, if any - $authSettings = array(); - + // make the API Call - $response = $this->apiClient->callAPI($resourcePath, $method, - $queryParams, $httpBody, - $headerParams, $authSettings); + try { + $response = $this->apiClient->callAPI($resourcePath, $method, + $queryParams, $httpBody, + $headerParams); + } catch (ApiException $e) { + switch ($e->getCode()) { + } + + throw $e; + } } - } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php index bb5229fb170..66204f0c4f3 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiClient.php @@ -25,146 +25,60 @@ class ApiClient { public static $PUT = "PUT"; public static $DELETE = "DELETE"; - /** @var string[] Array of default headers where the key is the header name and the value is the header value */ - private $default_header = array(); + /** @var Configuration */ + protected $config; - /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ - protected $curl_timeout = 0; - - /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ - protected $user_agent = "PHP-Swagger"; + /** @var ObjectSerializer */ + protected $serializer; /** - * @param string $host Base url of the API server (optional) + * @param Configuration $config config for this ApiClient */ - function __construct($host = null) { - if ($host === null) { - $this->host = 'http://petstore.swagger.io/v2'; - } else { - $this->host = $host; + function __construct(Configuration $config = null) { + if ($config == null) { + $config = Configuration::getDefaultConfiguration(); } + + $this->config = $config; + $this->serializer = new ObjectSerializer(); } /** - * add default header - * - * @param string $header_name header name (e.g. Token) - * @param string $header_value header value (e.g. 1z8wp3) + * get the config + * @return Configuration */ - public function addDefaultHeader($header_name, $header_value) { - if (!is_string($header_name)) - throw new \InvalidArgumentException('Header name must be a string.'); - - $this->default_header[$header_name] = $header_value; + public function getConfig() { + return $this->config; } /** - * get the default header - * - * @return array default header + * get the serializer + * @return ObjectSerializer */ - public function getDefaultHeader() { - return $this->default_header; + public function getSerializer() { + return $this->serializer; } - /** - * delete the default header based on header name - * - * @param string $header_name header name (e.g. Token) - */ - public function deleteDefaultHeader($header_name) { - unset($this->default_header[$header_name]); - } - - /** - * set the user agent of the api client - * - * @param string $user_agent the user agent of the api client - */ - public function setUserAgent($user_agent) { - if (!is_string($user_agent)) - throw new \InvalidArgumentException('User-agent must be a string.'); - - $this->user_agent= $user_agent; - } - - /** - * get the user agent of the api client - * - * @return string user agent - */ - public function getUserAgent($user_agent) { - return $this->user_agent; - } - - /** - * set the HTTP timeout value - * - * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] - */ - public function setTimeout($seconds) { - if (!is_numeric($seconds) || $seconds < 0) - throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); - - $this->curl_timeout = $seconds; - } - - /** - * get the HTTP timeout value - * - * @return string HTTP timeout value - */ - public function getTimeout() { - return $this->curl_timeout; - } - - /** * Get API key (with prefix if set) - * @param string key name + * @param string $apiKey name of apikey * @return string API key with the prefix */ public function getApiKeyWithPrefix($apiKey) { - if (isset(Configuration::$apiKeyPrefix[$apiKey])) { - return Configuration::$apiKeyPrefix[$apiKey]." ".Configuration::$apiKey[$apiKey]; - } else if (isset(Configuration::$apiKey[$apiKey])) { - return Configuration::$apiKey[$apiKey]; + $prefix = $this->config->getApiKeyPrefix($apiKey); + $apiKey = $this->config->getApiKey($apiKey); + + if (!isset($apiKey)) { + return null; + } + + if (isset($prefix)) { + $keyWithPrefix = $prefix." ".$apiKey; } else { - return; + $keyWithPrefix = $apiKey; } - } - /** - * update hearder and query param based on authentication setting - * - * @param array $headerParams header parameters (by ref) - * @param array $queryParams query parameters (by ref) - * @param array $authSettings array of authentication scheme (e.g ['api_key']) - */ - public function updateParamsForAuth(&$headerParams, &$queryParams, $authSettings) - { - if (count($authSettings) == 0) - return; - - // one endpoint can have more than 1 auth settings - foreach($authSettings as $auth) { - // determine which one to use - switch($auth) { - - case 'api_key': - $headerParams['api_key'] = $this->getApiKeyWithPrefix('api_key'); - - break; - - case 'petstore_auth': - - //TODO support oauth - break; - - default: - //TODO show warning about security definition not found - } - } + return $keyWithPrefix; } /** @@ -173,18 +87,15 @@ class ApiClient { * @param array $queryParams parameters to be place in query URL * @param array $postData parameters to be placed in POST body * @param array $headerParams parameters to be place in request header + * @throws \Swagger\Client\ApiException on a non 2xx response * @return mixed */ - public function callApi($resourcePath, $method, $queryParams, $postData, - $headerParams, $authSettings) { + public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams) { $headers = array(); - # determine authentication setting - $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); - # construct the http header - $headerParams = array_merge((array)$this->default_header, (array)$headerParams); + $headerParams = array_merge((array)$this->config->getDefaultHeaders(), (array)$headerParams); foreach ($headerParams as $key => $val) { $headers[] = "$key: $val"; @@ -195,15 +106,15 @@ class ApiClient { $postData = http_build_query($postData); } else if ((is_object($postData) or is_array($postData)) and !in_array('Content-Type: multipart/form-data', $headers)) { // json model - $postData = json_encode($this->sanitizeForSerialization($postData)); + $postData = json_encode($this->serializer->sanitizeForSerialization($postData)); } - $url = $this->host . $resourcePath; + $url = $this->config->getHost() . $resourcePath; $curl = curl_init(); // set timeout, if needed - if ($this->curl_timeout != 0) { - curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_timeout); + if ($this->config->getCurlTimeout() != 0) { + curl_setopt($curl, CURLOPT_TIMEOUT, $this->config->getCurlTimeout()); } // return the result on success, rather than just TRUE curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @@ -232,14 +143,14 @@ class ApiClient { curl_setopt($curl, CURLOPT_URL, $url); // Set user agent - curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + curl_setopt($curl, CURLOPT_USERAGENT, $this->config->getUserAgent()); // debugging for curl - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, $this->config->getDebugFile()); curl_setopt($curl, CURLOPT_VERBOSE, 1); - curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a')); + curl_setopt($curl, CURLOPT_STDERR, fopen($this->config->getDebugFile(), 'a')); } else { curl_setopt($curl, CURLOPT_VERBOSE, 0); } @@ -255,8 +166,8 @@ class ApiClient { $response_info = curl_getinfo($curl); // debug HTTP response body - if (Configuration::$debug) { - error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file); + if ($this->config->getDebug()) { + error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, $this->config->getDebugFile()); } // Handle the response @@ -274,153 +185,13 @@ class ApiClient { return $data; } - /** - * Build a JSON POST object - */ - protected function sanitizeForSerialization($data) - { - if (is_scalar($data) || null === $data) { - $sanitized = $data; - } else if ($data instanceof \DateTime) { - $sanitized = $data->format(\DateTime::ISO8601); - } else if (is_array($data)) { - foreach ($data as $property => $value) { - $data[$property] = $this->sanitizeForSerialization($value); - } - $sanitized = $data; - } else if (is_object($data)) { - $values = array(); - foreach (array_keys($data::$swaggerTypes) as $property) { - if ($data->$property !== null) { - $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); - } - } - $sanitized = $values; - } else { - $sanitized = (string)$data; - } - - return $sanitized; - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the path, by url-encoding. - * @param string $value a string which will be part of the path - * @return string the serialized object - */ - public function toPathValue($value) { - return rawurlencode($this->toString($value)); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the query, by imploding comma-separated if it's an object. - * If it's a string, pass through unchanged. It will be url-encoded - * later. - * @param object $object an object to be serialized to a string - * @return string the serialized object - */ - public function toQueryValue($object) { - if (is_array($object)) { - return implode(',', $object); - } else { - return $this->toString($object); - } - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the header. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value a string which will be part of the header - * @return string the header string - */ - public function toHeaderValue($value) { - return $this->toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the http body (form parameter). If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the form parameter - * @return string the form string - */ - public function toFormValue($value) { - return $this->toString($value); - } - - /** - * Take value and turn it into a string suitable for inclusion in - * the parameter. If it's a string, pass through unchanged - * If it's a datetime object, format it in ISO8601 - * @param string $value the value of the parameter - * @return string the header string - */ - public function toString($value) { - if ($value instanceof \DateTime) { // datetime in ISO8601 format - return $value->format(\DateTime::ISO8601); - } - else { - return $value; - } - } - - /** - * Deserialize a JSON string into an object - * - * @param object $object object or primitive to be deserialized - * @param string $class class name is passed as a string - * @return object an instance of $class - */ - public function deserialize($data, $class) - { - if (null === $data) { - $deserialized = null; - } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] - $inner = substr($class, 4, -1); - $deserialized = array(); - if(strrpos($inner, ",") !== false) { - $subClass_array = explode(',', $inner, 2); - $subClass = $subClass_array[1]; - foreach ($data as $key => $value) { - $deserialized[$key] = $this->deserialize($value, $subClass); - } - } - } elseif (strcasecmp(substr($class, -2),'[]') == 0) { - $subClass = substr($class, 0, -2); - $values = array(); - foreach ($data as $key => $value) { - $values[] = $this->deserialize($value, $subClass); - } - $deserialized = $values; - } elseif ($class == 'DateTime') { - $deserialized = new \DateTime($data); - } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { - settype($data, $class); - $deserialized = $data; - } else { - $instance = new $class(); - foreach ($instance::$swaggerTypes as $property => $type) { - $original_property_name = $instance::$attributeMap[$property]; - if (isset($original_property_name) && isset($data->$original_property_name)) { - $instance->$property = $this->deserialize($data->$original_property_name, $type); - } - } - $deserialized = $instance; - } - - return $deserialized; - } - /* * return the header 'Accept' based on an array of Accept provided * - * @param array[string] $accept Array of header + * @param string[] $accept Array of header * @return string Accept (e.g. application/json) */ - public function selectHeaderAccept($accept) { + public static function selectHeaderAccept($accept) { if (count($accept) === 0 or (count($accept) === 1 and $accept[0] === '')) { return NULL; } elseif (preg_grep("/application\/json/i", $accept)) { @@ -433,10 +204,10 @@ class ApiClient { /* * return the content type based on an array of content-type provided * - * @param array[string] content_type_array Array fo content-type + * @param string[] content_type_array Array fo content-type * @return string Content-Type (e.g. application/json) */ - public function selectHeaderContentType($content_type) { + public static function selectHeaderContentType($content_type) { if (count($content_type) === 0 or (count($content_type) === 1 and $content_type[0] === '')) { return 'application/json'; } elseif (preg_grep("/application\/json/i", $content_type)) { @@ -445,6 +216,4 @@ class ApiClient { return implode(',', $content_type); } } - } - diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php index 5f3b1812261..51774137aed 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php @@ -22,15 +22,20 @@ use \Exception; class ApiException extends Exception { /** @var string The HTTP body of the server response. */ - protected $response_body; + protected $responseBody; /** @var string[] The HTTP header of the server response. */ - protected $response_headers; + protected $responseHeaders; + + /** + * The deserialized response object + */ + protected $responseObject; public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { parent::__construct($message, $code); - $this->response_headers = $responseHeaders; - $this->response_body = $responseBody; + $this->responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; } /** @@ -39,7 +44,7 @@ class ApiException extends Exception { * @return string HTTP response header */ public function getResponseHeaders() { - return $this->response_headers; + return $this->responseHeaders; } /** @@ -48,7 +53,18 @@ class ApiException extends Exception { * @return string HTTP response body */ public function getResponseBody() { - return $this->response_body; + return $this->responseBody; } + /** + * sets the deseralized response object (during deserialization) + * @param mixed $obj + */ + public function setResponseObject($obj) { + $this->responseObject = $obj; + } + + public function getResponseObject() { + return $this->responseObject; + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php index e6381781bb0..a407fe4dd49 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php @@ -17,37 +17,250 @@ namespace Swagger\Client; -use \Swagger\Client\ApiClient; - class Configuration { + private static $defaultConfiguration = null; + /** @var string[] Associate array to store API key(s) */ - public static $apiKey = array(); + protected $apiKeys = array(); /** string[] Associate array to store API prefix (e.g. Bearer) */ - public static $apiKeyPrefix = array(); + protected $apiKeyPrefixes = array(); /** @var string Username for HTTP basic authentication */ - public static $username = ''; + protected $username = ''; /** @var string Password for HTTP basic authentication */ - public static $password = ''; + protected $password = ''; /** @var \Swagger\Client\ApiClient The default instance of ApiClient */ - public static $apiClient; + protected $defaultHeaders = array(); + + /** @var string The host */ + protected $host = 'http://localhost'; + + /** @var string timeout (second) of the HTTP request, by default set to 0, no timeout */ + protected $curlTimeout = 0; + + /** @var string user agent of the HTTP request, set to "PHP-Swagger" by default */ + protected $userAgent = "PHP-Swagger"; /** @var bool Debug switch (default set to false) */ - public static $debug = false; + protected $debug = false; /** @var string Debug file location (log to STDOUT by default) */ - public static $debug_file = 'php://output'; + protected $debugFile = 'php://output'; - /* - * manually initalize ApiClient + /** + * @param string $key + * @param string $value + * @return Configuration */ - public static function init() { - if (self::$apiClient === null) - self::$apiClient = new ApiClient(); + public function setApiKey($key, $value) { + $this->apiKeys[$key] = $value; + return $this; } + /** + * @param $key + * @return string + */ + public function getApiKey($key) { + return isset($this->apiKeys[$key]) ? $this->apiKeys[$key] : null; + } + + /** + * @param string $key + * @param string $value + * @return Configuration + */ + public function setApiKeyPrefix($key, $value) { + $this->apiKeyPrefixes[$key] = $value; + return $this; + } + + /** + * @param $key + * @return string + */ + public function getApiKeyPrefix($key) { + return isset($this->apiKeyPrefixes[$key]) ? $this->apiKeyPrefixes[$key] : null; + } + + /** + * @param string $username + * @return Configuration + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * @param string $password + * @return Configuration + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * add default header + * + * @param string $headerName header name (e.g. Token) + * @param string $headerValue header value (e.g. 1z8wp3) + * @return ApiClient + */ + public function addDefaultHeader($headerName, $headerValue) { + if (!is_string($headerName)) { + throw new \InvalidArgumentException('Header name must be a string.'); + } + + $this->defaultHeaders[$headerName] = $headerValue; + return $this; + } + + /** + * get the default header + * + * @return array default header + */ + public function getDefaultHeaders() { + return $this->defaultHeaders; + } + + /** + * delete a default header + * @param string $headerName the header to delete + * @return Configuration + */ + public function deleteDefaultHeader($headerName) { + unset($this->defaultHeaders[$headerName]); + } + + /** + * @param string $host + * @return Configuration + */ + public function setHost($host) { + $this->host = $host; + return $this; + } + + /** + * @return string + */ + public function getHost() { + return $this->host; + } + + /** + * set the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * @return ApiClient + */ + public function setUserAgent($userAgent) { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * get the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() { + return $this->userAgent; + } + + /** + * set the HTTP timeout value + * + * @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] + * @return ApiClient + */ + public function setCurlTimeout($seconds) { + if (!is_numeric($seconds) || $seconds < 0) { + throw new \InvalidArgumentException('Timeout value must be numeric and a non-negative number.'); + } + + $this->curlTimeout = $seconds; + return $this; + } + + /** + * get the HTTP timeout value + * + * @return string HTTP timeout value + */ + public function getCurlTimeout() { + return $this->curlTimeout; + } + + /** + * @param bool $debug + * @return Configuration + */ + public function setDebug($debug) { + $this->debug = $debug; + return $this; + } + + /** + * @return bool + */ + public function getDebug() { + return $this->debug; + } + + /** + * @param string $debugFile + * @return Configuration + */ + public function setDebugFile($debugFile) { + $this->debugFile = $debugFile; + return $this; + } + + /** + * @return string + */ + public function getDebugFile() { + return $this->debugFile; + } + + /** + * @return Configuration + */ + public static function getDefaultConfiguration() { + if (self::$defaultConfiguration == null) { + return new Configuration(); + } + + return self::$defaultConfiguration; + } + + public static function setDefaultConfiguration(Configuration $config) { + self::$defaultConfiguration = $config; + } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php index 750a8fee5df..75aaf2eeead 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Category.php @@ -38,21 +38,69 @@ class Category implements ArrayAccess { 'id' => 'id', 'name' => 'name' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'name' => 'setName' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'name' => 'getName' + ); + /** @var int $id */ - public $id; + protected $id; /** @var string $name */ - public $name; + protected $name; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->name = $data["name"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->name = @$data["name"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get name + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * set name + * @param string $name + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php index 64552afb763..c7a433c3d8c 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Order.php @@ -46,37 +46,165 @@ class Order implements ArrayAccess { 'status' => 'status', 'complete' => 'complete' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'pet_id' => 'setPetId', + 'quantity' => 'setQuantity', + 'ship_date' => 'setShipDate', + 'status' => 'setStatus', + 'complete' => 'setComplete' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'pet_id' => 'getPetId', + 'quantity' => 'getQuantity', + 'ship_date' => 'getShipDate', + 'status' => 'getStatus', + 'complete' => 'getComplete' + ); + /** @var int $id */ - public $id; + protected $id; /** @var int $pet_id */ - public $pet_id; + protected $pet_id; /** @var int $quantity */ - public $quantity; + protected $quantity; /** @var \DateTime $ship_date */ - public $ship_date; + protected $ship_date; /** @var string $status Order Status */ - public $status; + protected $status; /** @var bool $complete */ - public $complete; + protected $complete; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->pet_id = $data["pet_id"]; + $this->quantity = $data["quantity"]; + $this->ship_date = $data["ship_date"]; + $this->status = $data["status"]; + $this->complete = $data["complete"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->pet_id = @$data["pet_id"]; - $this->quantity = @$data["quantity"]; - $this->ship_date = @$data["ship_date"]; - $this->status = @$data["status"]; - $this->complete = @$data["complete"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get pet_id + * @return int + */ + public function getPetId() { + return $this->pet_id; + } + + /** + * set pet_id + * @param int $pet_id + * @return $this + */ + public function setPetId($pet_id) { + $this->pet_id = $pet_id; + return $this; + } + + /** + * get quantity + * @return int + */ + public function getQuantity() { + return $this->quantity; + } + + /** + * set quantity + * @param int $quantity + * @return $this + */ + public function setQuantity($quantity) { + $this->quantity = $quantity; + return $this; + } + + /** + * get ship_date + * @return \DateTime + */ + public function getShipDate() { + return $this->ship_date; + } + + /** + * set ship_date + * @param \DateTime $ship_date + * @return $this + */ + public function setShipDate($ship_date) { + $this->ship_date = $ship_date; + return $this; + } + + /** + * get status + * @return string + */ + public function getStatus() { + return $this->status; + } + + /** + * set status + * @param string $status + * @return $this + */ + public function setStatus($status) { + $this->status = $status; + return $this; + } + + /** + * get complete + * @return bool + */ + public function getComplete() { + return $this->complete; + } + + /** + * set complete + * @param bool $complete + * @return $this + */ + public function setComplete($complete) { + $this->complete = $complete; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php index ef2a4c76a0d..cbe27e1fce9 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php @@ -46,37 +46,165 @@ class Pet implements ArrayAccess { 'tags' => 'tags', 'status' => 'status' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'category' => 'setCategory', + 'name' => 'setName', + 'photo_urls' => 'setPhotoUrls', + 'tags' => 'setTags', + 'status' => 'setStatus' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'category' => 'getCategory', + 'name' => 'getName', + 'photo_urls' => 'getPhotoUrls', + 'tags' => 'getTags', + 'status' => 'getStatus' + ); + /** @var int $id */ - public $id; + protected $id; /** @var \Swagger\Client\Model\Category $category */ - public $category; + protected $category; /** @var string $name */ - public $name; + protected $name; /** @var string[] $photo_urls */ - public $photo_urls; + protected $photo_urls; /** @var \Swagger\Client\Model\Tag[] $tags */ - public $tags; + protected $tags; /** @var string $status pet status in the store */ - public $status; + protected $status; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->category = $data["category"]; + $this->name = $data["name"]; + $this->photo_urls = $data["photo_urls"]; + $this->tags = $data["tags"]; + $this->status = $data["status"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->category = @$data["category"]; - $this->name = @$data["name"]; - $this->photo_urls = @$data["photo_urls"]; - $this->tags = @$data["tags"]; - $this->status = @$data["status"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get category + * @return \Swagger\Client\Model\Category + */ + public function getCategory() { + return $this->category; + } + + /** + * set category + * @param \Swagger\Client\Model\Category $category + * @return $this + */ + public function setCategory($category) { + $this->category = $category; + return $this; + } + + /** + * get name + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * set name + * @param string $name + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + + /** + * get photo_urls + * @return string[] + */ + public function getPhotoUrls() { + return $this->photo_urls; + } + + /** + * set photo_urls + * @param string[] $photo_urls + * @return $this + */ + public function setPhotoUrls($photo_urls) { + $this->photo_urls = $photo_urls; + return $this; + } + + /** + * get tags + * @return \Swagger\Client\Model\Tag[] + */ + public function getTags() { + return $this->tags; + } + + /** + * set tags + * @param \Swagger\Client\Model\Tag[] $tags + * @return $this + */ + public function setTags($tags) { + $this->tags = $tags; + return $this; + } + + /** + * get status + * @return string + */ + public function getStatus() { + return $this->status; + } + + /** + * set status + * @param string $status + * @return $this + */ + public function setStatus($status) { + $this->status = $status; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php index 5959cb20a6a..3fd785f001b 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/Tag.php @@ -38,21 +38,69 @@ class Tag implements ArrayAccess { 'id' => 'id', 'name' => 'name' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'name' => 'setName' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'name' => 'getName' + ); + /** @var int $id */ - public $id; + protected $id; /** @var string $name */ - public $name; + protected $name; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->name = $data["name"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->name = @$data["name"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get name + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * set name + * @param string $name + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php b/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php index 1bfb7f332db..2bb31056bde 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Model/User.php @@ -50,45 +50,213 @@ class User implements ArrayAccess { 'phone' => 'phone', 'user_status' => 'userStatus' ); + + /** @var string[] Array of attributes to setter functions (for deserialization of responses) */ + static $setters = array( + 'id' => 'setId', + 'username' => 'setUsername', + 'first_name' => 'setFirstName', + 'last_name' => 'setLastName', + 'email' => 'setEmail', + 'password' => 'setPassword', + 'phone' => 'setPhone', + 'user_status' => 'setUserStatus' + ); + + /** @var string[] Array of attributes to getter functions (for serialization of requests) */ + static $getters = array( + 'id' => 'getId', + 'username' => 'getUsername', + 'first_name' => 'getFirstName', + 'last_name' => 'getLastName', + 'email' => 'getEmail', + 'password' => 'getPassword', + 'phone' => 'getPhone', + 'user_status' => 'getUserStatus' + ); + /** @var int $id */ - public $id; + protected $id; /** @var string $username */ - public $username; + protected $username; /** @var string $first_name */ - public $first_name; + protected $first_name; /** @var string $last_name */ - public $last_name; + protected $last_name; /** @var string $email */ - public $email; + protected $email; /** @var string $password */ - public $password; + protected $password; /** @var string $phone */ - public $phone; + protected $phone; /** @var int $user_status User Status */ - public $user_status; + protected $user_status; + + public function __construct(array $data = null) { + if ($data != null) { + $this->id = $data["id"]; + $this->username = $data["username"]; + $this->first_name = $data["first_name"]; + $this->last_name = $data["last_name"]; + $this->email = $data["email"]; + $this->password = $data["password"]; + $this->phone = $data["phone"]; + $this->user_status = $data["user_status"]; + } + } /** - * @param mixed[] Array of parameters to initialize the object with + * get id + * @return int */ - public function __construct(array $data = null) { - $this->id = @$data["id"]; - $this->username = @$data["username"]; - $this->first_name = @$data["first_name"]; - $this->last_name = @$data["last_name"]; - $this->email = @$data["email"]; - $this->password = @$data["password"]; - $this->phone = @$data["phone"]; - $this->user_status = @$data["user_status"]; + public function getId() { + return $this->id; } + /** + * set id + * @param int $id + * @return $this + */ + public function setId($id) { + $this->id = $id; + return $this; + } + + /** + * get username + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * set username + * @param string $username + * @return $this + */ + public function setUsername($username) { + $this->username = $username; + return $this; + } + + /** + * get first_name + * @return string + */ + public function getFirstName() { + return $this->first_name; + } + + /** + * set first_name + * @param string $first_name + * @return $this + */ + public function setFirstName($first_name) { + $this->first_name = $first_name; + return $this; + } + + /** + * get last_name + * @return string + */ + public function getLastName() { + return $this->last_name; + } + + /** + * set last_name + * @param string $last_name + * @return $this + */ + public function setLastName($last_name) { + $this->last_name = $last_name; + return $this; + } + + /** + * get email + * @return string + */ + public function getEmail() { + return $this->email; + } + + /** + * set email + * @param string $email + * @return $this + */ + public function setEmail($email) { + $this->email = $email; + return $this; + } + + /** + * get password + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * set password + * @param string $password + * @return $this + */ + public function setPassword($password) { + $this->password = $password; + return $this; + } + + /** + * get phone + * @return string + */ + public function getPhone() { + return $this->phone; + } + + /** + * set phone + * @param string $phone + * @return $this + */ + public function setPhone($phone) { + $this->phone = $phone; + return $this; + } + + /** + * get user_status + * @return int + */ + public function getUserStatus() { + return $this->user_status; + } + + /** + * set user_status + * @param int $user_status + * @return $this + */ + public function setUserStatus($user_status) { + $this->user_status = $user_status; + return $this; + } + public function offsetExists($offset) { return isset($this->$offset); } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php b/samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php new file mode 100644 index 00000000000..802a49bc01a --- /dev/null +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ObjectSerializer.php @@ -0,0 +1,151 @@ +format(\DateTime::ISO8601); + } else if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = $this->sanitizeForSerialization($value); + } + $sanitized = $data; + } else if (is_object($data)) { + $values = array(); + foreach (array_keys($data::$swaggerTypes) as $property) { + $getter = $data::$getters[$property]; + if ($data->$getter() !== null) { + $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$getter()); + } + } + $sanitized = $values; + } else { + $sanitized = (string)$data; + } + + return $sanitized; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * @param string $value a string which will be part of the path + * @return string the serialized object + */ + public function toPathValue($value) { + return rawurlencode($this->toString($value)); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the query, by imploding comma-separated if it's an object. + * If it's a string, pass through unchanged. It will be url-encoded + * later. + * @param object $object an object to be serialized to a string + * @return string the serialized object + */ + public function toQueryValue($object) { + if (is_array($object)) { + return implode(',', $object); + } else { + return $this->toString($object); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value a string which will be part of the header + * @return string the header string + */ + public function toHeaderValue($value) { + return $this->toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the http body (form parameter). If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the form parameter + * @return string the form string + */ + public function toFormValue($value) { + return $this->toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * @param string $value the value of the parameter + * @return string the header string + */ + public function toString($value) { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(\DateTime::ISO8601); + } else { + return $value; + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @return object an instance of $class + */ + public function deserialize($data, $class) { + if (null === $data) { + $deserialized = null; + } elseif (substr($class, 0, 4) == 'map[') { # for associative array e.g. map[string,int] + $inner = substr($class, 4, -1); + $deserialized = array(); + if(strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = $this->deserialize($value, $subClass); + } + } + } elseif (strcasecmp(substr($class, -2),'[]') == 0) { + $subClass = substr($class, 0, -2); + $values = array(); + foreach ($data as $key => $value) { + $values[] = $this->deserialize($value, $subClass); + } + $deserialized = $values; + } elseif ($class == 'DateTime') { + $deserialized = new \DateTime($data); + } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { + settype($data, $class); + $deserialized = $data; + } else { + $instance = new $class(); + foreach ($instance::$swaggerTypes as $property => $type) { + $propertySetter = $instance::$setters[$property]; + + if (!isset($propertySetter) || !isset($data->{$instance::$attributeMap[$property]})) { + continue; + } + + $propertyValue = $data->{$instance::$attributeMap[$property]}; + if (isset($propertyValue)) { + $instance->$propertySetter($this->deserialize($propertyValue, $type)); + } + } + $deserialized = $instance; + } + + return $deserialized; + } +} \ No newline at end of file diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index 131a79dba92..3ac28772291 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -22,19 +22,19 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // new pet $new_pet_id = 10005; $new_pet = new Swagger\Client\Model\Pet; - $new_pet->id = $new_pet_id; - $new_pet->name = "PHP Unit Test"; + $new_pet->setId($new_pet_id); + $new_pet->setName("PHP Unit Test"); // new tag $tag= new Swagger\Client\Model\Tag; - $tag->id = $new_pet_id; // use the same id as pet - $tag->name = "test php tag"; + $tag->setId($new_pet_id); // use the same id as pet + $tag->setName("test php tag"); // new category $category = new Swagger\Client\Model\Category; - $category->id = $new_pet_id; // use the same id as pet - $category->name = "test php category"; + $category->setId($new_pet_id); // use the same id as pet + $category->setName("test php category"); - $new_pet->tags = array($tag); - $new_pet->category = $category; + $new_pet->setTags(array($tag)); + $new_pet->setCategory($category); $pet_api = new Swagger\Client\Api\PetAPI(); // add a new pet (model) @@ -56,65 +56,53 @@ class PetApiTest extends \PHPUnit_Framework_TestCase $this->assertSame('application/yaml,application/xml', $api_client->selectHeaderContentType(array('application/yaml','application/xml'))); // test addDefaultHeader and getDefaultHeader - $api_client->addDefaultHeader('test1', 'value1'); - $api_client->addDefaultHeader('test2', 200); - $defaultHeader = $api_client->getDefaultHeader(); + $api_client->getConfig()->addDefaultHeader('test1', 'value1'); + $api_client->getConfig()->addDefaultHeader('test2', 200); + $defaultHeader = $api_client->getConfig()->getDefaultHeaders(); $this->assertSame('value1', $defaultHeader['test1']); $this->assertSame(200, $defaultHeader['test2']); // test deleteDefaultHeader - $api_client->deleteDefaultHeader('test2'); - $defaultHeader = $api_client->getDefaultHeader(); + $api_client->getConfig()->deleteDefaultHeader('test2'); + $defaultHeader = $api_client->getConfig()->getDefaultHeaders(); $this->assertFalse(isset($defaultHeader['test2'])); - $pet_api = new Swagger\Client\Api\PetAPI(); $pet_api2 = new Swagger\Client\Api\PetAPI(); $apiClient3 = new Swagger\Client\ApiClient(); - $apiClient3->setUserAgent = 'api client 3'; + $apiClient3->getConfig()->setUserAgent('api client 3'); $apiClient4 = new Swagger\Client\ApiClient(); - $apiClient4->setUserAgent = 'api client 4'; + $apiClient4->getConfig()->setUserAgent('api client 4'); $pet_api3 = new Swagger\Client\Api\PetAPI($apiClient3); - // same default api client - $this->assertSame($pet_api->getApiClient(), $pet_api2->getApiClient()); - // confirm using the default api client in the Configuration - $this->assertSame($pet_api->getApiClient(), Swagger\Client\Configuration::$apiClient); // 2 different api clients are not the same $this->assertNotEquals($apiClient3, $apiClient4); - // customized pet api not using the default (configuration) api client - $this->assertNotEquals($pet_api3->getApiClient(), Swagger\Client\Configuration::$apiClient); // customied pet api not using the old pet api's api client $this->assertNotEquals($pet_api2->getApiClient(), $pet_api3->getApiClient()); - - // both pet api and pet api2 share the same api client and confirm using timeout value - $pet_api->getApiClient()->setTimeout(999); - $this->assertSame(999, $pet_api2->getApiClient()->getTimeout()); - } // test getPetById with a Pet object (id 10005) public function testGetPetById() { // initialize the API client without host - $api_client = new Swagger\Client\ApiClient(); - Swagger\Client\Configuration::$apiKey['api_key'] = '111222333444555'; $pet_id = 10005; // ID of pet that needs to be fetched - $pet_api = new Swagger\Client\Api\PetAPI($api_client); + $pet_api = new Swagger\Client\Api\PetAPI(); + $pet_api->getApiClient()->getConfig()->setApiKey('api_key', '111222333444555'); // return Pet (model) $response = $pet_api->getPetById($pet_id); - $this->assertSame($response->id, $pet_id); - $this->assertSame($response->name, 'PHP Unit Test'); - $this->assertSame($response->category->id, $pet_id); - $this->assertSame($response->category->name, 'test php category'); - $this->assertSame($response->tags[0]->id, $pet_id); - $this->assertSame($response->tags[0]->name, 'test php tag'); + $this->assertSame($response->getId(), $pet_id); + $this->assertSame($response->getName(), 'PHP Unit Test'); + $this->assertSame($response->getCategory()->getId(), $pet_id); + $this->assertSame($response->getCategory()->getName(), 'test php category'); + $this->assertSame($response->getTags()[0]->getId(), $pet_id); + $this->assertSame($response->getTags()[0]->getName(), 'test php tag'); } // test getPetByStatus and verify by the "id" of the response public function testFindPetByStatus() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_api = new Swagger\Client\Api\PetAPI($api_client); // return Pet (model) $response = $pet_api->findPetsByStatus("available"); @@ -133,30 +121,32 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUpdatePet() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_id = 10001; // ID of pet that needs to be fetched $pet_api = new Swagger\Client\Api\PetAPI($api_client); // create updated pet object $updated_pet = new Swagger\Client\Model\Pet; - $updated_pet->id = $pet_id; - $updated_pet->name = 'updatePet'; // new name - $updated_pet->status = 'pending'; // new status + $updated_pet->setId($pet_id); + $updated_pet->setName('updatePet'); // new name + $updated_pet->setStatus('pending'); // new status // update Pet (model/json) $update_response = $pet_api->updatePet($updated_pet); // return nothing (void) $this->assertSame($update_response, NULL); // verify updated Pet $response = $pet_api->getPetById($pet_id); - $this->assertSame($response->id, $pet_id); - $this->assertSame($response->status, 'pending'); - $this->assertSame($response->name, 'updatePet'); + $this->assertSame($response->getId(), $pet_id); + $this->assertSame($response->getStatus(), 'pending'); + $this->assertSame($response->getName(), 'updatePet'); } // test updatePet and verify by the "id" of the response public function testUpdatePetWithForm() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_id = 10001; // ID of pet that needs to be fetched $pet_api = new Swagger\Client\Api\PetAPI($api_client); // update Pet (form) @@ -164,20 +154,21 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // return nothing (void) $this->assertSame($update_response, NULL); $response = $pet_api->getPetById($pet_id); - $this->assertSame($response->id, $pet_id); - $this->assertSame($response->name, 'update pet with form'); - $this->assertSame($response->status, 'sold'); + $this->assertSame($response->getId(), $pet_id); + $this->assertSame($response->getName(), 'update pet with form'); + $this->assertSame($response->getStatus(), 'sold'); } // test addPet and verify by the "id" and "name" of the response public function testAddPet() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $new_pet_id = 10001; $new_pet = new Swagger\Client\Model\Pet; - $new_pet->id = $new_pet_id; - $new_pet->name = "PHP Unit Test"; + $new_pet->setId($new_pet_id); + $new_pet->setName("PHP Unit Test"); $pet_api = new Swagger\Client\Api\PetAPI($api_client); // add a new pet (model) $add_response = $pet_api->addPet($new_pet); @@ -185,15 +176,16 @@ class PetApiTest extends \PHPUnit_Framework_TestCase $this->assertSame($add_response, NULL); // verify added Pet $response = $pet_api->getPetById($new_pet_id); - $this->assertSame($response->id, $new_pet_id); - $this->assertSame($response->name, 'PHP Unit Test'); + $this->assertSame($response->getId(), $new_pet_id); + $this->assertSame($response->getName(), 'PHP Unit Test'); } // test upload file public function testUploadFile() { // initialize the API client - $api_client = new Swagger\Client\ApiClient('http://petstore.swagger.io/v2'); + $config = (new Swagger\Client\Configuration())->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); $pet_api = new Swagger\Client\Api\PetAPI($api_client); // upload file $pet_id = 10001; @@ -206,7 +198,9 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testGetInventory() { // initialize the API client - $api_client = new Swagger\Client\APIClient('http://petstore.swagger.io/v2'); + $config = new Swagger\Client\Configuration(); + $config->setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\APIClient($config); $store_api = new Swagger\Client\Api\StoreAPI($api_client); // get inventory $get_response = $store_api->getInventory(); diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php index a92149fbaf3..05bd873c993 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/StoreApiTest.php @@ -1,6 +1,6 @@ setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); + $store_api = new Swagger\Client\Api\StoreAPI($api_client); // get inventory $get_response = $store_api->getInventory(); diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php index 181e8a1249e..3efce8b08ba 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/UserApiTest.php @@ -1,6 +1,6 @@ setHost('http://petstore.swagger.io/v2'); + $api_client = new Swagger\Client\ApiClient($config); + $user_api = new Swagger\Client\Api\UserApi($api_client); // login $response = $user_api->loginUser("xxxxx", "yyyyyyyy"); From 6a24b328e37de0f0d27dcb8d4db636de66993acd Mon Sep 17 00:00:00 2001 From: wing328 Date: Fri, 26 Jun 2015 10:30:12 +0800 Subject: [PATCH 163/499] fix variable name in path --- .../src/main/resources/Java/api.mustache | 2 +- .../main/resources/android-java/api.mustache | 2 +- .../java/io/swagger/client/model/Pet.java | 2 +- .../java/io/swagger/client/api/PetApi.java | 416 +++++++++--------- 4 files changed, 211 insertions(+), 211 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache index 63357afd896..ae4d1cb431e 100644 --- a/modules/swagger-codegen/src/main/resources/Java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache @@ -58,7 +58,7 @@ public class {{classname}} { // create path and map variables String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}} - .replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + .replaceAll("\\{" + "{{baseName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params Map queryParams = new HashMap(); diff --git a/modules/swagger-codegen/src/main/resources/android-java/api.mustache b/modules/swagger-codegen/src/main/resources/android-java/api.mustache index ed9538c1594..b7c99ebf6be 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/api.mustache @@ -55,7 +55,7 @@ public class {{classname}} { {{/required}}{{/allParams}} // create path and map variables - String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}}; + String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{baseName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params Map queryParams = new HashMap(); diff --git a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java index 26219b16a45..90a840e6e42 100644 --- a/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java +++ b/samples/client/petstore/android-java/src/main/java/io/swagger/client/model/Pet.java @@ -1,8 +1,8 @@ package io.swagger.client.model; import io.swagger.client.model.Category; -import java.util.*; import io.swagger.client.model.Tag; +import java.util.*; import io.swagger.annotations.*; import com.google.gson.annotations.SerializedName; diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index bc793fd41ee..613803b4352 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -272,214 +272,6 @@ public class PetApi { } } - /** - * Find pet by ID - * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - * @param petId ID of pet that needs to be fetched - * @return Pet - */ - public Pet getPetById (Long petId) throws ApiException { - Object postBody = null; - - // verify the required parameter 'petId' is set - if (petId == null) { - throw new ApiException(400, "Missing the required parameter 'petId' when calling getPetById"); - } - - - // create path and map variables - String path = "/pet/{petId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); - - // query params - Map queryParams = new HashMap(); - Map headerParams = new HashMap(); - Map formParams = new HashMap(); - - - - - - final String[] accepts = { - "application/json", "application/xml" - }; - final String accept = apiClient.selectHeaderAccept(accepts); - - final String[] contentTypes = { - - }; - final String contentType = apiClient.selectHeaderContentType(contentTypes); - - if(contentType.startsWith("multipart/form-data")) { - boolean hasFields = false; - FormDataMultiPart mp = new FormDataMultiPart(); - - if(hasFields) - postBody = mp; - } - else { - - } - - try { - String[] authNames = new String[] { "api_key", "petstore_auth" }; - String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); - if(response != null){ - return (Pet) apiClient.deserialize(response, "", Pet.class); - } - else { - return null; - } - } catch (ApiException ex) { - throw ex; - } - } - - /** - * Updates a pet in the store with form data - * - * @param petId ID of pet that needs to be updated - * @param name Updated name of the pet - * @param status Updated status of the pet - * @return void - */ - public void updatePetWithForm (String petId, String name, String status) throws ApiException { - Object postBody = null; - - // verify the required parameter 'petId' is set - if (petId == null) { - throw new ApiException(400, "Missing the required parameter 'petId' when calling updatePetWithForm"); - } - - - // create path and map variables - String path = "/pet/{petId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); - - // query params - Map queryParams = new HashMap(); - Map headerParams = new HashMap(); - Map formParams = new HashMap(); - - - - - - final String[] accepts = { - "application/json", "application/xml" - }; - final String accept = apiClient.selectHeaderAccept(accepts); - - final String[] contentTypes = { - "application/x-www-form-urlencoded" - }; - final String contentType = apiClient.selectHeaderContentType(contentTypes); - - if(contentType.startsWith("multipart/form-data")) { - boolean hasFields = false; - FormDataMultiPart mp = new FormDataMultiPart(); - - if (name != null) { - hasFields = true; - mp.field("name", apiClient.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE); - } - - if (status != null) { - hasFields = true; - mp.field("status", apiClient.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE); - } - - if(hasFields) - postBody = mp; - } - else { - if (name != null) - formParams.put("name", apiClient.parameterToString(name)); - if (status != null) - formParams.put("status", apiClient.parameterToString(status)); - - } - - try { - String[] authNames = new String[] { "petstore_auth" }; - String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); - if(response != null){ - return ; - } - else { - return ; - } - } catch (ApiException ex) { - throw ex; - } - } - - /** - * Deletes a pet - * - * @param apiKey - * @param petId Pet id to delete - * @return void - */ - public void deletePet (String apiKey, Long petId) throws ApiException { - Object postBody = null; - - // verify the required parameter 'petId' is set - if (petId == null) { - throw new ApiException(400, "Missing the required parameter 'petId' when calling deletePet"); - } - - - // create path and map variables - String path = "/pet/{petId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); - - // query params - Map queryParams = new HashMap(); - Map headerParams = new HashMap(); - Map formParams = new HashMap(); - - - - if (apiKey != null) - headerParams.put("api_key", apiClient.parameterToString(apiKey)); - - - final String[] accepts = { - "application/json", "application/xml" - }; - final String accept = apiClient.selectHeaderAccept(accepts); - - final String[] contentTypes = { - - }; - final String contentType = apiClient.selectHeaderContentType(contentTypes); - - if(contentType.startsWith("multipart/form-data")) { - boolean hasFields = false; - FormDataMultiPart mp = new FormDataMultiPart(); - - if(hasFields) - postBody = mp; - } - else { - - } - - try { - String[] authNames = new String[] { "petstore_auth" }; - String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); - if(response != null){ - return ; - } - else { - return ; - } - } catch (ApiException ex) { - throw ex; - } - } - /** * uploads an image * @@ -559,4 +351,212 @@ public class PetApi { } } + /** + * Find pet by ID + * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + * @param petId ID of pet that needs to be fetched + * @return Pet + */ + public Pet getPetById (Long petId) throws ApiException { + Object postBody = null; + + // verify the required parameter 'petId' is set + if (petId == null) { + throw new ApiException(400, "Missing the required parameter 'petId' when calling getPetById"); + } + + + // create path and map variables + String path = "/pet/{pet_id}".replaceAll("\\{format\\}","json") + .replaceAll("\\{" + "pet_id" + "\\}", apiClient.escapeString(petId.toString())); + + // query params + Map queryParams = new HashMap(); + Map headerParams = new HashMap(); + Map formParams = new HashMap(); + + + + + + final String[] accepts = { + "application/json", "application/xml" + }; + final String accept = apiClient.selectHeaderAccept(accepts); + + final String[] contentTypes = { + + }; + final String contentType = apiClient.selectHeaderContentType(contentTypes); + + if(contentType.startsWith("multipart/form-data")) { + boolean hasFields = false; + FormDataMultiPart mp = new FormDataMultiPart(); + + if(hasFields) + postBody = mp; + } + else { + + } + + try { + String[] authNames = new String[] { "api_key", "petstore_auth" }; + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); + if(response != null){ + return (Pet) apiClient.deserialize(response, "", Pet.class); + } + else { + return null; + } + } catch (ApiException ex) { + throw ex; + } + } + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet + * @param status Updated status of the pet + * @return void + */ + public void updatePetWithForm (String petId, String name, String status) throws ApiException { + Object postBody = null; + + // verify the required parameter 'petId' is set + if (petId == null) { + throw new ApiException(400, "Missing the required parameter 'petId' when calling updatePetWithForm"); + } + + + // create path and map variables + String path = "/pet/{pet_id}".replaceAll("\\{format\\}","json") + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); + + // query params + Map queryParams = new HashMap(); + Map headerParams = new HashMap(); + Map formParams = new HashMap(); + + + + + + final String[] accepts = { + "application/json", "application/xml" + }; + final String accept = apiClient.selectHeaderAccept(accepts); + + final String[] contentTypes = { + "application/x-www-form-urlencoded" + }; + final String contentType = apiClient.selectHeaderContentType(contentTypes); + + if(contentType.startsWith("multipart/form-data")) { + boolean hasFields = false; + FormDataMultiPart mp = new FormDataMultiPart(); + + if (name != null) { + hasFields = true; + mp.field("name", apiClient.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE); + } + + if (status != null) { + hasFields = true; + mp.field("status", apiClient.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE); + } + + if(hasFields) + postBody = mp; + } + else { + if (name != null) + formParams.put("name", apiClient.parameterToString(name)); + if (status != null) + formParams.put("status", apiClient.parameterToString(status)); + + } + + try { + String[] authNames = new String[] { "petstore_auth" }; + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + throw ex; + } + } + + /** + * Deletes a pet + * + * @param apiKey + * @param petId Pet id to delete + * @return void + */ + public void deletePet (String apiKey, Long petId) throws ApiException { + Object postBody = null; + + // verify the required parameter 'petId' is set + if (petId == null) { + throw new ApiException(400, "Missing the required parameter 'petId' when calling deletePet"); + } + + + // create path and map variables + String path = "/pet/{pet_id}".replaceAll("\\{format\\}","json") + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); + + // query params + Map queryParams = new HashMap(); + Map headerParams = new HashMap(); + Map formParams = new HashMap(); + + + + if (apiKey != null) + headerParams.put("api_key", apiClient.parameterToString(apiKey)); + + + final String[] accepts = { + "application/json", "application/xml" + }; + final String accept = apiClient.selectHeaderAccept(accepts); + + final String[] contentTypes = { + + }; + final String contentType = apiClient.selectHeaderContentType(contentTypes); + + if(contentType.startsWith("multipart/form-data")) { + boolean hasFields = false; + FormDataMultiPart mp = new FormDataMultiPart(); + + if(hasFields) + postBody = mp; + } + else { + + } + + try { + String[] authNames = new String[] { "petstore_auth" }; + String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + throw ex; + } + } + } From 091e76703ceb3b7eb52a8e9cfb0f8956c7947aa2 Mon Sep 17 00:00:00 2001 From: wing328 Date: Fri, 26 Jun 2015 10:35:50 +0800 Subject: [PATCH 164/499] update sample --- .../java/io/swagger/client/api/PetApi.java | 416 +++++++++--------- 1 file changed, 208 insertions(+), 208 deletions(-) diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index 613803b4352..bc793fd41ee 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -272,6 +272,214 @@ public class PetApi { } } + /** + * Find pet by ID + * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + * @param petId ID of pet that needs to be fetched + * @return Pet + */ + public Pet getPetById (Long petId) throws ApiException { + Object postBody = null; + + // verify the required parameter 'petId' is set + if (petId == null) { + throw new ApiException(400, "Missing the required parameter 'petId' when calling getPetById"); + } + + + // create path and map variables + String path = "/pet/{petId}".replaceAll("\\{format\\}","json") + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); + + // query params + Map queryParams = new HashMap(); + Map headerParams = new HashMap(); + Map formParams = new HashMap(); + + + + + + final String[] accepts = { + "application/json", "application/xml" + }; + final String accept = apiClient.selectHeaderAccept(accepts); + + final String[] contentTypes = { + + }; + final String contentType = apiClient.selectHeaderContentType(contentTypes); + + if(contentType.startsWith("multipart/form-data")) { + boolean hasFields = false; + FormDataMultiPart mp = new FormDataMultiPart(); + + if(hasFields) + postBody = mp; + } + else { + + } + + try { + String[] authNames = new String[] { "api_key", "petstore_auth" }; + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); + if(response != null){ + return (Pet) apiClient.deserialize(response, "", Pet.class); + } + else { + return null; + } + } catch (ApiException ex) { + throw ex; + } + } + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet + * @param status Updated status of the pet + * @return void + */ + public void updatePetWithForm (String petId, String name, String status) throws ApiException { + Object postBody = null; + + // verify the required parameter 'petId' is set + if (petId == null) { + throw new ApiException(400, "Missing the required parameter 'petId' when calling updatePetWithForm"); + } + + + // create path and map variables + String path = "/pet/{petId}".replaceAll("\\{format\\}","json") + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); + + // query params + Map queryParams = new HashMap(); + Map headerParams = new HashMap(); + Map formParams = new HashMap(); + + + + + + final String[] accepts = { + "application/json", "application/xml" + }; + final String accept = apiClient.selectHeaderAccept(accepts); + + final String[] contentTypes = { + "application/x-www-form-urlencoded" + }; + final String contentType = apiClient.selectHeaderContentType(contentTypes); + + if(contentType.startsWith("multipart/form-data")) { + boolean hasFields = false; + FormDataMultiPart mp = new FormDataMultiPart(); + + if (name != null) { + hasFields = true; + mp.field("name", apiClient.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE); + } + + if (status != null) { + hasFields = true; + mp.field("status", apiClient.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE); + } + + if(hasFields) + postBody = mp; + } + else { + if (name != null) + formParams.put("name", apiClient.parameterToString(name)); + if (status != null) + formParams.put("status", apiClient.parameterToString(status)); + + } + + try { + String[] authNames = new String[] { "petstore_auth" }; + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + throw ex; + } + } + + /** + * Deletes a pet + * + * @param apiKey + * @param petId Pet id to delete + * @return void + */ + public void deletePet (String apiKey, Long petId) throws ApiException { + Object postBody = null; + + // verify the required parameter 'petId' is set + if (petId == null) { + throw new ApiException(400, "Missing the required parameter 'petId' when calling deletePet"); + } + + + // create path and map variables + String path = "/pet/{petId}".replaceAll("\\{format\\}","json") + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); + + // query params + Map queryParams = new HashMap(); + Map headerParams = new HashMap(); + Map formParams = new HashMap(); + + + + if (apiKey != null) + headerParams.put("api_key", apiClient.parameterToString(apiKey)); + + + final String[] accepts = { + "application/json", "application/xml" + }; + final String accept = apiClient.selectHeaderAccept(accepts); + + final String[] contentTypes = { + + }; + final String contentType = apiClient.selectHeaderContentType(contentTypes); + + if(contentType.startsWith("multipart/form-data")) { + boolean hasFields = false; + FormDataMultiPart mp = new FormDataMultiPart(); + + if(hasFields) + postBody = mp; + } + else { + + } + + try { + String[] authNames = new String[] { "petstore_auth" }; + String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + throw ex; + } + } + /** * uploads an image * @@ -351,212 +559,4 @@ public class PetApi { } } - /** - * Find pet by ID - * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - * @param petId ID of pet that needs to be fetched - * @return Pet - */ - public Pet getPetById (Long petId) throws ApiException { - Object postBody = null; - - // verify the required parameter 'petId' is set - if (petId == null) { - throw new ApiException(400, "Missing the required parameter 'petId' when calling getPetById"); - } - - - // create path and map variables - String path = "/pet/{pet_id}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "pet_id" + "\\}", apiClient.escapeString(petId.toString())); - - // query params - Map queryParams = new HashMap(); - Map headerParams = new HashMap(); - Map formParams = new HashMap(); - - - - - - final String[] accepts = { - "application/json", "application/xml" - }; - final String accept = apiClient.selectHeaderAccept(accepts); - - final String[] contentTypes = { - - }; - final String contentType = apiClient.selectHeaderContentType(contentTypes); - - if(contentType.startsWith("multipart/form-data")) { - boolean hasFields = false; - FormDataMultiPart mp = new FormDataMultiPart(); - - if(hasFields) - postBody = mp; - } - else { - - } - - try { - String[] authNames = new String[] { "api_key", "petstore_auth" }; - String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); - if(response != null){ - return (Pet) apiClient.deserialize(response, "", Pet.class); - } - else { - return null; - } - } catch (ApiException ex) { - throw ex; - } - } - - /** - * Updates a pet in the store with form data - * - * @param petId ID of pet that needs to be updated - * @param name Updated name of the pet - * @param status Updated status of the pet - * @return void - */ - public void updatePetWithForm (String petId, String name, String status) throws ApiException { - Object postBody = null; - - // verify the required parameter 'petId' is set - if (petId == null) { - throw new ApiException(400, "Missing the required parameter 'petId' when calling updatePetWithForm"); - } - - - // create path and map variables - String path = "/pet/{pet_id}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); - - // query params - Map queryParams = new HashMap(); - Map headerParams = new HashMap(); - Map formParams = new HashMap(); - - - - - - final String[] accepts = { - "application/json", "application/xml" - }; - final String accept = apiClient.selectHeaderAccept(accepts); - - final String[] contentTypes = { - "application/x-www-form-urlencoded" - }; - final String contentType = apiClient.selectHeaderContentType(contentTypes); - - if(contentType.startsWith("multipart/form-data")) { - boolean hasFields = false; - FormDataMultiPart mp = new FormDataMultiPart(); - - if (name != null) { - hasFields = true; - mp.field("name", apiClient.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE); - } - - if (status != null) { - hasFields = true; - mp.field("status", apiClient.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE); - } - - if(hasFields) - postBody = mp; - } - else { - if (name != null) - formParams.put("name", apiClient.parameterToString(name)); - if (status != null) - formParams.put("status", apiClient.parameterToString(status)); - - } - - try { - String[] authNames = new String[] { "petstore_auth" }; - String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); - if(response != null){ - return ; - } - else { - return ; - } - } catch (ApiException ex) { - throw ex; - } - } - - /** - * Deletes a pet - * - * @param apiKey - * @param petId Pet id to delete - * @return void - */ - public void deletePet (String apiKey, Long petId) throws ApiException { - Object postBody = null; - - // verify the required parameter 'petId' is set - if (petId == null) { - throw new ApiException(400, "Missing the required parameter 'petId' when calling deletePet"); - } - - - // create path and map variables - String path = "/pet/{pet_id}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); - - // query params - Map queryParams = new HashMap(); - Map headerParams = new HashMap(); - Map formParams = new HashMap(); - - - - if (apiKey != null) - headerParams.put("api_key", apiClient.parameterToString(apiKey)); - - - final String[] accepts = { - "application/json", "application/xml" - }; - final String accept = apiClient.selectHeaderAccept(accepts); - - final String[] contentTypes = { - - }; - final String contentType = apiClient.selectHeaderContentType(contentTypes); - - if(contentType.startsWith("multipart/form-data")) { - boolean hasFields = false; - FormDataMultiPart mp = new FormDataMultiPart(); - - if(hasFields) - postBody = mp; - } - else { - - } - - try { - String[] authNames = new String[] { "petstore_auth" }; - String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, accept, contentType, authNames); - if(response != null){ - return ; - } - else { - return ; - } - } catch (ApiException ex) { - throw ex; - } - } - } From 16e80c65d7bf103c12f0100d446c5acfd7144917 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 15:56:59 +0800 Subject: [PATCH 165/499] Avoiding monkey-patching in Ruby API client --- .../src/main/resources/ruby/monkey.mustache | 51 -------- .../src/main/resources/ruby/swagger.mustache | 4 +- .../ruby/swagger/configuration.mustache | 3 +- .../resources/ruby/swagger/request.mustache | 111 ++++-------------- .../resources/ruby/swagger/response.mustache | 10 +- .../ruby/swagger_client.gemspec.mustache | 1 - 6 files changed, 29 insertions(+), 151 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache index 0751d42ce63..2f5b96f884f 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache @@ -1,39 +1,3 @@ -class Object - unless Object.method_defined? :blank? - def blank? - respond_to?(:empty?) ? empty? : !self - end - end - - unless Object.method_defined? :present? - def present? - !blank? - end - end -end - -class String - unless String.method_defined? :underscore - def underscore - self.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end - - unless String.method_defined? :camelize - def camelize(first_letter_in_uppercase = true) - if first_letter_in_uppercase != :lower - self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } - else - self.to_s[0].chr.downcase + camelize(self)[1..-1] - end - end - end -end - class Hash unless Hash.method_defined? :stringify_keys def stringify_keys @@ -64,19 +28,4 @@ class Hash self.replace(self.symbolize_keys) end end - - unless Hash.method_defined? :symbolize_and_underscore_keys - def symbolize_and_underscore_keys - inject({}) do |options, (key, value)| - options[(key.to_s.underscore.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys! - def symbolize_and_underscore_keys! - self.replace(self.symbolize_and_underscore_keys) - end - end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index f07bdec9c50..e11301327e0 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -37,7 +37,7 @@ module {{moduleName}} end def authenticated? - Swagger.configuration.auth_token.present? + !Swagger.configuration.auth_token.nil? end def de_authenticate @@ -47,7 +47,7 @@ module {{moduleName}} def authenticate return if Swagger.authenticated? - if Swagger.configuration.username.blank? || Swagger.configuration.password.blank? + if Swagger.configuration.username.nil? || Swagger.configuration.password.nil? raise ApiError, "Username and password are required to authenticate." end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index 1c7cb52c50f..0e693b23715 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -3,7 +3,7 @@ require 'logger' module {{moduleName}} module Swagger class Configuration - attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format, :camelize_params + attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format # Defines the username used with HTTP basic authentication. # @@ -69,7 +69,6 @@ module {{moduleName}} @user_agent = "ruby-swagger-#{Swagger::VERSION}" @inject_format = false @force_ending_format = false - @camelize_params = true @api_key = {} @api_key_prefix = {} diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index c05167c7fdc..bd5b2991cab 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -1,15 +1,14 @@ +require 'uri' +require 'typhoeus' + module {{moduleName}} module Swagger class Request - require 'uri' - require 'addressable/uri' - require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names, :response # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host - def initialize(http_method, path, attributes={}) + def initialize(http_method, path, attributes = {}) attributes[:format] ||= Swagger.configuration.format attributes[:params] ||= {} @@ -27,11 +26,10 @@ module {{moduleName}} attributes[:headers].merge!({:auth_token => Swagger.configuration.auth_token}) end - self.http_method = http_method.to_sym + self.http_method = http_method.to_sym.downcase self.path = path - attributes.each do |name, value| - send("#{name.to_s.underscore.to_sym}=", value) - end + + attributes.each { |name, value| send "#{name}=", value } update_params_for_auth! end @@ -54,26 +52,18 @@ module {{moduleName}} # Get API key (with prefix if set). # @param [String] param_name the parameter name of API key auth def get_api_key_with_prefix(param_name) - if Swagger.configuration.api_key_prefix[param_name].present? + if Swagger.configuration.api_key_prefix[param_name] "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" else Swagger.configuration.api_key[param_name] end end - # Construct a base URL + # Construct the request URL. def url(options = {}) - u = Addressable::URI.new( - :scheme => Swagger.configuration.scheme, - :host => Swagger.configuration.host, - :path => self.interpreted_path, - :query => self.query_string.sub(/\?/, '') - ).to_s - - # Drop trailing question mark, if present - u.sub! /\?$/, '' - - u + _path = self.interpreted_path + _path = "/#{_path}" unless _path.start_with?('/') + "#{Swagger.configuration.scheme}://#{Swagger.configuration.host}#{_path}" end # Iterate over the params hash, injecting any path values into the path string @@ -104,18 +94,6 @@ module {{moduleName}} URI.encode [Swagger.configuration.base_path, p].join("/").gsub(/\/+/, '/') end - # Massage the request body into a state of readiness - # If body is a hash, camelize all keys then convert to a json string - def body=(value) - if value.is_a?(Hash) - value = value.inject({}) do |memo, (k,v)| - memo[k.to_s.camelize(:lower).to_sym] = v - memo - end - end - @body = value - end - # If body is an object, JSONify it before making the actual request. # For form parameters, remove empty value def outgoing_body @@ -138,70 +116,20 @@ module {{moduleName}} data end - # Construct a query string from the query-string-type params - def query_string - # Iterate over all params, - # .. removing the ones that are part of the path itself. - # .. stringifying values so Addressable doesn't blow up. - query_values = {} - self.params.each_pair do |key, value| - next if self.path.include? "{#{key}}" # skip path params - next if value.blank? && value.class != FalseClass # skip empties - if Swagger.configuration.camelize_params - key = key.to_s.camelize(:lower).to_sym - end - query_values[key] = value.to_s - end - - # We don't want to end up with '?' as our query string - # if there aren't really any params - return "" if query_values.blank? - - # Addressable requires query_values to be set after initialization.. - qs = Addressable::URI.new - qs.query_values = query_values - qs.to_s - end - def make request_options = { + :method => self.http_method, + :headers => self.headers.stringify_keys, :ssl_verifypeer => Swagger.configuration.verify_ssl, :cainfo => Swagger.configuration.ssl_ca_cert, - :headers => self.headers.stringify_keys, :verbose => Swagger.configuration.debug } - raw = case self.http_method.to_sym - when :get,:GET - Typhoeus::Request.get( - self.url, - request_options - ) - when :post,:POST - Typhoeus::Request.post( - self.url, - request_options.merge(:body => self.outgoing_body) - ) - - when :patch,:PATCH - Typhoeus::Request.patch( - self.url, - request_options.merge(:body => self.outgoing_body) - ) - - when :put,:PUT - Typhoeus::Request.put( - self.url, - request_options.merge(:body => self.outgoing_body) - ) - - when :delete,:DELETE - Typhoeus::Request.delete( - self.url, - request_options.merge(:body => self.outgoing_body) - ) + if [:post, :patch, :put, :delete].include?(self.http_method) + request_options.update :body => self.outgoing_body end + raw = Typhoeus::Request.new(self.url, request_options).run @response = Response.new(raw) if Swagger.configuration.debug @@ -217,16 +145,17 @@ module {{moduleName}} :response_body => @response.body), @response.status_message end + @response end def response_code_pretty - return unless @response.present? + return unless @response @response.code.to_s end def response_headers_pretty - return unless @response.present? + return unless @response # JSON.pretty_generate(@response.headers).gsub(/\n/, '
') # <- This was for RestClient @response.headers.gsub(/\n/, '
') # <- This is for Typhoeus end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index d712aa29540..575bc5d0ae0 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -30,7 +30,7 @@ module {{moduleName}} # # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" def deserialize(return_type) - return nil if body.blank? + return nil if body.nil? || body.empty? # ensuring a default content type content_type = raw.headers_hash['Content-Type'] || 'application/json' @@ -106,9 +106,11 @@ module {{moduleName}} end def pretty_body - return unless body.present? - case format - when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') + return unless body + if format == 'json' + JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') + else + body end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.gemspec.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.gemspec.mustache index 8ae4bfa1a49..38d70c07dd5 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.gemspec.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.gemspec.mustache @@ -14,7 +14,6 @@ Gem::Specification.new do |s| s.license = "Apache-2.0" s.add_runtime_dependency 'typhoeus', '~> 0.2', '>= 0.2.1' - s.add_runtime_dependency 'addressable', '~> 2.2', '>= 2.2.4' s.add_runtime_dependency 'json', '~> 1.4', '>= 1.4.6' s.add_development_dependency 'rspec', '~> 3.2', '>= 3.2.0' From 327128dbba56afca635548b7edffe8959ef76377 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 15:57:46 +0800 Subject: [PATCH 166/499] Fix "date" type deserialization --- .../java/io/swagger/codegen/languages/RubyClientCodegen.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index c3c78710682..e7260d525d1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -55,6 +55,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("float", "Float"); typeMapping.put("double", "Float"); typeMapping.put("number", "Float"); + typeMapping.put("date", "DateTime"); typeMapping.put("DateTime", "DateTime"); typeMapping.put("boolean", "BOOLEAN"); typeMapping.put("array", "Array"); From 0ac1ef266f56fab222eb5868d4f5a569f41a36ba Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 16:04:18 +0800 Subject: [PATCH 167/499] Avoid more monkey-patching --- .../codegen/languages/RubyClientCodegen.java | 1 - .../src/main/resources/ruby/monkey.mustache | 31 ------------------- .../resources/ruby/swagger/request.mustache | 2 +- .../resources/ruby/swagger_client.mustache | 1 - 4 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/ruby/monkey.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index e7260d525d1..0ea0be21a78 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -107,7 +107,6 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec")); supportingFiles.add(new SupportingFile("swagger_client.mustache", libFolder, gemName + ".rb")); String baseFolder = libFolder + File.separator + gemName; - supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb")); supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb")); String swaggerFolder = baseFolder + File.separator + "swagger"; supportingFiles.add(new SupportingFile("swagger" + File.separator + "request.mustache", swaggerFolder, "request.rb")); diff --git a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache deleted file mode 100644 index 2f5b96f884f..00000000000 --- a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache +++ /dev/null @@ -1,31 +0,0 @@ -class Hash - unless Hash.method_defined? :stringify_keys - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end - end - end - - unless Hash.method_defined? :stringify_keys! - def stringify_keys! - self.replace(self.stringify_keys) - end - end - - unless Hash.method_defined? :symbolize_keys - def symbolize_keys - inject({}) do |options, (key, value)| - options[(key.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_keys! - def symbolize_keys! - self.replace(self.symbolize_keys) - end - end -end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index bd5b2991cab..decf7aa7708 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -119,7 +119,7 @@ module {{moduleName}} def make request_options = { :method => self.http_method, - :headers => self.headers.stringify_keys, + :headers => self.headers, :ssl_verifypeer => Swagger.configuration.verify_ssl, :cainfo => Swagger.configuration.ssl_ca_cert, :verbose => Swagger.configuration.debug diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache index 0be00aaec95..4ed0839f6eb 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache @@ -1,5 +1,4 @@ # Swagger common files -require '{{gemName}}/monkey' require '{{gemName}}/swagger' require '{{gemName}}/swagger/configuration' require '{{gemName}}/swagger/api_error' From 8c10e4f2b0e4f1bea678cf9871f38f05b80110a0 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 16:06:32 +0800 Subject: [PATCH 168/499] Remove unused code --- modules/swagger-codegen/src/main/resources/ruby/api.mustache | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index af87882fbe1..76a44659f81 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -3,8 +3,6 @@ require "uri" module {{moduleName}} {{#operations}} class {{classname}} - basePath = "{{basePath}}" - # apiInvoker = APIInvoker {{#operation}} {{newline}} # {{summary}} From 2d3d35cfd796642c80226d5e55f9eb270c5c6f17 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 16:37:58 +0800 Subject: [PATCH 169/499] Rebuild Ruby petstore client --- .../resources/ruby/swagger/request.mustache | 1 + samples/client/petstore/ruby/Gemfile.lock | 1 - .../petstore/ruby/lib/swagger_client.rb | 1 - .../ruby/lib/swagger_client/api/pet_api.rb | 2 - .../ruby/lib/swagger_client/api/store_api.rb | 2 - .../ruby/lib/swagger_client/api/user_api.rb | 2 - .../ruby/lib/swagger_client/monkey.rb | 82 ------------- .../ruby/lib/swagger_client/swagger.rb | 4 +- .../swagger_client/swagger/configuration.rb | 3 +- .../lib/swagger_client/swagger/request.rb | 112 ++++-------------- .../lib/swagger_client/swagger/response.rb | 10 +- .../client/petstore/ruby/spec/monkey_spec.rb | 33 ------ .../client/petstore/ruby/spec/request_spec.rb | 80 +------------ .../petstore/ruby/swagger_client.gemspec | 1 - 14 files changed, 33 insertions(+), 301 deletions(-) delete mode 100644 samples/client/petstore/ruby/lib/swagger_client/monkey.rb delete mode 100644 samples/client/petstore/ruby/spec/monkey_spec.rb diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index decf7aa7708..8f07e5ab66c 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -120,6 +120,7 @@ module {{moduleName}} request_options = { :method => self.http_method, :headers => self.headers, + :params => self.params, :ssl_verifypeer => Swagger.configuration.verify_ssl, :cainfo => Swagger.configuration.ssl_ca_cert, :verbose => Swagger.configuration.debug diff --git a/samples/client/petstore/ruby/Gemfile.lock b/samples/client/petstore/ruby/Gemfile.lock index e9e03f10b77..1b69e10f1fd 100644 --- a/samples/client/petstore/ruby/Gemfile.lock +++ b/samples/client/petstore/ruby/Gemfile.lock @@ -2,7 +2,6 @@ PATH remote: . specs: swagger_client (1.0.0) - addressable (~> 2.2, >= 2.2.4) json (~> 1.4, >= 1.4.6) typhoeus (~> 0.2, >= 0.2.1) diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 42380927f82..f91c8912d98 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -1,5 +1,4 @@ # Swagger common files -require 'swagger_client/monkey' require 'swagger_client/swagger' require 'swagger_client/swagger/configuration' require 'swagger_client/swagger/api_error' diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 8ec023a6f77..4b3e6bb6a50 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -2,8 +2,6 @@ require "uri" module SwaggerClient class PetApi - basePath = "http://petstore.swagger.io/v2" - # apiInvoker = APIInvoker # Update an existing pet # diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb index 7581c4d36d6..47e81d5af1c 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb @@ -2,8 +2,6 @@ require "uri" module SwaggerClient class StoreApi - basePath = "http://petstore.swagger.io/v2" - # apiInvoker = APIInvoker # Returns pet inventories by status # Returns a map of status codes to quantities diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb index 48407491fba..7d91c0bfd3d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb @@ -2,8 +2,6 @@ require "uri" module SwaggerClient class UserApi - basePath = "http://petstore.swagger.io/v2" - # apiInvoker = APIInvoker # Create user # This can only be done by the logged in user. diff --git a/samples/client/petstore/ruby/lib/swagger_client/monkey.rb b/samples/client/petstore/ruby/lib/swagger_client/monkey.rb deleted file mode 100644 index 0751d42ce63..00000000000 --- a/samples/client/petstore/ruby/lib/swagger_client/monkey.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Object - unless Object.method_defined? :blank? - def blank? - respond_to?(:empty?) ? empty? : !self - end - end - - unless Object.method_defined? :present? - def present? - !blank? - end - end -end - -class String - unless String.method_defined? :underscore - def underscore - self.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end - - unless String.method_defined? :camelize - def camelize(first_letter_in_uppercase = true) - if first_letter_in_uppercase != :lower - self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } - else - self.to_s[0].chr.downcase + camelize(self)[1..-1] - end - end - end -end - -class Hash - unless Hash.method_defined? :stringify_keys - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end - end - end - - unless Hash.method_defined? :stringify_keys! - def stringify_keys! - self.replace(self.stringify_keys) - end - end - - unless Hash.method_defined? :symbolize_keys - def symbolize_keys - inject({}) do |options, (key, value)| - options[(key.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_keys! - def symbolize_keys! - self.replace(self.symbolize_keys) - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys - def symbolize_and_underscore_keys - inject({}) do |options, (key, value)| - options[(key.to_s.underscore.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys! - def symbolize_and_underscore_keys! - self.replace(self.symbolize_and_underscore_keys) - end - end -end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index 285d92ae2c7..bf69f05b23a 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -37,7 +37,7 @@ module SwaggerClient end def authenticated? - Swagger.configuration.auth_token.present? + !Swagger.configuration.auth_token.nil? end def de_authenticate @@ -47,7 +47,7 @@ module SwaggerClient def authenticate return if Swagger.authenticated? - if Swagger.configuration.username.blank? || Swagger.configuration.password.blank? + if Swagger.configuration.username.nil? || Swagger.configuration.password.nil? raise ApiError, "Username and password are required to authenticate." end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index 50fe6a0bcc0..8811c44b4df 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -3,7 +3,7 @@ require 'logger' module SwaggerClient module Swagger class Configuration - attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format, :camelize_params + attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format # Defines the username used with HTTP basic authentication. # @@ -69,7 +69,6 @@ module SwaggerClient @user_agent = "ruby-swagger-#{Swagger::VERSION}" @inject_format = false @force_ending_format = false - @camelize_params = true @api_key = {} @api_key_prefix = {} diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index df0987b0d22..8b0276d356a 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -1,15 +1,14 @@ +require 'uri' +require 'typhoeus' + module SwaggerClient module Swagger class Request - require 'uri' - require 'addressable/uri' - require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names, :response # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host - def initialize(http_method, path, attributes={}) + def initialize(http_method, path, attributes = {}) attributes[:format] ||= Swagger.configuration.format attributes[:params] ||= {} @@ -27,11 +26,10 @@ module SwaggerClient attributes[:headers].merge!({:auth_token => Swagger.configuration.auth_token}) end - self.http_method = http_method.to_sym + self.http_method = http_method.to_sym.downcase self.path = path - attributes.each do |name, value| - send("#{name.to_s.underscore.to_sym}=", value) - end + + attributes.each { |name, value| send "#{name}=", value } update_params_for_auth! end @@ -53,26 +51,18 @@ module SwaggerClient # Get API key (with prefix if set). # @param [String] param_name the parameter name of API key auth def get_api_key_with_prefix(param_name) - if Swagger.configuration.api_key_prefix[param_name].present? + if Swagger.configuration.api_key_prefix[param_name] "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" else Swagger.configuration.api_key[param_name] end end - # Construct a base URL + # Construct the request URL. def url(options = {}) - u = Addressable::URI.new( - :scheme => Swagger.configuration.scheme, - :host => Swagger.configuration.host, - :path => self.interpreted_path, - :query => self.query_string.sub(/\?/, '') - ).to_s - - # Drop trailing question mark, if present - u.sub! /\?$/, '' - - u + _path = self.interpreted_path + _path = "/#{_path}" unless _path.start_with?('/') + "#{Swagger.configuration.scheme}://#{Swagger.configuration.host}#{_path}" end # Iterate over the params hash, injecting any path values into the path string @@ -103,18 +93,6 @@ module SwaggerClient URI.encode [Swagger.configuration.base_path, p].join("/").gsub(/\/+/, '/') end - # Massage the request body into a state of readiness - # If body is a hash, camelize all keys then convert to a json string - def body=(value) - if value.is_a?(Hash) - value = value.inject({}) do |memo, (k,v)| - memo[k.to_s.camelize(:lower).to_sym] = v - memo - end - end - @body = value - end - # If body is an object, JSONify it before making the actual request. # For form parameters, remove empty value def outgoing_body @@ -137,70 +115,21 @@ module SwaggerClient data end - # Construct a query string from the query-string-type params - def query_string - # Iterate over all params, - # .. removing the ones that are part of the path itself. - # .. stringifying values so Addressable doesn't blow up. - query_values = {} - self.params.each_pair do |key, value| - next if self.path.include? "{#{key}}" # skip path params - next if value.blank? && value.class != FalseClass # skip empties - if Swagger.configuration.camelize_params - key = key.to_s.camelize(:lower).to_sym - end - query_values[key] = value.to_s - end - - # We don't want to end up with '?' as our query string - # if there aren't really any params - return "" if query_values.blank? - - # Addressable requires query_values to be set after initialization.. - qs = Addressable::URI.new - qs.query_values = query_values - qs.to_s - end - def make request_options = { + :method => self.http_method, + :headers => self.headers, + :params => self.params, :ssl_verifypeer => Swagger.configuration.verify_ssl, :cainfo => Swagger.configuration.ssl_ca_cert, - :headers => self.headers.stringify_keys, :verbose => Swagger.configuration.debug } - raw = case self.http_method.to_sym - when :get,:GET - Typhoeus::Request.get( - self.url, - request_options - ) - when :post,:POST - Typhoeus::Request.post( - self.url, - request_options.merge(:body => self.outgoing_body) - ) - - when :patch,:PATCH - Typhoeus::Request.patch( - self.url, - request_options.merge(:body => self.outgoing_body) - ) - - when :put,:PUT - Typhoeus::Request.put( - self.url, - request_options.merge(:body => self.outgoing_body) - ) - - when :delete,:DELETE - Typhoeus::Request.delete( - self.url, - request_options.merge(:body => self.outgoing_body) - ) + if [:post, :patch, :put, :delete].include?(self.http_method) + request_options.update :body => self.outgoing_body end + raw = Typhoeus::Request.new(self.url, request_options).run @response = Response.new(raw) if Swagger.configuration.debug @@ -216,16 +145,17 @@ module SwaggerClient :response_body => @response.body), @response.status_message end + @response end def response_code_pretty - return unless @response.present? + return unless @response @response.code.to_s end def response_headers_pretty - return unless @response.present? + return unless @response # JSON.pretty_generate(@response.headers).gsub(/\n/, '
') # <- This was for RestClient @response.headers.gsub(/\n/, '
') # <- This is for Typhoeus end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 61d899e1f3b..0df6c2e54cd 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -30,7 +30,7 @@ module SwaggerClient # # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" def deserialize(return_type) - return nil if body.blank? + return nil if body.nil? || body.empty? # ensuring a default content type content_type = raw.headers_hash['Content-Type'] || 'application/json' @@ -106,9 +106,11 @@ module SwaggerClient end def pretty_body - return unless body.present? - case format - when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') + return unless body + if format == 'json' + JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') + else + body end end diff --git a/samples/client/petstore/ruby/spec/monkey_spec.rb b/samples/client/petstore/ruby/spec/monkey_spec.rb deleted file mode 100644 index 71c04921f1a..00000000000 --- a/samples/client/petstore/ruby/spec/monkey_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'spec_helper' - -describe String do - - it "underscores" do - "thisIsATest".underscore.should == "this_is_a_test" - end - - it "camelizes" do - "camel_toe".camelize.should == "CamelToe" - end - - it "camelizes with leading minisculity" do - "dromedary_larry".camelize(:lower).should == "dromedaryLarry" - end - -end - -describe Hash do - - it "symbolizes keys" do - h = {'a' => 1, :b => 2 } - h.symbolize_keys.should be_a Hash - h.symbolize_keys.keys.should == [:a, :b] - end - - it "symbolizes and underscores keys" do - h = {'assHat' => 1, :bargainBasement => 2 } - h.symbolize_and_underscore_keys.should be_a Hash - h.symbolize_and_underscore_keys.keys.should == [:ass_hat, :bargain_basement] - end - -end \ No newline at end of file diff --git a/samples/client/petstore/ruby/spec/request_spec.rb b/samples/client/petstore/ruby/spec/request_spec.rb index 49bbc5cdd1e..987a923547c 100644 --- a/samples/client/petstore/ruby/spec/request_spec.rb +++ b/samples/client/petstore/ruby/spec/request_spec.rb @@ -25,7 +25,7 @@ describe SwaggerClient::Swagger::Request do it "allows params to be nil" do @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, :params => nil) - @request.query_string.should == "" + @request.params.should == {} end end @@ -46,26 +46,8 @@ describe SwaggerClient::Swagger::Request do describe "url" do - it "constructs a query string" do - @request.query_string.should == "?bar=2&foo=1" - end - it "constructs a full url" do - @request.url.should == "http://petstore.swagger.io/v2/pet.json/fancy?bar=2&foo=1" - end - - end - - describe "body" do - - it "camelCases parameters" do - @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, @default_params.merge({ - :body => { - :bad_dog => 'bud', - :goodDog => "dud" - } - })) - @request.body.keys.should == [:badDog, :goodDog] + @request.url.should == "http://petstore.swagger.io/v2/pet.json/fancy" end end @@ -90,36 +72,6 @@ describe SwaggerClient::Swagger::Request do @request.url.should == "http://petstore.swagger.io/v2/word.xml/cat/entries" end - it "leaves path-bound params out of the query string" do - @request = SwaggerClient::Swagger::Request.new(:get, "/word.{format}/{word}/entries", @default_params.merge({ - :params => { - :word => "cat", - :limit => 20 - } - })) - @request.query_string.should == "?limit=20" - end - - it "returns a question-mark free (blank) query string if no query params are present" do - @request = SwaggerClient::Swagger::Request.new(:get, "/word.{format}/{word}/entries", @default_params.merge({ - :params => { - :word => "cat", - } - })) - @request.query_string.should == "" - end - - it "removes blank params" do - @request = SwaggerClient::Swagger::Request.new(:get, "words/fancy", @default_params.merge({ - :params => { - :word => "dog", - :limit => "", - :foo => "criminy" - } - })) - @request.query_string.should == "?foo=criminy&word=dog" - end - it "URI encodes the path" do @request = SwaggerClient::Swagger::Request.new(:get, "word.{format}/bill gates/definitions", @default_params.merge({ :params => { @@ -129,34 +81,6 @@ describe SwaggerClient::Swagger::Request do @request.url.should =~ /word.json\/bill\%20gates\/definitions/ end - it "converts numeric params to strings" do - @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, @default_params.merge({ - :params => { - :limit => 100 - } - })) - - @request.interpreted_path.should_not be_nil - @request.query_string.should =~ /\?limit=100/ - @request.url.should =~ /\?limit=100/ - end - - it "camelCases parameters" do - @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, @default_params.merge({ - :params => { - :bad_dog => 'bud', - :goodDog => "dud" - } - })) - @request.query_string.should == "?badDog=bud&goodDog=dud" - end - - it "converts boolean values to their string representation" do - params = {:stringy => "fish", :truthy => true, :falsey => false} - @request = SwaggerClient::Swagger::Request.new(:get, 'fakeMethod', :params => params) - @request.query_string.should == "?falsey=false&stringy=fish&truthy=true" - end - end describe "#update_params_for_auth!" do diff --git a/samples/client/petstore/ruby/swagger_client.gemspec b/samples/client/petstore/ruby/swagger_client.gemspec index c0d507b3c5b..bc09642eaf6 100644 --- a/samples/client/petstore/ruby/swagger_client.gemspec +++ b/samples/client/petstore/ruby/swagger_client.gemspec @@ -14,7 +14,6 @@ Gem::Specification.new do |s| s.license = "Apache-2.0" s.add_runtime_dependency 'typhoeus', '~> 0.2', '>= 0.2.1' - s.add_runtime_dependency 'addressable', '~> 2.2', '>= 2.2.4' s.add_runtime_dependency 'json', '~> 1.4', '>= 1.4.6' s.add_development_dependency 'rspec', '~> 3.2', '>= 3.2.0' From d8b0cb739fa186ffa717185fde60f8592ae03780 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 17:15:14 +0800 Subject: [PATCH 170/499] Add config file for bin/ruby-petstore.sh to rename swagger_client to petstore --- bin/ruby-petstore.json | 5 ++++ bin/ruby-petstore.sh | 2 +- samples/client/petstore/ruby/Gemfile.lock | 4 +-- samples/client/petstore/ruby/README.md | 14 +++++------ samples/client/petstore/ruby/lib/petstore.rb | 25 +++++++++++++++++++ .../api/pet_api.rb | 2 +- .../api/store_api.rb | 2 +- .../api/user_api.rb | 2 +- .../models/base_object.rb | 4 +-- .../models/category.rb | 2 +- .../models/order.rb | 2 +- .../models/pet.rb | 2 +- .../models/tag.rb | 2 +- .../models/user.rb | 2 +- .../{swagger_client => petstore}/swagger.rb | 2 +- .../swagger/api_error.rb | 2 +- .../swagger/configuration.rb | 2 +- .../swagger/request.rb | 2 +- .../swagger/response.rb | 4 +-- .../swagger/version.rb | 2 +- .../petstore/ruby/lib/swagger_client.rb | 25 ------------------- ...wagger_client.gemspec => petstore.gemspec} | 6 ++--- 22 files changed, 60 insertions(+), 55 deletions(-) create mode 100644 bin/ruby-petstore.json create mode 100644 samples/client/petstore/ruby/lib/petstore.rb rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/api/pet_api.rb (99%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/api/store_api.rb (99%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/api/user_api.rb (99%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/models/base_object.rb (96%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/models/category.rb (97%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/models/order.rb (98%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/models/pet.rb (98%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/models/tag.rb (97%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/models/user.rb (98%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/swagger.rb (99%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/swagger/api_error.rb (96%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/swagger/configuration.rb (99%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/swagger/request.rb (99%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/swagger/response.rb (97%) rename samples/client/petstore/ruby/lib/{swagger_client => petstore}/swagger/version.rb (70%) delete mode 100644 samples/client/petstore/ruby/lib/swagger_client.rb rename samples/client/petstore/ruby/{swagger_client.gemspec => petstore.gemspec} (90%) diff --git a/bin/ruby-petstore.json b/bin/ruby-petstore.json new file mode 100644 index 00000000000..ddb753471a1 --- /dev/null +++ b/bin/ruby-petstore.json @@ -0,0 +1,5 @@ +{ + "gemName": "petstore", + "moduleName": "Petstore", + "gemVersion": "1.0.0" +} diff --git a/bin/ruby-petstore.sh b/bin/ruby-petstore.sh index 971cc154fb9..05cf1ee995e 100755 --- a/bin/ruby-petstore.sh +++ b/bin/ruby-petstore.sh @@ -26,6 +26,6 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -t modules/swagger-codegen/src/main/resources/ruby -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -o samples/client/petstore/ruby" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/ruby -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -c bin/ruby-petstore.json -o samples/client/petstore/ruby" java $JAVA_OPTS -jar $executable $ags diff --git a/samples/client/petstore/ruby/Gemfile.lock b/samples/client/petstore/ruby/Gemfile.lock index 1b69e10f1fd..05a6aa23790 100644 --- a/samples/client/petstore/ruby/Gemfile.lock +++ b/samples/client/petstore/ruby/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - swagger_client (1.0.0) + petstore (1.0.0) json (~> 1.4, >= 1.4.6) typhoeus (~> 0.2, >= 0.2.1) @@ -54,7 +54,7 @@ DEPENDENCIES autotest-fsevent (~> 0.2, >= 0.2.10) autotest-growl (~> 0.2, >= 0.2.16) autotest-rails-pure (~> 4.1, >= 4.1.2) + petstore! rspec (~> 3.2, >= 3.2.0) - swagger_client! vcr (~> 2.9, >= 2.9.3) webmock (~> 1.6, >= 1.6.2) diff --git a/samples/client/petstore/ruby/README.md b/samples/client/petstore/ruby/README.md index 06ba93a5abc..c98d79e5a89 100644 --- a/samples/client/petstore/ruby/README.md +++ b/samples/client/petstore/ruby/README.md @@ -5,20 +5,20 @@ You can build the generated client into a gem: ```shell -gem build swagger_client.gemspec +gem build petstore.gemspec ``` Then you can either install the gem: ```shell -gem install ./swagger_client-1.0.0.gem +gem install ./petstore-1.0.0.gem ``` or publish the gem to a gem server like [RubyGems](https://rubygems.org/). Finally add this to your Gemfile: - gem 'swagger_client', '~> 1.0.0' + gem 'petstore', '~> 1.0.0' ### Host as a git repository @@ -27,7 +27,7 @@ https://github.com/xhh/swagger-petstore-ruby Then you can reference it in Gemfile: - gem 'swagger_client', :git => 'https://github.com/xhh/swagger-petstore-ruby.git' + gem 'petstore', :git => 'https://github.com/xhh/swagger-petstore-ruby.git' ### Use without installation @@ -40,9 +40,9 @@ ruby -Ilib script.rb ## Configuration ```ruby -require 'swagger_client' +require 'petstore' -SwaggerClient::Swagger.configure do |config| +Petstore::Swagger.configure do |config| config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' @@ -54,6 +54,6 @@ end ## Getting Started ```ruby -pet = SwaggerClient::PetApi.get_pet_by_id(5) +pet = Petstore::PetApi.get_pet_by_id(5) puts pet.to_body ``` diff --git a/samples/client/petstore/ruby/lib/petstore.rb b/samples/client/petstore/ruby/lib/petstore.rb new file mode 100644 index 00000000000..245170ede61 --- /dev/null +++ b/samples/client/petstore/ruby/lib/petstore.rb @@ -0,0 +1,25 @@ +# Swagger common files +require 'petstore/swagger' +require 'petstore/swagger/configuration' +require 'petstore/swagger/api_error' +require 'petstore/swagger/request' +require 'petstore/swagger/response' +require 'petstore/swagger/version' + +# Models +require 'petstore/models/base_object' +require 'petstore/models/user' +require 'petstore/models/category' +require 'petstore/models/pet' +require 'petstore/models/tag' +require 'petstore/models/order' + +# APIs +require 'petstore/api/user_api' +require 'petstore/api/pet_api' +require 'petstore/api/store_api' + +module Petstore + # Initialize the default configuration + Swagger.configuration ||= Swagger::Configuration.new +end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/petstore/api/pet_api.rb similarity index 99% rename from samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb rename to samples/client/petstore/ruby/lib/petstore/api/pet_api.rb index 4b3e6bb6a50..096d964752d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/petstore/api/pet_api.rb @@ -1,6 +1,6 @@ require "uri" -module SwaggerClient +module Petstore class PetApi # Update an existing pet diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/petstore/api/store_api.rb similarity index 99% rename from samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb rename to samples/client/petstore/ruby/lib/petstore/api/store_api.rb index 47e81d5af1c..456b8a2eebb 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/petstore/api/store_api.rb @@ -1,6 +1,6 @@ require "uri" -module SwaggerClient +module Petstore class StoreApi # Returns pet inventories by status diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/petstore/api/user_api.rb similarity index 99% rename from samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb rename to samples/client/petstore/ruby/lib/petstore/api/user_api.rb index 7d91c0bfd3d..d5aeae31513 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/petstore/api/user_api.rb @@ -1,6 +1,6 @@ require "uri" -module SwaggerClient +module Petstore class UserApi # Create user diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb b/samples/client/petstore/ruby/lib/petstore/models/base_object.rb similarity index 96% rename from samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb rename to samples/client/petstore/ruby/lib/petstore/models/base_object.rb index b0fa43c8359..8223b2e844d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb +++ b/samples/client/petstore/ruby/lib/petstore/models/base_object.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore # base class containing fundamental method such as to_hash, build_from_hash and more class BaseObject @@ -39,7 +39,7 @@ module SwaggerClient false end else # model - _model = SwaggerClient.const_get(type).new + _model = Petstore.const_get(type).new _model.build_from_hash(value) end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/category.rb b/samples/client/petstore/ruby/lib/petstore/models/category.rb similarity index 97% rename from samples/client/petstore/ruby/lib/swagger_client/models/category.rb rename to samples/client/petstore/ruby/lib/petstore/models/category.rb index d856563b11d..3a17b51a7ee 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/category.rb +++ b/samples/client/petstore/ruby/lib/petstore/models/category.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore # class Category < BaseObject attr_accessor :id, :name diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/order.rb b/samples/client/petstore/ruby/lib/petstore/models/order.rb similarity index 98% rename from samples/client/petstore/ruby/lib/swagger_client/models/order.rb rename to samples/client/petstore/ruby/lib/petstore/models/order.rb index 2cd1ff18f5d..bff40302650 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/order.rb +++ b/samples/client/petstore/ruby/lib/petstore/models/order.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore # class Order < BaseObject attr_accessor :id, :pet_id, :quantity, :ship_date, :status, :complete diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb b/samples/client/petstore/ruby/lib/petstore/models/pet.rb similarity index 98% rename from samples/client/petstore/ruby/lib/swagger_client/models/pet.rb rename to samples/client/petstore/ruby/lib/petstore/models/pet.rb index f1f1d1434f4..5ee3d84aaf3 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb +++ b/samples/client/petstore/ruby/lib/petstore/models/pet.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore # class Pet < BaseObject attr_accessor :id, :category, :name, :photo_urls, :tags, :status diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb b/samples/client/petstore/ruby/lib/petstore/models/tag.rb similarity index 97% rename from samples/client/petstore/ruby/lib/swagger_client/models/tag.rb rename to samples/client/petstore/ruby/lib/petstore/models/tag.rb index 677c828aede..fcbdd68f20f 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb +++ b/samples/client/petstore/ruby/lib/petstore/models/tag.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore # class Tag < BaseObject attr_accessor :id, :name diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/user.rb b/samples/client/petstore/ruby/lib/petstore/models/user.rb similarity index 98% rename from samples/client/petstore/ruby/lib/swagger_client/models/user.rb rename to samples/client/petstore/ruby/lib/petstore/models/user.rb index ed7a21e167f..f45f7e0c3cb 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/user.rb +++ b/samples/client/petstore/ruby/lib/petstore/models/user.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore # class User < BaseObject attr_accessor :id, :username, :first_name, :last_name, :email, :password, :phone, :user_status diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/petstore/swagger.rb similarity index 99% rename from samples/client/petstore/ruby/lib/swagger_client/swagger.rb rename to samples/client/petstore/ruby/lib/petstore/swagger.rb index bf69f05b23a..d2dcc6ab201 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/petstore/swagger.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore module Swagger class << self attr_accessor :logger, :last_response diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb b/samples/client/petstore/ruby/lib/petstore/swagger/api_error.rb similarity index 96% rename from samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb rename to samples/client/petstore/ruby/lib/petstore/swagger/api_error.rb index 12319927ace..9eab46b6eec 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb +++ b/samples/client/petstore/ruby/lib/petstore/swagger/api_error.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore module Swagger class ApiError < StandardError attr_reader :code, :response_headers, :response_body diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/petstore/swagger/configuration.rb similarity index 99% rename from samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb rename to samples/client/petstore/ruby/lib/petstore/swagger/configuration.rb index 8811c44b4df..406f729f068 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/petstore/swagger/configuration.rb @@ -1,6 +1,6 @@ require 'logger' -module SwaggerClient +module Petstore module Swagger class Configuration attr_accessor :scheme, :host, :base_path, :user_agent, :format, :auth_token, :inject_format, :force_ending_format diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/petstore/swagger/request.rb similarity index 99% rename from samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb rename to samples/client/petstore/ruby/lib/petstore/swagger/request.rb index 8b0276d356a..049c6c15cb1 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/petstore/swagger/request.rb @@ -1,7 +1,7 @@ require 'uri' require 'typhoeus' -module SwaggerClient +module Petstore module Swagger class Request attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names, :response diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/petstore/swagger/response.rb similarity index 97% rename from samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb rename to samples/client/petstore/ruby/lib/petstore/swagger/response.rb index 0df6c2e54cd..770f04f6e2c 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/petstore/swagger/response.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore module Swagger class Response require 'json' @@ -77,7 +77,7 @@ module SwaggerClient end else # models, e.g. Pet - SwaggerClient.const_get(return_type).new.tap do |model| + Petstore.const_get(return_type).new.tap do |model| model.build_from_hash data end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/version.rb b/samples/client/petstore/ruby/lib/petstore/swagger/version.rb similarity index 70% rename from samples/client/petstore/ruby/lib/swagger_client/swagger/version.rb rename to samples/client/petstore/ruby/lib/petstore/swagger/version.rb index c6e8d5aee53..ff3c48bb59e 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/version.rb +++ b/samples/client/petstore/ruby/lib/petstore/swagger/version.rb @@ -1,4 +1,4 @@ -module SwaggerClient +module Petstore module Swagger VERSION = "1.0.0" end diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb deleted file mode 100644 index f91c8912d98..00000000000 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Swagger common files -require 'swagger_client/swagger' -require 'swagger_client/swagger/configuration' -require 'swagger_client/swagger/api_error' -require 'swagger_client/swagger/request' -require 'swagger_client/swagger/response' -require 'swagger_client/swagger/version' - -# Models -require 'swagger_client/models/base_object' -require 'swagger_client/models/user' -require 'swagger_client/models/category' -require 'swagger_client/models/pet' -require 'swagger_client/models/tag' -require 'swagger_client/models/order' - -# APIs -require 'swagger_client/api/user_api' -require 'swagger_client/api/pet_api' -require 'swagger_client/api/store_api' - -module SwaggerClient - # Initialize the default configuration - Swagger.configuration ||= Swagger::Configuration.new -end diff --git a/samples/client/petstore/ruby/swagger_client.gemspec b/samples/client/petstore/ruby/petstore.gemspec similarity index 90% rename from samples/client/petstore/ruby/swagger_client.gemspec rename to samples/client/petstore/ruby/petstore.gemspec index bc09642eaf6..40a169d1741 100644 --- a/samples/client/petstore/ruby/swagger_client.gemspec +++ b/samples/client/petstore/ruby/petstore.gemspec @@ -1,10 +1,10 @@ # -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) -require "swagger_client/swagger/version" +require "petstore/swagger/version" Gem::Specification.new do |s| - s.name = "swagger_client" - s.version = SwaggerClient::Swagger::VERSION + s.name = "petstore" + s.version = Petstore::Swagger::VERSION s.platform = Gem::Platform::RUBY s.authors = ["Zeke Sikelianos", "Tony Tam"] s.email = ["zeke@wordnik.com", "fehguy@gmail.com"] From fafddbf04028b8dd4fe2e1f244d5735064132806 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 17:16:38 +0800 Subject: [PATCH 171/499] Fix naming in specs --- samples/client/petstore/ruby/spec/pet_spec.rb | 38 ++++++++--------- .../client/petstore/ruby/spec/request_spec.rb | 18 ++++---- .../petstore/ruby/spec/response_spec.rb | 8 ++-- .../client/petstore/ruby/spec/spec_helper.rb | 18 ++++---- .../client/petstore/ruby/spec/store_spec.rb | 4 +- .../client/petstore/ruby/spec/swagger_spec.rb | 42 +++++++++---------- 6 files changed, 64 insertions(+), 64 deletions(-) diff --git a/samples/client/petstore/ruby/spec/pet_spec.rb b/samples/client/petstore/ruby/spec/pet_spec.rb index 52030b7bf51..990c5b3764f 100644 --- a/samples/client/petstore/ruby/spec/pet_spec.rb +++ b/samples/client/petstore/ruby/spec/pet_spec.rb @@ -9,9 +9,9 @@ describe "Pet" do describe "pet methods" do it "should construct a new pet object" do - tag1 = SwaggerClient::Tag.new({'id' => 1, 'name'=> 'tag1'}) - tag2 = SwaggerClient::Tag.new({'id' => 2, 'name'=> 'tag2'}) - category1 = SwaggerClient::Category.new({:id => 1, :name => 'category unknown'}) + tag1 = Petstore::Tag.new({'id' => 1, 'name'=> 'tag1'}) + tag2 = Petstore::Tag.new({'id' => 2, 'name'=> 'tag2'}) + category1 = Petstore::Category.new({:id => 1, :name => 'category unknown'}) # initalize using both string and symbol key pet_hash = { :id => 10002, @@ -21,7 +21,7 @@ describe "Pet" do :category => category1, :tags => [tag1, tag2] } - pet = SwaggerClient::Pet.new(pet_hash) + pet = Petstore::Pet.new(pet_hash) # test new pet.name.should == "RUBY UNIT TESTING" pet.status.should == "pending" @@ -31,7 +31,7 @@ describe "Pet" do pet.category.name.should == 'category unknown' # test build_from_hash - pet2 = SwaggerClient::Pet.new + pet2 = Petstore::Pet.new pet2.build_from_hash(pet.to_hash) pet.to_hash.should == pet2.to_hash @@ -42,8 +42,8 @@ describe "Pet" do end it "should fetch a pet object" do - pet = SwaggerClient::PetApi.get_pet_by_id(10002) - pet.should be_a(SwaggerClient::Pet) + pet = Petstore::PetApi.get_pet_by_id(10002) + pet.should be_a(Petstore::Pet) pet.id.should == 10002 pet.name.should == "RUBY UNIT TESTING" pet.tags[0].name.should == "tag test" @@ -52,9 +52,9 @@ describe "Pet" do it "should not find a pet that does not exist" do begin - SwaggerClient::PetApi.get_pet_by_id(-1) + Petstore::PetApi.get_pet_by_id(-1) fail 'it should raise error' - rescue SwaggerClient::Swagger::ApiError => e + rescue Petstore::Swagger::ApiError => e e.code.should == 404 e.message.should == 'Not Found' e.response_body.should == '{"code":1,"type":"error","message":"Pet not found"}' @@ -64,21 +64,21 @@ describe "Pet" do end it "should find pets by status" do - pets = SwaggerClient::PetApi.find_pets_by_status(:status => 'available') + pets = Petstore::PetApi.find_pets_by_status(:status => 'available') pets.length.should >= 3 pets.each do |pet| - pet.should be_a(SwaggerClient::Pet) + pet.should be_a(Petstore::Pet) pet.status.should == 'available' end end it "should not find a pet with invalid status" do - pets = SwaggerClient::PetApi.find_pets_by_status(:status => 'invalid-status') + pets = Petstore::PetApi.find_pets_by_status(:status => 'invalid-status') pets.length.should == 0 end it "should find a pet by status" do - pets = SwaggerClient::PetApi.find_pets_by_status(:status => "available,sold") + pets = Petstore::PetApi.find_pets_by_status(:status => "available,sold") pets.each do |pet| if pet.status != 'available' && pet.status != 'sold' raise "pet status wasn't right" @@ -87,21 +87,21 @@ describe "Pet" do end it "should update a pet" do - pet = SwaggerClient::Pet.new({'id' => 10002, 'status' => 'sold'}) - SwaggerClient::PetApi.add_pet(:body => pet) + pet = Petstore::Pet.new({'id' => 10002, 'status' => 'sold'}) + Petstore::PetApi.add_pet(:body => pet) - fetched = SwaggerClient::PetApi.get_pet_by_id(10002) + fetched = Petstore::PetApi.get_pet_by_id(10002) fetched.id.should == 10002 fetched.status.should == 'sold' end it "should create a pet" do - pet = SwaggerClient::Pet.new('id' => 10002, 'name' => "RUBY UNIT TESTING") - result = SwaggerClient::PetApi.add_pet(:body => pet) + pet = Petstore::Pet.new('id' => 10002, 'name' => "RUBY UNIT TESTING") + result = Petstore::PetApi.add_pet(:body => pet) # nothing is returned result.should be_nil - pet = SwaggerClient::PetApi.get_pet_by_id(10002) + pet = Petstore::PetApi.get_pet_by_id(10002) pet.id.should == 10002 pet.name.should == "RUBY UNIT TESTING" end diff --git a/samples/client/petstore/ruby/spec/request_spec.rb b/samples/client/petstore/ruby/spec/request_spec.rb index 987a923547c..4fa68d4d1b7 100644 --- a/samples/client/petstore/ruby/spec/request_spec.rb +++ b/samples/client/petstore/ruby/spec/request_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' -describe SwaggerClient::Swagger::Request do +describe Petstore::Swagger::Request do before(:each) do - SwaggerClient::Swagger.configure do |config| + Petstore::Swagger.configure do |config| inject_format = true config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' @@ -15,7 +15,7 @@ describe SwaggerClient::Swagger::Request do @default_params = { :params => {:foo => "1", :bar => "2"} } - @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, @default_params) + @request = Petstore::Swagger::Request.new(@default_http_method, @default_path, @default_params) end describe "initialization" do @@ -24,7 +24,7 @@ describe SwaggerClient::Swagger::Request do end it "allows params to be nil" do - @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, :params => nil) + @request = Petstore::Swagger::Request.new(@default_http_method, @default_path, :params => nil) @request.params.should == {} end @@ -55,7 +55,7 @@ describe SwaggerClient::Swagger::Request do describe "path" do it "accounts for a total absence of format in the path string" do - @request = SwaggerClient::Swagger::Request.new(:get, "/word.{format}/cat/entries", @default_params.merge({ + @request = Petstore::Swagger::Request.new(:get, "/word.{format}/cat/entries", @default_params.merge({ :format => "xml", :params => { } @@ -64,7 +64,7 @@ describe SwaggerClient::Swagger::Request do end it "does string substitution (format) on path params" do - @request = SwaggerClient::Swagger::Request.new(:get, "/word.{format}/cat/entries", @default_params.merge({ + @request = Petstore::Swagger::Request.new(:get, "/word.{format}/cat/entries", @default_params.merge({ :format => "xml", :params => { } @@ -73,7 +73,7 @@ describe SwaggerClient::Swagger::Request do end it "URI encodes the path" do - @request = SwaggerClient::Swagger::Request.new(:get, "word.{format}/bill gates/definitions", @default_params.merge({ + @request = Petstore::Swagger::Request.new(:get, "word.{format}/bill gates/definitions", @default_params.merge({ :params => { :word => "bill gates" } @@ -85,7 +85,7 @@ describe SwaggerClient::Swagger::Request do describe "#update_params_for_auth!" do it "sets header api-key parameter with prefix" do - SwaggerClient::Swagger.configure do |config| + Petstore::Swagger.configure do |config| inject_format = true config.api_key_prefix['api_key'] = 'PREFIX' end @@ -95,7 +95,7 @@ describe SwaggerClient::Swagger::Request do end it "sets header api-key parameter without prefix" do - SwaggerClient::Swagger.configure do |config| + Petstore::Swagger.configure do |config| inject_format = true config.api_key_prefix['api_key'] = nil end diff --git a/samples/client/petstore/ruby/spec/response_spec.rb b/samples/client/petstore/ruby/spec/response_spec.rb index 8d75c6d1fae..c583b413fca 100644 --- a/samples/client/petstore/ruby/spec/response_spec.rb +++ b/samples/client/petstore/ruby/spec/response_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SwaggerClient::Swagger::Response do +describe Petstore::Swagger::Response do before do configure_swagger @@ -12,7 +12,7 @@ describe SwaggerClient::Swagger::Response do @raw = Typhoeus::Request.get("http://petstore.swagger.io/v2/pet/10002") end - @response = SwaggerClient::Swagger::Response.new(@raw) + @response = Petstore::Swagger::Response.new(@raw) end describe "initialization" do @@ -43,7 +43,7 @@ describe SwaggerClient::Swagger::Response do @raw = Typhoeus::Request.get("http://petstore.swagger.io/v2/pet/10002", :headers => {'Accept'=> "application/xml"}) end - @response = SwaggerClient::Swagger::Response.new(@raw) + @response = Petstore::Swagger::Response.new(@raw) @response.format.should == 'xml' @response.xml?.should == true end @@ -74,7 +74,7 @@ describe SwaggerClient::Swagger::Response do data.should be_a(Hash) data.keys.should == [:pet] pet = data[:pet] - pet.should be_a(SwaggerClient::Pet) + pet.should be_a(Petstore::Pet) pet.id.should == 10002 end end diff --git a/samples/client/petstore/ruby/spec/spec_helper.rb b/samples/client/petstore/ruby/spec/spec_helper.rb index f9081d3fe08..55279384e61 100644 --- a/samples/client/petstore/ruby/spec/spec_helper.rb +++ b/samples/client/petstore/ruby/spec/spec_helper.rb @@ -1,6 +1,6 @@ require 'rubygems' require 'bundler/setup' -require 'swagger_client' +require 'petstore' require 'vcr' require 'typhoeus' require 'json' @@ -37,7 +37,7 @@ end #end def configure_swagger - SwaggerClient::Swagger.configure do |config| + Petstore::Swagger.configure do |config| config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' @@ -47,25 +47,25 @@ end # always delete and then re-create the pet object with 10002 def prepare_pet # remove the pet - SwaggerClient::PetApi.delete_pet(10002) + Petstore::PetApi.delete_pet(10002) # recreate the pet - category = SwaggerClient::Category.new('id' => 20002, 'name' => 'category test') - tag = SwaggerClient::Tag.new('id' => 30002, 'name' => 'tag test') - pet = SwaggerClient::Pet.new('id' => 10002, 'name' => "RUBY UNIT TESTING", 'photo_urls' => 'photo url', + category = Petstore::Category.new('id' => 20002, 'name' => 'category test') + tag = Petstore::Tag.new('id' => 30002, 'name' => 'tag test') + pet = Petstore::Pet.new('id' => 10002, 'name' => "RUBY UNIT TESTING", 'photo_urls' => 'photo url', 'category' => category, 'tags' => [tag], 'status' => 'pending') - SwaggerClient::PetApi.add_pet(:'body'=> pet) + Petstore::PetApi.add_pet(:'body'=> pet) end # always delete and then re-create the store order def prepare_store - order = SwaggerClient::Order.new("id" => 10002, + order = Petstore::Order.new("id" => 10002, "petId" => 10002, "quantity" => 789, "shipDate" => "2015-04-06T23:42:01.678Z", "status" => "placed", "complete" => false) - SwaggerClient::StoreApi.place_order(:body => order) + Petstore::StoreApi.place_order(:body => order) end configure_swagger diff --git a/samples/client/petstore/ruby/spec/store_spec.rb b/samples/client/petstore/ruby/spec/store_spec.rb index 3ad09f1ad61..8c59de39fec 100644 --- a/samples/client/petstore/ruby/spec/store_spec.rb +++ b/samples/client/petstore/ruby/spec/store_spec.rb @@ -7,12 +7,12 @@ describe "Store" do end it "should fetch an order" do - item = SwaggerClient::StoreApi.get_order_by_id(10002) + item = Petstore::StoreApi.get_order_by_id(10002) item.id.should == 10002 end it "should featch the inventory" do - result = SwaggerClient::StoreApi.get_inventory + result = Petstore::StoreApi.get_inventory result.should be_a(Hash) result.should_not be_empty result.each do |k, v| diff --git a/samples/client/petstore/ruby/spec/swagger_spec.rb b/samples/client/petstore/ruby/spec/swagger_spec.rb index 38b4a850ae9..957da5e20a6 100644 --- a/samples/client/petstore/ruby/spec/swagger_spec.rb +++ b/samples/client/petstore/ruby/spec/swagger_spec.rb @@ -1,56 +1,56 @@ # require 'spec_helper' require File.dirname(__FILE__) + '/spec_helper' -describe SwaggerClient::Swagger do +describe Petstore::Swagger do before(:each) do configure_swagger end - + after(:each) do end context 'initialization' do - + context 'URL stuff' do context 'host' do it 'removes http from host' do - SwaggerClient::Swagger.configure {|c| c.host = 'http://example.com' } - SwaggerClient::Swagger.configuration.host.should == 'example.com' + Petstore::Swagger.configure {|c| c.host = 'http://example.com' } + Petstore::Swagger.configuration.host.should == 'example.com' end it 'removes https from host' do - SwaggerClient::Swagger.configure {|c| c.host = 'https://wookiee.com' } - SwaggerClient::Swagger.configuration.host.should == 'wookiee.com' + Petstore::Swagger.configure {|c| c.host = 'https://wookiee.com' } + Petstore::Swagger.configuration.host.should == 'wookiee.com' end it 'removes trailing path from host' do - SwaggerClient::Swagger.configure {|c| c.host = 'hobo.com/v4' } - SwaggerClient::Swagger.configuration.host.should == 'hobo.com' + Petstore::Swagger.configure {|c| c.host = 'hobo.com/v4' } + Petstore::Swagger.configuration.host.should == 'hobo.com' end end - + context 'base_path' do it "prepends a slash to base_path" do - SwaggerClient::Swagger.configure {|c| c.base_path = 'v4/dog' } - SwaggerClient::Swagger.configuration.base_path.should == '/v4/dog' + Petstore::Swagger.configure {|c| c.base_path = 'v4/dog' } + Petstore::Swagger.configuration.base_path.should == '/v4/dog' end - + it "doesn't prepend a slash if one is already there" do - SwaggerClient::Swagger.configure {|c| c.base_path = '/v4/dog' } - SwaggerClient::Swagger.configuration.base_path.should == '/v4/dog' + Petstore::Swagger.configure {|c| c.base_path = '/v4/dog' } + Petstore::Swagger.configuration.base_path.should == '/v4/dog' end - + it "ends up as a blank string if nil" do - SwaggerClient::Swagger.configure {|c| c.base_path = nil } - SwaggerClient::Swagger.configuration.base_path.should == '' + Petstore::Swagger.configure {|c| c.base_path = nil } + Petstore::Swagger.configuration.base_path.should == '' end - + end end - + end - + end From 1de6952279897cb36d4e52ca7eb63070d5f8154f Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 26 Jun 2015 19:09:20 +0800 Subject: [PATCH 172/499] Support customizing default headers via config option for example: config.default_headers['X-MY-HEADER'] = 'my-header-value' --- .../ruby/swagger/configuration.mustache | 10 +++++++ .../resources/ruby/swagger/request.mustache | 27 ++++++++----------- .../swagger_client/swagger/configuration.rb | 10 +++++++ .../lib/swagger_client/swagger/request.rb | 27 ++++++++----------- .../client/petstore/ruby/spec/request_spec.rb | 5 ++++ 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index 9400bdce6b7..fe341f1ced4 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -10,6 +10,11 @@ module {{moduleName}} # @return [String] attr_accessor :temp_folder_path + # Defines the headers to be used in HTTP requests of all API calls by default. + # + # @return [Hash] + attr_accessor :default_headers + # Defaults go in here.. def initialize @format = 'json' @@ -21,6 +26,11 @@ module {{moduleName}} @force_ending_format = false @camelize_params = true + @default_headers = { + 'Content-Type' => "application/#{@format.downcase}", + 'User-Agent' => @user_agent + } + # keys for API key authentication (param-name => api-key) @api_key = {} # api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix) diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 99b58d58be8..9c3e25caff9 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -10,27 +10,22 @@ module {{moduleName}} # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host def initialize(http_method, path, attributes={}) - attributes[:format] ||= Swagger.configuration.format - attributes[:params] ||= {} + @http_method = http_method.to_sym + @path = path - # Set default headers - default_headers = { - 'Content-Type' => "application/#{attributes[:format].downcase}", - 'User-Agent' => Swagger.configuration.user_agent - } + attributes.each do |name, value| + send("#{name.to_s.underscore.to_sym}=", value) + end - # Merge argument headers into defaults - attributes[:headers] = default_headers.merge(attributes[:headers] || {}) + @format ||= Swagger.configuration.format + @params ||= {} + + # Apply default headers + @headers = Swagger.configuration.default_headers.merge(@headers || {}) # Stick in the auth token if there is one if Swagger.authenticated? - attributes[:headers].merge!({:auth_token => Swagger.configuration.auth_token}) - end - - self.http_method = http_method.to_sym - self.path = path - attributes.each do |name, value| - send("#{name.to_s.underscore.to_sym}=", value) + @headers.merge!({:auth_token => Swagger.configuration.auth_token}) end update_params_for_auth! diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index 0b7836d989c..c8c2220a5f9 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -10,6 +10,11 @@ module SwaggerClient # @return [String] attr_accessor :temp_folder_path + # Defines the headers to be used in HTTP requests of all API calls by default. + # + # @return [Hash] + attr_accessor :default_headers + # Defaults go in here.. def initialize @format = 'json' @@ -21,6 +26,11 @@ module SwaggerClient @force_ending_format = false @camelize_params = true + @default_headers = { + 'Content-Type' => "application/#{@format.downcase}", + 'User-Agent' => @user_agent + } + # keys for API key authentication (param-name => api-key) @api_key = {} # api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix) diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index 4cd5d84b0b9..e4ce431e108 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -10,27 +10,22 @@ module SwaggerClient # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host def initialize(http_method, path, attributes={}) - attributes[:format] ||= Swagger.configuration.format - attributes[:params] ||= {} + @http_method = http_method.to_sym + @path = path - # Set default headers - default_headers = { - 'Content-Type' => "application/#{attributes[:format].downcase}", - 'User-Agent' => Swagger.configuration.user_agent - } + attributes.each do |name, value| + send("#{name.to_s.underscore.to_sym}=", value) + end - # Merge argument headers into defaults - attributes[:headers] = default_headers.merge(attributes[:headers] || {}) + @format ||= Swagger.configuration.format + @params ||= {} + + # Apply default headers + @headers = Swagger.configuration.default_headers.merge(@headers || {}) # Stick in the auth token if there is one if Swagger.authenticated? - attributes[:headers].merge!({:auth_token => Swagger.configuration.auth_token}) - end - - self.http_method = http_method.to_sym - self.path = path - attributes.each do |name, value| - send("#{name.to_s.underscore.to_sym}=", value) + @headers.merge!({:auth_token => Swagger.configuration.auth_token}) end update_params_for_auth! diff --git a/samples/client/petstore/ruby/spec/request_spec.rb b/samples/client/petstore/ruby/spec/request_spec.rb index 49bbc5cdd1e..9d9e61afcc5 100644 --- a/samples/client/petstore/ruby/spec/request_spec.rb +++ b/samples/client/petstore/ruby/spec/request_spec.rb @@ -19,10 +19,15 @@ describe SwaggerClient::Swagger::Request do end describe "initialization" do + it "sets default response format to json" do @request.format.should == 'json' end + it "sets default headers correctly" do + @request.headers.should == {'Content-Type' => 'application/json', 'User-Agent' => 'ruby-swagger-1.0.0'} + end + it "allows params to be nil" do @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, :params => nil) @request.query_string.should == "" From 38d62d768a42d08972168848b2788be30de0ae59 Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 25 Jun 2015 22:40:14 +0800 Subject: [PATCH 173/499] fix optional for python, python3 --- .../src/main/resources/python/api.mustache | 2 +- .../src/main/resources/python3/api.mustache | 2 +- .../python/swagger_client/apis/pet_api.py | 18 +++++++++--------- .../python/swagger_client/apis/store_api.py | 2 +- .../python/swagger_client/apis/user_api.py | 12 ++++++------ .../client/petstore/python3/client/pet_api.py | 18 +++++++++--------- .../petstore/python3/client/store_api.py | 2 +- .../client/petstore/python3/client/user_api.py | 12 ++++++------ 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index 867014d5e12..3fb62cb75ea 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -47,7 +47,7 @@ class {{classname}}(object): {{{summary}}} {{{notes}}} - {{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}} + {{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} :return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}} """ diff --git a/modules/swagger-codegen/src/main/resources/python3/api.mustache b/modules/swagger-codegen/src/main/resources/python3/api.mustache index 015158bccec..2ff659b11b5 100644 --- a/modules/swagger-codegen/src/main/resources/python3/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python3/api.mustache @@ -36,7 +36,7 @@ class {{classname}}(object): {{{notes}}} Args: - {{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} + {{#allParams}}{{paramName}}, {{dataType}}: {{{description}}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} Returns: {{returnType}} diff --git a/samples/client/petstore/python/swagger_client/apis/pet_api.py b/samples/client/petstore/python/swagger_client/apis/pet_api.py index 5f5c2fe81fa..7f022930869 100644 --- a/samples/client/petstore/python/swagger_client/apis/pet_api.py +++ b/samples/client/petstore/python/swagger_client/apis/pet_api.py @@ -46,7 +46,7 @@ class PetApi(object): Update an existing pet - :param Pet body: Pet object that needs to be added to the store + :param Pet body: Pet object that needs to be added to the store (optional) :return: None """ @@ -97,7 +97,7 @@ class PetApi(object): Add a new pet to the store - :param Pet body: Pet object that needs to be added to the store + :param Pet body: Pet object that needs to be added to the store (optional) :return: None """ @@ -148,7 +148,7 @@ class PetApi(object): Finds Pets by status Multiple status values can be provided with comma seperated strings - :param list[str] status: Status values that need to be considered for filter + :param list[str] status: Status values that need to be considered for filter (optional) :return: list[Pet] """ @@ -201,7 +201,7 @@ class PetApi(object): Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - :param list[str] tags: Tags to filter by + :param list[str] tags: Tags to filter by (optional) :return: list[Pet] """ @@ -312,8 +312,8 @@ class PetApi(object): :param str pet_id: ID of pet that needs to be updated (required) - :param str name: Updated name of the pet - :param str status: Updated status of the pet + :param str name: Updated name of the pet (optional) + :param str status: Updated status of the pet (optional) :return: None """ @@ -374,7 +374,7 @@ class PetApi(object): Deletes a pet - :param str api_key: + :param str api_key: (optional) :param int pet_id: Pet id to delete (required) :return: None @@ -434,8 +434,8 @@ class PetApi(object): :param int pet_id: ID of pet to update (required) - :param str additional_metadata: Additional data to pass to server - :param File file: file to upload + :param str additional_metadata: Additional data to pass to server (optional) + :param File file: file to upload (optional) :return: None """ diff --git a/samples/client/petstore/python/swagger_client/apis/store_api.py b/samples/client/petstore/python/swagger_client/apis/store_api.py index 1e024cfbb5b..f017df791d9 100644 --- a/samples/client/petstore/python/swagger_client/apis/store_api.py +++ b/samples/client/petstore/python/swagger_client/apis/store_api.py @@ -95,7 +95,7 @@ class StoreApi(object): Place an order for a pet - :param Order body: order placed for purchasing the pet + :param Order body: order placed for purchasing the pet (optional) :return: Order """ diff --git a/samples/client/petstore/python/swagger_client/apis/user_api.py b/samples/client/petstore/python/swagger_client/apis/user_api.py index 84a40b06579..177c5e3a565 100644 --- a/samples/client/petstore/python/swagger_client/apis/user_api.py +++ b/samples/client/petstore/python/swagger_client/apis/user_api.py @@ -46,7 +46,7 @@ class UserApi(object): Create user This can only be done by the logged in user. - :param User body: Created user object + :param User body: Created user object (optional) :return: None """ @@ -97,7 +97,7 @@ class UserApi(object): Creates list of users with given input array - :param list[User] body: List of user object + :param list[User] body: List of user object (optional) :return: None """ @@ -148,7 +148,7 @@ class UserApi(object): Creates list of users with given input array - :param list[User] body: List of user object + :param list[User] body: List of user object (optional) :return: None """ @@ -199,8 +199,8 @@ class UserApi(object): Logs user into the system - :param str username: The user name for login - :param str password: The password for login in clear text + :param str username: The user name for login (optional) + :param str password: The password for login in clear text (optional) :return: str """ @@ -361,7 +361,7 @@ class UserApi(object): This can only be done by the logged in user. :param str username: name that need to be deleted (required) - :param User body: Updated user object + :param User body: Updated user object (optional) :return: None """ diff --git a/samples/client/petstore/python3/client/pet_api.py b/samples/client/petstore/python3/client/pet_api.py index 9293a89d2b0..cebab131778 100644 --- a/samples/client/petstore/python3/client/pet_api.py +++ b/samples/client/petstore/python3/client/pet_api.py @@ -35,7 +35,7 @@ class PetApi(object): Args: - body, Pet: Pet object that needs to be added to the store (required) + body, Pet: Pet object that needs to be added to the store (optional) Returns: @@ -77,7 +77,7 @@ class PetApi(object): Args: - body, Pet: Pet object that needs to be added to the store (required) + body, Pet: Pet object that needs to be added to the store (optional) Returns: @@ -119,7 +119,7 @@ class PetApi(object): Multiple status values can be provided with comma seperated strings Args: - status, list[str]: Status values that need to be considered for filter (required) + status, list[str]: Status values that need to be considered for filter (optional) Returns: list[Pet] @@ -170,7 +170,7 @@ class PetApi(object): Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. Args: - tags, list[str]: Tags to filter by (required) + tags, list[str]: Tags to filter by (optional) Returns: list[Pet] @@ -275,8 +275,8 @@ class PetApi(object): Args: pet_id, str: ID of pet that needs to be updated (required) - name, str: Updated name of the pet (required) - status, str: Updated status of the pet (required) + name, str: Updated name of the pet (optional) + status, str: Updated status of the pet (optional) Returns: @@ -323,7 +323,7 @@ class PetApi(object): Args: - api_key, str: (required) + api_key, str: (optional) pet_id, int: Pet id to delete (required) @@ -375,8 +375,8 @@ class PetApi(object): Args: pet_id, int: ID of pet to update (required) - additional_metadata, str: Additional data to pass to server (required) - file, file: file to upload (required) + additional_metadata, str: Additional data to pass to server (optional) + file, file: file to upload (optional) Returns: diff --git a/samples/client/petstore/python3/client/store_api.py b/samples/client/petstore/python3/client/store_api.py index 8002b473f8a..802e116f1ff 100644 --- a/samples/client/petstore/python3/client/store_api.py +++ b/samples/client/petstore/python3/client/store_api.py @@ -82,7 +82,7 @@ class StoreApi(object): Args: - body, Order: order placed for purchasing the pet (required) + body, Order: order placed for purchasing the pet (optional) Returns: Order diff --git a/samples/client/petstore/python3/client/user_api.py b/samples/client/petstore/python3/client/user_api.py index c4c3c2ede52..54813ca2ddd 100644 --- a/samples/client/petstore/python3/client/user_api.py +++ b/samples/client/petstore/python3/client/user_api.py @@ -35,7 +35,7 @@ class UserApi(object): This can only be done by the logged in user. Args: - body, User: Created user object (required) + body, User: Created user object (optional) Returns: @@ -77,7 +77,7 @@ class UserApi(object): Args: - body, list[User]: List of user object (required) + body, list[User]: List of user object (optional) Returns: @@ -119,7 +119,7 @@ class UserApi(object): Args: - body, list[User]: List of user object (required) + body, list[User]: List of user object (optional) Returns: @@ -161,8 +161,8 @@ class UserApi(object): Args: - username, str: The user name for login (required) - password, str: The password for login in clear text (required) + username, str: The user name for login (optional) + password, str: The password for login in clear text (optional) Returns: str @@ -311,7 +311,7 @@ class UserApi(object): Args: username, str: name that need to be deleted (required) - body, User: Updated user object (required) + body, User: Updated user object (optional) Returns: From 3eca940e7de98f33c5ce29d265365061899d5078 Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 25 Jun 2015 23:10:25 +0800 Subject: [PATCH 174/499] fix perl and asyncscala optional tab --- .../main/resources/asyncscala/api.mustache | 11 +- .../src/main/resources/perl/api.mustache | 2 +- samples/client/petstore/async-scala/build.sbt | 12 +- .../io/swagger/client/SwaggerClient.scala | 28 +- .../scala/io/swagger/client/api/PetApi.scala | 360 +++++++++--------- .../io/swagger/client/api/StoreApi.scala | 171 ++++----- .../scala/io/swagger/client/api/UserApi.scala | 351 ++++++++--------- .../io/swagger/client/model/Category.scala | 12 +- .../scala/io/swagger/client/model/Order.scala | 20 +- .../scala/io/swagger/client/model/Pet.scala | 20 +- .../scala/io/swagger/client/model/Tag.scala | 12 +- .../scala/io/swagger/client/model/User.scala | 24 +- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 18 +- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 2 +- .../perl/lib/WWW/SwaggerClient/UserApi.pm | 12 +- 15 files changed, 526 insertions(+), 529 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache b/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache index cd12ae18806..49b7c089704 100644 --- a/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache +++ b/modules/swagger-codegen/src/main/resources/asyncscala/api.mustache @@ -11,10 +11,9 @@ import collection.mutable class {{classname}}(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { {{#operation}} - def {{nickname}}({{#allParams}}{{#optional}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}}, - {{/hasMore}} - {{/optional}}{{^optional}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}}, - {{/hasMore}}{{/optional}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = { + def {{nickname}}({{#allParams}}{{^required}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}},{{/hasMore}} + {{/required}}{{#required}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}}, + {{/hasMore}}{{/required}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = { // create path and map variables val path = (addFmt("{{path}}"){{#pathParams}} replaceAll ("\\{" + "{{baseName}}" + "\\}",{{paramName}}.toString){{/pathParams}}) @@ -27,8 +26,8 @@ class {{classname}}(client: TransportClient, config: SwaggerConfig) extends ApiC val paramCount = (Set[Any]({{/requiredParamCount}}{{#requiredParams}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) - null).size if (paramCount != {{requiredParamCount}}) sys.error("missing required params"){{/requiredParamCount}} - {{#queryParams}}{{#optional}}if({{paramName}} != null) {{paramName}}.foreach { v => queryParams += "{{baseName}}" -> v.toString }{{/optional}}{{^optional}} - if({{paramName}} != null) queryParams += "{{baseName}}" -> {{paramName}}.toString{{/optional}}{{/queryParams}} + {{#queryParams}}{{^required}}if({{paramName}} != null) {{paramName}}.foreach { v => queryParams += "{{baseName}}" -> v.toString }{{/required}}{{#required}} + if({{paramName}} != null) queryParams += "{{baseName}}" -> {{paramName}}.toString{{/required}}{{/queryParams}} {{#headerParams}}headerParams += "{{baseName}}" -> {{paramName}}.toString{{/headerParams}} diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index 93848cf5af8..e69e4e3066f 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -54,7 +54,7 @@ sub new { # # {{{summary}}} # -{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{^optional}}(required){{/optional}}{{#optional}}(optional){{/optional}} +{{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} # sub {{nickname}} { diff --git a/samples/client/petstore/async-scala/build.sbt b/samples/client/petstore/async-scala/build.sbt index 1d7306d541d..b02498c74e8 100644 --- a/samples/client/petstore/async-scala/build.sbt +++ b/samples/client/petstore/async-scala/build.sbt @@ -3,10 +3,10 @@ organization := "" name := "-client" libraryDependencies ++= Seq( -"com.wordnik" %% "swagger-async-httpclient" % "0.3.5", -"joda-time" % "joda-time" % "2.3", -"org.joda" % "joda-convert" % "1.3.1", -"ch.qos.logback" % "logback-classic" % "1.0.13" % "provided", -"org.scalatest" %% "scalatest" % "2.2.1" % "test", -"junit" % "junit" % "4.11" % "test" + "io.swagger" %% "swagger-async-httpclient" % "0.3.5", + "joda-time" % "joda-time" % "2.3", + "org.joda" % "joda-convert" % "1.3.1", + "ch.qos.logback" % "logback-classic" % "1.0.13" % "provided", + "org.scalatest" %% "scalatest" % "2.2.1" % "test", + "junit" % "junit" % "4.11" % "test" ) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala index 92262387823..9d0c05187a9 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala @@ -7,21 +7,21 @@ import io.swagger.client._ import java.io.Closeable class SwaggerClient(config: SwaggerConfig) extends Closeable { -val locator = config.locator -val name = config.name + val locator = config.locator + val name = config.name -private[this] val client = transportClient + private[this] val client = transportClient -protected def transportClient: TransportClient = new RestClient(config) + protected def transportClient: TransportClient = new RestClient(config) + + val user = new UserApi(client, config) + + val pet = new PetApi(client, config) + + val store = new StoreApi(client, config) + - val user = new UserApi(client, config) - - val pet = new PetApi(client, config) - - val store = new StoreApi(client, config) - - -def close() { -client.close() -} + def close() { + client.close() + } } \ No newline at end of file diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala index 5138049a22a..4b6a2b155d9 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/PetApi.scala @@ -7,187 +7,191 @@ import scala.concurrent.{ Future, Await } import scala.concurrent.duration._ import collection.mutable - class PetApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { +class PetApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { - - def updatePet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet")) + + def updatePet(body: Option[Pet] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet")) - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def addPet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def findPetsByStatus(status: List[String] = available)(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { - // create path and map variables - val path = (addFmt("/pet/findByStatus")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - if(status != null) queryParams += "status" -> status.toString - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def findPetsByTags(tags: List[String])(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { - // create path and map variables - val path = (addFmt("/pet/findByTags")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - if(tags != null) queryParams += "tags" -> tags.toString - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = { - // create path and map variables - val path = (addFmt("/pet/{petId}") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def updatePetWithForm(petId: String, - name: String, - status: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet/{petId}") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def deletePet(apiKey: String, - petId: Long)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet/{petId}") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - headerParams += "api_key" -> apiKey.toString - - val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def uploadFile(petId: Long, - additionalMetadata: String, - file: File)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/pet/{petId}/uploadImage") - replaceAll ("\\{" + "petId" + "\\}",petId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) } + } + + + def addPet(body: Option[Pet] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def findPetsByStatus(status: Option[List[String]] = Some(available) + )(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { + // create path and map variables + val path = (addFmt("/pet/findByStatus")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + if(status != null) status.foreach { v => queryParams += "status" -> v.toString } + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def findPetsByTags(tags: Option[List[String]] = None + )(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { + // create path and map variables + val path = (addFmt("/pet/findByTags")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + if(tags != null) tags.foreach { v => queryParams += "tags" -> v.toString } + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def updatePetWithForm(petId: String, + name: Option[String] = None, + status: Option[String] = None + )(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def deletePet(apiKey: Option[String] = None, + petId: Long)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + headerParams += "api_key" -> apiKey.toString + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def uploadFile(petId: Long, + additionalMetadata: Option[String] = None, + file: Option[File] = None + )(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}/uploadImage") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + +} diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala index c98675739de..c7a18efbf14 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/StoreApi.scala @@ -6,94 +6,95 @@ import scala.concurrent.{ Future, Await } import scala.concurrent.duration._ import collection.mutable - class StoreApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { +class StoreApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { - - def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = { - // create path and map variables - val path = (addFmt("/store/inventory")) + + def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = { + // create path and map variables + val path = (addFmt("/store/inventory")) - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def placeOrder(body: Order)(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = { - // create path and map variables - val path = (addFmt("/store/order")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def getOrderById(orderId: String)(implicit reader: ClientResponseReader[Order]): Future[Order] = { - // create path and map variables - val path = (addFmt("/store/order/{orderId}") - replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/store/order/{orderId}") - replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) } + } + + + def placeOrder(body: Option[Order] = None + )(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = { + // create path and map variables + val path = (addFmt("/store/order")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def getOrderById(orderId: String)(implicit reader: ClientResponseReader[Order]): Future[Order] = { + // create path and map variables + val path = (addFmt("/store/order/{orderId}") + replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/store/order/{orderId}") + replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + +} diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala index 3b8ba3cdc2e..766e4d22312 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/api/UserApi.scala @@ -6,183 +6,186 @@ import scala.concurrent.{ Future, Await } import scala.concurrent.duration._ import collection.mutable - class UserApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { +class UserApi(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { - - def createUser(body: User)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user")) + + def createUser(body: Option[User] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user")) - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def createUsersWithArrayInput(body: List[User])(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/createWithArray")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def createUsersWithListInput(body: List[User])(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/createWithList")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def loginUser(username: String, - password: String)(implicit reader: ClientResponseReader[String]): Future[String] = { - // create path and map variables - val path = (addFmt("/user/login")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - if(username != null) queryParams += "username" -> username.toString - if(password != null) queryParams += "password" -> password.toString - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def logoutUser()(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/logout")) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def getUserByName(username: String)(implicit reader: ClientResponseReader[User]): Future[User] = { - // create path and map variables - val path = (addFmt("/user/{username}") - replaceAll ("\\{" + "username" + "\\}",username.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def updateUser(username: String, - body: User)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/{username}") - replaceAll ("\\{" + "username" + "\\}",username.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) - resFuture flatMap { resp => - process(reader.read(resp)) - } - } - - - def deleteUser(username: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { - // create path and map variables - val path = (addFmt("/user/{username}") - replaceAll ("\\{" + "username" + "\\}",username.toString)) - - // query params - val queryParams = new mutable.HashMap[String, String] - val headerParams = new mutable.HashMap[String, String] - - - - - - - - val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") - resFuture flatMap { resp => - process(reader.read(resp)) - } - } + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) } + } + + + def createUsersWithArrayInput(body: Option[List[User]] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/createWithArray")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def createUsersWithListInput(body: Option[List[User]] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/createWithList")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def loginUser(username: Option[String] = None, + password: Option[String] = None + )(implicit reader: ClientResponseReader[String]): Future[String] = { + // create path and map variables + val path = (addFmt("/user/login")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + if(username != null) username.foreach { v => queryParams += "username" -> v.toString }if(password != null) password.foreach { v => queryParams += "password" -> v.toString } + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def logoutUser()(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/logout")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def getUserByName(username: String)(implicit reader: ClientResponseReader[User]): Future[User] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def updateUser(username: String, + body: Option[User] = None + )(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + def deleteUser(username: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + + + + + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + + +} diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala index a19b846e875..1b410e7c59e 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Category.scala @@ -3,10 +3,8 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Category ( - id: Long, - name: String - - ) - +case class Category ( + id: Long, + name: String + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala index 4e847e74b27..f7a10a44965 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Order.scala @@ -3,14 +3,12 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Order ( - id: Long, - petId: Long, - quantity: Integer, - shipDate: DateTime, - status: String, // Order Status - complete: Boolean - - ) - +case class Order ( + id: Long, + petId: Long, + quantity: Integer, + shipDate: DateTime, + status: String, // Order Status + complete: Boolean + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala index d7da69df9ee..7e76c72914b 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Pet.scala @@ -3,14 +3,12 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Pet ( - id: Long, - category: Category, - name: String, - photoUrls: List[String], - tags: List[Tag], - status: String // pet status in the store - - ) - +case class Pet ( + id: Long, + category: Category, + name: String, + photoUrls: List[String], + tags: List[Tag], + status: String // pet status in the store + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala index aa2a883063f..9dfe60d36f8 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/Tag.scala @@ -3,10 +3,8 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class Tag ( - id: Long, - name: String - - ) - +case class Tag ( + id: Long, + name: String + +) diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala index 692ec715347..598adae451a 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/model/User.scala @@ -3,16 +3,14 @@ package io.swagger.client.model import org.joda.time.DateTime - - case class User ( - id: Long, - username: String, - firstName: String, - lastName: String, - email: String, - password: String, - phone: String, - userStatus: Integer // User Status - - ) - +case class User ( + id: Long, + username: String, + firstName: String, + lastName: String, + email: String, + password: String, + phone: String, + userStatus: Integer // User Status + +) diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 7fe640aaea4..bf085889e79 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -52,7 +52,7 @@ sub new { # # Update an existing pet # -# @param Pet $body Pet object that needs to be added to the store (required) +# @param Pet $body Pet object that needs to be added to the store (optional) # @return void # sub update_pet { @@ -102,7 +102,7 @@ sub update_pet { # # Add a new pet to the store # -# @param Pet $body Pet object that needs to be added to the store (required) +# @param Pet $body Pet object that needs to be added to the store (optional) # @return void # sub add_pet { @@ -152,7 +152,7 @@ sub add_pet { # # Finds Pets by status # -# @param ARRAY[string] $status Status values that need to be considered for filter (required) +# @param ARRAY[string] $status Status values that need to be considered for filter (optional) # @return ARRAY[Pet] # sub find_pets_by_status { @@ -205,7 +205,7 @@ sub find_pets_by_status { # # Finds Pets by tags # -# @param ARRAY[string] $tags Tags to filter by (required) +# @param ARRAY[string] $tags Tags to filter by (optional) # @return ARRAY[Pet] # sub find_pets_by_tags { @@ -319,8 +319,8 @@ sub get_pet_by_id { # Updates a pet in the store with form data # # @param string $pet_id ID of pet that needs to be updated (required) -# @param string $name Updated name of the pet (required) -# @param string $status Updated status of the pet (required) +# @param string $name Updated name of the pet (optional) +# @param string $status Updated status of the pet (optional) # @return void # sub update_pet_with_form { @@ -387,7 +387,7 @@ sub update_pet_with_form { # # Deletes a pet # -# @param string $api_key (required) +# @param string $api_key (optional) # @param int $pet_id Pet id to delete (required) # @return void # @@ -449,8 +449,8 @@ sub delete_pet { # uploads an image # # @param int $pet_id ID of pet to update (required) -# @param string $additional_metadata Additional data to pass to server (required) -# @param file $file file to upload (required) +# @param string $additional_metadata Additional data to pass to server (optional) +# @param file $file file to upload (optional) # @return void # sub upload_file { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index 6072f61518c..a2ac9010e77 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -101,7 +101,7 @@ sub get_inventory { # # Place an order for a pet # -# @param Order $body order placed for purchasing the pet (required) +# @param Order $body order placed for purchasing the pet (optional) # @return Order # sub place_order { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index f588f1bb410..4c6e293aaaa 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -52,7 +52,7 @@ sub new { # # Create user # -# @param User $body Created user object (required) +# @param User $body Created user object (optional) # @return void # sub create_user { @@ -102,7 +102,7 @@ sub create_user { # # Creates list of users with given input array # -# @param ARRAY[User] $body List of user object (required) +# @param ARRAY[User] $body List of user object (optional) # @return void # sub create_users_with_array_input { @@ -152,7 +152,7 @@ sub create_users_with_array_input { # # Creates list of users with given input array # -# @param ARRAY[User] $body List of user object (required) +# @param ARRAY[User] $body List of user object (optional) # @return void # sub create_users_with_list_input { @@ -202,8 +202,8 @@ sub create_users_with_list_input { # # Logs user into the system # -# @param string $username The user name for login (required) -# @param string $password The password for login in clear text (required) +# @param string $username The user name for login (optional) +# @param string $password The password for login in clear text (optional) # @return string # sub login_user { @@ -366,7 +366,7 @@ sub get_user_by_name { # Updated user # # @param string $username name that need to be deleted (required) -# @param User $body Updated user object (required) +# @param User $body Updated user object (optional) # @return void # sub update_user { From 91af76cf4187f2f60c3e200cbca3a4ce5364b7ec Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Sat, 27 Jun 2015 21:04:01 +0900 Subject: [PATCH 175/499] Use CLI option --- README.md | 2 +- bin/swift-petstore.json | 4 + bin/swift-petstore.sh | 4 +- ...{SwiftGenerator.java => SwiftCodegen.java} | 85 ++++++++---- .../services/io.swagger.codegen.CodegenConfig | 2 +- .../src/main/resources/swift/APIs.mustache | 10 +- .../swift/AlamofireImplementations.mustache | 18 +-- .../main/resources/swift/Extensions.mustache | 18 ++- .../src/main/resources/swift/Models.mustache | 4 +- .../src/main/resources/swift/model.mustache | 10 +- .../petstore/swift/PetstoreClient/Cartfile | 2 - .../Classes/Swaggers/APIs.swift | 10 +- .../Classes/Swaggers/APIs/PetAPI.swift | 128 ++++++++++++++++-- .../Classes/Swaggers/APIs/StoreAPI.swift | 76 +++++++++-- .../Classes/Swaggers/APIs/UserAPI.swift | 18 ++- .../Swaggers/AlamofireImplementations.swift | 22 +-- .../Classes/Swaggers/Extensions.swift | 14 ++ 17 files changed, 326 insertions(+), 101 deletions(-) create mode 100644 bin/swift-petstore.json rename modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/{SwiftGenerator.java => SwiftCodegen.java} (78%) delete mode 100644 samples/client/petstore/swift/PetstoreClient/Cartfile diff --git a/README.md b/README.md index f2c44ebf718..2fb525528a3 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ StaticDocCodegen.java StaticHtmlGenerator.java SwaggerGenerator.java SwaggerYamlGenerator.java -SwiftGenerator.java +SwiftCodegen.java TizenClientCodegen.java ``` diff --git a/bin/swift-petstore.json b/bin/swift-petstore.json new file mode 100644 index 00000000000..700fdeff061 --- /dev/null +++ b/bin/swift-petstore.json @@ -0,0 +1,4 @@ +{ + "projectName": "PetstoreClient", + "responseAs": "PromiseKit" +} \ No newline at end of file diff --git a/bin/swift-petstore.sh b/bin/swift-petstore.sh index 4436ed8774d..96433e5b72d 100755 --- a/bin/swift-petstore.sh +++ b/bin/swift-petstore.sh @@ -26,6 +26,6 @@ fi # if you've executed sbt assembly previously it will use that instead. export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" -ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -c ./bin/swift-petstore.json -o samples/client/petstore/swift" -java -DsuppressRequired=true -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java similarity index 78% rename from modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java rename to modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java index 96f0666df52..5d4f5f341a7 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java @@ -11,6 +11,7 @@ import io.swagger.models.parameters.Parameter; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import javax.annotation.Nullable; @@ -19,8 +20,13 @@ import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { +public class SwiftCodegen extends DefaultCodegen implements CodegenConfig { private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); + protected static final String LIBRARY_PROMISE_KIT = "PromiseKit"; + protected static final String[] RESPONSE_LIBRARIES = { LIBRARY_PROMISE_KIT }; + protected String projectName = "SwaggerClient"; + protected boolean unwrapRequired = false; + protected String[] responseAs = new String[0]; protected String sourceFolder = "Classes" + File.separator + "Swaggers"; public CodegenType getTag() { @@ -35,7 +41,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { return "Generates a swift client library."; } - public SwiftGenerator() { + public SwiftCodegen() { super(); outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); @@ -44,34 +50,6 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { apiPackage = File.separator + "APIs"; modelPackage = File.separator + "Models"; - // Inject application name - String appName = System.getProperty("appName"); - if (appName == null) { - appName = "SwaggerClient"; - } - additionalProperties.put("projectName", appName); - - // Inject base url override - String basePathOverride = System.getProperty("basePathOverride"); - if (basePathOverride != null) { - additionalProperties.put("basePathOverride", basePathOverride); - } - - // Make all the variable optional - String suppressRequired = System.getProperty("suppressRequired"); - if (suppressRequired != null) { - additionalProperties.put("suppressRequired", suppressRequired); - } - - sourceFolder = appName + File.separator + sourceFolder; - - supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); - supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); - supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, "AlamofireImplementations.swift")); - supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift")); - supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); - supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - languageSpecificPrimitives = new HashSet( Arrays.asList( "Int", @@ -125,6 +103,53 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { typeMapping.put("file", "NSData"); importMapping = new HashMap(); + + cliOptions.add(new CliOption("projectName", "Project name in Xcode")); + cliOptions.add(new CliOption("responseAs", "Optionally use libraries to manage response. Currently " + + StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available.")); + cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " + + "(which would crash the app if api returns null as opposed to required option specified in json schema")); + } + + @Override + public void processOpts() { + super.processOpts(); + + // Setup project name + if (additionalProperties.containsKey("projectName")) { + projectName = (String) additionalProperties.get("projectName"); + } else { + additionalProperties.put("projectName", projectName); + } + sourceFolder = projectName + File.separator + sourceFolder; + + // Setup unwrapRequired option, which makes all the properties with "required" non-optional + if (additionalProperties.containsKey("unwrapRequired")) { + unwrapRequired = Boolean.parseBoolean(String.valueOf(additionalProperties.get("unwrapRequired"))); + } + additionalProperties.put("unwrapRequired", unwrapRequired); + + // Setup unwrapRequired option, which makes all the properties with "required" non-optional + if (additionalProperties.containsKey("responseAs")) { + Object responseAsObject = additionalProperties.get("responseAs"); + if (responseAsObject instanceof String) { + responseAs = ((String)responseAsObject).split(","); + } else { + responseAs = (String[]) responseAsObject; + } + } + additionalProperties.put("responseAs", responseAs); + if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) { + additionalProperties.put("usePromiseKit", true); + } + + supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); + supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); + supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, + "AlamofireImplementations.swift")); + supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift")); + supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); + supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); } @Override diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 7360129285e..29c7ed0f729 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -21,7 +21,7 @@ io.swagger.codegen.languages.StaticDocCodegen io.swagger.codegen.languages.StaticHtmlGenerator io.swagger.codegen.languages.SwaggerGenerator io.swagger.codegen.languages.SwaggerYamlGenerator -io.swagger.codegen.languages.SwiftGenerator +io.swagger.codegen.languages.SwiftCodegen io.swagger.codegen.languages.TizenClientCodegen io.swagger.codegen.languages.TypeScriptAngularClientCodegen io.swagger.codegen.languages.TypeScriptNodeClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache index d9fcb84c125..e473915cf24 100644 --- a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache @@ -5,10 +5,9 @@ // import Foundation -import PromiseKit -class {{projectName}}API { - static let basePath = "{{^basePathOverride}}{{basePath}}{{/basePathOverride}}{{basePathOverride}}" +class OneteamAPI { + static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/" static var credential: NSURLCredential? static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() } @@ -44,7 +43,7 @@ class RequestBuilder { self.isBody = isBody } - func execute() -> Promise> { fatalError("Not implemented") } + func execute(completion: (response: Response?, erorr: NSError?) -> Void) { } func addHeader(#name: String, value: String) -> Self { if !value.isEmpty { @@ -54,7 +53,7 @@ class RequestBuilder { } func addCredential() -> Self { - self.credential = {{projectName}}API.credential + self.credential = OneteamAPI.credential return self } } @@ -63,4 +62,3 @@ protocol RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type } - diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index edc7a51a169..61e2bf2886d 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -5,7 +5,6 @@ // import Alamofire -import PromiseKit class AlamofireRequestBuilderFactory: RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type { @@ -21,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder { super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) } - override func execute() -> Promise> { + override func execute(completion: (response: Response?, erorr: NSError?) -> Void) { let managerId = NSUUID().UUIDString // Create a new manager for each request to customize its request header let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() @@ -35,43 +34,41 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - let defer = Promise>.defer() request.responseJSON(options: .AllowFragments) { (req, res, json, error) in managerStore.removeValueForKey(managerId) if let error = error { - defer.reject(error) + completion(response: nil, erorr: error) return } if res!.statusCode >= 400 { //TODO: Add error entity let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) - defer.reject(error) + completion(response: nil, erorr: error) return } if () is T { let response = Response(response: res!, body: () as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } if let json: AnyObject = json { let body = Decoders.decode(clazz: T.self, source: json) let response = Response(response: res!, body: body) - defer.fulfill(response) + completion(response: response, erorr: nil) return } else if "" is T { // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release // https://github.com/swagger-api/swagger-parser/pull/34 let response = Response(response: res!, body: "" as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } - defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) } - return defer.promise } private func buildHeaders() -> [String: AnyObject] { @@ -83,4 +80,3 @@ class AlamofireRequestBuilder: RequestBuilder { } } - diff --git a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache index a06ebae7026..801e90514ff 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache @@ -4,8 +4,8 @@ // https://github.com/swagger-api/swagger-codegen // -import Alamofire -import PromiseKit +import Alamofire{{#usePromiseKit}} +import PromiseKit{{/usePromiseKit}} extension Bool: JSONEncodable { func encodeToJSON() -> AnyObject { return self } @@ -63,3 +63,17 @@ extension NSDate: JSONEncodable { return dateFormatter.stringFromDate(self) } } + +{{#usePromiseKit}}extension RequestBuilder { + func execute() -> Promise> { + let deferred = Promise>.defer() + self.execute { (response: Response?, error: NSError?) in + if let response = response { + deferred.fulfill(response) + } else { + deferred.reject(error!) + } + } + return deferred.promise + } +}{{/usePromiseKit}} diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index b2f72e483ad..f832cdab9a4 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}} {{/isEnum}}{{^isEnum}} - instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}}){{/isEnum}}{{/vars}} + instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}} {{/isEnum}}{{^isEnum}} + instance.{{name}} = Decoders.decode{{^unwrapRequired}}Optional{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}Optional{{/required}}{{/unwrapRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}}){{/isEnum}}{{/vars}} return instance }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 2302a6f44a5..bcd4702fb3b 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable { } {{/isEnum}}{{/vars}} {{#vars}}{{#isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatype}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} + {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ + {{/description}}var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/vars}} // MARK: JSONEncodable func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} - nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } diff --git a/samples/client/petstore/swift/PetstoreClient/Cartfile b/samples/client/petstore/swift/PetstoreClient/Cartfile deleted file mode 100644 index 245a690a74b..00000000000 --- a/samples/client/petstore/swift/PetstoreClient/Cartfile +++ /dev/null @@ -1,2 +0,0 @@ -github "Alamofire/Alamofire" >= 1.2 -github "mxcl/PromiseKit" \ No newline at end of file diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift index 75138ff689a..e473915cf24 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift @@ -5,10 +5,9 @@ // import Foundation -import PromiseKit -class PetstoreClientAPI { - static let basePath = "http://petstore.swagger.io/v2" +class OneteamAPI { + static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/" static var credential: NSURLCredential? static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() } @@ -44,7 +43,7 @@ class RequestBuilder { self.isBody = isBody } - func execute() -> Promise> { fatalError("Not implemented") } + func execute(completion: (response: Response?, erorr: NSError?) -> Void) { } func addHeader(#name: String, value: String) -> Self { if !value.isEmpty { @@ -54,7 +53,7 @@ class RequestBuilder { } func addCredential() -> Self { - self.credential = PetstoreClientAPI.credential + self.credential = OneteamAPI.credential return self } } @@ -63,4 +62,3 @@ protocol RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type } - diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index b136a04f8d2..5202240bbc9 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -71,8 +71,44 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - name: petstore_auth - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] :param: status (query) Status values that need to be considered for filter @@ -101,8 +137,44 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - name: petstore_auth - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] :param: tags (query) Tags to filter by @@ -134,14 +206,50 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - name: petstore_auth - - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example={ + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +}, contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] + - examples: [{example={ + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +}, contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] :param: petId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getPetById(#petId: Int?) -> RequestBuilder { + func getPetById(#petId: Int) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -170,7 +278,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updatePetWithForm(#petId: String?, name: String?, status: String?) -> RequestBuilder { + func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -197,7 +305,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deletePet(#petId: Int?) -> RequestBuilder { + func deletePet(#petId: Int) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -226,7 +334,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func uploadFile(#petId: Int?, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { var path = "/pet/{petId}/uploadImage" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index ed0c5a87889..ad122129939 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -21,8 +21,12 @@ extension PetstoreClientAPI { - API Key: - type: apiKey api_key - name: api_key - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] + - examples: [{example={ + "key" : 123 +}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@3e, contentType=application/xml}] + - examples: [{example={ + "key" : 123 +}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@3e, contentType=application/xml}] :returns: Promise> */ @@ -44,8 +48,36 @@ extension PetstoreClientAPI { - POST /store/order - - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.102+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.105Z + string + true +, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.102+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.105Z + string + true +, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -68,14 +100,42 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.106+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.106Z + string + true +, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.106+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.106Z + string + true +, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getOrderById(#orderId: String?) -> RequestBuilder { + func getOrderById(#orderId: String) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -99,7 +159,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteOrder(#orderId: String?) -> RequestBuilder { + func deleteOrder(#orderId: String) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift index 812d823459d..9c283396214 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -134,14 +134,22 @@ extension PetstoreClientAPI { - GET /user/{username} - - - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + - examples: [{example={ + "id" : 1, + "username" : "johnp", + "firstName" : "John", + "lastName" : "Public", + "email" : "johnp@swagger.io", + "password" : "-secret-", + "phone" : "0123456789", + "userStatus" : 0 +}, contentType=application/json}] :param: username (path) The name that needs to be fetched. Use user1 for testing. :returns: Promise> */ - func getUserByName(#username: String?) -> RequestBuilder { + func getUserByName(#username: String) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -166,7 +174,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updateUser(#username: String?, body: User?) -> RequestBuilder { + func updateUser(#username: String, body: User?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -189,7 +197,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteUser(#username: String?) -> RequestBuilder { + func deleteUser(#username: String) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift index 37edceea13c..61e2bf2886d 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift @@ -5,7 +5,6 @@ // import Alamofire -import PromiseKit class AlamofireRequestBuilderFactory: RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type { @@ -21,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder { super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) } - override func execute() -> Promise> { + override func execute(completion: (response: Response?, erorr: NSError?) -> Void) { let managerId = NSUUID().UUIDString // Create a new manager for each request to customize its request header let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() @@ -35,37 +34,41 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - let defer = Promise>.defer() request.responseJSON(options: .AllowFragments) { (req, res, json, error) in managerStore.removeValueForKey(managerId) if let error = error { - defer.reject(error) + completion(response: nil, erorr: error) return } if res!.statusCode >= 400 { //TODO: Add error entity let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) - defer.reject(error) + completion(response: nil, erorr: error) return } if () is T { let response = Response(response: res!, body: () as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } if let json: AnyObject = json { let body = Decoders.decode(clazz: T.self, source: json) let response = Response(response: res!, body: body) - defer.fulfill(response) + completion(response: response, erorr: nil) + return + } else if "" is T { + // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release + // https://github.com/swagger-api/swagger-parser/pull/34 + let response = Response(response: res!, body: "" as! T) + completion(response: response, erorr: nil) return } - defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) } - return defer.promise } private func buildHeaders() -> [String: AnyObject] { @@ -77,4 +80,3 @@ class AlamofireRequestBuilder: RequestBuilder { } } - diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift index a06ebae7026..80af4351f04 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift @@ -63,3 +63,17 @@ extension NSDate: JSONEncodable { return dateFormatter.stringFromDate(self) } } + +extension RequestBuilder { + func execute() -> Promise> { + let deferred = Promise>.defer() + self.execute { (response: Response?, error: NSError?) in + if let response = response { + deferred.fulfill(response) + } else { + deferred.reject(error!) + } + } + return deferred.promise + } +} From 76ece5a4eb1a108d4f8a70dd29eb0f8b7e9738c4 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 29 Jun 2015 12:17:49 +0800 Subject: [PATCH 176/499] add file response support for c# (passed test cases) --- .../languages/CSharpClientCodegen.java | 2 +- .../main/resources/csharp/ApiClient.mustache | 53 +++-- .../resources/csharp/Configuration.mustache | 59 +++++- .../src/main/resources/csharp/api.mustache | 61 +++--- .../src/main/csharp/IO/Swagger/Api/PetApi.cs | 193 ++++++++++-------- .../main/csharp/IO/Swagger/Api/StoreApi.cs | 73 ++++--- .../src/main/csharp/IO/Swagger/Api/UserApi.cs | 149 +++++++------- .../csharp/IO/Swagger/Client/ApiClient.cs | 51 +++-- .../csharp/IO/Swagger/Client/Configuration.cs | 59 +++++- .../SwaggerClientTest.userprefs | 9 +- .../bin/Debug/SwaggerClientTest.dll | Bin 51200 -> 53248 bytes .../bin/Debug/SwaggerClientTest.dll.mdb | Bin 15782 -> 16213 bytes .../obj/Debug/SwaggerClientTest.dll | Bin 51200 -> 53248 bytes .../obj/Debug/SwaggerClientTest.dll.mdb | Bin 15782 -> 16213 bytes 14 files changed, 440 insertions(+), 269 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index 33ea13b5e31..4f7ad02b95d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -68,7 +68,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.put("number", "double?"); typeMapping.put("datetime", "DateTime?"); typeMapping.put("date", "DateTime?"); - typeMapping.put("file", "string"); // path to file + typeMapping.put("file", "FileStream"); typeMapping.put("array", "List"); typeMapping.put("list", "List"); typeMapping.put("map", "Dictionary"); diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index c6f57bd4a37..5c1fb8d9125 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text.RegularExpressions; using System.IO; using System.Linq; using System.Net; @@ -19,21 +20,21 @@ namespace {{packageName}}.Client { /// /// The base path. public ApiClient(String basePath="{{basePath}}") { - this.basePath = basePath; - this.restClient = new RestClient(this.basePath); + this.BasePath = basePath; + this.RestClient = new RestClient(this.BasePath); } /// /// Gets or sets the base path. /// /// The base path. - public string basePath { get; set; } + public string BasePath { get; set; } /// /// Gets or sets the RestClient /// /// The RestClient. - public RestClient restClient { get; set; } + public RestClient RestClient { get; set; } private Dictionary defaultHeaderMap = new Dictionary(); @@ -77,7 +78,7 @@ namespace {{packageName}}.Client { request.AddParameter("application/json", PostBody, ParameterType.RequestBody); // http body (model) parameter } - return (Object) await restClient.ExecuteTaskAsync(request); + return (Object) await RestClient.ExecuteTaskAsync(request); } @@ -119,10 +120,12 @@ namespace {{packageName}}.Client { { if (obj is DateTime) { return ((DateTime)obj).ToString ("u"); + } else if (obj is FileStream) { + return ((FileStream)obj).Name; } else if (obj is List) { return String.Join(",", obj as List); } else { - return Convert.ToString (obj); + return Convert.ToString (obj); } } @@ -132,16 +135,38 @@ namespace {{packageName}}.Client { /// JSON string /// Object type /// Object representation of the JSON string - public object Deserialize(string content, Type type) { - if (type.GetType() == typeof(Object)) - return (Object)content; + public object Deserialize(string content, Type type, IList headers=null) { + if (type.GetType() == typeof(Object)) { + return (Object)content; + } else if (type.Name == "FileStream") { + // e.g. Content-Disposition: attachment; filename=checkimage.jpp + String fileName; + String filePath; + if (String.IsNullOrEmpty (Configuration.TempFolderPath)) { + filePath = System.IO.Path.GetTempPath (); + } else { + filePath = Configuration.TempFolderPath; + } + + Regex regex = new Regex(@"Content-Disposition:.*filename=['""]?([^'""\s]+)['""]?$"); + Match match = regex.Match(headers.ToString()); + if (match.Success) { + // replace first and last " or ', if found + fileName = filePath + match.Value.Replace("\"", "").Replace("'",""); + } else { + fileName = filePath + Guid.NewGuid().ToString(); + } + System.IO.File.WriteAllText (fileName, content); + return File.Open (fileName, FileMode.Open); + } + try { return JsonConvert.DeserializeObject(content, type); } catch (IOException e) { - throw new ApiException(500, e.Message); + throw new ApiException(500, e.Message); } } @@ -165,12 +190,12 @@ namespace {{packageName}}.Client { /// /// Object /// API key with prefix - public string GetApiKeyWithPrefix (string apiKey) + public string GetApiKeyWithPrefix (string apiKeyIdentifier) { var apiKeyValue = ""; - Configuration.apiKey.TryGetValue (apiKey, out apiKeyValue); + Configuration.ApiKey.TryGetValue (apiKeyIdentifier, out apiKeyValue); var apiKeyPrefix = ""; - if (Configuration.apiKeyPrefix.TryGetValue (apiKey, out apiKeyPrefix)) { + if (Configuration.ApiKeyPrefix.TryGetValue (apiKeyIdentifier, out apiKeyPrefix)) { return apiKeyPrefix + " " + apiKeyValue; } else { return apiKeyValue; @@ -192,7 +217,7 @@ namespace {{packageName}}.Client { 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}} + {{#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}} diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index 485d97058ce..8611d2c18b4 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Collections.Generic; using System.IO; using System.Linq; @@ -17,35 +18,81 @@ namespace {{packageName}}.Client { public const string Version = "{{packageVersion}}"; /// - /// Gets or sets the API client. This is the default API client for making HTTP calls. + /// Gets or sets the default API client for making HTTP calls. /// /// The API client. - public static ApiClient apiClient = new ApiClient(); + public static ApiClient DefaultApiClient = new ApiClient(); /// /// Gets or sets the username (HTTP basic authentication) /// /// The username. - public static String username { get; set; } + public static String Username { get; set; } /// /// Gets or sets the password (HTTP basic authentication) /// /// The password. - public static String password { get; set; } + public static String Password { get; set; } /// /// Gets or sets the API key based on the authentication name /// /// The API key. - public static Dictionary apiKey = new Dictionary(); + public static Dictionary ApiKey = new Dictionary(); /// /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name /// /// The prefix of the API key. - public static Dictionary apiKeyPrefix = new Dictionary(); + public static Dictionary ApiKeyPrefix = new Dictionary(); + private static string _tempFolderPath = Path.GetTempPath(); + /// + /// Gets or sets the temporary folder path to store the files downloaded from the server + /// + /// Folder path + public static String TempFolderPath { + get { + return _tempFolderPath; + } + + set { + if (!String.IsNullOrEmpty(value)) { + _tempFolderPath = value; + return; + } + + // create the directory if it does not exist + if (!Directory.Exists(value)) { + Directory.CreateDirectory(value); + } + + // check if the path contains directory separator at the end + if (value[value.Length - 1] == Path.DirectorySeparatorChar) { + _tempFolderPath = value; + } else { + _tempFolderPath = value + Path.DirectorySeparatorChar; + } + } + } + + /// + /// Return a string contain essential information for debugging + /// + /// Folder path + public static String ToDebugReport() { + String report = "C# SDK ({{invokerPackage}}) Debug Report:\n"; + report += " OS: " + Environment.OSVersion + "\n"; + report += " .NET Framework Version: " + Assembly + .GetExecutingAssembly() + .GetReferencedAssemblies() + .Where(x => x.Name == "System.Core").First().Version.ToString() + "\n"; + report += " Swagger Spec Version: {{version}}\n"; + report += " SDK Package Version: {{version}}\n"; + + return report; + } } } diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index 652d15a30b3..1ae7afbf39a 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Collections.Generic; using System.Threading.Tasks; using RestSharp; @@ -15,15 +16,15 @@ namespace {{packageName}}.Api { /// /// {{summary}} {{notes}} /// - {{#allParams}}/// {{description}}{{/allParams}} - /// {{#returnType}}{{{returnType}}}{{/returnType}} + {{#allParams}}/// {{description}} + {{/allParams}}/// {{#returnType}}{{{returnType}}}{{/returnType}} {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); /// /// {{summary}} {{notes}} /// - {{#allParams}}/// {{description}}{{/allParams}} - /// {{#returnType}}{{{returnType}}}{{/returnType}} + {{#allParams}}/// {{description}} + {{/allParams}}/// {{#returnType}}{{{returnType}}}{{/returnType}} {{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}} {{nickname}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{/operation}} } @@ -40,9 +41,9 @@ namespace {{packageName}}.Api { /// public {{classname}}(ApiClient apiClient = null) { if (apiClient == null) { // use the default one in Configuration - this.apiClient = Configuration.apiClient; + this.ApiClient = Configuration.DefaultApiClient; } else { - this.apiClient = apiClient; + this.ApiClient = apiClient; } } @@ -52,7 +53,7 @@ namespace {{packageName}}.Api { /// public {{classname}}(String basePath) { - this.apiClient = new ApiClient(basePath); + this.ApiClient = new ApiClient(basePath); } /// @@ -60,7 +61,7 @@ namespace {{packageName}}.Api { /// /// The base path public void SetBasePath(String basePath) { - this.apiClient.basePath = basePath; + this.ApiClient.BasePath = basePath; } /// @@ -68,22 +69,22 @@ namespace {{packageName}}.Api { /// /// The base path public String GetBasePath(String basePath) { - return this.apiClient.basePath; + return this.ApiClient.BasePath; } /// /// Gets or sets the API client. /// /// The API client - public ApiClient apiClient {get; set;} + public ApiClient ApiClient {get; set;} {{#operation}} /// /// {{summary}} {{notes}} /// - {{#allParams}}/// {{description}}{{/allParams}} - /// {{#returnType}}{{{returnType}}}{{/returnType}} + {{#allParams}}/// {{description}} + {{/allParams}}/// {{#returnType}}{{{returnType}}}{{/returnType}} public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} @@ -93,7 +94,7 @@ namespace {{packageName}}.Api { var path = "{{path}}"; path = path.Replace("{format}", "json"); - {{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", apiClient.ParameterToString({{{paramName}}})); + {{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", ApiClient.ParameterToString({{{paramName}}})); {{/pathParams}} var queryParams = new Dictionary(); @@ -102,33 +103,33 @@ namespace {{packageName}}.Api { var fileParams = new Dictionary(); String postBody = null; - {{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // query parameter + {{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter {{/queryParams}} - {{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // header parameter + {{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter {{/headerParams}} - {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} + {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} {{/formParams}} - {{#bodyParam}}postBody = apiClient.Serialize({{paramName}}); // 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 = (IRestResponse) apiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + 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}}}) apiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} + {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} return;{{/returnType}} } - - /// + + /// /// {{summary}} {{notes}} /// - {{#allParams}}/// {{description}}{{/allParams}} - /// {{#returnType}}{{{returnType}}}{{/returnType}} + {{#allParams}}/// {{description}} + {{/allParams}}/// {{#returnType}}{{{returnType}}}{{/returnType}} public async {{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}} {{nickname}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#allParams}}{{#required}} @@ -138,7 +139,7 @@ namespace {{packageName}}.Api { var path = "{{path}}"; path = path.Replace("{format}", "json"); - {{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", apiClient.ParameterToString({{{paramName}}})); + {{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", ApiClient.ParameterToString({{{paramName}}})); {{/pathParams}} var queryParams = new Dictionary(); @@ -147,24 +148,24 @@ namespace {{packageName}}.Api { var fileParams = new Dictionary(); String postBody = null; - {{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // query parameter + {{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter {{/queryParams}} - {{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // header parameter + {{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter {{/headerParams}} - {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} + {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} {{/formParams}} - {{#bodyParam}}postBody = apiClient.Serialize({{paramName}}); // 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 = (IRestResponse) await apiClient.CallApiAsync(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + 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); } - {{#returnType}}return ({{{returnType}}}) apiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} + {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} return;{{/returnType}} } {{/operation}} diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs index 5fdb38f2da9..f41cb46baa1 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Collections.Generic; using System.Threading.Tasks; using RestSharp; @@ -83,44 +84,54 @@ namespace IO.Swagger.Api { /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated/// Updated name of the pet/// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// void UpdatePetWithForm (string PetId, string Name, string Status); /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated/// Updated name of the pet/// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// Task UpdatePetWithFormAsync (string PetId, string Name, string Status); /// /// Deletes a pet /// - /// /// Pet id to delete + /// + /// Pet id to delete /// void DeletePet (string ApiKey, long? PetId); /// /// Deletes a pet /// - /// /// Pet id to delete + /// + /// Pet id to delete /// Task DeletePetAsync (string ApiKey, long? PetId); /// /// uploads an image /// - /// ID of pet to update/// Additional data to pass to server/// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - void UploadFile (long? PetId, string AdditionalMetadata, string File); + void UploadFile (long? PetId, string AdditionalMetadata, FileStream File); /// /// uploads an image /// - /// ID of pet to update/// Additional data to pass to server/// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - Task UploadFileAsync (long? PetId, string AdditionalMetadata, string File); + Task UploadFileAsync (long? PetId, string AdditionalMetadata, FileStream File); } @@ -136,9 +147,9 @@ namespace IO.Swagger.Api { /// public PetApi(ApiClient apiClient = null) { if (apiClient == null) { // use the default one in Configuration - this.apiClient = Configuration.apiClient; + this.ApiClient = Configuration.DefaultApiClient; } else { - this.apiClient = apiClient; + this.ApiClient = apiClient; } } @@ -148,7 +159,7 @@ namespace IO.Swagger.Api { /// public PetApi(String basePath) { - this.apiClient = new ApiClient(basePath); + this.ApiClient = new ApiClient(basePath); } /// @@ -156,7 +167,7 @@ namespace IO.Swagger.Api { /// /// The base path public void SetBasePath(String basePath) { - this.apiClient.basePath = basePath; + this.ApiClient.BasePath = basePath; } /// @@ -164,14 +175,14 @@ namespace IO.Swagger.Api { /// /// The base path public String GetBasePath(String basePath) { - return this.apiClient.basePath; + return this.ApiClient.BasePath; } /// /// Gets or sets the API client. /// /// The API client - public ApiClient apiClient {get; set;} + public ApiClient ApiClient {get; set;} @@ -197,14 +208,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePet: " + response.Content, response.Content); @@ -212,8 +223,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Update an existing pet /// /// Pet object that needs to be added to the store @@ -235,14 +246,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePet: " + response.Content, response.Content); } @@ -272,14 +283,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling AddPet: " + response.Content, response.Content); @@ -287,8 +298,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Add a new pet to the store /// /// Pet object that needs to be added to the store @@ -310,14 +321,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling AddPet: " + response.Content, response.Content); } @@ -344,7 +355,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Status != null) queryParams.Add("status", apiClient.ParameterToString(Status)); // query parameter + if (Status != null) queryParams.Add("status", ApiClient.ParameterToString(Status)); // query parameter @@ -354,15 +365,15 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByStatus: " + response.Content, response.Content); } - return (List) apiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List)); } - - /// + + /// /// Finds Pets by status Multiple status values can be provided with comma seperated strings /// /// Status values that need to be considered for filter @@ -381,7 +392,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Status != null) queryParams.Add("status", apiClient.ParameterToString(Status)); // query parameter + if (Status != null) queryParams.Add("status", ApiClient.ParameterToString(Status)); // query parameter @@ -391,11 +402,11 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByStatus: " + response.Content, response.Content); } - return (List) apiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List)); } /// @@ -417,7 +428,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Tags != null) queryParams.Add("tags", apiClient.ParameterToString(Tags)); // query parameter + if (Tags != null) queryParams.Add("tags", ApiClient.ParameterToString(Tags)); // query parameter @@ -427,15 +438,15 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByTags: " + response.Content, response.Content); } - return (List) apiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List)); } - - /// + + /// /// Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. /// /// Tags to filter by @@ -454,7 +465,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Tags != null) queryParams.Add("tags", apiClient.ParameterToString(Tags)); // query parameter + if (Tags != null) queryParams.Add("tags", ApiClient.ParameterToString(Tags)); // query parameter @@ -464,11 +475,11 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByTags: " + response.Content, response.Content); } - return (List) apiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List)); } /// @@ -485,7 +496,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -503,15 +514,15 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "api_key", "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetPetById: " + response.Content, response.Content); } - return (Pet) apiClient.Deserialize(response.Content, typeof(Pet)); + return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet)); } - - /// + + /// /// Find pet by ID Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions /// /// ID of pet that needs to be fetched @@ -525,7 +536,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -543,17 +554,19 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "api_key", "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetPetById: " + response.Content, response.Content); } - return (Pet) apiClient.Deserialize(response.Content, typeof(Pet)); + return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet)); } /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated/// Updated name of the pet/// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// public void UpdatePetWithForm (string PetId, string Name, string Status) { @@ -564,7 +577,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -575,8 +588,8 @@ namespace IO.Swagger.Api { - if (Name != null) formParams.Add("name", apiClient.ParameterToString(Name)); // form parameter - if (Status != null) formParams.Add("status", apiClient.ParameterToString(Status)); // form parameter + if (Name != null) formParams.Add("name", ApiClient.ParameterToString(Name)); // form parameter + if (Status != null) formParams.Add("status", ApiClient.ParameterToString(Status)); // form parameter @@ -584,7 +597,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePetWithForm: " + response.Content, response.Content); @@ -592,11 +605,13 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated/// Updated name of the pet/// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// public async Task UpdatePetWithFormAsync (string PetId, string Name, string Status) { @@ -607,7 +622,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -618,8 +633,8 @@ namespace IO.Swagger.Api { - if (Name != null) formParams.Add("name", apiClient.ParameterToString(Name)); // form parameter - if (Status != null) formParams.Add("status", apiClient.ParameterToString(Status)); // form parameter + if (Name != null) formParams.Add("name", ApiClient.ParameterToString(Name)); // form parameter + if (Status != null) formParams.Add("status", ApiClient.ParameterToString(Status)); // form parameter @@ -627,7 +642,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePetWithForm: " + response.Content, response.Content); } @@ -638,7 +653,8 @@ namespace IO.Swagger.Api { /// /// Deletes a pet /// - /// /// Pet id to delete + /// + /// Pet id to delete /// public void DeletePet (string ApiKey, long? PetId) { @@ -649,7 +665,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -659,7 +675,7 @@ namespace IO.Swagger.Api { String postBody = null; - if (ApiKey != null) headerParams.Add("api_key", apiClient.ParameterToString(ApiKey)); // header parameter + if (ApiKey != null) headerParams.Add("api_key", ApiClient.ParameterToString(ApiKey)); // header parameter @@ -668,7 +684,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeletePet: " + response.Content, response.Content); @@ -676,11 +692,12 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Deletes a pet /// - /// /// Pet id to delete + /// + /// Pet id to delete /// public async Task DeletePetAsync (string ApiKey, long? PetId) { @@ -691,7 +708,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -701,7 +718,7 @@ namespace IO.Swagger.Api { String postBody = null; - if (ApiKey != null) headerParams.Add("api_key", apiClient.ParameterToString(ApiKey)); // header parameter + if (ApiKey != null) headerParams.Add("api_key", ApiClient.ParameterToString(ApiKey)); // header parameter @@ -710,7 +727,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeletePet: " + response.Content, response.Content); } @@ -721,9 +738,11 @@ namespace IO.Swagger.Api { /// /// uploads an image /// - /// ID of pet to update/// Additional data to pass to server/// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - public void UploadFile (long? PetId, string AdditionalMetadata, string File) { + public void UploadFile (long? PetId, string AdditionalMetadata, FileStream File) { // verify the required parameter 'PetId' is set @@ -732,7 +751,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}/uploadImage"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -743,8 +762,8 @@ namespace IO.Swagger.Api { - if (AdditionalMetadata != null) formParams.Add("additionalMetadata", apiClient.ParameterToString(AdditionalMetadata)); // form parameter - if (File != null) fileParams.Add("file", File); + if (AdditionalMetadata != null) formParams.Add("additionalMetadata", ApiClient.ParameterToString(AdditionalMetadata)); // form parameter + if (File != null) fileParams.Add("file", ApiClient.ParameterToString(File)); @@ -752,7 +771,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UploadFile: " + response.Content, response.Content); @@ -760,13 +779,15 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// uploads an image /// - /// ID of pet to update/// Additional data to pass to server/// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - public async Task UploadFileAsync (long? PetId, string AdditionalMetadata, string File) { + public async Task UploadFileAsync (long? PetId, string AdditionalMetadata, FileStream File) { // verify the required parameter 'PetId' is set @@ -775,7 +796,7 @@ namespace IO.Swagger.Api { var path = "/pet/{petId}/uploadImage"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); var queryParams = new Dictionary(); @@ -786,8 +807,8 @@ namespace IO.Swagger.Api { - if (AdditionalMetadata != null) formParams.Add("additionalMetadata", apiClient.ParameterToString(AdditionalMetadata)); // form parameter - if (File != null) fileParams.Add("file", File); + if (AdditionalMetadata != null) formParams.Add("additionalMetadata", ApiClient.ParameterToString(AdditionalMetadata)); // form parameter + if (File != null) fileParams.Add("file", ApiClient.ParameterToString(File)); @@ -795,7 +816,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UploadFile: " + response.Content, response.Content); } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs index 739c9d30be3..b728accf45e 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Collections.Generic; using System.Threading.Tasks; using RestSharp; @@ -13,14 +14,12 @@ namespace IO.Swagger.Api { /// /// Returns pet inventories by status Returns a map of status codes to quantities /// - /// Dictionary Dictionary GetInventory (); /// /// Returns pet inventories by status Returns a map of status codes to quantities /// - /// Dictionary Task> GetInventoryAsync (); @@ -80,9 +79,9 @@ namespace IO.Swagger.Api { /// public StoreApi(ApiClient apiClient = null) { if (apiClient == null) { // use the default one in Configuration - this.apiClient = Configuration.apiClient; + this.ApiClient = Configuration.DefaultApiClient; } else { - this.apiClient = apiClient; + this.ApiClient = apiClient; } } @@ -92,7 +91,7 @@ namespace IO.Swagger.Api { /// public StoreApi(String basePath) { - this.apiClient = new ApiClient(basePath); + this.ApiClient = new ApiClient(basePath); } /// @@ -100,7 +99,7 @@ namespace IO.Swagger.Api { /// /// The base path public void SetBasePath(String basePath) { - this.apiClient.basePath = basePath; + this.ApiClient.BasePath = basePath; } /// @@ -108,21 +107,20 @@ namespace IO.Swagger.Api { /// /// The base path public String GetBasePath(String basePath) { - return this.apiClient.basePath; + return this.ApiClient.BasePath; } /// /// Gets or sets the API client. /// /// The API client - public ApiClient apiClient {get; set;} + public ApiClient ApiClient {get; set;} /// /// Returns pet inventories by status Returns a map of status codes to quantities /// - /// Dictionary public Dictionary GetInventory () { @@ -147,18 +145,17 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "api_key" }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetInventory: " + response.Content, response.Content); } - return (Dictionary) apiClient.Deserialize(response.Content, typeof(Dictionary)); + return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary)); } - - /// + + /// /// Returns pet inventories by status Returns a map of status codes to quantities /// - /// Dictionary public async Task> GetInventoryAsync () { @@ -183,11 +180,11 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { "api_key" }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetInventory: " + response.Content, response.Content); } - return (Dictionary) apiClient.Deserialize(response.Content, typeof(Dictionary)); + return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary)); } /// @@ -212,22 +209,22 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling PlaceOrder: " + response.Content, response.Content); } - return (Order) apiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); } - - /// + + /// /// Place an order for a pet /// /// order placed for purchasing the pet @@ -249,18 +246,18 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling PlaceOrder: " + response.Content, response.Content); } - return (Order) apiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); } /// @@ -277,7 +274,7 @@ namespace IO.Swagger.Api { var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", apiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); var queryParams = new Dictionary(); @@ -295,15 +292,15 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetOrderById: " + response.Content, response.Content); } - return (Order) apiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); } - - /// + + /// /// Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions /// /// ID of pet that needs to be fetched @@ -317,7 +314,7 @@ namespace IO.Swagger.Api { var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", apiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); var queryParams = new Dictionary(); @@ -335,11 +332,11 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetOrderById: " + response.Content, response.Content); } - return (Order) apiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); } /// @@ -356,7 +353,7 @@ namespace IO.Swagger.Api { var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", apiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); var queryParams = new Dictionary(); @@ -374,7 +371,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteOrder: " + response.Content, response.Content); @@ -382,8 +379,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors /// /// ID of the order that needs to be deleted @@ -397,7 +394,7 @@ namespace IO.Swagger.Api { var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", apiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); var queryParams = new Dictionary(); @@ -415,7 +412,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteOrder: " + response.Content, response.Content); } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs index ffee3f5fdd2..beda2ebe362 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Collections.Generic; using System.Threading.Tasks; using RestSharp; @@ -55,28 +56,28 @@ namespace IO.Swagger.Api { /// /// Logs user into the system /// - /// The user name for login/// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string string LoginUser (string Username, string Password); /// /// Logs user into the system /// - /// The user name for login/// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string Task LoginUserAsync (string Username, string Password); /// /// Logs out current logged in user session /// - /// void LogoutUser (); /// /// Logs out current logged in user session /// - /// Task LogoutUserAsync (); @@ -97,14 +98,16 @@ namespace IO.Swagger.Api { /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted/// Updated user object + /// name that need to be deleted + /// Updated user object /// void UpdateUser (string Username, User Body); /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted/// Updated user object + /// name that need to be deleted + /// Updated user object /// Task UpdateUserAsync (string Username, User Body); @@ -136,9 +139,9 @@ namespace IO.Swagger.Api { /// public UserApi(ApiClient apiClient = null) { if (apiClient == null) { // use the default one in Configuration - this.apiClient = Configuration.apiClient; + this.ApiClient = Configuration.DefaultApiClient; } else { - this.apiClient = apiClient; + this.ApiClient = apiClient; } } @@ -148,7 +151,7 @@ namespace IO.Swagger.Api { /// public UserApi(String basePath) { - this.apiClient = new ApiClient(basePath); + this.ApiClient = new ApiClient(basePath); } /// @@ -156,7 +159,7 @@ namespace IO.Swagger.Api { /// /// The base path public void SetBasePath(String basePath) { - this.apiClient.basePath = basePath; + this.ApiClient.BasePath = basePath; } /// @@ -164,14 +167,14 @@ namespace IO.Swagger.Api { /// /// The base path public String GetBasePath(String basePath) { - return this.apiClient.basePath; + return this.ApiClient.BasePath; } /// /// Gets or sets the API client. /// /// The API client - public ApiClient apiClient {get; set;} + public ApiClient ApiClient {get; set;} @@ -197,14 +200,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUser: " + response.Content, response.Content); @@ -212,8 +215,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Create user This can only be done by the logged in user. /// /// Created user object @@ -235,14 +238,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUser: " + response.Content, response.Content); } @@ -272,14 +275,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithArrayInput: " + response.Content, response.Content); @@ -287,8 +290,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Creates list of users with given input array /// /// List of user object @@ -310,14 +313,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithArrayInput: " + response.Content, response.Content); } @@ -347,14 +350,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithListInput: " + response.Content, response.Content); @@ -362,8 +365,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Creates list of users with given input array /// /// List of user object @@ -385,14 +388,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithListInput: " + response.Content, response.Content); } @@ -403,7 +406,8 @@ namespace IO.Swagger.Api { /// /// Logs user into the system /// - /// The user name for login/// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string public string LoginUser (string Username, string Password) { @@ -419,8 +423,8 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Username != null) queryParams.Add("username", apiClient.ParameterToString(Username)); // query parameter - if (Password != null) queryParams.Add("password", apiClient.ParameterToString(Password)); // query parameter + if (Username != null) queryParams.Add("username", ApiClient.ParameterToString(Username)); // query parameter + if (Password != null) queryParams.Add("password", ApiClient.ParameterToString(Password)); // query parameter @@ -430,18 +434,19 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LoginUser: " + response.Content, response.Content); } - return (string) apiClient.Deserialize(response.Content, typeof(string)); + return (string) ApiClient.Deserialize(response.Content, typeof(string)); } - - /// + + /// /// Logs user into the system /// - /// The user name for login/// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string public async Task LoginUserAsync (string Username, string Password) { @@ -457,8 +462,8 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Username != null) queryParams.Add("username", apiClient.ParameterToString(Username)); // query parameter - if (Password != null) queryParams.Add("password", apiClient.ParameterToString(Password)); // query parameter + if (Username != null) queryParams.Add("username", ApiClient.ParameterToString(Username)); // query parameter + if (Password != null) queryParams.Add("password", ApiClient.ParameterToString(Password)); // query parameter @@ -468,17 +473,16 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LoginUser: " + response.Content, response.Content); } - return (string) apiClient.Deserialize(response.Content, typeof(string)); + return (string) ApiClient.Deserialize(response.Content, typeof(string)); } /// /// Logs out current logged in user session /// - /// public void LogoutUser () { @@ -503,7 +507,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LogoutUser: " + response.Content, response.Content); @@ -511,11 +515,10 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Logs out current logged in user session /// - /// public async Task LogoutUserAsync () { @@ -540,7 +543,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LogoutUser: " + response.Content, response.Content); } @@ -562,7 +565,7 @@ namespace IO.Swagger.Api { var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); var queryParams = new Dictionary(); @@ -580,15 +583,15 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetUserByName: " + response.Content, response.Content); } - return (User) apiClient.Deserialize(response.Content, typeof(User)); + return (User) ApiClient.Deserialize(response.Content, typeof(User)); } - - /// + + /// /// Get user by user name /// /// The name that needs to be fetched. Use user1 for testing. @@ -602,7 +605,7 @@ namespace IO.Swagger.Api { var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); var queryParams = new Dictionary(); @@ -620,17 +623,18 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetUserByName: " + response.Content, response.Content); } - return (User) apiClient.Deserialize(response.Content, typeof(User)); + return (User) ApiClient.Deserialize(response.Content, typeof(User)); } /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted/// Updated user object + /// name that need to be deleted + /// Updated user object /// public void UpdateUser (string Username, User Body) { @@ -641,7 +645,7 @@ namespace IO.Swagger.Api { var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); var queryParams = new Dictionary(); @@ -653,14 +657,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdateUser: " + response.Content, response.Content); @@ -668,11 +672,12 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted/// Updated user object + /// name that need to be deleted + /// Updated user object /// public async Task UpdateUserAsync (string Username, User Body) { @@ -683,7 +688,7 @@ namespace IO.Swagger.Api { var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); var queryParams = new Dictionary(); @@ -695,14 +700,14 @@ namespace IO.Swagger.Api { - postBody = apiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(Body); // http body (model) parameter // authentication setting, if any String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdateUser: " + response.Content, response.Content); } @@ -724,7 +729,7 @@ namespace IO.Swagger.Api { var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); var queryParams = new Dictionary(); @@ -742,7 +747,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteUser: " + response.Content, response.Content); @@ -750,8 +755,8 @@ namespace IO.Swagger.Api { return; } - - /// + + /// /// Delete user This can only be done by the logged in user. /// /// The name that needs to be deleted @@ -765,7 +770,7 @@ namespace IO.Swagger.Api { var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); var queryParams = new Dictionary(); @@ -783,7 +788,7 @@ namespace IO.Swagger.Api { String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + IRestResponse response = (IRestResponse) await ApiClient.CallApiAsync(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteUser: " + response.Content, response.Content); } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs index b001a38845c..321e9bc2a36 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text.RegularExpressions; using System.IO; using System.Linq; using System.Net; @@ -19,21 +20,21 @@ namespace IO.Swagger.Client { /// /// The base path. public ApiClient(String basePath="http://petstore.swagger.io/v2") { - this.basePath = basePath; - this.restClient = new RestClient(this.basePath); + this.BasePath = basePath; + this.RestClient = new RestClient(this.BasePath); } /// /// Gets or sets the base path. /// /// The base path. - public string basePath { get; set; } + public string BasePath { get; set; } /// /// Gets or sets the RestClient /// /// The RestClient. - public RestClient restClient { get; set; } + public RestClient RestClient { get; set; } private Dictionary defaultHeaderMap = new Dictionary(); @@ -77,7 +78,7 @@ namespace IO.Swagger.Client { request.AddParameter("application/json", PostBody, ParameterType.RequestBody); // http body (model) parameter } - return (Object) await restClient.ExecuteTaskAsync(request); + return (Object) await RestClient.ExecuteTaskAsync(request); } @@ -119,10 +120,12 @@ namespace IO.Swagger.Client { { if (obj is DateTime) { return ((DateTime)obj).ToString ("u"); + } else if (obj is FileStream) { + return ((FileStream)obj).Name; } else if (obj is List) { return String.Join(",", obj as List); } else { - return Convert.ToString (obj); + return Convert.ToString (obj); } } @@ -132,16 +135,38 @@ namespace IO.Swagger.Client { /// JSON string /// Object type /// Object representation of the JSON string - public object Deserialize(string content, Type type) { - if (type.GetType() == typeof(Object)) - return (Object)content; + public object Deserialize(string content, Type type, IList headers=null) { + if (type.GetType() == typeof(Object)) { + return (Object)content; + } else if (type.Name == "FileStream") { + // e.g. Content-Disposition: attachment; filename=checkimage.jpp + String fileName; + String filePath; + if (String.IsNullOrEmpty (Configuration.TempFolderPath)) { + filePath = System.IO.Path.GetTempPath (); + } else { + filePath = Configuration.TempFolderPath; + } + + Regex regex = new Regex(@"Content-Disposition:.*filename=['""]?([^'""\s]+)['""]?$"); + Match match = regex.Match(headers.ToString()); + if (match.Success) { + // replace first and last " or ', if found + fileName = filePath + match.Value.Replace("\"", "").Replace("'",""); + } else { + fileName = filePath + Guid.NewGuid().ToString(); + } + System.IO.File.WriteAllText (fileName, content); + return File.Open (fileName, FileMode.Open); + } + try { return JsonConvert.DeserializeObject(content, type); } catch (IOException e) { - throw new ApiException(500, e.Message); + throw new ApiException(500, e.Message); } } @@ -165,12 +190,12 @@ namespace IO.Swagger.Client { /// /// Object /// API key with prefix - public string GetApiKeyWithPrefix (string apiKey) + public string GetApiKeyWithPrefix (string apiKeyIdentifier) { var apiKeyValue = ""; - Configuration.apiKey.TryGetValue (apiKey, out apiKeyValue); + Configuration.ApiKey.TryGetValue (apiKeyIdentifier, out apiKeyValue); var apiKeyPrefix = ""; - if (Configuration.apiKeyPrefix.TryGetValue (apiKey, out apiKeyPrefix)) { + if (Configuration.ApiKeyPrefix.TryGetValue (apiKeyIdentifier, out apiKeyPrefix)) { return apiKeyPrefix + " " + apiKeyValue; } else { return apiKeyValue; diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs index ab24fc1252c..5d3029e7cc3 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Collections.Generic; using System.IO; using System.Linq; @@ -17,35 +18,81 @@ namespace IO.Swagger.Client { public const string Version = "1.0.0"; /// - /// Gets or sets the API client. This is the default API client for making HTTP calls. + /// Gets or sets the default API client for making HTTP calls. /// /// The API client. - public static ApiClient apiClient = new ApiClient(); + public static ApiClient DefaultApiClient = new ApiClient(); /// /// Gets or sets the username (HTTP basic authentication) /// /// The username. - public static String username { get; set; } + public static String Username { get; set; } /// /// Gets or sets the password (HTTP basic authentication) /// /// The password. - public static String password { get; set; } + public static String Password { get; set; } /// /// Gets or sets the API key based on the authentication name /// /// The API key. - public static Dictionary apiKey = new Dictionary(); + public static Dictionary ApiKey = new Dictionary(); /// /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name /// /// The prefix of the API key. - public static Dictionary apiKeyPrefix = new Dictionary(); + public static Dictionary ApiKeyPrefix = new Dictionary(); + private static string _tempFolderPath = Path.GetTempPath(); + /// + /// Gets or sets the temporary folder path to store the files downloaded from the server + /// + /// Folder path + public static String TempFolderPath { + get { + return _tempFolderPath; + } + + set { + if (!String.IsNullOrEmpty(value)) { + _tempFolderPath = value; + return; + } + + // create the directory if it does not exist + if (!Directory.Exists(value)) { + Directory.CreateDirectory(value); + } + + // check if the path contains directory separator at the end + if (value[value.Length - 1] == Path.DirectorySeparatorChar) { + _tempFolderPath = value; + } else { + _tempFolderPath = value + Path.DirectorySeparatorChar; + } + } + } + + /// + /// Return a string contain essential information for debugging + /// + /// Folder path + public static String ToDebugReport() { + String report = "C# SDK () Debug Report:\n"; + report += " OS: " + Environment.OSVersion + "\n"; + report += " .NET Framework Version: " + Assembly + .GetExecutingAssembly() + .GetReferencedAssemblies() + .Where(x => x.Name == "System.Core").First().Version.ToString() + "\n"; + report += " Swagger Spec Version: 1.0.0\n"; + report += " SDK Package Version: 1.0.0\n"; + + return report; + } } } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs index 4fa44c936ae..929ee8f320f 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs @@ -1,9 +1,12 @@  - + - - + + + + + diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll index bac89714b9cad85af8d64fd3230169073c376c63..5541f7ccaa24dec882eb9e104daee63e000b3b28 100755 GIT binary patch literal 53248 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 R@7O($YlQ#*_y3*+{tveqyB+`l literal 51200 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 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb index a7a6c4d4364bdf59f6d3b8fd0b9f68752a88cea2..6cfbe6bdc2282421418c7e8b501b55b189932769 100644 GIT binary patch literal 16213 zcmd5@d0Z1$*FKX;n1p~!f~d$2f`EtyPz)#-Ko9}<4OhT`SVaohYTLI}v@W=7weH$} zR#Dr!Ra>=Mm)g2k>(bWUs&%XTQngn7o;#Ba1Y+NQe|%Q*d-6PU?&O|(=G=SdW^Qm< z`rcE&fGddxlKw6)zu&8{Pk!3x9&v9CU(&RoODs_VivANp6sS&1N04) zmuVm@f9!MY?>YX|U~AC_Tv(SPb74`~n|Xr<$7FXz+TSEb!j|6<)mQg(Vv;Qa%;m#CLt-h8}I>EmwPXSCqeYkcCc zY;!?z-jIAd?caa=?3quO#J=C|K)b#Ut=6=og|ArqzuvC4e-{WrM=vGmFi+Lkfr6x%PE`8L8Mbh*zhMT9-3gH-E#cGhn5r zw=3*#F0|9`*LQdsdp7xC*(SIAb?b(&&ZQZz)+NW(Zl~49rf#V={MJ#Euk(|ZCl>Fz z_NukIb7rocR?qW@>A3FQd;6Ac?>B2;{Js11%G^YyKEkGTJIz+SezWX|PyX6=O%25d ze7e-3{{Mfses=%2pYniD-=>H6wFg!%F*wHMd^?ReA_Wmoq$E-iIS>g%SfXHs;z*>G zmNp8GEnKQQ*Ok~SkoXxKXVl{rZq&Pl>xtu>!URuEHK7`y;%4dSLtUAURZaXNj*Hg2 z8N%5~Dxr>(iu+MVhjm9R#bq3)*BM!9Bf-g4#ogA?9o=0^;c8ZB$VOpfLGPjBCh2Li zeu`eI_$!V>fe*JrPb>AG+86`4Z}hZHza2(3DGM@-2N0)yeWB!4%)v#Za2jCF z#9+1@@{Tz}3I|&bl#V%hgUpr#mAYU^QL$-A|Ka4|lsU9`Kqqr?abA9I5ee!-b5X&N z{30`2Azq*n+)|GC?HuPCoz)^bIyyd3XKX!5S31b8MDI3mprHkeGC&aYb=~UJ5d@vP zAT%}#ZjCfyS;f_H*^cVzE0>)vVsto@8&`|Q*D9^`FT^lW@wYMf*^8m?>nw)Zwdk)} zV_oGK_Pf#n*B@~F67w*HTaP^aTpokJ(PT96f&v|=JR31OQ|Sy`<`&jq)b35=8ptWh zd%L>e*4$skopPmZwfEJQBU)I87S&l?=U<3uF)wH3ZzF0hN91ORL4UJ!vfSa8h(51F z)9Ws%D@Sy@F5Rhn7soF#M;o|P$kA0qRFcsmIxE_gWe|r9uU7EffvQ;w65PBI7GklC z9&1$DL#qoe;hrjPgd1ISyX7WF^<6#szTWP7FEy$Y+z18no0OcZQHshaMHRq0U^shg zR-p%q^Fey$!0I+O`U~|UT9zkn;5%$&{Zx-Ox$kn9<6G)M%RI_FUTS>%xI4(&bXDc7 z)n}naRSqqxQfO-TC{vK!9i=&Mg9pv^{KQj^>Mu`v>iG=EFR?FP<)$EOSE@v1$y$n? ztaYsvnh==U)gXwetJpDB+(a+B?e)Y?cs5AE^UE0+$kxw9%R`OsybD{^VEcxzRR z_NDiI$M{-n6s-Y@xxO^dcRs8yF-L{7ITrIf@(d_W6cu`$bvloNkmiE-_$Ps;+< z2FP(u2&9RDlLG&hxK8}nxWoy((TjrW{|2UQ#k@dz9$4Byj_7m)I@91RJGL_c@ce`- z3+u+^GXQ_10o`oyT&hgT^B-1TTJtM{Xl2l+L83RDu-JBS&F>4M{XqxhVsY(VzP#qI z1<~(8*X3fYzA;RE`0>G18ayG`TB&3X;1>teN5LP%{IZ7+&u@I;@DWpjRb16IHXA!C z{>xyR7xGDnH68r*5V{d^6UQ$RQ5%o!gvvbkk_RZzbF)r=2#Seh0wW%*BZ)E ztPQ1gp1T1%*7IJFD5abpI2#Z zEiTr?uM8FPV!g-2S%Xr08WV!WH~DVEmNm7T`l$GEVRSw0VVE4O!puFBQMsK$F5}hs$x@38%Z^_i+3YJKj=mznGh6RpPQY88ojP zQ>8_LiXRz4zeU`RkYm~vN#8|&ANf*avgYbAmePN}BCy;!UyvxN_Z^F*jZMF8Do6BT zGn(COPBZaXspJDV9e;~Gmr^)l(d-uPW)Pn-IY&Ds2~I+2T_=@tSu-kYwp{*%C%c__ zDvvj#6U|QATK$x_n$hiMcVw$SJJ(Ib&ev1e8@@e=B3>Z+7$qG(IhR;d~kD9=aHg{X^iwHcf~g*_XJQRCdZQFJfr zzFd~Y>0d*UQLR!=ZcbC0Pi<~(%xj!J9wiM0m9nfkEpNVpl_;f0QBDC8H;I=x-7K-W zkhStnPM@WJD?3YX1hTUAy8fs~CAe$6tJT-|RtwbBuBNG@QtoI@JDXobttw8<9*L!A z4mK+kqHK>xY6@Oeh`q^S3Z-grW^wiag#%|+t0h16{3MRLgmrduJ5JH17pExUR^ezp z_oL-`*(L72McwDdqv=Y1JX^1nWa#5{85ypI41KgwAMIj@b~D7gWw`j3lw=!GoXwJ* zt9R?~rZ*X4(DEKajT)iaYPD;JhPx&NX>|>>+Pd0MFKsQ)>LE?ywYuuT5n8RAwzi=4 z6g;#+HC4*lM%rn7YGeuI5R%kZ&P`&sP}Y<+9Ot4peW24DMIS+ewjpvESRDz9rianv zVo0GNZDv7UTl4U)nS+MnDWH>d)V|Q1lQ+z|ybFz!YK==~wc_ERJ~|~jIweCtPoE%O zbpek71G;OfX;jKpF?1m23~I*Az@9a7N`?4f(Pbps=~>Jve2X~VuZUH27!|!8q3amz zq8>WX5Yen@1b?S1D4bdEox}+m!K+57t8-voXJ@V8rBaS>LDO0+Yr!0-i_OD| zO~Z@L?8~H*zm58g(PFoa2x%;MsFc@Q&>t-x;#_uuim%NXb*R*-p1W#ROZu?o?3UIN zPtJslpv;&oIH^>tThf}AYvod3u~aPYW>!0^omHwITGGLmhvYM~tg-H@+b!u%%e%H# zAJv#x8XG$<*6OP!JJ(M&Kb986F0{2aR;`Vtb+KPaR-ERrJC^pu?zNodzE7LvA1QbpLFi%IC?*BOq}H1ffud84s+vZUfg`y8pY|^Xm@tjIINDN zHF0ZMiFF*-k+Sa>B5^`ni96(y(t(dbZ$~F@iZ@+!EjLpM>+tLJVr6y1YSwgi52;zt z+1bOjO-*N)ny7zo9PNv{j`}%rC^Q!gDJ*8mao{_nS8ZAu9j*>B7z`6$8^q>?V2!4s zMz7a5i%rsKG%AM`t>}wZ>swi4sm<{^MRl%UFPw_ATpTX7qRXwW$mJQFE(1lL-rf#l zOf=Rs&Ln;kCSkFOJ~DkQ9V-Q1%t>uwwTaf4*4kR#h3`!Cy=k{>b!FGpO*mzu)21`F zRxjbMiSC*1!^)AOD2qiV@Scdw7-KYMWZ=z!H>r;{s3ABCj=uE*1V?|5VCb4EVO%^- zj-L`Q1t{>1IK3Ooi@V^a626b8-SK;*GT77?;^|`iZ>Q(bn2~AhWb*y|C2~d5!CiFNQV-C zw6*%Ge@moGiI-uOFS(jGRJ`QkbuWKo84z<(B@OjG8w!pMd<>Si0IxYfaBvk4Tcv)mT!anVdvZlBU{P-8D;+=#!+SvQ>b4D2aYdIxJho)VOIbCDG-iE4EfI&0k6MH0haa6;o4RGd-DRB!7@> zZJB5d)|4gF^5hk=RZNYCW@|Eilf2E=>Z>`LOvjRclC5HD+%?yd>G$O8wpJg_h&D8` zO-Y*ysnOV`M$Cnsw<@U-vmy?YAm0effD!Y9)M#e4q4{kVzzrL38opv`G*8>mvo_DA zGNi_FP72LUnU^A+>u5=hhAbW3T;c-E?cEh<9IBEeoFb-*6QW>dkS4o zxdE%(3myLt1K)9ETN>MTTw80iDh_5grL3NmTt7Y zX=`=YmZZ|C)X}L@y;^DDdunH=(wx+}wpKsw=c%+Rb+v32dzY8?+f>?>`kk%SUwa~z zPNtrctztj&)ZR{|JE?bVt$x}uX*4!%T$;5FV(+S_ou5Vv(iYlUy|ru8XkFSDvQ_L| zp4#1Mv?pz^t<_I^CXLRfos+F$Y?7#_y`M%8(*CfudTUG5X+rwMbZZ+T*twqC#p(1> z`p33bKkbHe`ZE11Smjh|*=^2t4i_hKyKii!vEP5it}FKB@|i|d!G2A}`Cq#~oerlT zksH*#!X%^pz8&pux2K&Hf)g*Uj~tyYw4;mdeuLG4xB}wT*_NNCkU~>1U`X+hE`@`N zi06wlakp0Dy@*r}_~jjb{=^206JLXKi5?h^P4I~5j-a<<#G{OO-*Bu@BMtGs5x7#k zlhT2`>L{J@@~Ea%<5f$tDP5FW-sy2WTG{^7_UxM3R3E~*=%S~yl@%|YIHCiUc9_tC ztvszK+I|6X;v=x6h#nYij9~jsh6r6o_&{9faNIk^12D6tFcU16s@;@YWvEseBEHuT zZlqNjnni1sjlnTmWkapf7e&qD(A4D}XlsXW{cXKW$Ee7TJlzmTeMC$&@Gz%Sium^|0S-Hd2UCXr5&D1FJ+xN&UKV3 zCsm*mB=0n%6K(3WuM>KU<@?E5#WbGO{ACWCldjp*d+T~iuOw4epU)JFIIXcnZ!9e} zv{19?ny{x2bpl}i&I>w=JrU<}H#*bJ&bQdHt*^C;f8?u?eP7aM z{L{|#tn>ITvajP^=tP&3?AZFfOR<#2^;czI30c##qz&_m(Zv|EO4Sqa+4PD|E!*Z| zi1McS)h=|c%Y$;yN4nC{uE)Ao@w|(#6y<;MoMPiy+TIpD%bVL5y3)n2x0omV;rbrv zMn7~r*sa|2BK}7f^EB)xajqX{w8);`b8e|YPAQ%$3EYheIhCU}YCZj#du&0MXIBut zvj-O9CiLlUbf()?=1uaxuRHDUexQ4~_v`#ZCF@C|_bkbKR=M}q?81k$w`LWuywtCH z*lR$A?P9Sh(q{3=?sTgAW#(6E$B`a%w8ya? z))l==o4OZz(8V6Nm^aD$j~R40<48ui_s9H7b`@qi*!TXoS0U3*6Dn@M$_Y_%zh=<+ zj2q0a)Q;ml=|sp-t^k3TEM^P)$)bID+P{Vv+ZA$#yAhbZouo$N)YdR=BdB%j~(rft2q z_b&HY!ha$8Tqln6s=ZDO)~@eXT5tA)CAMQ%xzEdcb_aXYq24E%Ka2l9w5`wfK6d<% z5=Z+#@GtfE<}Y?G?X4Z`Lx=jDWS%6?8~f6xzMK1&dzP*?ujbEI&M%v}D@H7N41e*Z zR`GlK(%!zuSnZ-Wepx>%>$kk09d9ct&!_giCENFA+2i@LAAQwtC#zm^H!G7q%$%KR z$K8W}<}S&;JIiLw(o9;Gxt3KgxqCm0#$=7nDtEVlKZst0Yq`VjoGngT;)Y4Z%PNnW z4i%kO+%}P?4RO|EZ37~7x5 z^`Ftd+<$+1)c-L%w%nZ;@`t1=zFeH8tBxD{-73MJZ<}dD#g8@9IP(m%?E9XX?wcR5 zV~cM&_9rj!T_twwn0;a3(p4XoL!)!1smO?t-qWGNWR7VwKEo;Ni`9(@j z*u_7x94}H%Q*oLN%4?QKb@Ns0RaoZZ`3G(VE``1JM(PHZn0gM(GUT0asWbgEY0Nv{ zB1=Cv+C}lM6IzYu|Ftk(n@rVBnxL4PCX)~uSv^wY)39b_q$GnPWa%F!ORr!iJv221 zJltQFOJ%tu2UxF|a#0>F&ig2@JXb#F@Vpoe4@SfFiZafzr52Bel?=jfG_l?;N^fHbYXR(0Kgx*1pFRQAG%`=qQ6)fbQW}9 zAPjmT_&uO8^j7dnpb7LT@IC}?S0Pufa4gp{fAQJivcoEPP`X=~y zpc(XXT;NXX?K$ju0uK``5zXGoZxoZ26{lJBH@pqGoX7x_W*iAS4Z-XLHC08f_4XbLth5Z0s25c1m6exLT^R~ zc^&8ny$`$_$b_DR&XNdZK`#K$1+t+Jf>!|jp??FP0l!0EQ9eFz7Py zB49Z5R`7b@E$AP>`+&EhFM>}3??C?vz61ORx&{W20K5ww0QLahgN_4-10$dpg9ig6 zp-+J~0430Wfv*Cipj~|sFEAQ90PF|64;=#z2gX2m1h)akLJt7<1;#|1XvH<9-IVhfX)H;2EK%T2V4Yv1w9=+9@q$723`bgg5C;V4{U}$3f>2N z4Sfy#E3gHc0*M|%Z-sV+b_TwIZV2`Rwn3Y~&4KOETfm)x9nif?fok2z&?a6NLJpzlRf3&FVeLGOXihV}&ZLKlGxfPK&h!KJ`{=(FHc zzyatsAs7qLKS1|@?g|`)-U%)M4nZGb4EzY)sv*%e=)=$*pwodP(0jlGfTPgI!9M}V zpp!z0ZnI(e^MPNW&w@_@$Dvy_LVKW3KzD#n2Tnq-2M+*FLGJ?Z08T?k zhQS7X209Vi1e}Fl1?~l$gZ>8mHSjC6M`N@F`aEW#4n|ow+bD_I~rkj-}t8nTMo_Rf_s0qZ3efi`k6&H7mmJ?F)J@=1TB5~8lN;K zCvRkF!H6Oo?caa$%;|M2J5EYJkUqpNep5Ovd&=6MFrp~GVCbmgtj7d!Wmi&>f6q7f zY~gmj>hmyj8ZCNS0(b^<*|6Y*tkS%pBZ^HeG7w!N@R z_q4UTSJqG)t-f&IxoYrBhjUI1b3Z-lkzHeYYHp&^7-7@8jb>lFadM5@7mjmQ=>lJv zTb;0ga{vEs{p|j4JLP`s#?kM0v8EPMwziT#eL<%CFNJ*q3vLh0RutdQM#hyqj zEo~GWTevi8;3Bc7Kk-vJ&Y;ID%%FD-(-X%z1PdOThC)L?#Vyd$LfvW|tD5+E9B0(K zhK8||RD!dEiaVmC?{r7ahnI4kUT0uOg9HaB6?a2NH+8qn2P@dY&>S2L5%lgVZib#_ z>fg{y6|d(w9Pr}S>ghfGIxC|ew_Q&=^gCfxlX7HM>9fRXpC6T1{9?DP;;i8%q;PmP zFAEp5xyak+k0>5)E-3Bu3x?&H3o7-<5hbOj5xFmtokP~B(r0_-m6jG14J{!-U7S}k zazs%{9$F!G(0HzrBYq3VIT^EKj7DREzs}HUhHlz0*D}3pVPR+ti_%XJ^e(Q>&VrzG z6NC_h;2NX}&Ms|)Zu?$OpE!QyC`N}fxv5R5yy>*2|3VC}DgH4AA6qdDd7j0vs44x~ zbc&N4!+s|^;B*k>CzyvfxXsAJ{+bwk4JJb@pj}di{BXSLm#&|OivY{`UBii6h zb6l3X$PwLep_?wZP=10r+QL;KN2d`{Sw@U8+i1!T6)zcHt>C!>^|KTpxVAu8h{b&M zSfa`q)kts*^H6c)UFm}Bbyqp6J|?P_kRis}}0 zsl@~KS=_4?{J=W*RK-d!s_?4xvK-H|x~VF5dC_jKJ@V1vR(Dm!IWIczbwNHlO1!Nq z#(UFi-eumF8bzz0Vu3d;^j-w(6U%rY^K-PQ|)XX;OOfpQ$R)(C7&IYqQkDem~t z3Ey+RawzY&q>U{%wS1zXEaJWpW0{GYto2kU=Eg=$A%dGXo4`Y(>rCJ*MPgjrThhCJ z8~o(BrufrT|8oC-C9a?TYh2>w9rU=Ma$mp%pjhZn5B(>%k|R3VicYoqk(F&s0KAPw zbx6$&z+Y-bms>rQDpT_Hm(_e_0IdpG9Uywc33V3M{N4ciI^Y}maGj+!e=&f54XBn6 zn-|yoq(GV+I3>_hsbu!!-wLFqfy-ci(w7fkcYR%JsEH}T3avvjP z(!p1^rc13aqx|H9sI$PX8-%1~n)2zLhik}!v)xo!e<>e%QPSu;5<#2W?`SVaG&hpwMb3{D%St8R zlGE|m*)u7HJr>QbVXmR#^Q8txhh)J)XzSvjQob8WDKW2qNq1v<+z#$Kv!aw?sI5{pIG{WoMQ5VU%GLJg^l9w5P_!E7UW=mZQ8(mcS)Bek95Sd? z%4r?w^$ycJSQ=Bv=@W3Iji6Gl>_8PAD%lZUdJN^@Cvm$JiBo#B*1f>#v-M+hvh~?H zdR;C)s}kHaEgJf3nl)53Q7OOZK-)WZ? z-VhqiS|&7ZtP!*xg1g4QkxDtyK;?$T2J1>VSE&-$wycsx9OtMv&9hVxAZXj5o7jiH zG0;K78GKkl+N_ZUo%3GolQnD<9_6UztD#Yh?j;|qDk5W$IUBdA`C9I-PQPH?? zU5`LV^{B$o@W}Sz{55f$aUAccXut->3{KDpo{if&HSl+7&_FAAs+4DqRBe1DI#8G9 zjVU#~SenQFPE+#7QJ=vmj)?HqA%eR~xigv$L?4Wn5~<>waRwbKb!hIUx*AQ_qOZ$G zJUA0ZHtXaR!9k^(5<^pC%3~~_^A?Ya$NT1~8>kzoR24B)8M8`0L(3ZLrrH}rU&nl7 zZS_+96ho(D&dAm#>|7t!?HIZfbJyA$qAHK2X|b=zik@+r-SSv^JN6x^thD2u*=JkY zy&p>(V>ek_1MPOl(w^A8veiR6_s3YOiv7vj8fbSjmTtw~maRID*C`rtnW$Z_*V|3$ zNK-qOceJ!ZsOU(Q9al+ZrNE03G!r&=q%9pkwzj$n-*%+^9S_J>C)NsA;pdKYuH$)Y ztEcdLN4nqf4_G-;lw`9k3cLqKmm%6<$jHE3DBh%uwrVWc3-;d4{RDeo_dw_-Dq%(( z&5fHEC#6Z?gE+k_n-1IrSCz0ojt;~fl#aosu8yNiahJ{Ks?8y&@5j*}aSyDmZt9uw z^hW%wc&T1BFNL698BZ1QmDW~I_11X$EdF!Z+MI>!ral}`N8-P;wtA^A#?!Cy)v~n( zJJ(D7XFUBC|H#_vr=DY?xu$t0OB-5B^{zJ28q->9tC#u<6Kyx`kgb92TzB>NCi=m2 z%-ZU$zHFi^rr%)YEM2bVLu+@r*zYxOECXUL>ZPHjM;pPul~<_w&CfH)tdJV@_yn4q zFeSm#{IpuBQU97i)d`oRV`!;nLLyB}oRlb?t1+iWGdGduCC<0Dx@p!V(%QuLWUH8( z7Mksev?Fn+wY8<@heSG-cwDxMsd3d@Nu=KruUcC@HLoR6S<-|gOB=-0wA3t2qD4t> zT3Z7(>yv0h()+SiOpUwdt0dZ$wAh@tzv52G}n{pM$%1dtCwa{Cz{-8 zN~c<>(O9QO%!Q4&dZ`h!B3>o|-r?p8M$8XVqgm34-s!XgZrJsv;cKTxQSn(ynRX}dk*(5IV}B}{eoU^iwtCv%NT!>~ zw_ue=q5c2i!ndECLeo=bq(~vyTV43}yHjXS%3kRhLeT!4Lg!M>o6psnL(tw#p<5}p zt*vg_DXBCywLDd-S1Vok9@?d;v@CVGwbe)aVJdx;x>>f0qsvqKO)Bk6{npy*t38uS zXH$Qct>WnN(B4g@d#S%$TYa>zr_uDZ8EKX_h@-2y_MJ3Zk@l{&wT1TMH2Ng%Q`stx zE)VU2G&-1e$lB_oJ)cGw(teSx!EBOfuKgp89;7|Awzkl|(V1p-p558fhH!SShqj_K zRd!xwZS~Q9)|o!4#_^u}fy+v8Upy5dN#nQ257=+j=D|FuUt z)A7zH zck!?i;`!37p;%Dhy@XVD`1%*VgTpQs2fi`qXeom)W)+=ELJ{${0W1-Oy&Ne+l!*v;9h3MHZ+&jernAy^p2^MqJu1c-4tybAu zd~X>Tq*aDS8nwz0aI{w0MyvG3p~yHibwgMBs_U+QY(Zz%g5t7pG$IVHbQ$KRi0xpG z%}#x_O6C`}!*#G$8K6~)uHlP!*qBbc)Ayv4LRk~3eMxCn>8O$}1tq1V5Qc%U(~k5Y zBOEU+D}7(!xX`|w!qA7MXAo=2*l1UyPFLt^WIN`eVf>%snv&c5dLT zR5_^p9Uys!Mcrt7x5M2qTFl$aXB4w}Qu9?DcF3G^<_yvekY35A?7{05%Q>x~OmCPr zEi^{WqHD+g40aJ*1!ug($4Iqyniq7Zh22+l7e^w_OivP)1kZoVm zj&NBIn$Tlr582o09(1P1Syndtx}&IMaow!zD=~XcwzO+oJGy8?cA5Hhe70+Cr{=v| zF+_Ri_F50R-s3@y=Mz2YWY1GQ>v`VF*NO7KcuuqOEbXz1p5-0Z>Yj9|=N;w=|IokR z^`fJ_zVB7zc{zWC#XK3?8l2OLjF_A`0~SvUl~anx8v=K=R!-%p4O$OuGl~14HQ5zJ z@9ZyUaVPX#FFN1r8uKQ3Kir#+^!~1QjrZU9WlDHIA$rf2yl2;V@5DMjjJ-wH?s;ik z^|#f4T6>maQ=}csv%Tr(-oG)wQaeucp_6@1^{Hvc*Zc$43+q(2dm)K6A*y~85^OZV zytgQNmv$Db`_QF6cbGTH`?0=syzhy=HQq1rOIRU9s-?e4?jW5y}ZwLxgTBW zcaM1xJu3G1rvv>D_OJ1HTv5)89xvDR$mWsZw#J;%${~CDB!?(&+*I|apZZrbACk`< z8MHIw%ZwVIW&B5y&n@CLUVp@i!P@j4uWf;iaBF<5}u${xP$5?T96hVUO=> z6~AvFeLL_Nt6lWQuO38e2CW@r!<)@{yS}#++uqC@4WA66PY3N{)l2Rc4yHwe-yCei z-L1M)cio{R1($5woq0!K)nHmZ_(N8`{k;q@|gwS>2Ma`D$kmiRpUR4{>Xa3%H})sGXAjC<157(y8d-zJI{%>d|OQ$Dt>A$4yC_TmaoD(&aCDLDQ-w?HA4w<$L8oa%eU6!W@p z1HW9!3A_3G=JImoY!#>3qP(n>9%a6z+N{D7U(L6}4au>1;Jyf5VVP+_VRmT2xmbKz z?SGPnf^#w1`o%^^#VZbIH6B7Y#dK{lH8N=eqMMjZLPSKP2#r^pCJ_;m3<#H{Z?G&q z1DSN!G!gKGd37$W$t}yX^qBJPe0nE;MLx>rTzQ?vlT|c401ekGR&(|P)a} z?#hk%v?>2HcD6Xmm8bLRO#WGvo8bGV$@rpa0HA};2loQ>&=bHVfFtzV;8{RZ=*{5u zfD`mS@RvX{=vVM<)kMG=;B61et<7@8TeJ8C3M%u zM1Qhl(1W1|0Kw3U!Q+4s=&j&YKs)FY;JpBTaAbE6{0o2|7uh+W^LQW}+8gWwL_nVc zF9F&^Uk3jQL_$}fgL8l==*{2{fDX_vqqBnn12n!|OVa=&bUHd-0Pv$GyCL9#z%$Tq zfnNf;LT>}F0n(wX!25u1&=0|vfbP&bBux$UfDQnA0zIKmgI55(ps#_i0KK7CBC$h( zKF}Y5HvxU23z6iuKtJfQ;L$*T=oBRU4s-@|Kj_}T0B9|ee*}6UbaQBDU=Z|q@O)q} z^ldP{`ba~dKgIwV4rD^_1@8i~pvy5>;(=`FH^B>l9O!Ssl|U}^&)^dP9{Jn-4!#ED zLpQ+SQUXJveZa23v(UZ3MxX#X7n}tYLXQVO4?G9G7(4?Q2K^Cu6)+t70r(_P1l zwmC2Y`Xz8CFcSJ07+rQC2fPT~6c>jBFc!Kc*c%uJZ3Kq`FF|()rvNWQ4+RefUV(lYTnfAj zy#zcB7!Um(cs1}E^iJ?6KpFIL@Ihb#^i}W$U?Mb+i}C^VBxnulJgKh|HhHeY?1-3vZfDORM(EY*PfKQ-Dfb)S*p(lY~0=7ag z0nY(GgT~kKXf^OT^j`26z&2=;AFf|kh8_%^4s3@m1wRMufPM)60N4rb>rd1K_!7Dj zoCJIY-LMt<6M7f)bm;EDZs=<8yTBgk`{294Ug%x{M2p>x4mz&Fqb!Q+5^(5Jya z0^dTX1md&M`=R?m_XZ9??*Weh4niLT9|aCUcWq5{75XsrVCVtB5$OHkQNVZ5Rp67r zQRr@Mkay_sp);We0Y5;02_6j`gZ>VD2sjSizAdgh=o8SLpc8KcN0<;dg5%3Fi5jX(22>l9p9PlgjHSm0(8u}6VA#e%0upQJ-|(X>(EYNm=~dMK>I=a05_p~fun(2(7E6&fFtofAuh=L zQQ%R=0*?Izh!!ct-vLo?80}DQ3Zno%23CV-tE68qr{bVJ%725k;LSM60Xz&RvHEX; vQ5D?esDd7WS^bETdzaIP_?WJMB diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll index bac89714b9cad85af8d64fd3230169073c376c63..5541f7ccaa24dec882eb9e104daee63e000b3b28 100755 GIT binary patch literal 53248 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 R@7O($YlQ#*_y3*+{tveqyB+`l literal 51200 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 diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb index a7a6c4d4364bdf59f6d3b8fd0b9f68752a88cea2..6cfbe6bdc2282421418c7e8b501b55b189932769 100644 GIT binary patch literal 16213 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 vQ5D?esDd7WS^bETdzaIP_?WJMB From 9726ada8d1c288727d2b1663856008706ebcff40 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 29 Jun 2015 15:30:34 +0800 Subject: [PATCH 177/499] fix return type and tempfolder --- .../src/main/resources/csharp/Configuration.mustache | 2 +- .../swagger-codegen/src/main/resources/csharp/api.mustache | 2 +- .../SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs | 6 +++--- .../src/main/csharp/IO/Swagger/Api/StoreApi.cs | 6 +++--- .../src/main/csharp/IO/Swagger/Api/UserApi.cs | 4 ++-- .../src/main/csharp/IO/Swagger/Client/Configuration.cs | 2 +- .../csharp/SwaggerClientTest/SwaggerClientTest.userprefs | 7 +++---- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index 8611d2c18b4..dcede1b4ca5 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -59,7 +59,7 @@ namespace {{packageName}}.Client { } set { - if (!String.IsNullOrEmpty(value)) { + if (String.IsNullOrEmpty(value)) { _tempFolderPath = value; return; } diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index 1ae7afbf39a..8d34ee33ed9 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -121,7 +121,7 @@ namespace {{packageName}}.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content); } - {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} + {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}), response.Headers);{{/returnType}}{{^returnType}} return;{{/returnType}} } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs index f41cb46baa1..3537293211a 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs @@ -370,7 +370,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByStatus: " + response.Content, response.Content); } - return (List) ApiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); } /// @@ -443,7 +443,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByTags: " + response.Content, response.Content); } - return (List) ApiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); } /// @@ -519,7 +519,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetPetById: " + response.Content, response.Content); } - return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet)); + return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet), response.Headers); } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs index b728accf45e..0a311b1071b 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs @@ -150,7 +150,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetInventory: " + response.Content, response.Content); } - return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary)); + return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary), response.Headers); } /// @@ -221,7 +221,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling PlaceOrder: " + response.Content, response.Content); } - return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order), response.Headers); } /// @@ -297,7 +297,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetOrderById: " + response.Content, response.Content); } - return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order), response.Headers); } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs index beda2ebe362..470d9ee5f41 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs @@ -439,7 +439,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LoginUser: " + response.Content, response.Content); } - return (string) ApiClient.Deserialize(response.Content, typeof(string)); + return (string) ApiClient.Deserialize(response.Content, typeof(string), response.Headers); } /// @@ -588,7 +588,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetUserByName: " + response.Content, response.Content); } - return (User) ApiClient.Deserialize(response.Content, typeof(User)); + return (User) ApiClient.Deserialize(response.Content, typeof(User), response.Headers); } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs index 5d3029e7cc3..7dd139d6542 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/Configuration.cs @@ -59,7 +59,7 @@ namespace IO.Swagger.Client { } set { - if (!String.IsNullOrEmpty(value)) { + if (String.IsNullOrEmpty(value)) { _tempFolderPath = value; return; } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs index 929ee8f320f..f202e578741 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs @@ -1,12 +1,11 @@  - + - + + - - From 2d59c5d1903d594cc83dfbffa48d96c38f8be0d4 Mon Sep 17 00:00:00 2001 From: cbornet Date: Mon, 29 Jun 2015 13:39:39 +0200 Subject: [PATCH 178/499] generate oauth2 fields in the data for the templates Fixes #347 --- .../io/swagger/codegen/CodegenSecurity.java | 5 +++++ .../io/swagger/codegen/DefaultCodegen.java | 14 +++++++++++--- .../io/swagger/codegen/DefaultGenerator.java | 18 +++++++++++++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenSecurity.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenSecurity.java index 8613e0a8d41..edd65cc0603 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenSecurity.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenSecurity.java @@ -1,5 +1,7 @@ package io.swagger.codegen; +import java.util.Set; + public class CodegenSecurity { public String name; public String type; @@ -7,4 +9,7 @@ public class CodegenSecurity { // ApiKey specific public String keyParamName; public Boolean isKeyInQuery, isKeyInHeader; + // Oauth specific + public String flow, authorizationUrl, tokenUrl; + public Set scopes; } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 71b6295c9be..e4967cd8b2b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -14,6 +14,7 @@ import io.swagger.models.Swagger; import io.swagger.models.auth.ApiKeyAuthDefinition; import io.swagger.models.auth.BasicAuthDefinition; import io.swagger.models.auth.In; +import io.swagger.models.auth.OAuth2Definition; import io.swagger.models.auth.SecuritySchemeDefinition; import io.swagger.models.parameters.BodyParameter; import io.swagger.models.parameters.CookieParameter; @@ -1056,10 +1057,17 @@ public class DefaultCodegen { sec.keyParamName = apiKeyDefinition.getName(); sec.isKeyInHeader = apiKeyDefinition.getIn() == In.HEADER; sec.isKeyInQuery = !sec.isKeyInHeader; + } else if(schemeDefinition instanceof BasicAuthDefinition) { + sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isOAuth = false; + sec.isBasic = true; } else { - sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = false; - sec.isBasic = schemeDefinition instanceof BasicAuthDefinition; - sec.isOAuth = !sec.isBasic; + final OAuth2Definition oauth2Definition = (OAuth2Definition) schemeDefinition; + sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false; + sec.isOAuth = true; + sec.flow = oauth2Definition.getFlow(); + sec.authorizationUrl = oauth2Definition.getAuthorizationUrl(); + sec.tokenUrl = oauth2Definition.getTokenUrl(); + sec.scopes = oauth2Definition.getScopes().keySet(); } sec.hasMore = it.hasNext(); diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index a04e517bee5..8ace77d5641 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -9,6 +9,7 @@ import io.swagger.models.Model; import io.swagger.models.Operation; import io.swagger.models.Path; import io.swagger.models.Swagger; +import io.swagger.models.auth.OAuth2Definition; import io.swagger.models.auth.SecuritySchemeDefinition; import io.swagger.util.Json; import org.apache.commons.io.IOUtils; @@ -366,7 +367,22 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { String securityName = security.keySet().iterator().next(); SecuritySchemeDefinition securityDefinition = fromSecurity(securityName); if (securityDefinition != null) { - authMethods.put(securityName, securityDefinition); + if(securityDefinition instanceof OAuth2Definition) { + OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition; + OAuth2Definition oauth2Operation = new OAuth2Definition(); + oauth2Operation.setType(oauth2Definition.getType()); + oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl()); + oauth2Operation.setFlow(oauth2Definition.getFlow()); + oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl()); + for (String scope : security.values().iterator().next()) { + if (oauth2Definition.getScopes().containsKey(scope)) { + oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope)); + } + } + authMethods.put(securityName, oauth2Operation); + } else { + authMethods.put(securityName, securityDefinition); + } } } if (!authMethods.isEmpty()) { From 59987a54a952841abb65d78b9270cb076216e4e5 Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 29 Jun 2015 22:16:38 +0800 Subject: [PATCH 179/499] fix deserialization of string and other primitive --- .../main/resources/csharp/ApiClient.mustache | 22 ++++++++++++++---- .../src/main/resources/csharp/api.mustache | 2 +- .../src/main/csharp/IO/Swagger/Api/PetApi.cs | 6 ++--- .../main/csharp/IO/Swagger/Api/StoreApi.cs | 6 ++--- .../src/main/csharp/IO/Swagger/Api/UserApi.cs | 4 ++-- .../csharp/IO/Swagger/Client/ApiClient.cs | 22 ++++++++++++++---- .../SwaggerClientTest.csproj | 1 + .../bin/Debug/SwaggerClientTest.dll | Bin 53248 -> 54784 bytes .../bin/Debug/SwaggerClientTest.dll.mdb | Bin 16213 -> 16334 bytes .../obj/Debug/SwaggerClientTest.dll | Bin 53248 -> 54784 bytes .../obj/Debug/SwaggerClientTest.dll.mdb | Bin 16213 -> 16334 bytes 11 files changed, 46 insertions(+), 17 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index 5c1fb8d9125..e3061aa94bc 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -132,13 +132,13 @@ namespace {{packageName}}.Client { /// /// Deserialize the JSON string into a proper object /// - /// JSON string + /// HTTP body (e.g. string, JSON) /// Object type /// Object representation of the JSON string public object Deserialize(string content, Type type, IList headers=null) { - if (type.GetType() == typeof(Object)) { + if (type.GetType() == typeof(Object)) { // return an object return (Object)content; - } else if (type.Name == "FileStream") { + } else if (type.Name == "FileStream") { // return a file // e.g. Content-Disposition: attachment; filename=checkimage.jpp String fileName; String filePath; @@ -158,9 +158,13 @@ namespace {{packageName}}.Client { } System.IO.File.WriteAllText (fileName, content); return File.Open (fileName, FileMode.Open); + } else if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) { // return a datetime object + return DateTime.Parse(content, null, System.Globalization.DateTimeStyles.RoundtripKind); + } else if (type.Name == "String" || type.Name.StartsWith("System.Nullable")) { // return primitive + return ConvertType(content, type); } - + // at this point, it must be a model (json) try { return JsonConvert.DeserializeObject(content, type); @@ -238,5 +242,15 @@ namespace {{packageName}}.Client { return System.Convert.ToBase64String(textByte); } + /// + /// Dynamically cast the object into target type + /// Ref: http://stackoverflow.com/questions/4925718/c-dynamic-runtime-cast + /// + /// Object to be casted + /// Target type + public static dynamic ConvertType(dynamic source, Type dest) { + return Convert.ChangeType(source, dest); + } + } } diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index 8d34ee33ed9..a2a9a0d156f 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -165,7 +165,7 @@ namespace {{packageName}}.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content); } - {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} + {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}), response.Headers);{{/returnType}}{{^returnType}} return;{{/returnType}} } {{/operation}} diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs index 3537293211a..4e6cc56fd16 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs @@ -406,7 +406,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByStatus: " + response.Content, response.Content); } - return (List) ApiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); } /// @@ -479,7 +479,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByTags: " + response.Content, response.Content); } - return (List) ApiClient.Deserialize(response.Content, typeof(List)); + return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); } /// @@ -558,7 +558,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetPetById: " + response.Content, response.Content); } - return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet)); + return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet), response.Headers); } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs index 0a311b1071b..294910b4539 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs @@ -184,7 +184,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetInventory: " + response.Content, response.Content); } - return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary)); + return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary), response.Headers); } /// @@ -257,7 +257,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling PlaceOrder: " + response.Content, response.Content); } - return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order), response.Headers); } /// @@ -336,7 +336,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetOrderById: " + response.Content, response.Content); } - return (Order) ApiClient.Deserialize(response.Content, typeof(Order)); + return (Order) ApiClient.Deserialize(response.Content, typeof(Order), response.Headers); } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs index 470d9ee5f41..65aaf490d92 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs @@ -477,7 +477,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LoginUser: " + response.Content, response.Content); } - return (string) ApiClient.Deserialize(response.Content, typeof(string)); + return (string) ApiClient.Deserialize(response.Content, typeof(string), response.Headers); } /// @@ -627,7 +627,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetUserByName: " + response.Content, response.Content); } - return (User) ApiClient.Deserialize(response.Content, typeof(User)); + return (User) ApiClient.Deserialize(response.Content, typeof(User), response.Headers); } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs index 321e9bc2a36..648f10df280 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs @@ -132,13 +132,13 @@ namespace IO.Swagger.Client { /// /// Deserialize the JSON string into a proper object /// - /// JSON string + /// HTTP body (e.g. string, JSON) /// Object type /// Object representation of the JSON string public object Deserialize(string content, Type type, IList headers=null) { - if (type.GetType() == typeof(Object)) { + if (type.GetType() == typeof(Object)) { // return an object return (Object)content; - } else if (type.Name == "FileStream") { + } else if (type.Name == "FileStream") { // return a file // e.g. Content-Disposition: attachment; filename=checkimage.jpp String fileName; String filePath; @@ -158,9 +158,13 @@ namespace IO.Swagger.Client { } System.IO.File.WriteAllText (fileName, content); return File.Open (fileName, FileMode.Open); + } else if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) { // return a datetime object + return DateTime.Parse(content, null, System.Globalization.DateTimeStyles.RoundtripKind); + } else if (type.Name == "String" || type.Name.StartsWith("System.Nullable")) { // return primitive + return ConvertType(content, type); } - + // at this point, it must be a model (json) try { return JsonConvert.DeserializeObject(content, type); @@ -243,5 +247,15 @@ namespace IO.Swagger.Client { return System.Convert.ToBase64String(textByte); } + /// + /// Dynamically cast the object into target type + /// Ref: http://stackoverflow.com/questions/4925718/c-dynamic-runtime-cast + /// + /// Object to be casted + /// Target type + public static dynamic ConvertType(dynamic source, Type dest) { + return Convert.ChangeType(source, dest); + } + } } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj index 7a0b8f7674b..da68ed6dc6b 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.csproj @@ -39,6 +39,7 @@ Lib\SwaggerClient\bin\RestSharp.dll + diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll index 5541f7ccaa24dec882eb9e104daee63e000b3b28..e13ef14ee625adf11dab00bd6a32d017da294e0b 100755 GIT binary patch delta 19016 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 VCf`fn*|hqhO@Y_`rfx5A{V&@AzV`qC delta 17737 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 H$nk#wchsT~ diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb index 6cfbe6bdc2282421418c7e8b501b55b189932769..970220989a7008a68176508bc413e4a366b00175 100644 GIT binary patch delta 6585 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 Wye)VK4?#MCW_SWJ&W~Zb9rz!YL_qfd delta 6482 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 VCf`fn*|hqhO@Y_`rfx5A{V&@AzV`qC delta 17737 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 H$nk#wchsT~ diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb index 6cfbe6bdc2282421418c7e8b501b55b189932769..970220989a7008a68176508bc413e4a366b00175 100644 GIT binary patch delta 6585 zcmZ9R2Urv77KTqcAz%qE0g}){?^2{#K$;*$YzT#C|Ixn z0(KN#3xaj+z4xxzyy>1w~_KGF2RTyTRwn6X$+z7NzFSk`3B;g3A;NrZZbPd}b8aLV9w? z&Vr`>hm1#Dw;B}{WIvsj6pblhuJH^RSDv}FyUjcgvp0t?ru8;BTv@WWl8SZR`%<;3 zZ*;lggQY%m&gIwsl(3Q(p;MVAC=zn#dNVI2HuAxC0?rjvs*^Ryh^x6$4u`YSj8>Vg zHe>cnM=^_yoHe8MM!M0hW;D-yg*iL=#+=@ozcbg4jxcuBj4m`*$@^FeIFl{tfyHYJ zcJ#QM8s$xL?P&Klsj@3_s#7#5*#0IZl`A(ZwSAkmePp|pw9;~;CEK55Mfp~ft+f5- zwyCCbt>~TAL~FKx%bIRm-(iNg>!f~VO|Pvd+h|*SE^i>Gvx$Yb58j%QKxAel;BK~| zEjC-(em2KM8l-7^h>T1H+$I}3VRMr0jzrfx3tcafiBiCQVna`Dp0VAr9CU2B(`{*n z?Mz$U8QXDr+Oh+8r7f+pU2Utq=B4fJG}}|xULpU}N5HMNr6sBoRqN$*U#RG%>Xk}6 znkCha7D%lu60HT?JUhB$_sotR-D6LC?e{Tt(xsXMrkbeanyE&6+UBs^ft_0DNQ)d7 zJK})jm^K|EO-mhVhSLHkw*SzH9yvW`ay$5|KRD4xry0)L7N5sk$oanw<5fFTjdLwK zu#%&Yy?3P#t{+|5nIBC%%L?4+iQ79jc4n_T?Q^el zZwMVP zO!TEmzWKh|V~(^)kQMpTTi-lCw*QYGo%1{Ir#)t*Jj(R0A06#5>0q{i=%p&7blDCI+<5+G%F(`11p3LBK-&sxyCM z0Bs5=XFL?Hruze^F`!8|fLHKe1<>n&H_T{-Y0#uV$`70z*m}fFj>!m21Q`hU%L8de z;7YbLf@2bfj+;opuMMOffjgOfiUi^5KsponhWSD1&NVb-!j-NzpEwMc^9_I6?%_7H zSOfQBi(TYCWBycn8fQsUQcOZ;NK-PA%m$^ORU4TiULtQJlX>~|lSoApOOaCI++M&h z3!*bYt2#3;lnTyv#@NzaSkZ-Qx*TELEIZjB!p+*bXXnm6Q%shcgyZrAB9THQa!3-l z5exXwyU?tz%eykuEbTbwm`#>`!;f~QQ(fu3c>4c^rqWe z#@)(HG%J{92hRy+Vy)!rjlr}jxI9>QGyzYd`Q#LW#$aj+KA~T=5!?=@JHdC^YJ1JB zO7J0=J_di%uX+jQgiv8fQHb`q7!$4yp>-jpx;0QgdtnM_s`<(7fly$hm%%gpKV})yb zxv{a*G`hWUhxQmK?M`Lgk9KFuto_u}La8WpZm4b_gxENql-rh*o{D3cn3!}B)`!x; z&_irLg(FQt%hK9fcsrEtgx=M4P!fF!rLUpiS|&w2?Jmhgv%+Y0*qkuk@ms12(V8$S z30sS*i{{f7@k}-E)Izi)jCO|YVu!U=E76HCIvI8kaC{X@B?u-I{OEazO?s!|7D`Y5l6g;9fZ04}ZW`b=PC?Ih?+P zfBmki#<{Ev=0*?`F)u>*o(y<$&BZGW$|7ie#0LGUjltds+80sBR;@L&HU?)S=%0vl z`c(&mM-lWm;t5-|*Bv)6k|st@iqxL1E8d5;Y-6w>k`_iT(v?wl(F`jMHbqi-ehU5%Z7;`_n;>| zp6XW>;)zi-DJnlow+CX~2WTx`7)6Vs7VB5-#pO}7Icf`A)$W&txLzGa2cr(@m#xGX zqv%r9Wwxr_FnjUyD0&g~QorgVo)S${qo+l;UW9gMl;Wk)v@E(qX(zA5~4d3;o z=AQ3$YrbL21{zL{p=mJ%F}ka4sVWSY#ZYm~a<;0w;|wces4}MNyQ&dBRx86JF?2NM zSPY}K4^Ur=p*t~m*^%!b0mI^0S{}P1w)KJ}J7Q^P>@MA!FKM|T$;(LDlIl2viEI&O`A)lO0qN40S~ z*sAsuwUji*QB&Lr{i;fGJC5$e-DRuVPgE}X5Jw;5KIy7zybo>JS~4e|3ge67TQ5TU z2v|zi#?!j^QvIq*vMZi;$M0dQo|?x+E;$uXr{mA)SFI)YCL$>OxnYEOBiKnme z-{MVMPp2)bBup=w*K2++rl;fB!1cXoORufHS|^geyH_M73A8q0U4pJ>#52|$)X=Cd zf%YdHNMM>B^F-$osG#>>y_pG4w!*8u>3;7AjFYpHsdq{fP3=QV`z-6jI6G&E3i?uU z-{pOoBIjR4FZ$BLer5fbwl4i;&-&5xejod3Pk>`{j`gR8{>S?>f1r1%KV9yBuRq(X zPNbT|+C=8QOJ{C{H=}a3)Bf!8cOo55Je|mnRSclY0aXK-3|H+~am(0&0aQPrX#hL6 zIf=F;ZB1e>yLL6G@HUu%vj;IN-8wjmL>3-m&#ZB6MIC%JKgH}#qJ2rnlKy>RGHprT zn#?4-jgjq5rhUoBlG$E$3e}|4rZ6|%hRXg>_wcq#G z4Wj*njt^qT)(xi8!DWM)Mvq|4n6amWcC30Z)eJr`m>nxiqxESU(wI2UELm+D?MOSA z#`adH)0*^>bmp+<09i#kRi^JvZ|(64GpHzIZU*D$l_Xo4L8~%0Ww5<(8I+efF_S6r zN-~|3Nrjn9Guhs=OnRRAf{}I%(_B?zM`sJoH`-q_>09RXEOzQ$7By$RXBKr#luga1 zY1wnL+19OWx}AL|o8kDFFlOFvnxjN`J7~YPew9tHv%mg3dMAhO=G@C+rg-Pb-sI5R zoV+3IVQvhen?r65!C|sOUJRj^Lq7l8yEK$854|$9b(a5VC_NtfM7PE_crIK6&Mn+2 zuCDx#L+R7d&rFHWE7`nZG=JE$VeE@$=F+U(*||))ucK^PE*0mN=CZwGxzvz*JePUw zJ3(!VUl<&h5Gja+4saDv!XF`50!#QuWHYdWA222w3#{R%ktcu+e03Y5SYQjUKyCpl z`1rO&Zom#+fSdyC;Ysa?xa~+y4pf5zKo|IEBwmy8J=Q>ZwWyPJQq0>41_DqiEhJF z;qGu3FbLj^RF~qf!B~ha@M4e#Z$M52>F~?Q3m^ktEXRd`On5nR1IU73NA3jK@VCe( z06&cgCAg`$UX$FSE{gEDE7|t&o2I&QcqcI*i4&=h;A*X;5@Xg3oU?ltqau*l{ zx5SFJQ*1YCc}S04gpi(`N%vl6}}i* z2&TceAlCtP0TzcKyTM=Z%gEDUI@|&e^HcZ?cqh0cm|lKxPd$m=E2_~pMv>tBYYL%fdz0|q&Zj!4?uc? zMeulJ1Xv8;j!Xwj;HQuWz*6{4-6j;EZQY=}dG4i+jiw;3z!Xg~%BkgV!Pd01fby z$VPA+?&eB#U$cgHfd_&ncp0)UI03IkZU-mfc5bM_Pr-fR9l>eMvt9y;0cYS<$Zg;( z+|3;)h5rNZ0uKb|;2V&A!Fl*jWDU3g_x8ZS;TPed@L+HWz7ClTF2k#lmEa0o;fY7I z5sRx>xMAT8uECch!@za;X5>b218(Mp?S$WiJHhS2E%;PqFt`n0fMmcO_*-N-xC<9_ z#J>gL9y}YV0QYfz;aJER@Bob`$Qj@v{4??ccmz-K##cJ<7(NV{1D?PyA=Th1{1Ng# zcm_}O!T%tD=kOuOEbsz;68T^75`F`D)hCMR6&5eBcnV&_4Sk8ez~8{Re)tCk>$h+z Wye)VK4?#MCW_SWJ&W~Zb9rz!YL_qfd delta 6482 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 Date: Mon, 29 Jun 2015 23:14:00 +0800 Subject: [PATCH 180/499] update parameter name to camelize lower --- .../languages/CSharpClientCodegen.java | 20 +- .../src/main/csharp/IO/Swagger/Api/PetApi.cs | 252 +++++++++--------- .../main/csharp/IO/Swagger/Api/StoreApi.cs | 76 +++--- .../src/main/csharp/IO/Swagger/Api/UserApi.cs | 188 ++++++------- .../bin/Debug/SwaggerClientTest.dll | Bin 54784 -> 54784 bytes .../bin/Debug/SwaggerClientTest.dll.mdb | Bin 16334 -> 16334 bytes .../obj/Debug/SwaggerClientTest.dll | Bin 54784 -> 54784 bytes .../obj/Debug/SwaggerClientTest.dll.mdb | Bin 16334 -> 16334 bytes 8 files changed, 276 insertions(+), 260 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index 4f7ad02b95d..a200c2f7c86 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -163,8 +163,24 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig @Override public String toParamName(String name) { - // should be the same as variable name - return toVarName(name); + // replace - with _ e.g. created-at => created_at + name = name.replaceAll("-", "_"); + + // if it's all uppper case, do nothing + if (name.matches("^[A-Z_]*$")) { + return name; + } + + // camelize(lower) the variable name + // pet_id => petId + name = camelize(name, true); + + // for reserved word or word starting with number, append _ + if (reservedWords.contains(name) || name.matches("^\\d.*")) { + name = escapeReservedWord(name); + } + + return name; } @Override diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs index 4e6cc56fd16..609ea7326e5 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs @@ -14,124 +14,124 @@ namespace IO.Swagger.Api { /// /// Update an existing pet /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - void UpdatePet (Pet Body); + void UpdatePet (Pet body); /// /// Update an existing pet /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - Task UpdatePetAsync (Pet Body); + Task UpdatePetAsync (Pet body); /// /// Add a new pet to the store /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - void AddPet (Pet Body); + void AddPet (Pet body); /// /// Add a new pet to the store /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - Task AddPetAsync (Pet Body); + Task AddPetAsync (Pet body); /// /// Finds Pets by status Multiple status values can be provided with comma seperated strings /// - /// Status values that need to be considered for filter + /// Status values that need to be considered for filter /// List - List FindPetsByStatus (List Status); + List FindPetsByStatus (List status); /// /// Finds Pets by status Multiple status values can be provided with comma seperated strings /// - /// Status values that need to be considered for filter + /// Status values that need to be considered for filter /// List - Task> FindPetsByStatusAsync (List Status); + Task> FindPetsByStatusAsync (List status); /// /// Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. /// - /// Tags to filter by + /// Tags to filter by /// List - List FindPetsByTags (List Tags); + List FindPetsByTags (List tags); /// /// Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. /// - /// Tags to filter by + /// Tags to filter by /// List - Task> FindPetsByTagsAsync (List Tags); + Task> FindPetsByTagsAsync (List tags); /// /// Find pet by ID Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Pet - Pet GetPetById (long? PetId); + Pet GetPetById (long? petId); /// /// Find pet by ID Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Pet - Task GetPetByIdAsync (long? PetId); + Task GetPetByIdAsync (long? petId); /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated - /// Updated name of the pet - /// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// - void UpdatePetWithForm (string PetId, string Name, string Status); + void UpdatePetWithForm (string petId, string name, string status); /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated - /// Updated name of the pet - /// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// - Task UpdatePetWithFormAsync (string PetId, string Name, string Status); + Task UpdatePetWithFormAsync (string petId, string name, string status); /// /// Deletes a pet /// - /// - /// Pet id to delete + /// + /// Pet id to delete /// - void DeletePet (string ApiKey, long? PetId); + void DeletePet (string apiKey, long? petId); /// /// Deletes a pet /// - /// - /// Pet id to delete + /// + /// Pet id to delete /// - Task DeletePetAsync (string ApiKey, long? PetId); + Task DeletePetAsync (string apiKey, long? petId); /// /// uploads an image /// - /// ID of pet to update - /// Additional data to pass to server - /// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - void UploadFile (long? PetId, string AdditionalMetadata, FileStream File); + void UploadFile (long? petId, string additionalMetadata, FileStream file); /// /// uploads an image /// - /// ID of pet to update - /// Additional data to pass to server - /// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - Task UploadFileAsync (long? PetId, string AdditionalMetadata, FileStream File); + Task UploadFileAsync (long? petId, string additionalMetadata, FileStream file); } @@ -189,9 +189,9 @@ namespace IO.Swagger.Api { /// /// Update an existing pet /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - public void UpdatePet (Pet Body) { + public void UpdatePet (Pet body) { @@ -208,7 +208,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -227,9 +227,9 @@ namespace IO.Swagger.Api { /// /// Update an existing pet /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - public async Task UpdatePetAsync (Pet Body) { + public async Task UpdatePetAsync (Pet body) { @@ -246,7 +246,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -264,9 +264,9 @@ namespace IO.Swagger.Api { /// /// Add a new pet to the store /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - public void AddPet (Pet Body) { + public void AddPet (Pet body) { @@ -283,7 +283,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -302,9 +302,9 @@ namespace IO.Swagger.Api { /// /// Add a new pet to the store /// - /// Pet object that needs to be added to the store + /// Pet object that needs to be added to the store /// - public async Task AddPetAsync (Pet Body) { + public async Task AddPetAsync (Pet body) { @@ -321,7 +321,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -339,9 +339,9 @@ namespace IO.Swagger.Api { /// /// Finds Pets by status Multiple status values can be provided with comma seperated strings /// - /// Status values that need to be considered for filter + /// Status values that need to be considered for filter /// List - public List FindPetsByStatus (List Status) { + public List FindPetsByStatus (List status) { @@ -355,7 +355,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Status != null) queryParams.Add("status", ApiClient.ParameterToString(Status)); // query parameter + if (status != null) queryParams.Add("status", ApiClient.ParameterToString(status)); // query parameter @@ -376,9 +376,9 @@ namespace IO.Swagger.Api { /// /// Finds Pets by status Multiple status values can be provided with comma seperated strings /// - /// Status values that need to be considered for filter + /// Status values that need to be considered for filter /// List - public async Task> FindPetsByStatusAsync (List Status) { + public async Task> FindPetsByStatusAsync (List status) { @@ -392,7 +392,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Status != null) queryParams.Add("status", ApiClient.ParameterToString(Status)); // query parameter + if (status != null) queryParams.Add("status", ApiClient.ParameterToString(status)); // query parameter @@ -412,9 +412,9 @@ namespace IO.Swagger.Api { /// /// Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. /// - /// Tags to filter by + /// Tags to filter by /// List - public List FindPetsByTags (List Tags) { + public List FindPetsByTags (List tags) { @@ -428,7 +428,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Tags != null) queryParams.Add("tags", ApiClient.ParameterToString(Tags)); // query parameter + if (tags != null) queryParams.Add("tags", ApiClient.ParameterToString(tags)); // query parameter @@ -449,9 +449,9 @@ namespace IO.Swagger.Api { /// /// Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. /// - /// Tags to filter by + /// Tags to filter by /// List - public async Task> FindPetsByTagsAsync (List Tags) { + public async Task> FindPetsByTagsAsync (List tags) { @@ -465,7 +465,7 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Tags != null) queryParams.Add("tags", ApiClient.ParameterToString(Tags)); // query parameter + if (tags != null) queryParams.Add("tags", ApiClient.ParameterToString(tags)); // query parameter @@ -485,18 +485,18 @@ namespace IO.Swagger.Api { /// /// Find pet by ID Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Pet - public Pet GetPetById (long? PetId) { + public Pet GetPetById (long? petId) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling GetPetById"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling GetPetById"); var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -525,18 +525,18 @@ namespace IO.Swagger.Api { /// /// Find pet by ID Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Pet - public async Task GetPetByIdAsync (long? PetId) { + public async Task GetPetByIdAsync (long? petId) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling GetPetById"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling GetPetById"); var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -564,20 +564,20 @@ namespace IO.Swagger.Api { /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated - /// Updated name of the pet - /// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// - public void UpdatePetWithForm (string PetId, string Name, string Status) { + public void UpdatePetWithForm (string petId, string name, string status) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling UpdatePetWithForm"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling UpdatePetWithForm"); var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -588,8 +588,8 @@ namespace IO.Swagger.Api { - if (Name != null) formParams.Add("name", ApiClient.ParameterToString(Name)); // form parameter - if (Status != null) formParams.Add("status", ApiClient.ParameterToString(Status)); // form parameter + if (name != null) formParams.Add("name", ApiClient.ParameterToString(name)); // form parameter + if (status != null) formParams.Add("status", ApiClient.ParameterToString(status)); // form parameter @@ -609,20 +609,20 @@ namespace IO.Swagger.Api { /// /// Updates a pet in the store with form data /// - /// ID of pet that needs to be updated - /// Updated name of the pet - /// Updated status of the pet + /// ID of pet that needs to be updated + /// Updated name of the pet + /// Updated status of the pet /// - public async Task UpdatePetWithFormAsync (string PetId, string Name, string Status) { + public async Task UpdatePetWithFormAsync (string petId, string name, string status) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling UpdatePetWithForm"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling UpdatePetWithForm"); var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -633,8 +633,8 @@ namespace IO.Swagger.Api { - if (Name != null) formParams.Add("name", ApiClient.ParameterToString(Name)); // form parameter - if (Status != null) formParams.Add("status", ApiClient.ParameterToString(Status)); // form parameter + if (name != null) formParams.Add("name", ApiClient.ParameterToString(name)); // form parameter + if (status != null) formParams.Add("status", ApiClient.ParameterToString(status)); // form parameter @@ -653,19 +653,19 @@ namespace IO.Swagger.Api { /// /// Deletes a pet /// - /// - /// Pet id to delete + /// + /// Pet id to delete /// - public void DeletePet (string ApiKey, long? PetId) { + public void DeletePet (string apiKey, long? petId) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling DeletePet"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling DeletePet"); var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -675,7 +675,7 @@ namespace IO.Swagger.Api { String postBody = null; - if (ApiKey != null) headerParams.Add("api_key", ApiClient.ParameterToString(ApiKey)); // header parameter + if (apiKey != null) headerParams.Add("api_key", ApiClient.ParameterToString(apiKey)); // header parameter @@ -696,19 +696,19 @@ namespace IO.Swagger.Api { /// /// Deletes a pet /// - /// - /// Pet id to delete + /// + /// Pet id to delete /// - public async Task DeletePetAsync (string ApiKey, long? PetId) { + public async Task DeletePetAsync (string apiKey, long? petId) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling DeletePet"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling DeletePet"); var path = "/pet/{petId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -718,7 +718,7 @@ namespace IO.Swagger.Api { String postBody = null; - if (ApiKey != null) headerParams.Add("api_key", ApiClient.ParameterToString(ApiKey)); // header parameter + if (apiKey != null) headerParams.Add("api_key", ApiClient.ParameterToString(apiKey)); // header parameter @@ -738,20 +738,20 @@ namespace IO.Swagger.Api { /// /// uploads an image /// - /// ID of pet to update - /// Additional data to pass to server - /// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - public void UploadFile (long? PetId, string AdditionalMetadata, FileStream File) { + public void UploadFile (long? petId, string additionalMetadata, FileStream file) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling UploadFile"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling UploadFile"); var path = "/pet/{petId}/uploadImage"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -762,8 +762,8 @@ namespace IO.Swagger.Api { - if (AdditionalMetadata != null) formParams.Add("additionalMetadata", ApiClient.ParameterToString(AdditionalMetadata)); // form parameter - if (File != null) fileParams.Add("file", ApiClient.ParameterToString(File)); + if (additionalMetadata != null) formParams.Add("additionalMetadata", ApiClient.ParameterToString(additionalMetadata)); // form parameter + if (file != null) fileParams.Add("file", ApiClient.ParameterToString(file)); @@ -783,20 +783,20 @@ namespace IO.Swagger.Api { /// /// uploads an image /// - /// ID of pet to update - /// Additional data to pass to server - /// file to upload + /// ID of pet to update + /// Additional data to pass to server + /// file to upload /// - public async Task UploadFileAsync (long? PetId, string AdditionalMetadata, FileStream File) { + public async Task UploadFileAsync (long? petId, string additionalMetadata, FileStream file) { - // verify the required parameter 'PetId' is set - if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling UploadFile"); + // verify the required parameter 'petId' is set + if (petId == null) throw new ApiException(400, "Missing required parameter 'petId' when calling UploadFile"); var path = "/pet/{petId}/uploadImage"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(PetId)); + path = path.Replace("{" + "petId" + "}", ApiClient.ParameterToString(petId)); var queryParams = new Dictionary(); @@ -807,8 +807,8 @@ namespace IO.Swagger.Api { - if (AdditionalMetadata != null) formParams.Add("additionalMetadata", ApiClient.ParameterToString(AdditionalMetadata)); // form parameter - if (File != null) fileParams.Add("file", ApiClient.ParameterToString(File)); + if (additionalMetadata != null) formParams.Add("additionalMetadata", ApiClient.ParameterToString(additionalMetadata)); // form parameter + if (file != null) fileParams.Add("file", ApiClient.ParameterToString(file)); diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs index 294910b4539..67276bbce88 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs @@ -26,44 +26,44 @@ namespace IO.Swagger.Api { /// /// Place an order for a pet /// - /// order placed for purchasing the pet + /// order placed for purchasing the pet /// Order - Order PlaceOrder (Order Body); + Order PlaceOrder (Order body); /// /// Place an order for a pet /// - /// order placed for purchasing the pet + /// order placed for purchasing the pet /// Order - Task PlaceOrderAsync (Order Body); + Task PlaceOrderAsync (Order body); /// /// Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Order - Order GetOrderById (string OrderId); + Order GetOrderById (string orderId); /// /// Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Order - Task GetOrderByIdAsync (string OrderId); + Task GetOrderByIdAsync (string orderId); /// /// Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors /// - /// ID of the order that needs to be deleted + /// ID of the order that needs to be deleted /// - void DeleteOrder (string OrderId); + void DeleteOrder (string orderId); /// /// Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors /// - /// ID of the order that needs to be deleted + /// ID of the order that needs to be deleted /// - Task DeleteOrderAsync (string OrderId); + Task DeleteOrderAsync (string orderId); } @@ -190,9 +190,9 @@ namespace IO.Swagger.Api { /// /// Place an order for a pet /// - /// order placed for purchasing the pet + /// order placed for purchasing the pet /// Order - public Order PlaceOrder (Order Body) { + public Order PlaceOrder (Order body) { @@ -209,7 +209,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -227,9 +227,9 @@ namespace IO.Swagger.Api { /// /// Place an order for a pet /// - /// order placed for purchasing the pet + /// order placed for purchasing the pet /// Order - public async Task PlaceOrderAsync (Order Body) { + public async Task PlaceOrderAsync (Order body) { @@ -246,7 +246,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -263,18 +263,18 @@ namespace IO.Swagger.Api { /// /// Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Order - public Order GetOrderById (string OrderId) { + public Order GetOrderById (string orderId) { - // verify the required parameter 'OrderId' is set - if (OrderId == null) throw new ApiException(400, "Missing required parameter 'OrderId' when calling GetOrderById"); + // verify the required parameter 'orderId' is set + if (orderId == null) throw new ApiException(400, "Missing required parameter 'orderId' when calling GetOrderById"); var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(orderId)); var queryParams = new Dictionary(); @@ -303,18 +303,18 @@ namespace IO.Swagger.Api { /// /// Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions /// - /// ID of pet that needs to be fetched + /// ID of pet that needs to be fetched /// Order - public async Task GetOrderByIdAsync (string OrderId) { + public async Task GetOrderByIdAsync (string orderId) { - // verify the required parameter 'OrderId' is set - if (OrderId == null) throw new ApiException(400, "Missing required parameter 'OrderId' when calling GetOrderById"); + // verify the required parameter 'orderId' is set + if (orderId == null) throw new ApiException(400, "Missing required parameter 'orderId' when calling GetOrderById"); var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(orderId)); var queryParams = new Dictionary(); @@ -342,18 +342,18 @@ namespace IO.Swagger.Api { /// /// Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors /// - /// ID of the order that needs to be deleted + /// ID of the order that needs to be deleted /// - public void DeleteOrder (string OrderId) { + public void DeleteOrder (string orderId) { - // verify the required parameter 'OrderId' is set - if (OrderId == null) throw new ApiException(400, "Missing required parameter 'OrderId' when calling DeleteOrder"); + // verify the required parameter 'orderId' is set + if (orderId == null) throw new ApiException(400, "Missing required parameter 'orderId' when calling DeleteOrder"); var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(orderId)); var queryParams = new Dictionary(); @@ -383,18 +383,18 @@ namespace IO.Swagger.Api { /// /// Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors /// - /// ID of the order that needs to be deleted + /// ID of the order that needs to be deleted /// - public async Task DeleteOrderAsync (string OrderId) { + public async Task DeleteOrderAsync (string orderId) { - // verify the required parameter 'OrderId' is set - if (OrderId == null) throw new ApiException(400, "Missing required parameter 'OrderId' when calling DeleteOrder"); + // verify the required parameter 'orderId' is set + if (orderId == null) throw new ApiException(400, "Missing required parameter 'orderId' when calling DeleteOrder"); var path = "/store/order/{orderId}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(OrderId)); + path = path.Replace("{" + "orderId" + "}", ApiClient.ParameterToString(orderId)); var queryParams = new Dictionary(); diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs index 65aaf490d92..2d87996dd9e 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs @@ -14,60 +14,60 @@ namespace IO.Swagger.Api { /// /// Create user This can only be done by the logged in user. /// - /// Created user object + /// Created user object /// - void CreateUser (User Body); + void CreateUser (User body); /// /// Create user This can only be done by the logged in user. /// - /// Created user object + /// Created user object /// - Task CreateUserAsync (User Body); + Task CreateUserAsync (User body); /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - void CreateUsersWithArrayInput (List Body); + void CreateUsersWithArrayInput (List body); /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - Task CreateUsersWithArrayInputAsync (List Body); + Task CreateUsersWithArrayInputAsync (List body); /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - void CreateUsersWithListInput (List Body); + void CreateUsersWithListInput (List body); /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - Task CreateUsersWithListInputAsync (List Body); + Task CreateUsersWithListInputAsync (List body); /// /// Logs user into the system /// - /// The user name for login - /// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string - string LoginUser (string Username, string Password); + string LoginUser (string username, string password); /// /// Logs user into the system /// - /// The user name for login - /// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string - Task LoginUserAsync (string Username, string Password); + Task LoginUserAsync (string username, string password); /// /// Logs out current logged in user session @@ -84,46 +84,46 @@ namespace IO.Swagger.Api { /// /// Get user by user name /// - /// The name that needs to be fetched. Use user1 for testing. + /// The name that needs to be fetched. Use user1 for testing. /// User - User GetUserByName (string Username); + User GetUserByName (string username); /// /// Get user by user name /// - /// The name that needs to be fetched. Use user1 for testing. + /// The name that needs to be fetched. Use user1 for testing. /// User - Task GetUserByNameAsync (string Username); + Task GetUserByNameAsync (string username); /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted - /// Updated user object + /// name that need to be deleted + /// Updated user object /// - void UpdateUser (string Username, User Body); + void UpdateUser (string username, User body); /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted - /// Updated user object + /// name that need to be deleted + /// Updated user object /// - Task UpdateUserAsync (string Username, User Body); + Task UpdateUserAsync (string username, User body); /// /// Delete user This can only be done by the logged in user. /// - /// The name that needs to be deleted + /// The name that needs to be deleted /// - void DeleteUser (string Username); + void DeleteUser (string username); /// /// Delete user This can only be done by the logged in user. /// - /// The name that needs to be deleted + /// The name that needs to be deleted /// - Task DeleteUserAsync (string Username); + Task DeleteUserAsync (string username); } @@ -181,9 +181,9 @@ namespace IO.Swagger.Api { /// /// Create user This can only be done by the logged in user. /// - /// Created user object + /// Created user object /// - public void CreateUser (User Body) { + public void CreateUser (User body) { @@ -200,7 +200,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -219,9 +219,9 @@ namespace IO.Swagger.Api { /// /// Create user This can only be done by the logged in user. /// - /// Created user object + /// Created user object /// - public async Task CreateUserAsync (User Body) { + public async Task CreateUserAsync (User body) { @@ -238,7 +238,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -256,9 +256,9 @@ namespace IO.Swagger.Api { /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - public void CreateUsersWithArrayInput (List Body) { + public void CreateUsersWithArrayInput (List body) { @@ -275,7 +275,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -294,9 +294,9 @@ namespace IO.Swagger.Api { /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - public async Task CreateUsersWithArrayInputAsync (List Body) { + public async Task CreateUsersWithArrayInputAsync (List body) { @@ -313,7 +313,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -331,9 +331,9 @@ namespace IO.Swagger.Api { /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - public void CreateUsersWithListInput (List Body) { + public void CreateUsersWithListInput (List body) { @@ -350,7 +350,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -369,9 +369,9 @@ namespace IO.Swagger.Api { /// /// Creates list of users with given input array /// - /// List of user object + /// List of user object /// - public async Task CreateUsersWithListInputAsync (List Body) { + public async Task CreateUsersWithListInputAsync (List body) { @@ -388,7 +388,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -406,10 +406,10 @@ namespace IO.Swagger.Api { /// /// Logs user into the system /// - /// The user name for login - /// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string - public string LoginUser (string Username, string Password) { + public string LoginUser (string username, string password) { @@ -423,8 +423,8 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Username != null) queryParams.Add("username", ApiClient.ParameterToString(Username)); // query parameter - if (Password != null) queryParams.Add("password", ApiClient.ParameterToString(Password)); // query parameter + if (username != null) queryParams.Add("username", ApiClient.ParameterToString(username)); // query parameter + if (password != null) queryParams.Add("password", ApiClient.ParameterToString(password)); // query parameter @@ -445,10 +445,10 @@ namespace IO.Swagger.Api { /// /// Logs user into the system /// - /// The user name for login - /// The password for login in clear text + /// The user name for login + /// The password for login in clear text /// string - public async Task LoginUserAsync (string Username, string Password) { + public async Task LoginUserAsync (string username, string password) { @@ -462,8 +462,8 @@ namespace IO.Swagger.Api { var fileParams = new Dictionary(); String postBody = null; - if (Username != null) queryParams.Add("username", ApiClient.ParameterToString(Username)); // query parameter - if (Password != null) queryParams.Add("password", ApiClient.ParameterToString(Password)); // query parameter + if (username != null) queryParams.Add("username", ApiClient.ParameterToString(username)); // query parameter + if (password != null) queryParams.Add("password", ApiClient.ParameterToString(password)); // query parameter @@ -554,18 +554,18 @@ namespace IO.Swagger.Api { /// /// Get user by user name /// - /// The name that needs to be fetched. Use user1 for testing. + /// The name that needs to be fetched. Use user1 for testing. /// User - public User GetUserByName (string Username) { + public User GetUserByName (string username) { - // verify the required parameter 'Username' is set - if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling GetUserByName"); + // verify the required parameter 'username' is set + if (username == null) throw new ApiException(400, "Missing required parameter 'username' when calling GetUserByName"); var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(username)); var queryParams = new Dictionary(); @@ -594,18 +594,18 @@ namespace IO.Swagger.Api { /// /// Get user by user name /// - /// The name that needs to be fetched. Use user1 for testing. + /// The name that needs to be fetched. Use user1 for testing. /// User - public async Task GetUserByNameAsync (string Username) { + public async Task GetUserByNameAsync (string username) { - // verify the required parameter 'Username' is set - if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling GetUserByName"); + // verify the required parameter 'username' is set + if (username == null) throw new ApiException(400, "Missing required parameter 'username' when calling GetUserByName"); var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(username)); var queryParams = new Dictionary(); @@ -633,19 +633,19 @@ namespace IO.Swagger.Api { /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted - /// Updated user object + /// name that need to be deleted + /// Updated user object /// - public void UpdateUser (string Username, User Body) { + public void UpdateUser (string username, User body) { - // verify the required parameter 'Username' is set - if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling UpdateUser"); + // verify the required parameter 'username' is set + if (username == null) throw new ApiException(400, "Missing required parameter 'username' when calling UpdateUser"); var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(username)); var queryParams = new Dictionary(); @@ -657,7 +657,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -676,19 +676,19 @@ namespace IO.Swagger.Api { /// /// Updated user This can only be done by the logged in user. /// - /// name that need to be deleted - /// Updated user object + /// name that need to be deleted + /// Updated user object /// - public async Task UpdateUserAsync (string Username, User Body) { + public async Task UpdateUserAsync (string username, User body) { - // verify the required parameter 'Username' is set - if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling UpdateUser"); + // verify the required parameter 'username' is set + if (username == null) throw new ApiException(400, "Missing required parameter 'username' when calling UpdateUser"); var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(username)); var queryParams = new Dictionary(); @@ -700,7 +700,7 @@ namespace IO.Swagger.Api { - postBody = ApiClient.Serialize(Body); // http body (model) parameter + postBody = ApiClient.Serialize(body); // http body (model) parameter // authentication setting, if any @@ -718,18 +718,18 @@ namespace IO.Swagger.Api { /// /// Delete user This can only be done by the logged in user. /// - /// The name that needs to be deleted + /// The name that needs to be deleted /// - public void DeleteUser (string Username) { + public void DeleteUser (string username) { - // verify the required parameter 'Username' is set - if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling DeleteUser"); + // verify the required parameter 'username' is set + if (username == null) throw new ApiException(400, "Missing required parameter 'username' when calling DeleteUser"); var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(username)); var queryParams = new Dictionary(); @@ -759,18 +759,18 @@ namespace IO.Swagger.Api { /// /// Delete user This can only be done by the logged in user. /// - /// The name that needs to be deleted + /// The name that needs to be deleted /// - public async Task DeleteUserAsync (string Username) { + public async Task DeleteUserAsync (string username) { - // verify the required parameter 'Username' is set - if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling DeleteUser"); + // verify the required parameter 'username' is set + if (username == null) throw new ApiException(400, "Missing required parameter 'username' when calling DeleteUser"); var path = "/user/{username}"; path = path.Replace("{format}", "json"); - path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(Username)); + path = path.Replace("{" + "username" + "}", ApiClient.ParameterToString(username)); var queryParams = new Dictionary(); diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll index e13ef14ee625adf11dab00bd6a32d017da294e0b..60d81e320bc21585e4b8b5f705740db319735e78 100755 GIT binary patch delta 9126 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 F{Tsf7-~#{v diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb index 970220989a7008a68176508bc413e4a366b00175..53958fc7ab656c4f94f02dfbbeb038505958144c 100644 GIT binary patch delta 126 zcmX?Cf399ZWLf=RWwjTsMhp<3S>+x0rhl*7&U_VF_w@T|6BWJ*6*)$Uu^P{2o7;J) zkt;dwBg3?bg*}tEFiH#T?&MURH{D?IFS*<69+$69n>>NFYw`w0mdUwHQbNBZE6;6r e`z`gtpjY=+7vBbkSrZF8Cf{S`+N{mI*aiSzyEBsj delta 126 zcmV-^0D=F`f6jj(6sCXuBPQrYG5`Po00000g2*NsqtRDQm31AOH7{+Sks$UG!kq7I zZ;;tIyjj#l1Kvs60G5$)jFYqh8xUUCtyYr!_Xk{RjTc?3&jOQ>1&Wif0R)q60vZy~ gxw?qX!Nm=0-ydyAIwgt#nvrpclimXgvnvCmJSG=4djJ3c diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll index e13ef14ee625adf11dab00bd6a32d017da294e0b..60d81e320bc21585e4b8b5f705740db319735e78 100755 GIT binary patch delta 9126 zcmchdd32OT*2bUeCEe+L$tDH}JAvRq(YOT##UL0k#(;>7(2&StLIO0h^TLRXjvPQc zqxczC5uphr*sKyH0!ENkML%R1g|ViY6j^MlCLL#%?sD@gvkf)e{;OGza>hyR7?&sF&?T;eu;KAI*>ggi z?3rq5XR+Z%i<}{cwb&xv?G`!eI7bpSYnmwzmGN@0-zL-dwRI4746^|?%(UfE+-R5T zwaa1m*!$RR2*4C*yv~l=wha=lz!w83T zw>q?4jwIAO(o9LX(J5D#<;*lB;a+MtL5_2dEo6#30ruS*Ni+Pin(Tk4&?PG+EW`bFYj{Pp&pSEM82ORa}~!78*0`3+|Ct=5CbQHe*0!vfX6aTLCy@3qPa*AZ)<_G?Pm_)^|B3X^ z<^%`~vz#{wY_drA8s^k~*GV@R@1*pXTWA+?`Gsn~zWeHHoHT4~a+Niph01bWT++JB zt~6|v3%#1czQa8?uwJeb7ay6{aAsG(>e{QE`l@Eu(D*{z&r=^aRv0dSiWjfFA;HyD z<>E?&jPl}rnN<6&SMLur_;Qo}gW{LY+1`4EEw$hF-aT#l`R>1^ z$Zz;Okk^01hs+J;-)Yion3JymYyIR}%4Zp7z4);78tkQQTzUmu;Uc~G`oG+Cm%rxq zMOTc8i8Xc?;)4L9|eNOSwwl7KNbNdx;FX#3eZtDp)bL1V4 z=*jkRpJJ`5ij3DjXRw;$fsbS*1XO0 ziBsr6^q%LKQ&~ixkY|i~e{@QcWNzX`%&U@D$-2`!)YTkE6@B0x zKy-?!PROdIp}Ym?RVQTCTHu%>S+$nX%3A8CEL$raRwT>T8oOKRo-A7%SX=8P%hnbb z6v?W!LslEzlT~Yv0c~}XRZGVLMY3ugP|;5JWYs$1f~HWGtuv6Wo3d;-;eJK3Y&WB* zgYL<)-71^(qVx4Oci*7{(K&BMBeMFsHX^^Thx^WG&sM$%-C0DMjMSPt`}(=NM$LPC zVar`n>gyZqz8eGC){m(hW<@D%>5f-);$yl8D;3FOx)-~3;$!N86N=<9^}v~~oWD-U zUEGIVoU=~IUEGHYisUZt!;!n?dg_GSMK)5p=_Gg26A9gQlAE|6`HJKwdZG0_x+gc$ zTQ=!cYaZ-7>3)FQwEtT3DBsua97ai#ec!qJM5)Yo-rYA!5%M04(mwKXqjcK$7#@n! zS)bYSaFmSxJoJl_%fGOJG)maa@AkyZ41c1hf3)k}{^p)XqSV{p*7InT2KvL6$D&l| zAM7548+cp#G5rApq7=3~j$)nomsuf@e7p_josug01B3ZR3kjrJP6S8Wt|x#D#~R;?I6DUwwijU#!oICVl+trTf|8g)WeZ7jZ1q{*_4 zL)${xRhBJm2_j!7>v(@L#$&XiKhnVQn5bx;KjL``FDhE(-$qof6V~{5dL|&@37!)h z{Pi9Ua~19IH}(DrOB8*i`CECPL$$(F{w(WrIIO7Ne~b6e$RDmxV@&AgeICb0=;Thg z#XA=nBXzniABNFis|%joT9?&CrQcypCse;uNoAnIf6tbyO(oM(J13`(I&iGFRY` zqWnaI?+u(*6iDCXOnS>wXibnDi786ikez zh+u|JoFal}b>a*WEK?*iL{Kr2?|-xDZBdN%s8wb~LfEn%hZG^H7#na}kt-=|*?_Z( zQpwv0*Cf4$>EvxhilR*NHsK~k-N@U7EJa%=-)8hDqW#ad)>6XF7^2MHG;j+hE6S&V zTQEz}<4FeJTUey1ILSw}l1Z<{R-Bz2tHoA$rZ90WwxYF8n3|M_t@uuoMsJ{*jHy%g zfzL6upQh6SCQR39EmO6661u}Br>V%0UY#&oGmTqOtw?&+sJJ2KRij#w^tR!r&eGHL zf!kocQSU0vx6z|ZY~b6-S0ugdsJbSsJtJc#yu1JVZ`1fGm}htOH|lvO)~(CBHYq1{tbv@m`B5{Rh*?@+{u z4bk|;ky?ryRR6|pIfDWFdF=5)M{a zJ_@vdQ2(R!3TxJvY`Ve}7tKIrZW)?BEiSN>!c;akf8G|55nT;xReB$NZ4K@(E{7_Z zuKj%G#u=|Ai+)7ic#FD*x#^<<~0E$|iVb#@tVVfT29XiM#e_H)VLducox(SF(f54k^Cs(B$jHJ>vs zqftMa6T~F^)7(n*LUa1Z%~a~yn^g8prJe&sYb=aAAu>3g!SM{ds*$mdrufEiGp1N9 z#w^UXoDc!LWJ#j-8cRoG0DCN*Nk6gV;RCe@`JtG~eNx#?B{!EMGM>Tl431}TJcHvo zoH&OQ=kS8^DWdfj`5emUP!12y;lVjPIEM%4b3C8p`5e#Z_#mEi5YI4(XDHxE0Y?fr zGKj|x;<1Bx>>wUnAmf^`fQqFwGeFo{5_SrP}2m3rL{ifw8vyKt{9ZRfx z5Ofq{jF{obvpTTU@dou-V5*|_8b^YdDGoU{S!aq*9ouMGCmcJi&r!-etP*q0pINtv zh0d?6v*_!pIXQk7_Bva~&%uYzTjPUVt{_(>$W;k)RqCl8E9f^?;aU@42DfW_d^xUn zbu^aaZTm;@^=RcfLh(CXC&Z`XLAo#3;}MF~W2Eai=~J$+xLqF~k2x-rZ8=|U70~46 zR>2qA9=^DwhAm%h7`+6zqg+k~OLyDzu%ZC=BJ z?t!EQ?jg4Id~oT8jqa(obVIef+;*K|hkF(GtfaO)j@u3Vjx(Ios35%_t_jmf7e z5|=Fd>uoznyvg5Fq)GC5(pKztNH+Q#`jo*=ZGBXiWDm8wCZ~|AFfJGfjvt3$fc}ff=sQzD&Sd~>(n2vx0ggw{ve^52^y*{1KYt=p_0|l(>)A81dirb8nUMIXiI^XG^uRMB;yQHRXsF7H Mcn|+wywKV5|9RSa85S;OpP{+RJm}n`Z$n%zsq?4@DU20unbzn2M_gUpASCZ89qcBScdB7~wH#nujCCB<)ty}?gb@g&NFw!OC z>s|U=u4Ei@wX!6mvsB#c!}dNY9}GhBNyGnBNsi5 z+Z#M`(vMmFUYRnPHIucMS1$ct)~6|wj78p;?(#aYTy!^GjGf+t-iz@)sRMrBTeQ-S zzFw}jxXjnr*A}<17PC%eeT3A3B|e#EEolo?vrqjpGN{Ey%gtgGT@-YDEm}nDURg@Zo?}(pA{Sl$9i@FLpEC&s2atOjS%H@n1|^nI>Q_Qv*{OK4OAR&N2_5 zF#S%G^aA!Vd6F4l=D{`Ur=Z-eWp~BTU~heT@dD)^?c!;&Y~J zn7raB(_p4l@g>t_dmq^~U3|qjm(8oiai)_*7oeZ`n&}d{U#g^Z4z}u~qpS~;jq$>7K`&`fobvdh@lE{!9zKLY#S_`Y-Rk_B9&NS^T$EW|~X8R2$J*PR1>p=f?_wG^4k9YqS zMSjKa19|;7{gS!V`WsDp9&^(5f4;xDD)}s{SWiDJqXzHNHhy{qoaG`t{rW%Cbf@31 zO*fUXh_g(3+C6oqId4j8TB6>3_vb$88uR&G0cV~0m#+VxyR540@}^p4Uu`pEyRVhpw5?;BGyLEcm;ZMEw z0)L~M-b)m9@tZyLLZRp?zuQAE6pH%$FY-9!G|b=Dp~P5zOdR@kTL zUH=fGBTNlKR;@KE+JHU{LRPH}_A8QAYYV-+tzpWtwZmRTvTW_Ky`AC7vUPyg-XK}F zjyR=ARxJ%#9Sl!a?Gg;>XppR0CoEJXtCo(MG{cis>w;6dLRq###zRJf`ch-5@@uY#dS~k0~2p_Tc;t zLhhmuwsOt}A$QRSrxeLu^uZ@R<$4-~+(loc^fE~9q8~!N4U(Jaj{-$<6FF#qo#Dw% z+#s9uskaUd9QNMGZQ6gmwJ7j~H2KX2)RIcT2qM)xlQ2TjP`+?C2XBr-ER$?Y21G z8NAaw9GCL8jAObTL*i6zy91>L@iEGwC2-j5VC5Ma9oit z%QhJui)B|?wrX1h1qNy3gQb{)af)Wrz$uufXihNZyBAL@S{U3!RACTa4!-T1iqKs= zCsqd=eLChUstvaE{{fYX-qVBa{BuyN@Uvi+HV1nZ9Se5zKZb(Q#x&mtd-)&7!7&Ee zL*4vykulbwU?@wQhgpi!LihORBXqa)p2fAHS^g-p6!j0y^OvLh1Rh7*)$_3cJ>$6A zzW{l0TJK+kF$QV3g|ZwKcu3LMP@TU5PbiuiddI&Q%b6b39u4jAKabUhM=A300$yi& zR$CMruf2c|6fFnvnCfwiyk#hwEECSg6=6wb262jIc+?E=qK9ZPRk&QyleFwAWGPx0zA{jaTNEt| z_ao9rFdBPWiD^?3ds>NdgLqFXQDG48X(cu&l6zW-Iz{Wkd4U@2Q?xlejOd6WSb+5xdMRMKiaD>T75kt|mM2Z;7 z4B`|qJZcbUh+&B$nIVRnY5e?~O}9lUUPZk!mxrotuVRm)leEM2II2iXuC}em2}Q}t zrPu(^bfbpt$lHJvMVaKihRYRQL*8r1QWT?nuj3XX+W%~=juO6(5z5S_fp1`jqJcE< z4a`zBB-s>r6VEFeog5%q!DQ58BTmdn)M6ui_c3uTHln>jxHmZ;8*yBcPB+kfjHxq? zfe$lXa=$@OGvNV)Rxs77H=(W`IZaK5^csXk>u%nNT1C>UMa`uNuNJk6q_+wG%#@yP z4BQ0mGNY?B-$M2kiGgpSK#}w|qqbYZ+l*a`q*sUjS0%hU3{fP#Em*_vX-2*+s53|x z()<&0`NhaE|AZp-)*`*PF(ErK>Dwq%B)zSu?3?hmVvQo{y@ONz6W%*;f0F&z9ye(%iVHb}*&}?i|#OD(@!tsAKSNb+j>3c>S?{E1ZU5?DUhI1R5 zMqeKV(gqnnl%8eH#*!^(nc}n=sLXAn58R(rSV>_Ms@VK-TR=t(HK|n@eT=m=xj(xc zs$eJm$1^w2cs^N-BkIXpG_=Yt*T0HX{=ovU&>t)SD|V75;bT%84(aqm!{0~+{jK60 z1~lt`z#;n^$qrLn;IFJHP8o0Q^!d!_K<%dZV=md2OEK{x%#@d&2z07s7$1RC)HcEF zmhlB1*?y5U(Uy}|aYQC=8r6K?&D-0(a%}U+kJ|dr+y77QcQ&~!sq`1Y1pMdPW;%2$ z{R5{h`b^pFx_nW+8d7^B*K!+N+|I#B%NXR~aZ4%17g#1@D8~!&r1fzWqTD*4^f~Kd zdTajHyo5&m!x|FPanjmO}5JnMyr}i1w&RIwUeUp26`9Jg1YfmZmsn z>WUdQn>h=Q*ba$8JY!3yc8#sGxe(iJnWTTV<>Ldj2>DAfmHVW!n@VmTMPxjK;~5;! z;CKedb2)J?C(h*s6;MRKK@@PPfJ3=FIF|?K^59$^T)^=Hju&vefaAk?(&0SAaGs%v zBSjo3;>d6wJDkT3=dr_iY>|xX<{~zV*eGJdPP?qOm5^?-jl~6yw{2a~($U!*;i)4$ zb%dvGLthZGv?|CK$KLqf(NFV>V~%`nI=VP-CGF-Mu3aDux0|y_>y0~{cWZ4#iF3Tx zNysevW&9nZlUVGWtX(atoQFhjvB_DA9I?weL%T`rb(WF-k8?H+{=0LY)&?h?<=RA% z=c?3pV4SNI6U7WyzUIOoT`yCg1(r3`e%Tcg4~m_x*R%)4hptVuto^RHwK z>u1^|mrokKZZ$l9JJ%`?v=o#o!kI+o)TS*M$x@IC9EZd&A9LhcIRTK7!W5LIid zdp}jHvw1()=0)n?Cb*VIdC(rQqqADu^xEV<2Y^=MQ_^>mKO=oV`4DNP)<9atx<6UA zk0l=^-DZ~kjrJC^jC_^+HR*TBCrQ_{ix%c!Q=f7;scnq1xA0NB)|^6W^gP!6CzDoc zGC{C~)RwFrS*tjn!R^aqo1Zu=M33mwxgEs(=#IH*qF1zWZm`Fq7V^;$e?m}uWN_I} zVtK)X^nj2LnIw8h9=<}h?+I>*^`3Xwl6l?uqUpFfQW%*s83l#(UqteXBRNGFSXf$& z-bF=YBV)&pD=ZmM94Ra+j1;18Y;bu$ix?DLyl|Rh@Z{o2<7CIYSgS?p=Gedr&DpJ> zxO76_@g+sYlky59^qaK^H%%!V7a1F&G-Jk2$S#Z&qIuDBGt?ta7e^?cW zE?Tug42tEgUS|@6qbp-w$k?u02UobFM`9hL@@G-3uNWL#8S7y4J+!^!g-buUb-*)I zT0Yn9ccm}H4!&6y^bGk@R>=5_`!Xs%yikmY&Ds5ki0;{)8T0HpX*QK*#r%8!E}qJ? F{Tsf7-~#{v diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb index 970220989a7008a68176508bc413e4a366b00175..53958fc7ab656c4f94f02dfbbeb038505958144c 100644 GIT binary patch delta 126 zcmX?Cf399ZWLf=RWwjTsMhp<3S>+x0rhl*7&U_VF_w@T|6BWJ*6*)$Uu^P{2o7;J) zkt;dwBg3?bg*}tEFiH#T?&MURH{D?IFS*<69+$69n>>NFYw`w0mdUwHQbNBZE6;6r e`z`gtpjY=+7vBbkSrZF8Cf{S`+N{mI*aiSzyEBsj delta 126 zcmV-^0D=F`f6jj(6sCXuBPQrYG5`Po00000g2*NsqtRDQm31AOH7{+Sks$UG!kq7I zZ;;tIyjj#l1Kvs60G5$)jFYqh8xUUCtyYr!_Xk{RjTc?3&jOQ>1&Wif0R)q60vZy~ gxw?qX!Nm=0-ydyAIwgt#nvrpclimXgvnvCmJSG=4djJ3c From 2e76b56f307b9daf2f2afeaa24182afbf4f678da Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 30 Jun 2015 17:50:22 +0800 Subject: [PATCH 181/499] revert file to String, add test case for upload file --- .../languages/CSharpClientCodegen.java | 3 +- .../main/resources/csharp/ApiClient.mustache | 6 +-- .../src/main/resources/csharp/api.mustache | 7 +++- .../src/main/csharp/IO/Swagger/Api/PetApi.cs | 36 ++++++++++++------ .../main/csharp/IO/Swagger/Api/StoreApi.cs | 20 ++++++++-- .../src/main/csharp/IO/Swagger/Api/UserApi.cs | 24 ++++++++---- .../csharp/IO/Swagger/Client/ApiClient.cs | 6 +-- .../SwaggerClientTest.userprefs | 7 ++-- .../csharp/SwaggerClientTest/TestPet.cs | 34 +++++++++++++++++ .../bin/Debug/SwaggerClientTest.dll | Bin 54784 -> 55808 bytes .../bin/Debug/SwaggerClientTest.dll.mdb | Bin 16334 -> 16834 bytes ...ClientTest.csproj.FilesWrittenAbsolute.txt | 6 +-- .../obj/Debug/SwaggerClientTest.dll | Bin 54784 -> 55808 bytes .../obj/Debug/SwaggerClientTest.dll.mdb | Bin 16334 -> 16834 bytes 14 files changed, 107 insertions(+), 42 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index a200c2f7c86..6f5140495c1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -37,6 +37,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig languageSpecificPrimitives = new HashSet( Arrays.asList( + "String", "string", "bool?", "double?", @@ -68,7 +69,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.put("number", "double?"); typeMapping.put("datetime", "DateTime?"); typeMapping.put("date", "DateTime?"); - typeMapping.put("file", "FileStream"); + typeMapping.put("file", "String"); typeMapping.put("array", "List"); typeMapping.put("list", "List"); typeMapping.put("map", "Dictionary"); diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index e3061aa94bc..0ae71bda25c 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -120,8 +120,6 @@ namespace {{packageName}}.Client { { if (obj is DateTime) { return ((DateTime)obj).ToString ("u"); - } else if (obj is FileStream) { - return ((FileStream)obj).Name; } else if (obj is List) { return String.Join(",", obj as List); } else { @@ -138,7 +136,7 @@ namespace {{packageName}}.Client { public object Deserialize(string content, Type type, IList headers=null) { if (type.GetType() == typeof(Object)) { // return an object return (Object)content; - } else if (type.Name == "FileStream") { // return a file + } else if (type.Name == "FileStream") { // return a file (full path) // e.g. Content-Disposition: attachment; filename=checkimage.jpp String fileName; String filePath; @@ -157,7 +155,7 @@ namespace {{packageName}}.Client { fileName = filePath + Guid.NewGuid().ToString(); } System.IO.File.WriteAllText (fileName, content); - return File.Open (fileName, FileMode.Open); + return fileName; } else if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) { // return a datetime object return DateTime.Parse(content, null, System.Globalization.DateTimeStyles.RoundtripKind); } else if (type.Name == "String" || type.Name.StartsWith("System.Nullable")) { // return primitive diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index a2a9a0d156f..de5083b6b22 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -121,8 +121,11 @@ namespace {{packageName}}.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content); } - {{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}), response.Headers);{{/returnType}}{{^returnType}} - return;{{/returnType}} + + {{#returnType}} // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "{{{returnType}}}"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof({{{returnType}}}); + return ({{{returnType}}}) ApiClient.Deserialize(response.Content, returnType, response.Headers);{{/returnType}}{{^returnType}}return;{{/returnType}} } /// diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs index 609ea7326e5..db51ab1f753 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/PetApi.cs @@ -122,7 +122,7 @@ namespace IO.Swagger.Api { /// Additional data to pass to server /// file to upload /// - void UploadFile (long? petId, string additionalMetadata, FileStream file); + void UploadFile (long? petId, string additionalMetadata, String file); /// /// uploads an image @@ -131,7 +131,7 @@ namespace IO.Swagger.Api { /// Additional data to pass to server /// file to upload /// - Task UploadFileAsync (long? petId, string additionalMetadata, FileStream file); + Task UploadFileAsync (long? petId, string additionalMetadata, String file); } @@ -220,7 +220,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePet: " + response.Content, response.Content); } - + return; } @@ -295,7 +295,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling AddPet: " + response.Content, response.Content); } - + return; } @@ -370,7 +370,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByStatus: " + response.Content, response.Content); } - return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "List"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(List); + return (List) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -443,7 +447,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByTags: " + response.Content, response.Content); } - return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "List"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(List); + return (List) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -519,7 +527,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetPetById: " + response.Content, response.Content); } - return (Pet) ApiClient.Deserialize(response.Content, typeof(Pet), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "Pet"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(Pet); + return (Pet) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -602,7 +614,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePetWithForm: " + response.Content, response.Content); } - + return; } @@ -689,7 +701,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeletePet: " + response.Content, response.Content); } - + return; } @@ -742,7 +754,7 @@ namespace IO.Swagger.Api { /// Additional data to pass to server /// file to upload /// - public void UploadFile (long? petId, string additionalMetadata, FileStream file) { + public void UploadFile (long? petId, string additionalMetadata, String file) { // verify the required parameter 'petId' is set @@ -776,7 +788,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UploadFile: " + response.Content, response.Content); } - + return; } @@ -787,7 +799,7 @@ namespace IO.Swagger.Api { /// Additional data to pass to server /// file to upload /// - public async Task UploadFileAsync (long? petId, string additionalMetadata, FileStream file) { + public async Task UploadFileAsync (long? petId, string additionalMetadata, String file) { // verify the required parameter 'petId' is set diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs index 67276bbce88..b7bab55ed9a 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/StoreApi.cs @@ -150,7 +150,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetInventory: " + response.Content, response.Content); } - return (Dictionary) ApiClient.Deserialize(response.Content, typeof(Dictionary), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "Dictionary"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(Dictionary); + return (Dictionary) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -221,7 +225,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling PlaceOrder: " + response.Content, response.Content); } - return (Order) ApiClient.Deserialize(response.Content, typeof(Order), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "Order"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(Order); + return (Order) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -297,7 +305,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetOrderById: " + response.Content, response.Content); } - return (Order) ApiClient.Deserialize(response.Content, typeof(Order), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "Order"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(Order); + return (Order) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -376,7 +388,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteOrder: " + response.Content, response.Content); } - + return; } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs index 2d87996dd9e..27cd4afc92e 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Api/UserApi.cs @@ -212,7 +212,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUser: " + response.Content, response.Content); } - + return; } @@ -287,7 +287,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithArrayInput: " + response.Content, response.Content); } - + return; } @@ -362,7 +362,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithListInput: " + response.Content, response.Content); } - + return; } @@ -439,7 +439,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LoginUser: " + response.Content, response.Content); } - return (string) ApiClient.Deserialize(response.Content, typeof(string), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "string"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(string); + return (string) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -512,7 +516,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LogoutUser: " + response.Content, response.Content); } - + return; } @@ -588,7 +592,11 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetUserByName: " + response.Content, response.Content); } - return (User) ApiClient.Deserialize(response.Content, typeof(User), response.Headers); + + // if return type is "String" (not "string"), it implies a Filestream and should return the file path + String returnTypeString = "User"; + Type returnType = returnTypeString == "String" ? typeof(FileStream) : typeof(User); + return (User) ApiClient.Deserialize(response.Content, returnType, response.Headers); } /// @@ -669,7 +677,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdateUser: " + response.Content, response.Content); } - + return; } @@ -752,7 +760,7 @@ namespace IO.Swagger.Api { if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteUser: " + response.Content, response.Content); } - + return; } diff --git a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs index 648f10df280..a6b5c3a91da 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/Lib/SwaggerClient/src/main/csharp/IO/Swagger/Client/ApiClient.cs @@ -120,8 +120,6 @@ namespace IO.Swagger.Client { { if (obj is DateTime) { return ((DateTime)obj).ToString ("u"); - } else if (obj is FileStream) { - return ((FileStream)obj).Name; } else if (obj is List) { return String.Join(",", obj as List); } else { @@ -138,7 +136,7 @@ namespace IO.Swagger.Client { public object Deserialize(string content, Type type, IList headers=null) { if (type.GetType() == typeof(Object)) { // return an object return (Object)content; - } else if (type.Name == "FileStream") { // return a file + } else if (type.Name == "FileStream") { // return a file (full path) // e.g. Content-Disposition: attachment; filename=checkimage.jpp String fileName; String filePath; @@ -157,7 +155,7 @@ namespace IO.Swagger.Client { fileName = filePath + Guid.NewGuid().ToString(); } System.IO.File.WriteAllText (fileName, content); - return File.Open (fileName, FileMode.Open); + return fileName; } else if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) { // return a datetime object return DateTime.Parse(content, null, System.Globalization.DateTimeStyles.RoundtripKind); } else if (type.Name == "String" || type.Name.StartsWith("System.Nullable")) { // return primitive diff --git a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs index f202e578741..3bc490c9a58 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs +++ b/samples/client/petstore/csharp/SwaggerClientTest/SwaggerClientTest.userprefs @@ -1,10 +1,9 @@  - + - - - + + diff --git a/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs b/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs index 8e6ea0f99d2..bc8fe0fb757 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs +++ b/samples/client/petstore/csharp/SwaggerClientTest/TestPet.cs @@ -1,5 +1,6 @@ using NUnit.Framework; using System; +using System.IO; using System.Collections.Generic; using IO.Swagger.Api; using IO.Swagger.Model; @@ -48,6 +49,30 @@ namespace SwaggerClient.TestPet } + [Test ()] + public void TestGetPetByIdAsync () + { + PetApi petApi = new PetApi (); + var task = petApi.GetPetByIdAsync (petId); + Pet response = task.Result; + Assert.IsInstanceOf (response, "Response is a Pet"); + + Assert.AreEqual ("Csharp test", response.Name); + Assert.AreEqual ("available", response.Status); + + Assert.IsInstanceOf> (response.Tags, "Response.Tags is a Array"); + Assert.AreEqual (petId, response.Tags [0].Id); + Assert.AreEqual ("sample tag name1", response.Tags [0].Name); + + Assert.IsInstanceOf> (response.PhotoUrls, "Response.PhotoUrls is a Array"); + Assert.AreEqual ("sample photoUrls", response.PhotoUrls [0]); + + Assert.IsInstanceOf (response.Category, "Response.Category is a Category"); + Assert.AreEqual (56, response.Category.Id); + Assert.AreEqual ("sample category name2", response.Category.Name); + + } + [Test ()] public void TestGetPetById () { @@ -89,6 +114,15 @@ namespace SwaggerClient.TestPet Assert.AreEqual (56, response.Category.Id); } + [Test ()] + public void TestUploadFile () + { + PetApi petApi = new PetApi (); + //NOTE: please provide a valid file (full path) + petApi.UploadFile(petId, "new form name", "/var/tmp/small.gif"); + } + + [Test ()] public void TestFindPetByStatus () { diff --git a/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll index 60d81e320bc21585e4b8b5f705740db319735e78..b9ffd217f0c5433081d6e017af35f6cf00168475 100755 GIT binary patch delta 17949 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 Sr+H}M&8^Z-T@veZZT|z(9$hd1 delta 17154 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 literal 16334 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 AK>z>% diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt index 9afb7990f57..ff57f8c80e3 100644 --- a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt +++ b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.csproj.FilesWrittenAbsolute.txt @@ -1,8 +1,8 @@ /Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttribute.cs -/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/nunit.framework.dll -/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/Newtonsoft.Json.dll -/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/RestSharp.dll /Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll.mdb /Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/SwaggerClientTest.dll /Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll /Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll.mdb +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/nunit.framework.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/Newtonsoft.Json.dll +/Users/williamcheng/Code/swagger-codegen/samples/client/petstore/csharp/SwaggerClientTest/bin/Debug/RestSharp.dll diff --git a/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll b/samples/client/petstore/csharp/SwaggerClientTest/obj/Debug/SwaggerClientTest.dll index 60d81e320bc21585e4b8b5f705740db319735e78..b9ffd217f0c5433081d6e017af35f6cf00168475 100755 GIT binary patch delta 17949 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 Sr+H}M&8^Z-T@veZZT|z(9$hd1 delta 17154 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 literal 16334 zcmd5@d0bRg`+x4eGu#;lG-nWT*cTCS0S8bRP;fv5WpQ6{Wf>5{CBQeWex+#TlDXto z=90OUYwlX^`d02*uccO&TV|$~TQ24Ad+r_XFgW)1`{QTI=R4o;dG6&r=Q+0T^Oecl(zXl@@oisxrs!}I(J)-P97E&=9)j{fFw=Ex`UrGx zEYW%`gzX>uJ@)S*{%OF~m!@-(-7Bo+6_L-El$Dj_4K5gD9a0>bGPKYdS@C>caj~_$ zSpf>g)*+Ds)i*@89aa+A$yy0&UQjV`$&lnDg;kjwuUozxUB2|~^0v92 z>gYKxbI0!fH0oi)hBv)Nq!0=k31N zaOB}lY4?qnq9!#vHKEQLdgp0rw>-YsaFLah(b6_>dULOvpPn4hS@Y?-McdcW+^4Vc z?M4(>hgFsg9pa?@2Tz{)ZpEUcS91>K3~*`tQ4Y;}%G#eYbVyN2@$mAz#{}?-XH3RQ z*GqGvC!ZLzd03|fH2Y}@APZ|*S!7CHrL}ly`A8>y-|*|v{MIr-lR0Kx(OCVv8=syD zD>pr-ywFEx{q&#{e5UH67E`!^=xEsirA@Dpt|7^4luac+^KpSF%z2T*e}^)ySrOwXz&VLrzt z7>uT9c9UB4a#M51^mJVRh3)b(jx*@Z>}qq-%~Q=?*VC{1-)tAxu#2VwT#OP8zG`lg zf!;JsHpmrk<~UpkEJ-V<@-7Ksyb)VAPOmSYG8I;&jgqx0a9WlvkcNxPo}M zLDoD>W?NBkEgD)r*j7-v7L}A)Z3VSv*wBhf%h1A+e$ymC-iYh`80km3pwHRaZd zVMB*hSkVfpgGO;nI1+YooM%FQ>x6`al*W2<+9dsiGGmp&SXydo&7uqyMMFcQmzOB& zeMB+JEE=0@Bl9ckqT9YS&}NT49#V9;lN(o`#@C-v{~w6q4gN1<2zD03fah2Yv+L7? z`mcK`F&y-yL!O6Geu8KDx^QowT2EJgRUoYnT%%ksba=e-hXd(I;8EpjnZxsyzY<8l1YT9HR!R?8enJpU z40XM?{UOuq*IhVm1PWW+ovlHHD*g)AqFUW5`!jST}^@H}IC1gQB@A#^_E zYKRidwnntQ(T+w>G?>}kb}5>Pc;q@Rc~X9yMHMCb1hJ*ulvryiXK9inJJg6i3jHKh ziELJ5n%(&A#{WoUr~YeX(lXxsaZwfi3yU|uv@uN#n;E7=^ivpJ4*Qvvoh$=_F!7O1 zc9eY`5blQ2y|9VlQe`SZm{oh5Eo=;@P2roB8x}Zjw1uz2>Fe;5%4KOEZr^GPx5Md9 z`0vVP?8LEE3KV8U(9DQg5!GI0bEvQ)f>uVXg84~LAwk&k*eN8X1RJ_X_uFjxsD(Wd zw6w`bO{&u&{N9A_Ho1rLlMiC7eY48`Xs9t`q#%?nYRx|y%Exjnig8WpO4Hj-l_<71 zqaDq5Hv1={IP%v~BsxpQb7Q0^4mYE<%|B_bL@_p!UX6S$@`*;Vh}(~4Oc3VO+GR^y zHtElY8hKHkG|AObY5dHo5z>e9%wfBm1}%F9s)gy1^n2u(C?&r0QFI~dBFay2td&lY z!nulDjR4L1MkfRr%g>2foQzHV{0g%ZM26D>1+V0xk<$WIzUSoO%}x^^f^ep-mW z?C(`Ex^=B5P0@(DV*QwI{%T>9iRMHviB=*T9Ya+yV`83YWJ|b%Qg;4)Br<0ULVWF@ zYV8fw!qgbL6*DSUiRnMFbRzaEl%L>$tIpPOY^wiyUtoKBJ|@33azNA%VUcbT5q}f4syPjNMV6g6 z*vj*g?1Wcryr3?}S>*^`r5>DDSuluq;jFH%vLEkYnd2^U9G{-U@!k7!d=nO&#D*+SEz@D#B3-%=HMW zswyz!ase9v1-QdtnW)dr2OEnG#zLdPVoF48y~SsqX{M{wph2@}&(v_8K1`=;sB7l0 ztM6C0NsAPnzHUT}PG{6LsMEkFTj!1YqGG%0^rFsB^woveQ>&Jl=?n9F2`u3px3V}%@)$1anj-g&>#9|26KPZ8XNkn~q{|yt($PAyM_$=*yhU`A zOP$KCMI|Guw}j1-TH# zN?bFii*9Q5q$GMXX>yWWsagnTEpL9X7)?@butM4Y!y`=k&)+qJlWSWvZHCghE+guhW(~{(+a#`gf__E(^#(8al`OR`LN^S#t;-XlHBC$=)5K@X*di05)i%`{42D)o z?X_C1+U0c%O|?w3$a!%=J_S8rmmAm@x8g1jmpvBRYuTq<&*k*Fxa1cQ;BwAF=PeiH zD=>+FSm;m7L))FAAmyZiI4OnROqrY_*Kf1>i0`M+qLjso)sywBQQVS3TT?!EwEBxj zQs`*PF<3d`EAm-nqTq+f%!y`mZZ1Ad_>c#1*fXN5=o;i5D!PXFMnKn7ix*Pp=aef- zrOi2mk>$llG^)i#skAtCNow`b(Ckd5U8%d}vPxqML31>fj-?)VwEAc+rqYk8mlUfU zg62Ug{gL{oqt#zCtsTA9ZhAYp6EuQ13)e@ptQ~#O?n6gwpk{kJ+R<*OVhv#T25P=+ zNB?Pe!qFP4x!jI^Zg)koHj?Wdl}4k}s?w^xN!CEk%ru&nHe0bquzP(qE7E9X+A2qD zkY;xp?Md4UtJ38f!Bn%$rGB@6unb7Kcq9#t{F;icVSy&wN2q^un?h}>tt~a$pWD-w_P;nu3$qew0CLGuA0qDK$RYPc!JVjL#jdf!c2~=(~(F zuqvt1I;KX-g_Dm*QX^$WnkL~vF}4XKqxJ69M@6q0Grjv_1%s%x8pp;D$g3%wH;|)$Mud@f7j1C(&rub z!>WYp`hS@CuHSW}^BpfJmDZg2u5&YKUgrGF>JW5WGHGk($8uSvvxT7hJd^fk9&oh! z=+0!)_nAK^Rw)EO-K|Wzoq5O68mya`MQ>zH%91-lCr^BT-FsQIFzbCsYlv=B7H!Vj zqFANT<)=H8MTfJFI9h{s=d$R0)&<2XjV^E9-7LD7b>Gn%pqrdcQ?jRKSGPeLU4FX7 z*|a2ksiQSm_i;9TlD$o_MzTf1TX!s*j%R=2XbsT)m`#_me^RV5>|Q_JAKCP0_CrT& zu@nxKhD!^%(+{@NI3K^#(3M8AeWj69L~u)K{nvevL#uPvz%_ev z=!9N178%{5PPDkwl1}n9H$mDwxw`G_M7uiehSi0*VZ><)Y~On!UOQ~i(8{6R%gZWA z5GwQVv{vD>g48bfS|7e!#ay@v&u|_IrO`NHk4fkPdLdCN<)#EhV{030N(qWVPYG@+ z7xv?&a>tKv9hC+@^<|sN0}XXM(TT=&9^aYunM3tWI1hcoG`6!63Oh0zMgd2I~ zM#sNq+=LixDH2K(%rWd3%M_!}jV?t;N8{Nk6~N5aftg^jRc%!1RLyj%Ceml4h~_$# zsa1kb6$MVzsha9kLAcZ^8BKky3(e{BZkNAmK}Xht@~Rj#A{wsrxwfWA?O={=PD6Am z<`=cYb)-%eu2V^_;Y)BE*OlgWo!6Ckl|53|ipspo;T4%B6_vz`WgvWm0_j0UI6>Y; zhy07DsjE167^umwyIZ*wzI+;AGrB}`{#uh}B3hkY)2r=FUW(Cv zBLD9m^l6Xd%$MwYZBJU)bA8W8eD4!##rfZScX046pPfs-?I-8Ed(xhshnX+g_o`mB zy4RXscHi@bV=V5eIH=-07v{DunAYc=2__}2cu^&CztqU9J#w?oFN8G!=iBxai;{o# z3Pe8P-rkFL^xDt-+5GpW)xFpBw)?*#%u})PB>B&m{pZ{Lr?KvjW*@C;_P;#3dOK@D zjk9Q}E%Hh9_TIFk_kQMAZpX%4+LXIF*WQlLgnO(XwyB->Lp#=lxJR3i;-m?-Gh@lS zd}93XT>3QkIP)fZU*Cr|^x4?Q?)|Q?ob|#C7w6vpvKR84G@<6%u96Wox3>@N>vNR( zmD}-2U)t7pdtZAy_VBmx+Je{Mdr-B;qBIa{#%~`8X*GwTD31X9`Q^dBbg1vw%!lNY zU(=61>bJI^-RD>QctP^%bWIuTbnGQKxMZ&rl_=%oxSjoISHFYIi|lnte_GmqS%16N zDq+3sb)7WhA02s8z|Ot5)djFGMzQ0-+9Th7Ah@wVZR)?9d6ZkQYyf>Q;KKn6x5QQ}XAq>ScFV^XXdt^&0Nx3P&)G(3iWNuHMqpC7s69>{k2S>0Hx$ z%`+Kg^^i|w{>-O``4bA1cHAzYI|aY9vhBJ2G5-r@F4{3cT1jg>nI9R*a#GnzeeKaJ zzq)>{kX|pGR;c(oTS(^$&$F`4mppgi>%?PL?MGbN1GeY_8#B*1;Hd50e#G%xA>Ana z)82yfR=QxlXtlRso^Vv|^$(==`q8=Ld}yUQbMCNusD+zWx@8?zq(uLH5&ckfmX&Kq zfB!MQABnzt-aa;Rx!?TmGIjmz-^#Z+Iuc zgMZl#t;XR(eXQCROI?dLJh7g|BF4tnjnxJ=trr_B%kUUQhD0jTKY~eLZ9Neu2h#`9 zj6qiiDLwQ?DNQPUv(%oe!0+*L84Zs>!wvj0&b5z*okukB4fFL?y<19iOP8{{rMa!z zUrGl`529QT-z{#BFBOLadgvl>H^2Zr23!GnKraAK0qR3<0Ivi*q4$G#0}Y^G#y68w z0Wat`!4rXo&=!1MSpyiMyMS{5Z)i{a_pF1^KG31i!GJIHW$*&P5BeVX4&V>H+nuNq z2!K8gJ^}W0iB?A zNYq{E&d@>7UO*Sp*YlTqIltqr8|%hy%PK(Pyl@fycH;fz6HJl;MBuKhXKU{MbLp@FQ6E@6}UMt2zn4W2PlCa z0Ui#NLQe<33OozF3j7{W2K^cMV_-0}9|q|y=poQy7^DkP9tv%R&H#o%?*PvSo`Vj+ z;JpN04xI@d2UI|pfO`X#&||>=0)|7s2cE*p(0jnEfajr4f{y|tps#^10wbZ-m=F)3 zUx4<8)&nm>HvxwMFG05j#{vHX-4mP*ybL`UTnM}ZJqG*&FbaAucnUBY`Va7apb9!3 z6V3pPf$j}X1I9vEfQx`vp~rwn0k1*74W0tL4!s(@1Q-Xs5Bv!*9{M!+I4}X)h)Mhl z^hD^E(2apNpwqx9z$ECt;I6=%(B6bbz+2GY zgTDf%L*EAf0?dGR!{Q+TGogdP4S`wEao|W`Hgq<)9q=~v2Jk@O9q41=-M}2^AHd%M z??T@JUj^nuyN6)R1M{GR!A4*{bUZi;SOA>^P6OV9wu1Wt3!z^GmjmxZPX&(y7C|os z&jS`iZv(FfmOy_2-VZE={t5g&unf9WBg}W`51`AS`vD(9zXTo$EQg*39uKU5UIv~I ztc2bU-T&lyc0!K_j{z`vm% zfbnfY`V{)*a6I3D&!8`Y=L4TZ7e?Uu3+#v934Rec0DTmE2sjAcvO9CbsVgtkB@0jHpsfO`X{p*Mop0pCFTM567`-$FNq4hO!2o(E0= z&OomMF9*Jd_KHGZLjM3A2Hgla3;h~62{;Em6Z{r%9{Lt|C2#>+-2&@Ba1pu?>;wD= zT?u{;xCDI#JQ4T_`T_VZa2dLn3F{m1GxQ*^6}SR@3j7N23-o31kHA&v9?^K82V8?L z0v7<+p^t+92ly5Gd+@iwZ_wAlzW_I&U1Ny;fW8UM$Kn}+@-1jRbY0*!bTT*$xC7k@ zoCR@CmR6JQWwU;0#=J1wRDqz#DLr8@LQN zvHE`lv-)p=S^d9*S^f9Hto}d2tbPuavHDeDm`DV(`d#tC>URgT`kw)_`VHX!1!T|e AK>z>% From eca827613da943b41615b84f86743765f1911c4f Mon Sep 17 00:00:00 2001 From: Nadezhda Makarkina Date: Tue, 9 Jun 2015 16:20:54 +0300 Subject: [PATCH 182/499] Fixed #831: skipOverwrite flag has been added --- README.md | 5 + modules/swagger-codegen-cli/pom.xml | 7 + .../java/io/swagger/codegen/cmd/Generate.java | 5 + .../java/io.swagger.codegen/GenerateTest.java | 73 ++ .../src/test/resources/petstore.json | 977 ++++++++++++++++++ .../io/swagger/codegen/CodegenConfig.java | 4 + .../io/swagger/codegen/DefaultCodegen.java | 11 +- .../io/swagger/codegen/DefaultGenerator.java | 8 +- .../codegen/languages/JaxRSServerCodegen.java | 5 +- 9 files changed, 1090 insertions(+), 5 deletions(-) create mode 100644 modules/swagger-codegen-cli/src/test/java/io.swagger.codegen/GenerateTest.java create mode 100644 modules/swagger-codegen-cli/src/test/resources/petstore.json diff --git a/README.md b/README.md index cace22c92e9..4ba70e15ea1 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ SYNOPSIS [(-o | --output )] [(-t