From 9af16c0d79f65879d77c209422390dbf98efd7e4 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 2 Sep 2015 13:36:35 +0100 Subject: [PATCH 1/7] Support dots in output folder for C# generator --- .../io/swagger/codegen/languages/CSharpClientCodegen.java | 5 +++-- 1 file changed, 3 insertions(+), 2 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 09ec05b078..f10d9a0f29 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 @@ -137,11 +137,12 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig @Override public String apiFileFolder() { - return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar); + + return outputFolder + File.separator + (sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar); } public String modelFileFolder() { - return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar); + return outputFolder + File.separator + (sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar); } @Override From 8ce06fc898456b784ebb418a78842fe4f33ba7f8 Mon Sep 17 00:00:00 2001 From: wing328 Date: Thu, 3 Sep 2015 22:38:19 +0800 Subject: [PATCH 2/7] fix HTML-escaped description on nodejs json files --- .../main/resources/nodejs/package.mustache | 2 +- .../main/resources/nodejs/swagger.mustache | 2 +- .../server/petstore/nodejs/api/swagger.json | 751 +++++++++--------- .../server/petstore/nodejs/controllers/Pet.js | 4 +- .../petstore/nodejs/controllers/PetService.js | 2 +- .../nodejs/controllers/StoreService.js | 4 +- samples/server/petstore/nodejs/package.json | 2 +- 7 files changed, 394 insertions(+), 373 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nodejs/package.mustache b/modules/swagger-codegen/src/main/resources/nodejs/package.mustache index 7add6e813f..89db4c0b91 100644 --- a/modules/swagger-codegen/src/main/resources/nodejs/package.mustache +++ b/modules/swagger-codegen/src/main/resources/nodejs/package.mustache @@ -1,7 +1,7 @@ { "name": "{{projectName}}", "version": "{{appVersion}}", - "description": "{{appDescription}}", + "description": "{{{appDescription}}}", "main": "index.js", "keywords": [ "swagger" diff --git a/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache b/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache index 3b975e53b8..1d0f7d7816 100644 --- a/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/nodejs/swagger.mustache @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "title": "{{appName}}", - "description": "{{appDescription}}", + "description": "{{{appDescription}}}", "version": "{{apiVersion}}" }, {{#apiInfo}} diff --git a/samples/server/petstore/nodejs/api/swagger.json b/samples/server/petstore/nodejs/api/swagger.json index 02c5ca0f97..4f091973cf 100644 --- a/samples/server/petstore/nodejs/api/swagger.json +++ b/samples/server/petstore/nodejs/api/swagger.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "title": "Swagger Petstore", - "description": "This is a sample server Petstore server. You can find out more about Swagger at <a href=\"http://swagger.io\">http://swagger.io</a> or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters", + "description": "This is a sample server Petstore server. You can find out more about Swagger at http://swagger.io or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters", "version": "1.0.0" }, "produces": ["application/json"], @@ -10,68 +10,8 @@ "basePath": "/v2", "paths": { - "/user": { - "post": { - "summary": "Create user", - "description":"This can only be done by the logged in user.", - "x-swagger-router-controller": "User", - "tags": ["User"], - "operationId": "createUser", - "parameters": [ - { - "in" : "body", - "name" : "body", - "description" : "Created user object", - "required" : false, - "schema" : { - "$ref" : "#/definitions/User" - } -} - - ], - "responses": { - "default": { - "description" : "successful operation" -} - - - } - } - } , - - "/user/createWithArray": { - "post": { - "summary": "Creates list of users with given input array", - "description":"", - "x-swagger-router-controller": "User", - "tags": ["User"], - "operationId": "createUsersWithArrayInput", - "parameters": [ - { - "in" : "body", - "name" : "body", - "description" : "List of user object", - "required" : false, - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/definitions/User" - } - } -} - - ], - "responses": { - "default": { - "description" : "successful operation" -} - - - } - } - } , - "/user/createWithList": { + "post": { "summary": "Creates list of users with given input array", "description":"", @@ -100,57 +40,33 @@ } - } + } + } , - "/user/login": { - "get": { - "summary": "Logs user into the system", + "/user/createWithArray": { + + "post": { + "summary": "Creates list of users with given input array", "description":"", "x-swagger-router-controller": "User", "tags": ["User"], - "operationId": "loginUser", + "operationId": "createUsersWithArrayInput", "parameters": [ { - "name" : "username", - "in" : "query", - "description" : "The user name for login", + "in" : "body", + "name" : "body", + "description" : "List of user object", "required" : false, - "type" : "string" -}, - { - "name" : "password", - "in" : "query", - "description" : "The password for login in clear text", - "required" : false, - "type" : "string" + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/User" + } + } } ], - "responses": { - "200": { - "description" : "successful operation", - "schema" : { - "type" : "string" - } -} - , - "400": { - "description" : "Invalid username/password supplied" -} - - - } - } - } , - - "/user/logout": { - "get": { - "summary": "Logs out current logged in user session", - "description":"", - "x-swagger-router-controller": "User", - "tags": ["User"], - "operationId": "logoutUser", "responses": { "default": { "description" : "successful operation" @@ -158,10 +74,12 @@ } - } + } + } , "/user/{username}": { + "get": { "summary": "Get user by user name", "description":"", @@ -208,10 +126,8 @@ } - } - } , - - "/user/{username}": { + } , + "put": { "summary": "Updated user", "description":"This can only be done by the logged in user.", @@ -248,10 +164,8 @@ } - } - } , - - "/user/{username}": { + } , + "delete": { "summary": "Delete user", "description":"This can only be done by the logged in user.", @@ -279,12 +193,106 @@ } - } - } + } + + } , + + "/user": { + + "post": { + "summary": "Create user", + "description":"This can only be done by the logged in user.", + "x-swagger-router-controller": "User", + "tags": ["User"], + "operationId": "createUser", + "parameters": [ + { + "in" : "body", + "name" : "body", + "description" : "Created user object", + "required" : false, + "schema" : { + "$ref" : "#/definitions/User" + } +} + + ], + "responses": { + "default": { + "description" : "successful operation" +} + + + } + } + + } , + + "/user/logout": { + + "get": { + "summary": "Logs out current logged in user session", + "description":"", + "x-swagger-router-controller": "User", + "tags": ["User"], + "operationId": "logoutUser", + "responses": { + "default": { + "description" : "successful operation" +} + + + } + } + + } , + + "/user/login": { + + "get": { + "summary": "Logs user into the system", + "description":"", + "x-swagger-router-controller": "User", + "tags": ["User"], + "operationId": "loginUser", + "parameters": [ + { + "name" : "username", + "in" : "query", + "description" : "The user name for login", + "required" : false, + "type" : "string" +}, + { + "name" : "password", + "in" : "query", + "description" : "The password for login in clear text", + "required" : false, + "type" : "string" +} + + ], + "responses": { + "200": { + "description" : "successful operation", + "schema" : { + "type" : "string" + } +} + , + "400": { + "description" : "Invalid username/password supplied" +} + + + } + } + + } , - , "/pet": { + "put": { "summary": "Update an existing pet", "description":"", @@ -318,10 +326,8 @@ } - } - } , - - "/pet": { + } , + "post": { "summary": "Add a new pet to the store", "description":"", @@ -347,208 +353,12 @@ } - } - } , - - "/pet/findByStatus": { - "get": { - "summary": "Finds Pets by status", - "description":"Multiple status values can be provided with comma seperated strings", - "x-swagger-router-controller": "Pet", - "tags": ["Pet"], - "operationId": "findPetsByStatus", - "parameters": [ - { - "name" : "status", - "in" : "query", - "description" : "Status values that need to be considered for filter", - "required" : false, - "type" : "array", - "items" : { - "type" : "string" - }, - "collectionFormat" : "multi", - "default" : "available" -} - - ], - "responses": { - "200": { - "description" : "successful operation", - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/definitions/Pet" - } - } -} - , - "400": { - "description" : "Invalid status value" -} - - - } - } - } , - - "/pet/findByTags": { - "get": { - "summary": "Finds Pets by tags", - "description":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", - "x-swagger-router-controller": "Pet", - "tags": ["Pet"], - "operationId": "findPetsByTags", - "parameters": [ - { - "name" : "tags", - "in" : "query", - "description" : "Tags to filter by", - "required" : false, - "type" : "array", - "items" : { - "type" : "string" - }, - "collectionFormat" : "multi" -} - - ], - "responses": { - "200": { - "description" : "successful operation", - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/definitions/Pet" - } - } -} - , - "400": { - "description" : "Invalid tag value" -} - - - } - } - } , - - "/pet/{petId}": { - "get": { - "summary": "Find pet by ID", - "description":"Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions", - "x-swagger-router-controller": "Pet", - "tags": ["Pet"], - "operationId": "getPetById", - "parameters": [ - { - "name" : "petId", - "in" : "path", - "description" : "ID of pet that needs to be fetched", - "required" : true, - "type" : "integer", - "format" : "int64" -} - - ], - "responses": { - "404": { - "description" : "Pet not found" -} - , - "200": { - "description" : "successful operation", - "schema" : { - "$ref" : "#/definitions/Pet" - } -} - , - "400": { - "description" : "Invalid ID supplied" -} - - - } - } - } , - - "/pet/{petId}": { - "post": { - "summary": "Updates a pet in the store with form data", - "description":"", - "x-swagger-router-controller": "Pet", - "tags": ["Pet"], - "operationId": "updatePetWithForm", - "parameters": [ - { - "name" : "petId", - "in" : "path", - "description" : "ID of pet that needs to be updated", - "required" : true, - "type" : "string" -}, - { - "name" : "name", - "in" : "formData", - "description" : "Updated name of the pet", - "required" : false, - "type" : "string" -}, - { - "name" : "status", - "in" : "formData", - "description" : "Updated status of the pet", - "required" : false, - "type" : "string" -} - - ], - "responses": { - "405": { - "description" : "Invalid input" -} - - - } - } - } , - - "/pet/{petId}": { - "delete": { - "summary": "Deletes a pet", - "description":"", - "x-swagger-router-controller": "Pet", - "tags": ["Pet"], - "operationId": "deletePet", - "parameters": [ - { - "name" : "api_key", - "in" : "header", - "description" : "", - "required" : false, - "type" : "string" -}, - { - "name" : "petId", - "in" : "path", - "description" : "Pet id to delete", - "required" : true, - "type" : "integer", - "format" : "int64" -} - - ], - "responses": { - "400": { - "description" : "Invalid pet value" -} - - - } - } + } + } , "/pet/{petId}/uploadImage": { + "post": { "summary": "uploads an image", "description":"", @@ -587,51 +397,30 @@ } - } - } - - , - - "/store/inventory": { - "get": { - "summary": "Returns pet inventories by status", - "description":"Returns a map of status codes to quantities", - "x-swagger-router-controller": "Store", - "tags": ["Store"], - "operationId": "getInventory", - "responses": { - "200": { - "description" : "successful operation", - "schema" : { - "type" : "object", - "additionalProperties" : { - "type" : "integer", - "format" : "int32" - } - } -} - - - } - } + } + } , - "/store/order": { - "post": { - "summary": "Place an order for a pet", - "description":"", - "x-swagger-router-controller": "Store", - "tags": ["Store"], - "operationId": "placeOrder", + "/pet/findByStatus": { + + "get": { + "summary": "Finds Pets by status", + "description":"Multiple status values can be provided with comma seperated strings", + "x-swagger-router-controller": "Pet", + "tags": ["Pet"], + "operationId": "findPetsByStatus", "parameters": [ { - "in" : "body", - "name" : "body", - "description" : "order placed for purchasing the pet", + "name" : "status", + "in" : "query", + "description" : "Status values that need to be considered for filter", "required" : false, - "schema" : { - "$ref" : "#/definitions/Order" - } + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi", + "default" : "available" } ], @@ -639,20 +428,182 @@ "200": { "description" : "successful operation", "schema" : { - "$ref" : "#/definitions/Order" + "type" : "array", + "items" : { + "$ref" : "#/definitions/Pet" + } } } , "400": { - "description" : "Invalid Order" + "description" : "Invalid status value" } } - } + } + } , + "/pet/findByTags": { + + "get": { + "summary": "Finds Pets by tags", + "description":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", + "x-swagger-router-controller": "Pet", + "tags": ["Pet"], + "operationId": "findPetsByTags", + "parameters": [ + { + "name" : "tags", + "in" : "query", + "description" : "Tags to filter by", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" +} + + ], + "responses": { + "200": { + "description" : "successful operation", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Pet" + } + } +} + , + "400": { + "description" : "Invalid tag value" +} + + + } + } + + } , + + "/pet/{petId}": { + + "get": { + "summary": "Find pet by ID", + "description":"Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions", + "x-swagger-router-controller": "Pet", + "tags": ["Pet"], + "operationId": "getPetById", + "parameters": [ + { + "name" : "petId", + "in" : "path", + "description" : "ID of pet that needs to be fetched", + "required" : true, + "type" : "integer", + "format" : "int64" +} + + ], + "responses": { + "404": { + "description" : "Pet not found" +} + , + "200": { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/Pet" + } +} + , + "400": { + "description" : "Invalid ID supplied" +} + + + } + } , + + "post": { + "summary": "Updates a pet in the store with form data", + "description":"", + "x-swagger-router-controller": "Pet", + "tags": ["Pet"], + "operationId": "updatePetWithForm", + "parameters": [ + { + "name" : "petId", + "in" : "path", + "description" : "ID of pet that needs to be updated", + "required" : true, + "type" : "string" +}, + { + "name" : "name", + "in" : "formData", + "description" : "Updated name of the pet", + "required" : false, + "type" : "string" +}, + { + "name" : "status", + "in" : "formData", + "description" : "Updated status of the pet", + "required" : false, + "type" : "string" +} + + ], + "responses": { + "405": { + "description" : "Invalid input" +} + + + } + } , + + "delete": { + "summary": "Deletes a pet", + "description":"", + "x-swagger-router-controller": "Pet", + "tags": ["Pet"], + "operationId": "deletePet", + "parameters": [ + { + "name" : "petId", + "in" : "path", + "description" : "Pet id to delete", + "required" : true, + "type" : "integer", + "format" : "int64" +}, + { + "name" : "api_key", + "in" : "header", + "description" : "", + "required" : false, + "type" : "string" +} + + ], + "responses": { + "400": { + "description" : "Invalid pet value" +} + + + } + } + + } , + + "/store/order/{orderId}": { + "get": { "summary": "Find purchase order by ID", "description":"For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", @@ -687,10 +638,8 @@ } - } - } , - - "/store/order/{orderId}": { + } , + "delete": { "summary": "Delete purchase order by ID", "description":"For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", @@ -718,10 +667,74 @@ } + } + + } , + + "/store/order": { + + "post": { + "summary": "Place an order for a pet", + "description":"", + "x-swagger-router-controller": "Store", + "tags": ["Store"], + "operationId": "placeOrder", + "parameters": [ + { + "in" : "body", + "name" : "body", + "description" : "order placed for purchasing the pet", + "required" : false, + "schema" : { + "$ref" : "#/definitions/Order" + } +} + + ], + "responses": { + "200": { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/Order" + } +} + , + "400": { + "description" : "Invalid Order" +} + + + } + } + + } , + + "/store/inventory": { + + "get": { + "summary": "Returns pet inventories by status", + "description":"Returns a map of status codes to quantities", + "x-swagger-router-controller": "Store", + "tags": ["Store"], + "operationId": "getInventory", + "responses": { + "200": { + "description" : "successful operation", + "schema" : { + "type" : "object", + "additionalProperties" : { + "type" : "integer", + "format" : "int32" } + } +} + + + } + } + } - }, "definitions": { "User": { "properties" : { @@ -785,12 +798,20 @@ }, "photoUrls" : { "type" : "array", + "xml" : { + "name" : "photoUrl", + "wrapped" : true + }, "items" : { "type" : "string" } }, "tags" : { "type" : "array", + "xml" : { + "name" : "tag", + "wrapped" : true + }, "items" : { "$ref" : "#/definitions/Tag" } diff --git a/samples/server/petstore/nodejs/controllers/Pet.js b/samples/server/petstore/nodejs/controllers/Pet.js index f23f593f41..a268c8fa70 100644 --- a/samples/server/petstore/nodejs/controllers/Pet.js +++ b/samples/server/petstore/nodejs/controllers/Pet.js @@ -93,11 +93,11 @@ module.exports.updatePetWithForm = function updatePetWithForm (req, res, next) { }; module.exports.deletePet = function deletePet (req, res, next) { - var apiKey = req.swagger.params['api_key'].value; var petId = req.swagger.params['petId'].value; + var apiKey = req.swagger.params['api_key'].value; - var result = Pet.deletePet(apiKey, petId); + var result = Pet.deletePet(petId, apiKey); if(typeof result !== 'undefined') { res.setHeader('Content-Type', 'application/json'); diff --git a/samples/server/petstore/nodejs/controllers/PetService.js b/samples/server/petstore/nodejs/controllers/PetService.js index cdfac3466a..f238fa410a 100644 --- a/samples/server/petstore/nodejs/controllers/PetService.js +++ b/samples/server/petstore/nodejs/controllers/PetService.js @@ -96,7 +96,7 @@ exports.updatePetWithForm = function(petId, name, status) { } -exports.deletePet = function(apiKey, petId) { +exports.deletePet = function(petId, apiKey) { var examples = {}; diff --git a/samples/server/petstore/nodejs/controllers/StoreService.js b/samples/server/petstore/nodejs/controllers/StoreService.js index ba9ffd4fc4..947774aad2 100644 --- a/samples/server/petstore/nodejs/controllers/StoreService.js +++ b/samples/server/petstore/nodejs/controllers/StoreService.js @@ -24,7 +24,7 @@ exports.placeOrder = function(body) { "complete" : true, "status" : "aeiou", "quantity" : 123, - "shipDate" : "2015-07-09T06:03:19.571+0000" + "shipDate" : "2015-09-03T14:34:08.343+0000" }; @@ -43,7 +43,7 @@ exports.getOrderById = function(orderId) { "complete" : true, "status" : "aeiou", "quantity" : 123, - "shipDate" : "2015-07-09T06:03:19.576+0000" + "shipDate" : "2015-09-03T14:34:08.347+0000" }; diff --git a/samples/server/petstore/nodejs/package.json b/samples/server/petstore/nodejs/package.json index 7bb6df08fb..35390feefd 100644 --- a/samples/server/petstore/nodejs/package.json +++ b/samples/server/petstore/nodejs/package.json @@ -1,7 +1,7 @@ { "name": "", "version": "1.0.0", - "description": "This is a sample server Petstore server. You can find out more about Swagger at <a href=\"http://swagger.io\">http://swagger.io</a> or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters", + "description": "This is a sample server Petstore server. You can find out more about Swagger at http://swagger.io or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters", "main": "index.js", "keywords": [ "swagger" From 2822e9ea387ab26be927dec04af6b94e9257791f Mon Sep 17 00:00:00 2001 From: Matthew Davis Date: Thu, 3 Sep 2015 12:18:00 -0700 Subject: [PATCH 3/7] added support for retrieving HTTP response headers in obj-c. Also added a +sharedAPI class method for easy initialization of an API class without passing headers --- .../main/resources/objc/ApiClient-body.mustache | 17 ++++++++++++++++- .../resources/objc/ApiClient-header.mustache | 3 +++ .../src/main/resources/objc/api-body.mustache | 11 ++++++++++- .../src/main/resources/objc/api-header.mustache | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache index b7643de6dd..5b2a290ab8 100644 --- a/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache @@ -9,6 +9,13 @@ static bool cacheEnabled = false; static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable; static void (^reachabilityChangeBlock)(int); + +@interface {{classPrefix}}ApiClient () + +@property (readwrite, nonatomic) NSDictionary *HTTPResponseHeaders; + +@end + @implementation {{classPrefix}}ApiClient - (instancetype)init { @@ -385,6 +392,8 @@ static void (^reachabilityChangeBlock)(int); if([[{{classPrefix}}Configuration sharedConfig] debug]) { [self logResponse:operation forRequest:request error:nil]; } + NSDictionary *responseHeaders = [[operation response] allHeaderFields]; + self.HTTPResponseHeaders = responseHeaders; completionBlock(response, nil); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { @@ -398,6 +407,10 @@ static void (^reachabilityChangeBlock)(int); if([[{{classPrefix}}Configuration sharedConfig] debug]) [self logResponse:nil forRequest:request error:augmentedError]; + + NSDictionary *responseHeaders = [[operation response] allHeaderFields]; + self.HTTPResponseHeaders = responseHeaders; + completionBlock(nil, augmentedError); } }]; @@ -441,6 +454,7 @@ static void (^reachabilityChangeBlock)(int); NSURL *file = [NSURL fileURLWithPath:filepath]; [operation.responseData writeToURL:file atomically:YES]; + self.HTTPResponseHeaders = headers; completionBlock(file, nil); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { @@ -455,7 +469,8 @@ static void (^reachabilityChangeBlock)(int); if ([[{{classPrefix}}Configuration sharedConfig] debug]) { [self logResponse:nil forRequest:request error:augmentedError]; } - + NSDictionary *responseHeaders = [[operation response] allHeaderFields]; + self.HTTPResponseHeaders = responseHeaders; completionBlock(nil, augmentedError); } }]; diff --git a/modules/swagger-codegen/src/main/resources/objc/ApiClient-header.mustache b/modules/swagger-codegen/src/main/resources/objc/ApiClient-header.mustache index eba6270587..fef1a2b79e 100644 --- a/modules/swagger-codegen/src/main/resources/objc/ApiClient-header.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/ApiClient-header.mustache @@ -31,6 +31,9 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey; @property(nonatomic, assign) NSTimeInterval timeoutInterval; @property(nonatomic, readonly) NSOperationQueue* queue; +/// In order to ensure the HTTPResponseHeaders are correct, it is recommended to initialize one {{classPrefix}}ApiClient instance per thread. +@property(nonatomic, readonly) NSDictionary* HTTPResponseHeaders; + /** * Clears Cache */ 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 534c887fe7..1aa22a0a0c 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache @@ -11,6 +11,8 @@ @implementation {{classname}} +static {{classname}}* singletonAPI = nil; + #pragma mark - Initialize methods - (id) init { @@ -38,7 +40,6 @@ #pragma mark - +({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { - static {{classname}}* singletonAPI = nil; if (singletonAPI == nil) { singletonAPI = [[{{classname}} alloc] init]; @@ -47,6 +48,14 @@ return singletonAPI; } ++({{classname}}*) sharedAPI { + + if (singletonAPI == nil) { + singletonAPI = [[{{classname}} alloc] init]; + } + return singletonAPI; +} + -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } 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 d9f691f722..29c7d9477f 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache @@ -20,6 +20,7 @@ -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; ++({{classname}}*) sharedAPI; {{#operation}} /// /// From f067b86fa036a67148b89c49086213c59e917812 Mon Sep 17 00:00:00 2001 From: Matthew Davis Date: Thu, 3 Sep 2015 12:31:30 -0700 Subject: [PATCH 4/7] re-built sample objc-petstore --- samples/client/petstore/objc/README.md | 4 ++++ .../petstore/objc/SwaggerClient/SWGApiClient.h | 3 +++ .../petstore/objc/SwaggerClient/SWGApiClient.m | 17 ++++++++++++++++- .../petstore/objc/SwaggerClient/SWGPetApi.h | 1 + .../petstore/objc/SwaggerClient/SWGPetApi.m | 11 ++++++++++- .../petstore/objc/SwaggerClient/SWGStoreApi.h | 1 + .../petstore/objc/SwaggerClient/SWGStoreApi.m | 11 ++++++++++- .../petstore/objc/SwaggerClient/SWGUserApi.h | 3 ++- .../petstore/objc/SwaggerClient/SWGUserApi.m | 13 +++++++++++-- 9 files changed, 58 insertions(+), 6 deletions(-) diff --git a/samples/client/petstore/objc/README.md b/samples/client/petstore/objc/README.md index 4cce2c882b..10e4498468 100644 --- a/samples/client/petstore/objc/README.md +++ b/samples/client/petstore/objc/README.md @@ -12,6 +12,10 @@ To install it, put the API client library in your project and then simply add th pod "SwaggerClient", :path => "/path/to/lib" ``` +## Recommendation + +It's recommended to create an instance of ApiClient per thread in a multithreaded environment to avoid any potential issue. + ## Author apiteam@swagger.io diff --git a/samples/client/petstore/objc/SwaggerClient/SWGApiClient.h b/samples/client/petstore/objc/SwaggerClient/SWGApiClient.h index 84f28faa8c..580efa739a 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGApiClient.h +++ b/samples/client/petstore/objc/SwaggerClient/SWGApiClient.h @@ -35,6 +35,9 @@ extern NSString *const SWGResponseObjectErrorKey; @property(nonatomic, assign) NSTimeInterval timeoutInterval; @property(nonatomic, readonly) NSOperationQueue* queue; +/// In order to ensure the HTTPResponseHeaders are correct, it is recommended to initialize one SWGApiClient instance per thread. +@property(nonatomic, readonly) NSDictionary* HTTPResponseHeaders; + /** * Clears Cache */ diff --git a/samples/client/petstore/objc/SwaggerClient/SWGApiClient.m b/samples/client/petstore/objc/SwaggerClient/SWGApiClient.m index 906169f4d1..826443453b 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGApiClient.m +++ b/samples/client/petstore/objc/SwaggerClient/SWGApiClient.m @@ -9,6 +9,13 @@ static bool cacheEnabled = false; static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable; static void (^reachabilityChangeBlock)(int); + +@interface SWGApiClient () + +@property (readwrite, nonatomic) NSDictionary *HTTPResponseHeaders; + +@end + @implementation SWGApiClient - (instancetype)init { @@ -385,6 +392,8 @@ static void (^reachabilityChangeBlock)(int); if([[SWGConfiguration sharedConfig] debug]) { [self logResponse:operation forRequest:request error:nil]; } + NSDictionary *responseHeaders = [[operation response] allHeaderFields]; + self.HTTPResponseHeaders = responseHeaders; completionBlock(response, nil); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { @@ -398,6 +407,10 @@ static void (^reachabilityChangeBlock)(int); if([[SWGConfiguration sharedConfig] debug]) [self logResponse:nil forRequest:request error:augmentedError]; + + NSDictionary *responseHeaders = [[operation response] allHeaderFields]; + self.HTTPResponseHeaders = responseHeaders; + completionBlock(nil, augmentedError); } }]; @@ -441,6 +454,7 @@ static void (^reachabilityChangeBlock)(int); NSURL *file = [NSURL fileURLWithPath:filepath]; [operation.responseData writeToURL:file atomically:YES]; + self.HTTPResponseHeaders = headers; completionBlock(file, nil); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { @@ -455,7 +469,8 @@ static void (^reachabilityChangeBlock)(int); if ([[SWGConfiguration sharedConfig] debug]) { [self logResponse:nil forRequest:request error:augmentedError]; } - + NSDictionary *responseHeaders = [[operation response] allHeaderFields]; + self.HTTPResponseHeaders = responseHeaders; completionBlock(nil, augmentedError); } }]; diff --git a/samples/client/petstore/objc/SwaggerClient/SWGPetApi.h b/samples/client/petstore/objc/SwaggerClient/SWGPetApi.h index f7e67d0aa1..7ea1821e57 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGPetApi.h +++ b/samples/client/petstore/objc/SwaggerClient/SWGPetApi.h @@ -18,6 +18,7 @@ -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +(SWGPetApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; ++(SWGPetApi*) sharedAPI; /// /// /// Update an existing pet diff --git a/samples/client/petstore/objc/SwaggerClient/SWGPetApi.m b/samples/client/petstore/objc/SwaggerClient/SWGPetApi.m index d79584f90b..4b8eba7056 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGPetApi.m +++ b/samples/client/petstore/objc/SwaggerClient/SWGPetApi.m @@ -9,6 +9,8 @@ @implementation SWGPetApi +static SWGPetApi* singletonAPI = nil; + #pragma mark - Initialize methods - (id) init { @@ -36,7 +38,6 @@ #pragma mark - +(SWGPetApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { - static SWGPetApi* singletonAPI = nil; if (singletonAPI == nil) { singletonAPI = [[SWGPetApi alloc] init]; @@ -45,6 +46,14 @@ return singletonAPI; } ++(SWGPetApi*) sharedAPI { + + if (singletonAPI == nil) { + singletonAPI = [[SWGPetApi alloc] init]; + } + return singletonAPI; +} + -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } diff --git a/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.h b/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.h index 09e67e38ed..e1c644ef5f 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.h +++ b/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.h @@ -18,6 +18,7 @@ -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +(SWGStoreApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; ++(SWGStoreApi*) sharedAPI; /// /// /// Returns pet inventories by status diff --git a/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.m b/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.m index 792147ebed..5fdf86b43a 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.m +++ b/samples/client/petstore/objc/SwaggerClient/SWGStoreApi.m @@ -9,6 +9,8 @@ @implementation SWGStoreApi +static SWGStoreApi* singletonAPI = nil; + #pragma mark - Initialize methods - (id) init { @@ -36,7 +38,6 @@ #pragma mark - +(SWGStoreApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { - static SWGStoreApi* singletonAPI = nil; if (singletonAPI == nil) { singletonAPI = [[SWGStoreApi alloc] init]; @@ -45,6 +46,14 @@ return singletonAPI; } ++(SWGStoreApi*) sharedAPI { + + if (singletonAPI == nil) { + singletonAPI = [[SWGStoreApi alloc] init]; + } + return singletonAPI; +} + -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } diff --git a/samples/client/petstore/objc/SwaggerClient/SWGUserApi.h b/samples/client/petstore/objc/SwaggerClient/SWGUserApi.h index a6e69a8947..21f314684f 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGUserApi.h +++ b/samples/client/petstore/objc/SwaggerClient/SWGUserApi.h @@ -18,6 +18,7 @@ -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +(SWGUserApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; ++(SWGUserApi*) sharedAPI; /// /// /// Create user @@ -98,7 +99,7 @@ /// Get user by user name /// /// -/// @param username The name that needs to be fetched. Use user1 for testing. +/// @param username The name that needs to be fetched. Use user1 for testing. /// /// /// @return SWGUser* diff --git a/samples/client/petstore/objc/SwaggerClient/SWGUserApi.m b/samples/client/petstore/objc/SwaggerClient/SWGUserApi.m index 92dd00fa28..75cf8d51b0 100644 --- a/samples/client/petstore/objc/SwaggerClient/SWGUserApi.m +++ b/samples/client/petstore/objc/SwaggerClient/SWGUserApi.m @@ -9,6 +9,8 @@ @implementation SWGUserApi +static SWGUserApi* singletonAPI = nil; + #pragma mark - Initialize methods - (id) init { @@ -36,7 +38,6 @@ #pragma mark - +(SWGUserApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { - static SWGUserApi* singletonAPI = nil; if (singletonAPI == nil) { singletonAPI = [[SWGUserApi alloc] init]; @@ -45,6 +46,14 @@ return singletonAPI; } ++(SWGUserApi*) sharedAPI { + + if (singletonAPI == nil) { + singletonAPI = [[SWGUserApi alloc] init]; + } + return singletonAPI; +} + -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } @@ -461,7 +470,7 @@ /// /// Get user by user name /// -/// @param username The name that needs to be fetched. Use user1 for testing. +/// @param username The name that needs to be fetched. Use user1 for testing. /// /// @returns SWGUser* /// From 75bb59572aec8a67b04b722473b393dfe8ec213d Mon Sep 17 00:00:00 2001 From: Matthew Davis Date: Thu, 3 Sep 2015 12:54:25 -0700 Subject: [PATCH 5/7] added extra CLI options required to generate a valid (lint-able) podspec file. --- .../codegen/languages/ObjcClientCodegen.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) 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 dfb4094f2b..ef36916982 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 @@ -23,6 +23,10 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { protected String podName = "SwaggerClient"; protected String podVersion = "1.0.0"; protected String classPrefix = "SWG"; + protected String authorName = "Swagger"; + protected String authorEmail = "apiteam@swagger.io"; + protected String license = "MIT"; + protected String gitRepoURL = "https://github.com/swagger-api/swagger-codegen"; public ObjcClientCodegen() { super(); @@ -112,6 +116,10 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { cliOptions.add(new CliOption("classPrefix", "prefix for generated classes (convention: Abbreviation of pod name e.g. `HN` for `HackerNews`), default: `SWG`")); cliOptions.add(new CliOption("podName", "cocoapods package name (convention: CameCase), default: `SwaggerClient`")); cliOptions.add(new CliOption("podVersion", "cocoapods package version, default: `1.0.0`")); + cliOptions.add(new CliOption("authorName", "Name to use in the podspec file, default: `Swagger`")); + cliOptions.add(new CliOption("authorEmail", "Email to use in the podspec file, default: `apiteam@swagger.io`")); + cliOptions.add(new CliOption("gitRepoURL", "URL for the git repo where this podspec should point to, default: `https://github.com/swagger-api/swagger-codegen`")); + cliOptions.add(new CliOption("license", "License to use in the podspec file, default: `MIT`")); } public CodegenType getTag() { @@ -141,10 +149,30 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { if (additionalProperties.containsKey("classPrefix")) { setClassPrefix((String) additionalProperties.get("classPrefix")); } + + if (additionalProperties.containsKey("authorName")) { + setAuthorName((String) additionalProperties.get("authorName")); + } + + if (additionalProperties.containsKey("authorEmail")) { + setAuthorEmail((String) additionalProperties.get("authorEmail")); + } + + if (additionalProperties.containsKey("gitRepoURL")) { + setGitRepoURL((String) additionalProperties.get("gitRepoURL")); + } + + if (additionalProperties.containsKey("license")) { + setLicense((String) additionalProperties.get("license")); + } additionalProperties.put("podName", podName); additionalProperties.put("podVersion", podVersion); additionalProperties.put("classPrefix", classPrefix); + additionalProperties.put("authorName", authorName); + additionalProperties.put("authorEmail", authorEmail); + additionalProperties.put("gitRepoURL", gitRepoURL); + additionalProperties.put("license", license); String swaggerFolder = podName; @@ -384,4 +412,20 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { public void setPodVersion(String podVersion) { this.podVersion = podVersion; } + + public void setAuthorEmail(String authorEmail) { + this.authorEmail = authorEmail; + } + + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + public void setGitRepoURL(String gitRepoURL) { + this.gitRepoURL = gitRepoURL; + } + + public void setLicense(String license) { + this.license = license; + } } From f705e03fc4b04f7c2f8ab4d7be59c855b3181057 Mon Sep 17 00:00:00 2001 From: Matthew Davis Date: Thu, 3 Sep 2015 13:02:24 -0700 Subject: [PATCH 6/7] changes to podspec.mustache to accept new params --- .../swagger-codegen/src/main/resources/objc/podspec.mustache | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/objc/podspec.mustache b/modules/swagger-codegen/src/main/resources/objc/podspec.mustache index 9ce03695bc..338ded84e8 100644 --- a/modules/swagger-codegen/src/main/resources/objc/podspec.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/podspec.mustache @@ -20,6 +20,11 @@ Pod::Spec.new do |s| s.requires_arc = true s.framework = 'SystemConfiguration' + + s.homepage = "{{gitRepoURL}}" + s.license = "{{license}}" + s.source = { :git => "{{gitRepoURL}}.git", :tag => "#{s.version}" } + s.author = { "{{authorName}}" => "{{authorEmail}}" } s.source_files = '{{podName}}/**/*' s.public_header_files = '{{podName}}/**/*.h' From ba701be2f25c712d6560f927c245468152d2cf74 Mon Sep 17 00:00:00 2001 From: "sparrow.jang" Date: Fri, 4 Sep 2015 15:20:34 +0800 Subject: [PATCH 7/7] fixed a empty object for response --- .../src/main/resources/python/api_client.mustache | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 1becd5547d..84a1dca45f 100644 --- a/modules/swagger-codegen/src/main/resources/python/api_client.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api_client.mustache @@ -270,7 +270,7 @@ class ApiClient(object): if klass in [int, float, str, bool]: return self.__deserialize_primitive(data, klass) elif klass == object: - return self.__deserialize_object() + return self.__deserialize_object(data) elif klass == date: return self.__deserialize_date(data) elif klass == datetime: @@ -495,13 +495,13 @@ class ApiClient(object): value = data return value - def __deserialize_object(self): + def __deserialize_object(self, value): """ - Deserializes empty object. + Return a original value. :return: object. """ - return object() + return value def __deserialize_date(self, string): """