diff --git a/.gitignore b/.gitignore index ca54f525660..b17bf46aa10 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ target .idea .lib atlassian-ide-plugin.xml +.DS_Store diff --git a/bin/csharp-petstore.sh b/bin/csharp-petstore.sh new file mode 100755 index 00000000000..3941d90896f --- /dev/null +++ b/bin/csharp-petstore.sh @@ -0,0 +1,6 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +export CLASSPATH="$DIR/../target/lib/*:$DIR/../target/*" +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +JAVA_OPTS=$JAVA_OPTS scala -cp $CLASSPATH "$@" samples/client/petstore/csharp/CsharpPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs.json special-key \ No newline at end of file diff --git a/build.sbt b/build.sbt index 635c4675b20..00c094bf131 100644 --- a/build.sbt +++ b/build.sbt @@ -96,6 +96,11 @@ pomExtra <<= (pomExtra, name, description) {(pom, name, desc) => pom ++ Group( Ivan Porto Carrero http://flanders.co.nz/ + + radius314 + Danny Gershman + danny.gershman@gmail.com + )} diff --git a/samples/client/petstore/csharp/CSharpPetstoreCodegen.scala b/samples/client/petstore/csharp/CSharpPetstoreCodegen.scala new file mode 100644 index 00000000000..4f876fa0751 --- /dev/null +++ b/samples/client/petstore/csharp/CSharpPetstoreCodegen.scala @@ -0,0 +1,45 @@ +/** + * Copyright 2012 Wordnik, Inc. + * + * 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 com.wordnik.swagger.codegen.BasicCSharpGenerator + +object CSharpPetstoreCodegen extends BasicCSharpGenerator { + def main(args: Array[String]) = generateClient(args) + + // location of templates + override def templateDir = "csharp" + + // where to write generated code + override def destinationDir = "samples/client/petstore/csharp/src" + + // package for api invoker, error files + override def invokerPackage = Some("Com.Wordnik.Petstore") + + // package for models + override def modelPackage = Some("Com.Wordnik.Petstore.Model") + + // package for api classes + override def apiPackage = Some("Com.Wordnik.Petstore.Api") + + // supporting classes + override def supportingFiles = + List( + ("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiInvoker.cs"), + ("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiException.cs"), + ("Newtonsoft.Json.dll", "samples/client/petstore/csharp/bin", "Newtonsoft.Json.dll"), + ("compile.mustache", "samples/client/petstore/csharp", "compile.bat")) +} + diff --git a/samples/client/petstore/csharp/bin/Com.Wordnik.Petstore.dll b/samples/client/petstore/csharp/bin/Com.Wordnik.Petstore.dll new file mode 100644 index 00000000000..f4656a1bf40 Binary files /dev/null and b/samples/client/petstore/csharp/bin/Com.Wordnik.Petstore.dll differ diff --git a/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll b/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll new file mode 100644 index 00000000000..26fdaffec14 Binary files /dev/null and b/samples/client/petstore/csharp/bin/Newtonsoft.Json.dll differ diff --git a/samples/client/petstore/csharp/compile.bat b/samples/client/petstore/csharp/compile.bat new file mode 100644 index 00000000000..13a6e91643e --- /dev/null +++ b/samples/client/petstore/csharp/compile.bat @@ -0,0 +1,2 @@ +SET CSCPATH=C:\windows\microsoft.net\Framework\v4.0.30319 +%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/Com.Wordnik.Petstore.dll /recurse:src\*.cs diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/PetApi.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/PetApi.cs new file mode 100644 index 00000000000..ede61e78a28 --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/PetApi.cs @@ -0,0 +1,172 @@ + using System; + using System.Collections.Generic; + using Com.Wordnik.Petstore; + using Com.Wordnik.Petstore.Model; + namespace Com.Wordnik.Petstore.Api { + public class PetApi { + string basePath = "http://petstore.swagger.wordnik.com/api"; + private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance(); + + public ApiInvoker getInvoker() { + return apiInvoker; + } + + public void setBasePath(string basePath) { + this.basePath = basePath; + } + + public String getBasePath() { + return basePath; + } + + public Pet getPetById (string Petid) { + // create path and map variables + var path = "/pet.{format}/{petId}".Replace("{format}","json").Replace("{" + "Petid" + "}", apiInvoker.escapeString(Petid.ToString())); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Petid == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return (Pet) ApiInvoker.deserialize(response, typeof(Pet)); + } + else { + return null; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return null; + } + else { + throw ex; + } + } + } + public void addPet (Pet body) { + // create path and map variables + var path = "/pet.{format}".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public void updatePet (Pet body) { + // create path and map variables + var path = "/pet.{format}".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "PUT", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public List findPetsByStatus (string Status) { + // create path and map variables + var path = "/pet.{format}/findByStatus".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Status == null ) { + throw new ApiException(400, "missing required params"); + } + if (Status != null) + queryParams.Add("Status", Status); + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return (List) ApiInvoker.deserialize(response, typeof(List)); + } + else { + return null; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return null; + } + else { + throw ex; + } + } + } + public List findPetsByTags (string Tags) { + // create path and map variables + var path = "/pet.{format}/findByTags".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Tags == null ) { + throw new ApiException(400, "missing required params"); + } + if (Tags != null) + queryParams.Add("Tags", Tags); + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return (List) ApiInvoker.deserialize(response, typeof(List)); + } + else { + return null; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return null; + } + else { + throw ex; + } + } + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/StoreApi.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/StoreApi.cs new file mode 100644 index 00000000000..90ed1f5d6c1 --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/StoreApi.cs @@ -0,0 +1,110 @@ + using System; + using System.Collections.Generic; + using Com.Wordnik.Petstore; + using Com.Wordnik.Petstore.Model; + namespace Com.Wordnik.Petstore.Api { + public class StoreApi { + string basePath = "http://petstore.swagger.wordnik.com/api"; + private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance(); + + public ApiInvoker getInvoker() { + return apiInvoker; + } + + public void setBasePath(string basePath) { + this.basePath = basePath; + } + + public String getBasePath() { + return basePath; + } + + public Order getOrderById (string Orderid) { + // create path and map variables + var path = "/store.{format}/order/{orderId}".Replace("{format}","json").Replace("{" + "Orderid" + "}", apiInvoker.escapeString(Orderid.ToString())); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Orderid == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return (Order) ApiInvoker.deserialize(response, typeof(Order)); + } + else { + return null; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return null; + } + else { + throw ex; + } + } + } + public void deleteOrder (string Orderid) { + // create path and map variables + var path = "/store.{format}/order/{orderId}".Replace("{format}","json").Replace("{" + "Orderid" + "}", apiInvoker.escapeString(Orderid.ToString())); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Orderid == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, null, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public void placeOrder (Order body) { + // create path and map variables + var path = "/store.{format}/order".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/UserApi.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/UserApi.cs new file mode 100644 index 00000000000..74b92228edd --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Api/UserApi.cs @@ -0,0 +1,255 @@ + using System; + using System.Collections.Generic; + using Com.Wordnik.Petstore; + using Com.Wordnik.Petstore.Model; + namespace Com.Wordnik.Petstore.Api { + public class UserApi { + string basePath = "http://petstore.swagger.wordnik.com/api"; + private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance(); + + public ApiInvoker getInvoker() { + return apiInvoker; + } + + public void setBasePath(string basePath) { + this.basePath = basePath; + } + + public String getBasePath() { + return basePath; + } + + public void createUsersWithArrayInput (List body) { + // create path and map variables + var path = "/user.{format}/createWithArray".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public void createUser (User body) { + // create path and map variables + var path = "/user.{format}".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public void createUsersWithListInput (List body) { + // create path and map variables + var path = "/user.{format}/createWithList".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public void updateUser (string Username, User body) { + // create path and map variables + var path = "/user.{format}/{username}".Replace("{format}","json").Replace("{" + "Username" + "}", apiInvoker.escapeString(Username.ToString())); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Username == null || body == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "PUT", queryParams, body, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public void deleteUser (string Username) { + // create path and map variables + var path = "/user.{format}/{username}".Replace("{format}","json").Replace("{" + "Username" + "}", apiInvoker.escapeString(Username.ToString())); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Username == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, null, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + public User getUserByName (string Username) { + // create path and map variables + var path = "/user.{format}/{username}".Replace("{format}","json").Replace("{" + "Username" + "}", apiInvoker.escapeString(Username.ToString())); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Username == null ) { + throw new ApiException(400, "missing required params"); + } + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return (User) ApiInvoker.deserialize(response, typeof(User)); + } + else { + return null; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return null; + } + else { + throw ex; + } + } + } + public string loginUser (string Username, string Password) { + // create path and map variables + var path = "/user.{format}/login".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + // verify required params are set + if (Username == null || Password == null ) { + throw new ApiException(400, "missing required params"); + } + if (Username != null) + queryParams.Add("Username", Username); + if (Password != null) + queryParams.Add("Password", Password); + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return (string) ApiInvoker.deserialize(response, typeof(string)); + } + else { + return null; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return null; + } + else { + throw ex; + } + } + } + public void logoutUser () { + // create path and map variables + var path = "/user.{format}/logout".Replace("{format}","json"); + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + try { + var response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, null, headerParams); + if(response != null){ + return ; + } + else { + return ; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return ; + } + else { + throw ex; + } + } + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiException.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiException.cs new file mode 100644 index 00000000000..0da40246867 --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiException.cs @@ -0,0 +1,21 @@ +using System; + +namespace Com.Wordnik.Petstore { + public class ApiException : Exception { + + private int errorCode = 0; + + public ApiException() {} + + public int ErrorCode { + get + { + return errorCode; + } + } + + public ApiException(int errorCode, string message) : base(message) { + this.errorCode = errorCode; + } + } +} diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiInvoker.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiInvoker.cs new file mode 100644 index 00000000000..1388f77762b --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/ApiInvoker.cs @@ -0,0 +1,99 @@ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using Newtonsoft.Json; + + namespace Com.Wordnik.Petstore { + public class ApiInvoker { + private static readonly ApiInvoker _instance = new ApiInvoker(); + private Dictionary defaultHeaderMap = new Dictionary(); + + public static ApiInvoker GetInstance() { + return _instance; + } + + public void addDefaultHeader(string key, string value) { + defaultHeaderMap.Add(key, value); + } + + public string escapeString(string str) { + return str; + } + + public static object deserialize(string json, Type type) { + try + { + return JsonConvert.DeserializeObject(json, type); + } + catch (IOException e) { + throw new ApiException(500, e.Message); + } + + } + + public static string serialize(object obj) { + try + { + return obj != null ? JsonConvert.SerializeObject(obj) : null; + } + catch (Exception e) { + throw new ApiException(500, e.Message); + } + } + + public string invokeAPI(string host, string path, string method, Dictionary queryParams, object body, Dictionary headerParams) { + var b = new StringBuilder(); + + foreach (var queryParamItem in queryParams) + { + var value = queryParamItem.Value; + if (value == null) continue; + b.Append(b.ToString().Length == 0 ? "?" : "&"); + b.Append(escapeString(queryParamItem.Key)).Append("=").Append(escapeString(value)); + } + + var querystring = b.ToString(); + + host = host.EndsWith("/") ? host.Substring(0, host.Length - 1) : host; + + var client = WebRequest.Create(host + path + querystring); + client.ContentType = "application/json"; + + foreach (var headerParamsItem in headerParams) + { + client.Headers.Add(headerParamsItem.Key, headerParamsItem.Value); + } + foreach (var defaultHeaderMapItem in defaultHeaderMap.Where(defaultHeaderMapItem => !headerParams.ContainsKey(defaultHeaderMapItem.Key))) + { + client.Headers.Add(defaultHeaderMapItem.Key, defaultHeaderMapItem.Value); + } + + switch (method) + { + case "GET": + break; + case "POST": + case "PUT": + case "DELETE": + var swRequestWriter = new StreamWriter(client.GetRequestStream()); + swRequestWriter.Write(serialize(body)); + swRequestWriter.Close(); + break; + default: + throw new ApiException(500, "unknown method type " + method); + } + var webResponse = (HttpWebResponse) client.GetResponse(); + if (webResponse.StatusCode != HttpStatusCode.OK) throw new ApiException((int) webResponse.StatusCode, webResponse.StatusDescription); + + var responseReader = new StreamReader(webResponse.GetResponseStream()); + var responseData = responseReader.ReadToEnd(); + responseReader.Close(); + return responseData; + } + + } + } + diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Category.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Category.cs new file mode 100644 index 00000000000..48285458f91 --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Category.cs @@ -0,0 +1,21 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +namespace Com.Wordnik.Petstore.Model { + public class Category { + public long Id { get; set; } + + public string Name { get; set; } + + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class Category {\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Name: ").Append(Name).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Order.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Order.cs new file mode 100644 index 00000000000..a3bf7af3a88 --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Order.cs @@ -0,0 +1,31 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +namespace Com.Wordnik.Petstore.Model { + public class Order { + public long Id { get; set; } + + public long Petid { get; set; } + + /* Order Status */ + public string Status { get; set; } + + public int Quantity { get; set; } + + public DateTime Shipdate { get; set; } + + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class Order {\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Petid: ").Append(Petid).Append("\n"); + sb.Append(" Status: ").Append(Status).Append("\n"); + sb.Append(" Quantity: ").Append(Quantity).Append("\n"); + sb.Append(" Shipdate: ").Append(Shipdate).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Pet.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Pet.cs new file mode 100644 index 00000000000..7fe96a64ddc --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Pet.cs @@ -0,0 +1,34 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +namespace Com.Wordnik.Petstore.Model { + public class Pet { + public List Tags { get; set; } + + public long Id { get; set; } + + public Category Category { get; set; } + + /* pet status in the store */ + public string Status { get; set; } + + public string Name { get; set; } + + public List Photourls { get; set; } + + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class Pet {\n"); + sb.Append(" Tags: ").Append(Tags).Append("\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Category: ").Append(Category).Append("\n"); + sb.Append(" Status: ").Append(Status).Append("\n"); + sb.Append(" Name: ").Append(Name).Append("\n"); + sb.Append(" Photourls: ").Append(Photourls).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Tag.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Tag.cs new file mode 100644 index 00000000000..c73dc74c47a --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/Tag.cs @@ -0,0 +1,21 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +namespace Com.Wordnik.Petstore.Model { + public class Tag { + public long Id { get; set; } + + public string Name { get; set; } + + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class Tag {\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Name: ").Append(Name).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + } + } diff --git a/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/User.cs b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/User.cs new file mode 100644 index 00000000000..f3032e9a7bb --- /dev/null +++ b/samples/client/petstore/csharp/src/Com/Wordnik/Petstore/Model/User.cs @@ -0,0 +1,40 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +namespace Com.Wordnik.Petstore.Model { + public class User { + public long Id { get; set; } + + public string Lastname { get; set; } + + public string Phone { get; set; } + + public string Username { get; set; } + + public string Email { get; set; } + + /* User Status */ + public int Userstatus { get; set; } + + public string Firstname { get; set; } + + public string Password { get; set; } + + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class User {\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Lastname: ").Append(Lastname).Append("\n"); + sb.Append(" Phone: ").Append(Phone).Append("\n"); + sb.Append(" Username: ").Append(Username).Append("\n"); + sb.Append(" Email: ").Append(Email).Append("\n"); + sb.Append(" Userstatus: ").Append(Userstatus).Append("\n"); + sb.Append(" Firstname: ").Append(Firstname).Append("\n"); + sb.Append(" Password: ").Append(Password).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + } + } diff --git a/src/main/resources/csharp/Newtonsoft.Json.dll b/src/main/resources/csharp/Newtonsoft.Json.dll new file mode 100644 index 00000000000..26fdaffec14 Binary files /dev/null and b/src/main/resources/csharp/Newtonsoft.Json.dll differ diff --git a/src/main/resources/csharp/api.mustache b/src/main/resources/csharp/api.mustache new file mode 100644 index 00000000000..b08081d81e9 --- /dev/null +++ b/src/main/resources/csharp/api.mustache @@ -0,0 +1,69 @@ + using System; + using System.Collections.Generic; + using {{invokerPackage}}; + using {{invokerPackage}}.Model; + {{#imports}} + {{/imports}} + + namespace {{package}} { + {{#operations}} + public class {{classname}} { + string basePath = "{{basePath}}"; + private readonly ApiInvoker apiInvoker = ApiInvoker.GetInstance(); + + public ApiInvoker getInvoker() { + return apiInvoker; + } + + public void setBasePath(string basePath) { + this.basePath = basePath; + } + + public String getBasePath() { + return basePath; + } + + {{#operation}} + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { + // create path and map variables + var path = "{{path}}".Replace("{format}","json"){{#pathParams}}.Replace("{" + "{{paramName}}" + "}", apiInvoker.escapeString({{{paramName}}}.ToString())){{/pathParams}}; + + // query params + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + + {{#requiredParamCount}} + // verify required params are set + if ({{/requiredParamCount}}{{#requiredParams}} {{paramName}} == null {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) { + throw new ApiException(400, "missing required params"); + } + {{/requiredParamCount}} + + {{#queryParams}}if ({{paramName}} != null) + queryParams.Add("{{paramName}}", {{paramName}}); + {{/queryParams}} + + {{#headerParams}}headerParams.Add("{{paramName}}", {{paramName}}); + {{/headerParams}} + + try { + var response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams); + if(response != null){ + return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, typeof({{{returnType}}})){{/returnType}}; + } + else { + return {{#returnType}}null{{/returnType}}; + } + } catch (ApiException ex) { + if(ex.ErrorCode == 404) { + return {{#returnType}} null{{/returnType}}; + } + else { + throw ex; + } + } + } + {{/operation}} + } + {{/operations}} + } \ No newline at end of file diff --git a/src/main/resources/csharp/apiException.mustache b/src/main/resources/csharp/apiException.mustache new file mode 100644 index 00000000000..3b371aea9a8 --- /dev/null +++ b/src/main/resources/csharp/apiException.mustache @@ -0,0 +1,21 @@ +using System; + +namespace {{invokerPackage}} { + public class ApiException : Exception { + + private int errorCode = 0; + + public ApiException() {} + + public int ErrorCode { + get + { + return errorCode; + } + } + + public ApiException(int errorCode, string message) : base(message) { + this.errorCode = errorCode; + } + } +} \ No newline at end of file diff --git a/src/main/resources/csharp/apiInvoker.mustache b/src/main/resources/csharp/apiInvoker.mustache new file mode 100644 index 00000000000..c522d1545f6 --- /dev/null +++ b/src/main/resources/csharp/apiInvoker.mustache @@ -0,0 +1,98 @@ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using Newtonsoft.Json; + + namespace {{invokerPackage}} { + public class ApiInvoker { + private static readonly ApiInvoker _instance = new ApiInvoker(); + private Dictionary defaultHeaderMap = new Dictionary(); + + public static ApiInvoker GetInstance() { + return _instance; + } + + public void addDefaultHeader(string key, string value) { + defaultHeaderMap.Add(key, value); + } + + public string escapeString(string str) { + return str; + } + + public static object deserialize(string json, Type type) { + try + { + return JsonConvert.DeserializeObject(json, type); + } + catch (IOException e) { + throw new ApiException(500, e.Message); + } + + } + + public static string serialize(object obj) { + try + { + return obj != null ? JsonConvert.SerializeObject(obj) : null; + } + catch (Exception e) { + throw new ApiException(500, e.Message); + } + } + + public string invokeAPI(string host, string path, string method, Dictionary queryParams, object body, Dictionary headerParams) { + var b = new StringBuilder(); + + foreach (var queryParamItem in queryParams) + { + var value = queryParamItem.Value; + if (value == null) continue; + b.Append(b.ToString().Length == 0 ? "?" : "&"); + b.Append(escapeString(queryParamItem.Key)).Append("=").Append(escapeString(value)); + } + + var querystring = b.ToString(); + + host = host.EndsWith("/") ? host.Substring(0, host.Length - 1) : host; + + var client = WebRequest.Create(host + path + querystring); + client.ContentType = "application/json"; + + foreach (var headerParamsItem in headerParams) + { + client.Headers.Add(headerParamsItem.Key, headerParamsItem.Value); + } + foreach (var defaultHeaderMapItem in defaultHeaderMap.Where(defaultHeaderMapItem => !headerParams.ContainsKey(defaultHeaderMapItem.Key))) + { + client.Headers.Add(defaultHeaderMapItem.Key, defaultHeaderMapItem.Value); + } + + switch (method) + { + case "GET": + break; + case "POST": + case "PUT": + case "DELETE": + var swRequestWriter = new StreamWriter(client.GetRequestStream()); + swRequestWriter.Write(serialize(body)); + swRequestWriter.Close(); + break; + default: + throw new ApiException(500, "unknown method type " + method); + } + var webResponse = (HttpWebResponse) client.GetResponse(); + if (webResponse.StatusCode != HttpStatusCode.OK) throw new ApiException((int) webResponse.StatusCode, webResponse.StatusDescription); + + var responseReader = new StreamReader(webResponse.GetResponseStream()); + var responseData = responseReader.ReadToEnd(); + responseReader.Close(); + return responseData; + } + + } + } diff --git a/src/main/resources/csharp/compile.mustache b/src/main/resources/csharp/compile.mustache new file mode 100644 index 00000000000..b19235fde3c --- /dev/null +++ b/src/main/resources/csharp/compile.mustache @@ -0,0 +1,2 @@ +SET CSCPATH=C:\windows\microsoft.net\Framework\v4.0.30319 +%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/{{invokerPackage}}.dll /recurse:src\*.cs \ No newline at end of file diff --git a/src/main/resources/csharp/model.mustache b/src/main/resources/csharp/model.mustache new file mode 100644 index 00000000000..d9ef4ffbedd --- /dev/null +++ b/src/main/resources/csharp/model.mustache @@ -0,0 +1,30 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +{{#models}} +{{#model}} +namespace {{package}} { + public class {{classname}} { + {{#vars}} + + {{#description}}/* {{{description}}} */ + {{/description}} + public {{{datatype}}} {{name}} { get; set; } + + {{/vars}} + + public override string ToString() { + var sb = new StringBuilder(); + sb.Append("class {{classname}} {\n"); + {{#vars}} + sb.Append(" {{name}}: ").Append({{name}}).Append("\n"); + {{/vars}} + sb.Append("}\n"); + return sb.ToString(); + } + } + {{/model}} + {{/models}} +} \ No newline at end of file diff --git a/src/main/scala/com/wordnik/swagger/codegen/BasicCSharpGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/BasicCSharpGenerator.scala new file mode 100644 index 00000000000..b7f2d1aab59 --- /dev/null +++ b/src/main/scala/com/wordnik/swagger/codegen/BasicCSharpGenerator.scala @@ -0,0 +1,189 @@ +/** + * Copyright 2012 Wordnik, Inc. + * + * 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. + */ + +package com.wordnik.swagger.codegen + +import com.wordnik.swagger.model._ + +object BasicCSharpGenerator extends BasicCSharpGenerator { + def main(args: Array[String]) = generateClient(args) +} + +class BasicCSharpGenerator extends BasicGenerator { + override def defaultIncludes = Set( + "double", + "int", + "long", + "float", + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float") + + /** + * We are using csharp objects instead of primitives to avoid showing default + * primitive values when the API returns missing data. For instance, having a + * {"count":0} != count is unknown. You can change this to use primitives if you + * desire, but update the default values as well or they'll be set to null in + * variable declarations. + */ + override def typeMapping = Map( + "boolean" -> "bool", + "string" -> "string", + "int" -> "int", + "float" -> "float", + "long" -> "long", + "double" -> "double", + "object" -> "object", + "Date" -> "DateTime", + "date" -> "DateTime") + + // location of templates + override def templateDir = "csharp" + + // where to write generated code + override def destinationDir = "generated-code/csharp/src/main/csharp" + + // template used for models + modelTemplateFiles += "model.mustache" -> ".cs" + + // template used for models + apiTemplateFiles += "api.mustache" -> ".cs" + + override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert", + "default", "if", "package", "synchronized", "boolean", "do", "goto", "private", + "this", "break", "double", "implements", "protected", "throw", "byte", "else", + "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", + "catch", "extends", "short", "try", "char", "final", "interface", "static", + "void", "class", "finally", "strictfp", "volatile", "const", "float", + "native", "super", "while") + + // import/require statements for specific datatypes + override def importMapping = Map() + + // package for models + override def modelPackage = Some("Com.Wordnik.Client.Model") + + // package for api classes + override def apiPackage = Some("Com.Wordnik.Client.Api") + + // file suffix + override def fileSuffix = ".cs" + + // response classes + override def processResponseClass(responseClass: String): Option[String] = { + responseClass match { + case "void" => None + case e: String => Some(typeMapping.getOrElse(e, e.replaceAll("\\[", "<").replaceAll("\\]", ">"))) + } + } + + override def processResponseDeclaration(responseClass: String): Option[String] = { + responseClass match { + case "void" => None + case e: String => Some(typeMapping.getOrElse(e, e.replaceAll("\\[", "<").replaceAll("\\]", ">"))) + } + } + + override def toDeclaredType(dt: String): String = { + val declaredType = dt.indexOf("[") match { + case -1 => dt + case n: Int => { + if (dt.substring(0, n) == "Array") + "List" + dt.substring(n).replaceAll("\\[", "<").replaceAll("\\]", ">") + else dt.replaceAll("\\[", "<").replaceAll("\\]", ">") + } + } + typeMapping.getOrElse(declaredType, declaredType) + } + + override def toDeclaration(obj: ModelProperty) = { + var declaredType = toDeclaredType(obj.`type`) + + declaredType match { + case "Array" => declaredType = "List" + case e: String => e + } + + val defaultValue = toDefaultValue(declaredType, obj) + declaredType match { + case "List" => { + val inner = { + obj.items match { + case Some(items) => items.ref.getOrElse(items.`type`) + case _ => throw new Exception("no inner type defined") + } + } + declaredType += "<" + toDeclaredType(inner) + ">" + } + case _ => + } + (declaredType, defaultValue) + } + + /** + * we are defaulting to null values since the codegen uses csharp objects instead of primitives + * If you change to primitives, you can put in the appropriate values (0.0f, etc). + */ + override def toDefaultValue(dataType: String, obj: ModelProperty) = { + dataType match { + case "Boolean" => "null" + case "Integer" => "null" + case "Long" => "null" + case "Float" => "null" + case "Double" => "null" + case "List" => { + val inner = { + obj.items match { + case Some(items) => items.ref.getOrElse(items.`type`) + case _ => throw new Exception("no inner type defined") + } + } + "new ArrayList<" + toDeclaredType(inner) + ">" + "()" + } + case _ => "null" + } + } + + override def escapeReservedWord(word: String) = { + if (reservedWords.contains(word)) + throw new Exception("reserved word " + "\"" + word + "\" not allowed") + else word + } + + /*override def toVarName(name: String): String = { + name match { + case _ if (reservedWords.contains(name)) => escapeReservedWord(name) + case _ => typeMapping.getOrElse(name, name) + } + capitalize(name) + } + + def capitalize(s: String) = { + s(0).toUpper + s.substring(1, s.length).toLowerCase + }*/ + + // supporting classes + override def supportingFiles = + List( + ("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiInvoker.java"), + ("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiException.java"), + ("Newtonsoft.Json.dll", "generated-code/csharp/bin", "Newtonsoft.Json.dll"), + ("compile.mustache", "generated-code/csharp", "compile.bat")) +} \ No newline at end of file