From 496de14cffb78fb9738be9a6df54106c3166dcd9 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 16 May 2016 10:49:24 +0200 Subject: [PATCH 01/64] Main files of nancyfx generator. --- .../languages/NancyFXServerCodegen.java | 127 +++++++++++++++ .../services/io.swagger.codegen.CodegenConfig | 1 + .../main/resources/nancyfx/Project.mustache | 54 ++++++ .../main/resources/nancyfx/Solution.mustache | 25 +++ .../src/main/resources/nancyfx/api.mustache | 45 +++++ .../main/resources/nancyfx/bodyParam.mustache | 1 + .../main/resources/nancyfx/formParam.mustache | 1 + .../resources/nancyfx/headerParam.mustache | 1 + .../resources/nancyfx/listReturn.mustache | 4 + .../main/resources/nancyfx/mapReturn.mustache | 4 + .../src/main/resources/nancyfx/model.mustache | 154 ++++++++++++++++++ .../resources/nancyfx/objectReturn.mustache | 4 + .../main/resources/nancyfx/pathParam.mustache | 1 + .../resources/nancyfx/queryParam.mustache | 1 + .../src/main/resources/nancyfx/tags.mustache | 1 + .../options/NancyFXServerOptionsProvider.java | 35 ++++ 16 files changed, 459 insertions(+) create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/api.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/model.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache create mode 100644 modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java new file mode 100644 index 000000000000..029f46ed1b50 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -0,0 +1,127 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.CodegenOperation; +import io.swagger.codegen.CodegenType; +import io.swagger.codegen.SupportingFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Arrays; + +public class NancyFXServerCodegen extends AbstractCSharpCodegen { + + protected String sourceFolder = "src" + File.separator + packageName; + protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}"; + + @SuppressWarnings("hiding") + protected Logger LOGGER = LoggerFactory.getLogger(NancyFXServerCodegen.class); + + public NancyFXServerCodegen() { + super(); + + outputFolder = "generated-code" + File.separator + this.getName(); + + modelTemplateFiles.put("model.mustache", ".cs"); + apiTemplateFiles.put("api.mustache", ".cs"); + + // contextually reserved words + setReservedWordsLowerCase( + Arrays.asList("var", "async", "await", "dynamic", "yield") + ); + + cliOptions.clear(); + + // CLI options + addOption(CodegenConstants.PACKAGE_NAME, + "C# package name (convention: Title.Case).", + this.packageName); + + addOption(CodegenConstants.PACKAGE_VERSION, + "C# package version.", + this.packageVersion); + + addOption(CodegenConstants.SOURCE_FOLDER, + CodegenConstants.SOURCE_FOLDER_DESC, + sourceFolder); + + // CLI Switches + addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, + CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC, + this.sortParamsByRequiredFlag); + + addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE, + CodegenConstants.OPTIONAL_PROJECT_FILE_DESC, + this.optionalProjectFileFlag); + + addSwitch(CodegenConstants.USE_DATETIME_OFFSET, + CodegenConstants.USE_DATETIME_OFFSET_DESC, + this.useDateTimeOffsetFlag); + + addSwitch(CodegenConstants.USE_COLLECTION, + CodegenConstants.USE_COLLECTION_DESC, + this.useCollection); + + addSwitch(CodegenConstants.RETURN_ICOLLECTION, + CodegenConstants.RETURN_ICOLLECTION_DESC, + this.returnICollection); + } + + @Override + public CodegenType getTag() { + return CodegenType.SERVER; + } + + @Override + public String getName() { + return "nancyfx"; + } + + @Override + public String getHelp() { + return "Generates a NancyFX Web API server."; + } + + @Override + public void processOpts() { + super.processOpts(); + + String packageFolder = sourceFolder + File.separator + packageName; + apiPackage = packageName + ".Api"; + modelPackage = packageName + ".Models"; + + if (optionalProjectFileFlag) { + supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); + supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder, packageName + ".csproj")); + } + additionalProperties.put("packageGuid", packageGuid); + } + + @Override + public String apiFileFolder() { + return outputFolder + File.separator + sourceFolder + File.separator + "Api"; + } + + @Override + public String modelFileFolder() { + return outputFolder + File.separator + sourceFolder + File.separator + "Models"; + } + + @Override + protected void processOperation(CodegenOperation operation) { + super.processOperation(operation); + + // HACK: Unlikely in the wild, but we need to clean operation paths for MVC Routing + if (operation.path != null) { + String original = operation.path; + operation.path = operation.path.replace("?", "/"); + if (!original.equals(operation.path)) { + LOGGER.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source."); + } + } + + // Converts, for example, PUT to HttpPut for controller attributes + operation.httpMethod = "Http" + operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); + } +} 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 c84abac129ca..b1925c4d5a08 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 @@ -16,6 +16,7 @@ io.swagger.codegen.languages.JavascriptClientCodegen io.swagger.codegen.languages.JavascriptClosureAngularClientCodegen io.swagger.codegen.languages.JavaJerseyServerCodegen io.swagger.codegen.languages.JMeterCodegen +io.swagger.codegen.languages.NancyFXServerCodegen io.swagger.codegen.languages.NodeJSServerCodegen io.swagger.codegen.languages.ObjcClientCodegen io.swagger.codegen.languages.PerlClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache new file mode 100644 index 000000000000..3a753d150f6b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -0,0 +1,54 @@ + + + + Debug + AnyCPU + {{packageGuid}} + Library + Properties + {{packageTitle}} + {{packageTitle}} + {{^supportsUWP}} + {{targetFramework}} + {{/supportsUWP}} + {{#supportsUWP}} + UAP + 10.0.10240.0 + 10.0.10240.0 + 14 + {{/supportsUWP}} + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache new file mode 100644 index 000000000000..7f2d34e366ea --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +VisualStudioVersion = 12.0.0.0 +MinimumVisualStudioVersion = 10.0.0.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{packageName}}", "src\{{packageName}}\{{packageName}}.csproj", "{{packageGuid}}" +EndProject +Global +GlobalSection(SolutionConfigurationPlatforms) = preSolution +Debug|Any CPU = Debug|Any CPU +Release|Any CPU = Release|Any CPU +EndGlobalSection +GlobalSection(ProjectConfigurationPlatforms) = postSolution +{{packageGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{{packageGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU +{{packageGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU +{{packageGuid}}.Release|Any CPU.Build.0 = Release|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU +EndGlobalSection +GlobalSection(SolutionProperties) = preSolution +HideSolutionNode = FALSE +EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache new file mode 100644 index 000000000000..e9c5c919898f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNet.Mvc; +using Newtonsoft.Json; +using Swashbuckle.SwaggerGen.Annotations; +using {{packageName}}.Models; + +namespace {{packageName}}.Controllers +{ {{#operations}} + /// + /// {{description}} + /// {{#description}}{{#basePath}} + [Route("{{basePath}}")] + {{/basePath}}[Description("{{description}}")]{{/description}} + public class {{classname}}Controller : Controller + { {{#operation}} + + /// + /// {{#summary}}{{summary}}{{/summary}} + /// + {{#notes}}/// {{notes}}{{/notes}}{{#allParams}} + /// {{description}}{{/allParams}}{{#responses}} + /// {{message}}{{/responses}} + [{{httpMethod}}] + [Route("{{path}}")] + [SwaggerOperation("{{operationId}}")]{{#returnType}} + [SwaggerResponse(200, type: typeof({{&returnType}}))]{{/returnType}} + public {{#returnType}}IActionResult{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + { {{#returnType}} + string exampleJson = null; + {{#isListCollection}}{{>listReturn}}{{/isListCollection}}{{^isListCollection}}{{#isMapContainer}}{{>mapReturn}}{{/isMapContainer}}{{^isMapContainer}}{{>objectReturn}}{{/isMapContainer}}{{/isListCollection}} + {{!TODO: defaultResponse, examples, auth, consumes, produces, nickname, externalDocs, imports, security}} + return new ObjectResult(example);{{/returnType}}{{^returnType}} + throw new NotImplementedException();{{/returnType}} + } +{{/operation}} + } +{{/operations}} +} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache new file mode 100644 index 000000000000..02b0fa1d2dea --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache new file mode 100644 index 000000000000..1e743e1e4c73 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache @@ -0,0 +1 @@ +{{#isFormParam}}[FromForm]{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache new file mode 100644 index 000000000000..e61cadb11315 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}[FromHeader]{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache new file mode 100644 index 000000000000..d609e67148c2 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache @@ -0,0 +1,4 @@ + + var example = exampleJson != null + ? JsonConvert.DeserializeObject<{{returnContainer}}<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson) + : Enumerable.Empty<{{#returnType}}{{{returnType}}}{{/returnType}}>(); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache new file mode 100644 index 000000000000..856fb1b3507c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache @@ -0,0 +1,4 @@ + + var example = exampleJson != null + ? JsonConvert.DeserializeObject>(exampleJson) + : new Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>(); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache new file mode 100644 index 000000000000..08aaed01f3db --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -0,0 +1,154 @@ +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; + +{{#models}} +{{#model}} +namespace {{packageName}}.Models +{ + /// + /// {{description}} + /// + public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + { + /// + /// Initializes a new instance of the class. + /// +{{#vars}} /// {{#description}}{{description}}{{/description}}{{^description}}{{name}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}. +{{/vars}} + public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) + { + {{#vars}}{{#required}}// to ensure "{{name}}" is required (not null) + if ({{name}} == null) + { + throw new InvalidDataException("{{name}} is a required property for {{classname}} and cannot be null"); + } + else + { + this.{{name}} = {{name}}; + } + {{/required}}{{/vars}}{{#vars}}{{^required}}{{#defaultValue}}// use default value if no "{{name}}" provided + if ({{name}} == null) + { + this.{{name}} = {{{defaultValue}}}; + } + else + { + this.{{name}} = {{name}}; + } + {{/defaultValue}}{{^defaultValue}}this.{{name}} = {{name}}; + {{/defaultValue}}{{/required}}{{/vars}} + } + + {{#vars}} + /// + /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}} + /// {{#description}} + /// {{{description}}}{{/description}} + public {{{datatype}}} {{name}} { get; set; } + + {{/vars}} + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + 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(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public {{#parent}} new {{/parent}}string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals(({{classname}})obj); + } + + /// + /// Returns true if {{classname}} instances are equal + /// + /// Instance of {{classname}} to be compared + /// Boolean + public bool Equals({{classname}} other) + { + + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return {{#vars}}{{#isNotContainer}} + ( + this.{{name}} == other.{{name}} || + this.{{name}} != null && + this.{{name}}.Equals(other.{{name}}) + ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{^isNotContainer}} + ( + this.{{name}} == other.{{name}} || + this.{{name}} != null && + this.{{name}}.SequenceEqual(other.{{name}}) + ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}}; + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + // credit: http://stackoverflow.com/a/263416/677735 + unchecked // Overflow is fine, just wrap + { + int hash = 41; + // Suitable nullity checks etc, of course :) + {{#vars}} + if (this.{{name}} != null) + hash = hash * 59 + this.{{name}}.GetHashCode(); + {{/vars}} + return hash; + } + } + + #region Operators + + public static bool operator ==({{classname}} left, {{classname}} right) + { + return Equals(left, right); + } + + public static bool operator !=({{classname}} left, {{classname}} right) + { + return !Equals(left, right); + } + + #endregion Operators + + } +{{/model}} +{{/models}} +} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache new file mode 100644 index 000000000000..4059a61ac0b8 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache @@ -0,0 +1,4 @@ + + var example = exampleJson != null + ? JsonConvert.DeserializeObject<{{#returnType}}{{{returnType}}}{{/returnType}}>(exampleJson) + : default({{#returnType}}{{{returnType}}}{{/returnType}}); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache new file mode 100644 index 000000000000..5aa27eb4cb3e --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache @@ -0,0 +1 @@ +{{#isPathParam}}[FromRoute]{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache new file mode 100644 index 000000000000..42ce87a2b7fe --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}[FromQuery]{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache new file mode 100644 index 000000000000..c97df19949e6 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache @@ -0,0 +1 @@ +{{!TODO: Need iterable tags object...}}{{#tags}}, Tags = new[] { {{/tags}}"{{#tags}}{{tag}} {{/tags}}"{{#tags}} }{{/tags}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java new file mode 100644 index 000000000000..e24df8847138 --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java @@ -0,0 +1,35 @@ +package io.swagger.codegen.options; + +import com.google.common.collect.ImmutableMap; +import io.swagger.codegen.CodegenConstants; + +import java.util.Map; + +public class NancyFXServerOptionsProvider implements OptionsProvider { + public static final String PACKAGE_NAME_VALUE = "swagger_server_nancyfx"; + public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT"; + public static final String SOURCE_FOLDER_VALUE = "src_nancyfx"; + + @Override + public String getLanguage() { + return "nancyfx"; + } + + @Override + public Map createOptions() { + ImmutableMap.Builder builder = new ImmutableMap.Builder(); + return builder.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE) + .put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE) + .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE) + .put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true") + .put(CodegenConstants.USE_DATETIME_OFFSET, "true") + .put(CodegenConstants.USE_COLLECTION, "false") + .put(CodegenConstants.RETURN_ICOLLECTION, "false") + .build(); + } + + @Override + public boolean isServer() { + return true; + } +} From 4145f2d76a4fa70cb5b2332005cb2553ea59e00a Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 16 May 2016 16:25:17 +0200 Subject: [PATCH 02/64] Introducing service interface and some validation. --- .../languages/NancyFXServerCodegen.java | 2 +- .../src/main/resources/nancyfx/api.mustache | 67 +++++++++---------- .../main/resources/nancyfx/bodyParam.mustache | 2 +- .../main/resources/nancyfx/formParam.mustache | 2 +- .../resources/nancyfx/headerParam.mustache | 2 +- .../src/main/resources/nancyfx/model.mustache | 9 --- .../main/resources/nancyfx/pathParam.mustache | 2 +- .../resources/nancyfx/queryParam.mustache | 2 +- 8 files changed, 39 insertions(+), 49 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 029f46ed1b50..a6a021407a46 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -122,6 +122,6 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { } // Converts, for example, PUT to HttpPut for controller attributes - operation.httpMethod = "Http" + operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); + operation.httpMethod = operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); } } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index e9c5c919898f..d29b750c9e5a 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -1,45 +1,44 @@ using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.IO; -using System.Linq; -using System.Net; -using System.Threading.Tasks; -using Microsoft.AspNet.Mvc; -using Newtonsoft.Json; -using Swashbuckle.SwaggerGen.Annotations; +using Nancy; using {{packageName}}.Models; -namespace {{packageName}}.Controllers +namespace {{packageName}}.Api { {{#operations}} - /// - /// {{description}} - /// {{#description}}{{#basePath}} - [Route("{{basePath}}")] - {{/basePath}}[Description("{{description}}")]{{/description}} - public class {{classname}}Controller : Controller - { {{#operation}} - /// - /// {{#summary}}{{summary}}{{/summary}} - /// - {{#notes}}/// {{notes}}{{/notes}}{{#allParams}} - /// {{description}}{{/allParams}}{{#responses}} - /// {{message}}{{/responses}} - [{{httpMethod}}] - [Route("{{path}}")] - [SwaggerOperation("{{operationId}}")]{{#returnType}} - [SwaggerResponse(200, type: typeof({{&returnType}}))]{{/returnType}} - public {{#returnType}}IActionResult{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) - { {{#returnType}} - string exampleJson = null; - {{#isListCollection}}{{>listReturn}}{{/isListCollection}}{{^isListCollection}}{{#isMapContainer}}{{>mapReturn}}{{/isMapContainer}}{{^isMapContainer}}{{>objectReturn}}{{/isMapContainer}}{{/isListCollection}} - {{!TODO: defaultResponse, examples, auth, consumes, produces, nickname, externalDocs, imports, security}} - return new ObjectResult(example);{{/returnType}}{{^returnType}} - throw new NotImplementedException();{{/returnType}} + public sealed class {{classname}}Module : NancyModule + { + public {{classname}}Module({{classname}}Service service) : base("") + { {{#operation}} + {{httpMethod}}["{{path}}"] = parameters => + { + // existence validation of obligatory parameters + {{#allParams}}{{#required}} + if (parameters.{{paramName}} == null) { + throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}}{{/allParams}} + {{#allParams}}{{#isBodyParam}} + {{&dataType}} {{paramName}} = Bind<{{&dataType}}>(); + {{/isBodyParam}}{{#isPathParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isPathParam}}{{#isHeaderParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isHeaderParam}}{{#isQueryParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isQueryParam}}{{/allParams}} + return service.{{operationId}}( + {{#allParams}} + {{paramName}}{{#hasMore}},{{/hasMore}} + {{/allParams}} + ); + }; +{{/operation}} } + } + + interface {{classname}}Service + { {{#operation}} + public {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{/operation}} } + {{/operations}} } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache index 02b0fa1d2dea..0d354f2365ed 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache @@ -1 +1 @@ -{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file +{{#isBodyParam}}{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache index 1e743e1e4c73..1a15c1d76394 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache @@ -1 +1 @@ -{{#isFormParam}}[FromForm]{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file +{{#isFormParam}}{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache index e61cadb11315..86bb66082301 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache @@ -1 +1 @@ -{{#isHeaderParam}}[FromHeader]{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file +{{#isHeaderParam}}{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 08aaed01f3db..7df65b03b410 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -69,15 +69,6 @@ namespace {{packageName}}.Models return sb.ToString(); } - /// - /// Returns the JSON string presentation of the object - /// - /// JSON string presentation of the object - public {{#parent}} new {{/parent}}string ToJson() - { - return JsonConvert.SerializeObject(this, Formatting.Indented); - } - /// /// Returns true if objects are equal /// diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache index 5aa27eb4cb3e..5139812e1eff 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache @@ -1 +1 @@ -{{#isPathParam}}[FromRoute]{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file +{{#isPathParam}}{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache index 42ce87a2b7fe..8af670122a85 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache @@ -1 +1 @@ -{{#isQueryParam}}[FromQuery]{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file +{{#isQueryParam}}{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file From 37e76f4c682e4bfc174905d0b86a17994e2f1051 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 16 May 2016 10:49:24 +0200 Subject: [PATCH 03/64] Main files of nancyfx generator. --- .../languages/NancyFXServerCodegen.java | 127 +++++++++++++++ .../services/io.swagger.codegen.CodegenConfig | 1 + .../main/resources/nancyfx/Project.mustache | 54 ++++++ .../main/resources/nancyfx/Solution.mustache | 25 +++ .../src/main/resources/nancyfx/api.mustache | 45 +++++ .../main/resources/nancyfx/bodyParam.mustache | 1 + .../main/resources/nancyfx/formParam.mustache | 1 + .../resources/nancyfx/headerParam.mustache | 1 + .../resources/nancyfx/listReturn.mustache | 4 + .../main/resources/nancyfx/mapReturn.mustache | 4 + .../src/main/resources/nancyfx/model.mustache | 154 ++++++++++++++++++ .../resources/nancyfx/objectReturn.mustache | 4 + .../main/resources/nancyfx/pathParam.mustache | 1 + .../resources/nancyfx/queryParam.mustache | 1 + .../src/main/resources/nancyfx/tags.mustache | 1 + .../options/NancyFXServerOptionsProvider.java | 35 ++++ 16 files changed, 459 insertions(+) create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/api.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/model.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache create mode 100644 modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java new file mode 100644 index 000000000000..029f46ed1b50 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -0,0 +1,127 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.CodegenOperation; +import io.swagger.codegen.CodegenType; +import io.swagger.codegen.SupportingFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Arrays; + +public class NancyFXServerCodegen extends AbstractCSharpCodegen { + + protected String sourceFolder = "src" + File.separator + packageName; + protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}"; + + @SuppressWarnings("hiding") + protected Logger LOGGER = LoggerFactory.getLogger(NancyFXServerCodegen.class); + + public NancyFXServerCodegen() { + super(); + + outputFolder = "generated-code" + File.separator + this.getName(); + + modelTemplateFiles.put("model.mustache", ".cs"); + apiTemplateFiles.put("api.mustache", ".cs"); + + // contextually reserved words + setReservedWordsLowerCase( + Arrays.asList("var", "async", "await", "dynamic", "yield") + ); + + cliOptions.clear(); + + // CLI options + addOption(CodegenConstants.PACKAGE_NAME, + "C# package name (convention: Title.Case).", + this.packageName); + + addOption(CodegenConstants.PACKAGE_VERSION, + "C# package version.", + this.packageVersion); + + addOption(CodegenConstants.SOURCE_FOLDER, + CodegenConstants.SOURCE_FOLDER_DESC, + sourceFolder); + + // CLI Switches + addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, + CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC, + this.sortParamsByRequiredFlag); + + addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE, + CodegenConstants.OPTIONAL_PROJECT_FILE_DESC, + this.optionalProjectFileFlag); + + addSwitch(CodegenConstants.USE_DATETIME_OFFSET, + CodegenConstants.USE_DATETIME_OFFSET_DESC, + this.useDateTimeOffsetFlag); + + addSwitch(CodegenConstants.USE_COLLECTION, + CodegenConstants.USE_COLLECTION_DESC, + this.useCollection); + + addSwitch(CodegenConstants.RETURN_ICOLLECTION, + CodegenConstants.RETURN_ICOLLECTION_DESC, + this.returnICollection); + } + + @Override + public CodegenType getTag() { + return CodegenType.SERVER; + } + + @Override + public String getName() { + return "nancyfx"; + } + + @Override + public String getHelp() { + return "Generates a NancyFX Web API server."; + } + + @Override + public void processOpts() { + super.processOpts(); + + String packageFolder = sourceFolder + File.separator + packageName; + apiPackage = packageName + ".Api"; + modelPackage = packageName + ".Models"; + + if (optionalProjectFileFlag) { + supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); + supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder, packageName + ".csproj")); + } + additionalProperties.put("packageGuid", packageGuid); + } + + @Override + public String apiFileFolder() { + return outputFolder + File.separator + sourceFolder + File.separator + "Api"; + } + + @Override + public String modelFileFolder() { + return outputFolder + File.separator + sourceFolder + File.separator + "Models"; + } + + @Override + protected void processOperation(CodegenOperation operation) { + super.processOperation(operation); + + // HACK: Unlikely in the wild, but we need to clean operation paths for MVC Routing + if (operation.path != null) { + String original = operation.path; + operation.path = operation.path.replace("?", "/"); + if (!original.equals(operation.path)) { + LOGGER.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source."); + } + } + + // Converts, for example, PUT to HttpPut for controller attributes + operation.httpMethod = "Http" + operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); + } +} 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 f0d0fde5e576..868922a6ddf8 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 @@ -16,6 +16,7 @@ io.swagger.codegen.languages.JavascriptClientCodegen io.swagger.codegen.languages.JavascriptClosureAngularClientCodegen io.swagger.codegen.languages.JavaJerseyServerCodegen io.swagger.codegen.languages.JMeterCodegen +io.swagger.codegen.languages.NancyFXServerCodegen io.swagger.codegen.languages.NodeJSServerCodegen io.swagger.codegen.languages.ObjcClientCodegen io.swagger.codegen.languages.PerlClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache new file mode 100644 index 000000000000..3a753d150f6b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -0,0 +1,54 @@ + + + + Debug + AnyCPU + {{packageGuid}} + Library + Properties + {{packageTitle}} + {{packageTitle}} + {{^supportsUWP}} + {{targetFramework}} + {{/supportsUWP}} + {{#supportsUWP}} + UAP + 10.0.10240.0 + 10.0.10240.0 + 14 + {{/supportsUWP}} + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache new file mode 100644 index 000000000000..7f2d34e366ea --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Solution.mustache @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +VisualStudioVersion = 12.0.0.0 +MinimumVisualStudioVersion = 10.0.0.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{packageName}}", "src\{{packageName}}\{{packageName}}.csproj", "{{packageGuid}}" +EndProject +Global +GlobalSection(SolutionConfigurationPlatforms) = preSolution +Debug|Any CPU = Debug|Any CPU +Release|Any CPU = Release|Any CPU +EndGlobalSection +GlobalSection(ProjectConfigurationPlatforms) = postSolution +{{packageGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{{packageGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU +{{packageGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU +{{packageGuid}}.Release|Any CPU.Build.0 = Release|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU +EndGlobalSection +GlobalSection(SolutionProperties) = preSolution +HideSolutionNode = FALSE +EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache new file mode 100644 index 000000000000..e9c5c919898f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNet.Mvc; +using Newtonsoft.Json; +using Swashbuckle.SwaggerGen.Annotations; +using {{packageName}}.Models; + +namespace {{packageName}}.Controllers +{ {{#operations}} + /// + /// {{description}} + /// {{#description}}{{#basePath}} + [Route("{{basePath}}")] + {{/basePath}}[Description("{{description}}")]{{/description}} + public class {{classname}}Controller : Controller + { {{#operation}} + + /// + /// {{#summary}}{{summary}}{{/summary}} + /// + {{#notes}}/// {{notes}}{{/notes}}{{#allParams}} + /// {{description}}{{/allParams}}{{#responses}} + /// {{message}}{{/responses}} + [{{httpMethod}}] + [Route("{{path}}")] + [SwaggerOperation("{{operationId}}")]{{#returnType}} + [SwaggerResponse(200, type: typeof({{&returnType}}))]{{/returnType}} + public {{#returnType}}IActionResult{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + { {{#returnType}} + string exampleJson = null; + {{#isListCollection}}{{>listReturn}}{{/isListCollection}}{{^isListCollection}}{{#isMapContainer}}{{>mapReturn}}{{/isMapContainer}}{{^isMapContainer}}{{>objectReturn}}{{/isMapContainer}}{{/isListCollection}} + {{!TODO: defaultResponse, examples, auth, consumes, produces, nickname, externalDocs, imports, security}} + return new ObjectResult(example);{{/returnType}}{{^returnType}} + throw new NotImplementedException();{{/returnType}} + } +{{/operation}} + } +{{/operations}} +} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache new file mode 100644 index 000000000000..02b0fa1d2dea --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache new file mode 100644 index 000000000000..1e743e1e4c73 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache @@ -0,0 +1 @@ +{{#isFormParam}}[FromForm]{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache new file mode 100644 index 000000000000..e61cadb11315 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}[FromHeader]{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache new file mode 100644 index 000000000000..d609e67148c2 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache @@ -0,0 +1,4 @@ + + var example = exampleJson != null + ? JsonConvert.DeserializeObject<{{returnContainer}}<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson) + : Enumerable.Empty<{{#returnType}}{{{returnType}}}{{/returnType}}>(); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache new file mode 100644 index 000000000000..856fb1b3507c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache @@ -0,0 +1,4 @@ + + var example = exampleJson != null + ? JsonConvert.DeserializeObject>(exampleJson) + : new Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>(); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache new file mode 100644 index 000000000000..08aaed01f3db --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -0,0 +1,154 @@ +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; + +{{#models}} +{{#model}} +namespace {{packageName}}.Models +{ + /// + /// {{description}} + /// + public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + { + /// + /// Initializes a new instance of the class. + /// +{{#vars}} /// {{#description}}{{description}}{{/description}}{{^description}}{{name}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}. +{{/vars}} + public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) + { + {{#vars}}{{#required}}// to ensure "{{name}}" is required (not null) + if ({{name}} == null) + { + throw new InvalidDataException("{{name}} is a required property for {{classname}} and cannot be null"); + } + else + { + this.{{name}} = {{name}}; + } + {{/required}}{{/vars}}{{#vars}}{{^required}}{{#defaultValue}}// use default value if no "{{name}}" provided + if ({{name}} == null) + { + this.{{name}} = {{{defaultValue}}}; + } + else + { + this.{{name}} = {{name}}; + } + {{/defaultValue}}{{^defaultValue}}this.{{name}} = {{name}}; + {{/defaultValue}}{{/required}}{{/vars}} + } + + {{#vars}} + /// + /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}} + /// {{#description}} + /// {{{description}}}{{/description}} + public {{{datatype}}} {{name}} { get; set; } + + {{/vars}} + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + 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(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public {{#parent}} new {{/parent}}string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals(({{classname}})obj); + } + + /// + /// Returns true if {{classname}} instances are equal + /// + /// Instance of {{classname}} to be compared + /// Boolean + public bool Equals({{classname}} other) + { + + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return {{#vars}}{{#isNotContainer}} + ( + this.{{name}} == other.{{name}} || + this.{{name}} != null && + this.{{name}}.Equals(other.{{name}}) + ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{^isNotContainer}} + ( + this.{{name}} == other.{{name}} || + this.{{name}} != null && + this.{{name}}.SequenceEqual(other.{{name}}) + ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}}; + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + // credit: http://stackoverflow.com/a/263416/677735 + unchecked // Overflow is fine, just wrap + { + int hash = 41; + // Suitable nullity checks etc, of course :) + {{#vars}} + if (this.{{name}} != null) + hash = hash * 59 + this.{{name}}.GetHashCode(); + {{/vars}} + return hash; + } + } + + #region Operators + + public static bool operator ==({{classname}} left, {{classname}} right) + { + return Equals(left, right); + } + + public static bool operator !=({{classname}} left, {{classname}} right) + { + return !Equals(left, right); + } + + #endregion Operators + + } +{{/model}} +{{/models}} +} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache new file mode 100644 index 000000000000..4059a61ac0b8 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache @@ -0,0 +1,4 @@ + + var example = exampleJson != null + ? JsonConvert.DeserializeObject<{{#returnType}}{{{returnType}}}{{/returnType}}>(exampleJson) + : default({{#returnType}}{{{returnType}}}{{/returnType}}); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache new file mode 100644 index 000000000000..5aa27eb4cb3e --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache @@ -0,0 +1 @@ +{{#isPathParam}}[FromRoute]{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache new file mode 100644 index 000000000000..42ce87a2b7fe --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}[FromQuery]{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache new file mode 100644 index 000000000000..c97df19949e6 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache @@ -0,0 +1 @@ +{{!TODO: Need iterable tags object...}}{{#tags}}, Tags = new[] { {{/tags}}"{{#tags}}{{tag}} {{/tags}}"{{#tags}} }{{/tags}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java new file mode 100644 index 000000000000..e24df8847138 --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java @@ -0,0 +1,35 @@ +package io.swagger.codegen.options; + +import com.google.common.collect.ImmutableMap; +import io.swagger.codegen.CodegenConstants; + +import java.util.Map; + +public class NancyFXServerOptionsProvider implements OptionsProvider { + public static final String PACKAGE_NAME_VALUE = "swagger_server_nancyfx"; + public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT"; + public static final String SOURCE_FOLDER_VALUE = "src_nancyfx"; + + @Override + public String getLanguage() { + return "nancyfx"; + } + + @Override + public Map createOptions() { + ImmutableMap.Builder builder = new ImmutableMap.Builder(); + return builder.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE) + .put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE) + .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE) + .put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true") + .put(CodegenConstants.USE_DATETIME_OFFSET, "true") + .put(CodegenConstants.USE_COLLECTION, "false") + .put(CodegenConstants.RETURN_ICOLLECTION, "false") + .build(); + } + + @Override + public boolean isServer() { + return true; + } +} From 874509a5922c204718697232e8bea31b59ccf512 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 16 May 2016 16:25:17 +0200 Subject: [PATCH 04/64] Introducing service interface and some validation. --- .../languages/NancyFXServerCodegen.java | 2 +- .../src/main/resources/nancyfx/api.mustache | 67 +++++++++---------- .../main/resources/nancyfx/bodyParam.mustache | 2 +- .../main/resources/nancyfx/formParam.mustache | 2 +- .../resources/nancyfx/headerParam.mustache | 2 +- .../src/main/resources/nancyfx/model.mustache | 9 --- .../main/resources/nancyfx/pathParam.mustache | 2 +- .../resources/nancyfx/queryParam.mustache | 2 +- 8 files changed, 39 insertions(+), 49 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 029f46ed1b50..a6a021407a46 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -122,6 +122,6 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { } // Converts, for example, PUT to HttpPut for controller attributes - operation.httpMethod = "Http" + operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); + operation.httpMethod = operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); } } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index e9c5c919898f..d29b750c9e5a 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -1,45 +1,44 @@ using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.IO; -using System.Linq; -using System.Net; -using System.Threading.Tasks; -using Microsoft.AspNet.Mvc; -using Newtonsoft.Json; -using Swashbuckle.SwaggerGen.Annotations; +using Nancy; using {{packageName}}.Models; -namespace {{packageName}}.Controllers +namespace {{packageName}}.Api { {{#operations}} - /// - /// {{description}} - /// {{#description}}{{#basePath}} - [Route("{{basePath}}")] - {{/basePath}}[Description("{{description}}")]{{/description}} - public class {{classname}}Controller : Controller - { {{#operation}} - /// - /// {{#summary}}{{summary}}{{/summary}} - /// - {{#notes}}/// {{notes}}{{/notes}}{{#allParams}} - /// {{description}}{{/allParams}}{{#responses}} - /// {{message}}{{/responses}} - [{{httpMethod}}] - [Route("{{path}}")] - [SwaggerOperation("{{operationId}}")]{{#returnType}} - [SwaggerResponse(200, type: typeof({{&returnType}}))]{{/returnType}} - public {{#returnType}}IActionResult{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) - { {{#returnType}} - string exampleJson = null; - {{#isListCollection}}{{>listReturn}}{{/isListCollection}}{{^isListCollection}}{{#isMapContainer}}{{>mapReturn}}{{/isMapContainer}}{{^isMapContainer}}{{>objectReturn}}{{/isMapContainer}}{{/isListCollection}} - {{!TODO: defaultResponse, examples, auth, consumes, produces, nickname, externalDocs, imports, security}} - return new ObjectResult(example);{{/returnType}}{{^returnType}} - throw new NotImplementedException();{{/returnType}} + public sealed class {{classname}}Module : NancyModule + { + public {{classname}}Module({{classname}}Service service) : base("") + { {{#operation}} + {{httpMethod}}["{{path}}"] = parameters => + { + // existence validation of obligatory parameters + {{#allParams}}{{#required}} + if (parameters.{{paramName}} == null) { + throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}}{{/allParams}} + {{#allParams}}{{#isBodyParam}} + {{&dataType}} {{paramName}} = Bind<{{&dataType}}>(); + {{/isBodyParam}}{{#isPathParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isPathParam}}{{#isHeaderParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isHeaderParam}}{{#isQueryParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isQueryParam}}{{/allParams}} + return service.{{operationId}}( + {{#allParams}} + {{paramName}}{{#hasMore}},{{/hasMore}} + {{/allParams}} + ); + }; +{{/operation}} } + } + + interface {{classname}}Service + { {{#operation}} + public {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{/operation}} } + {{/operations}} } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache index 02b0fa1d2dea..0d354f2365ed 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache @@ -1 +1 @@ -{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file +{{#isBodyParam}}{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache index 1e743e1e4c73..1a15c1d76394 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache @@ -1 +1 @@ -{{#isFormParam}}[FromForm]{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file +{{#isFormParam}}{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache index e61cadb11315..86bb66082301 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache @@ -1 +1 @@ -{{#isHeaderParam}}[FromHeader]{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file +{{#isHeaderParam}}{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 08aaed01f3db..7df65b03b410 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -69,15 +69,6 @@ namespace {{packageName}}.Models return sb.ToString(); } - /// - /// Returns the JSON string presentation of the object - /// - /// JSON string presentation of the object - public {{#parent}} new {{/parent}}string ToJson() - { - return JsonConvert.SerializeObject(this, Formatting.Indented); - } - /// /// Returns true if objects are equal /// diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache index 5aa27eb4cb3e..5139812e1eff 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache @@ -1 +1 @@ -{{#isPathParam}}[FromRoute]{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file +{{#isPathParam}}{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache index 42ce87a2b7fe..8af670122a85 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache @@ -1 +1 @@ -{{#isQueryParam}}[FromQuery]{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file +{{#isQueryParam}}{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file From 12fc1332a4002f692fe9b485fff281c1d632c14a Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 16 May 2016 17:20:07 +0200 Subject: [PATCH 05/64] NancyFX generation script. --- bin/windows/nancyfx-petstore-server.bat | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 bin/windows/nancyfx-petstore-server.bat diff --git a/bin/windows/nancyfx-petstore-server.bat b/bin/windows/nancyfx-petstore-server.bat new file mode 100644 index 000000000000..72af10287ce8 --- /dev/null +++ b/bin/windows/nancyfx-petstore-server.bat @@ -0,0 +1,10 @@ +set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar + +If Not Exist %executable% ( + mvn clean package +) + +set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties +set ags=generate -t modules\swagger-codegen\src\main\resources\nancyfx -i modules\swagger-codegen\src\test\resources\2_0\petstore.json -l nancyfx -o samples\server\petstore\nancyfx\ + +java %JAVA_OPTS% -jar %executable% %ags% From 3a2cbd890482f6b3b67100dc27574a3847c3c8d6 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Tue, 17 May 2016 12:58:50 +0200 Subject: [PATCH 06/64] Added nuget packages, handling empty return types and fixes. --- .../languages/NancyFXServerCodegen.java | 3 + .../resources/nancyfx/ApiException.mustache | 49 ++++++ .../main/resources/nancyfx/Project.mustache | 139 +++++++++++------- .../src/main/resources/nancyfx/api.mustache | 29 ++-- .../src/main/resources/nancyfx/model.mustache | 53 +------ .../nancyfx/packages.config.mustache | 12 ++ 6 files changed, 173 insertions(+), 112 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index a6a021407a46..90104d5b05d1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -91,6 +91,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { apiPackage = packageName + ".Api"; modelPackage = packageName + ".Models"; + supportingFiles.add(new SupportingFile("ApiException.mustache", sourceFolder, "ApiException.cs")); + supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder, "packages.config")); + if (optionalProjectFileFlag) { supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder, packageName + ".csproj")); diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache new file mode 100644 index 000000000000..6bc23093a873 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache @@ -0,0 +1,49 @@ +using System; + +namespace {{packageName}}.Api +{ + /// + /// API Exception + /// + public class ApiException : Exception + { + /// + /// Gets or sets the error code (HTTP status code) + /// + /// The error code (HTTP status code). + public int ErrorCode { get; set; } + + /// + /// Gets or sets the error content (body json object) + /// + /// The error content (Http response body). + public {{#supportsAsync}}dynamic{{/supportsAsync}}{{^supportsAsync}}object{{/supportsAsync}} ErrorContent { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + public ApiException() {} + + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// Error message. + public ApiException(int errorCode, string message) : base(message) + { + this.ErrorCode = errorCode; + } + + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// Error message. + /// Error content. + public ApiException(int errorCode, string message, {{#supportsAsync}}dynamic{{/supportsAsync}}{{^supportsAsync}}object{{/supportsAsync}} errorContent = null) : base(message) + { + this.ErrorCode = errorCode; + this.ErrorContent = errorContent; + } + } +} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index 3a753d150f6b..fb2a115d4df5 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -1,54 +1,93 @@ - - Debug - AnyCPU - {{packageGuid}} - Library - Properties - {{packageTitle}} - {{packageTitle}} - {{^supportsUWP}} - {{targetFramework}} - {{/supportsUWP}} - {{#supportsUWP}} - UAP - 10.0.10240.0 - 10.0.10240.0 - 14 - {{/supportsUWP}} - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - + + Debug + AnyCPU + {{packageGuid}} + Library + Properties + {{packageTitle}} + {{packageTitle}} + {{^supportsUWP}} + v4.5 + {{/supportsUWP}} + {{#supportsUWP}} + UAP + 10.0.10240.0 + 10.0.10240.0 + 14 + {{/supportsUWP}} + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Nancy.1.3.0\lib\net40\Nancy.dll + True + + + ..\..\packages\Nancy.Authentication.Token.1.3.0\lib\net40\Nancy.Authentication.Token.dll + True + + + ..\..\packages\Nancy.Hosting.Aspnet.1.3.0\lib\net40\Nancy.Hosting.Aspnet.dll + True + + + ..\..\packages\Nancy.Metadata.Modules.1.3.0\lib\net40\Nancy.Metadata.Modules.dll + True + + + ..\..\packages\Nancy.Serialization.JsonNet.1.3.0\lib\net40\Nancy.Serialization.JsonNet.dll + True + + + ..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + + + ..\..\packages\NodaTime.1.3.1\lib\net35-Client\NodaTime.dll + True + + + ..\..\packages\Sharpility.1.2.1\lib\net45\Sharpility.dll + True + + + ..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + True + + + + + + + + + + + + + + + + + diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index d29b750c9e5a..3c4ba5309b0d 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -1,6 +1,7 @@ -using System; -using System.IO; using Nancy; +using Nancy.ModelBinding; +using System.Collections.Generic; +using Sharpility.Net; using {{packageName}}.Models; namespace {{packageName}}.Api @@ -11,32 +12,28 @@ namespace {{packageName}}.Api public {{classname}}Module({{classname}}Service service) : base("") { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => - { - // existence validation of obligatory parameters - {{#allParams}}{{#required}} + { {{#allParams}}{{#required}} if (parameters.{{paramName}} == null) { throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); } - {{/required}}{{/allParams}} - {{#allParams}}{{#isBodyParam}} - {{&dataType}} {{paramName}} = Bind<{{&dataType}}>(); - {{/isBodyParam}}{{#isPathParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; - {{/isPathParam}}{{#isHeaderParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; - {{/isHeaderParam}}{{#isQueryParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; - {{/isQueryParam}}{{/allParams}} - return service.{{operationId}}( + {{/required}}{{/allParams}}{{#allParams}}{{#isBodyParam}} + var {{paramName}} = this.Bind<{{&dataType}}>(); + {{/isBodyParam}}{{^isBodyParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isBodyParam}}{{/allParams}} + {{#returnType}}return {{/returnType}}service.{{operationId}}( {{#allParams}} {{paramName}}{{#hasMore}},{{/hasMore}} {{/allParams}} - ); + );{{^returnType}} + return new Response { ContentType = "{{produces.0.mediaType}}"};{{/returnType}} }; {{/operation}} } } - interface {{classname}}Service + public interface {{classname}}Service { {{#operation}} - public {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{/operation}} } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 7df65b03b410..ab15150cad8f 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -1,12 +1,8 @@ using System; -using System.Linq; +using System.Collections.Generic; using System.IO; using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Runtime.Serialization; -using Newtonsoft.Json; +using Sharpility.Extensions; {{#models}} {{#model}} @@ -15,7 +11,7 @@ namespace {{packageName}}.Models /// /// {{description}} /// - public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + public class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { /// /// Initializes a new instance of the class. @@ -61,12 +57,7 @@ namespace {{packageName}}.Models /// String presentation of the object 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(); + return this.PropertiesToString(); } /// @@ -76,10 +67,7 @@ namespace {{packageName}}.Models /// Boolean public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals(({{classname}})obj); + return this.EqualsByProperties(obj); } /// @@ -89,21 +77,7 @@ namespace {{packageName}}.Models /// Boolean public bool Equals({{classname}} other) { - - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - return {{#vars}}{{#isNotContainer}} - ( - this.{{name}} == other.{{name}} || - this.{{name}} != null && - this.{{name}}.Equals(other.{{name}}) - ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{^isNotContainer}} - ( - this.{{name}} == other.{{name}} || - this.{{name}} != null && - this.{{name}}.SequenceEqual(other.{{name}}) - ){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}false{{/vars}}; + return this.Equals((object) other); } /// @@ -112,21 +86,10 @@ namespace {{packageName}}.Models /// Hash code public override int GetHashCode() { - // credit: http://stackoverflow.com/a/263416/677735 - unchecked // Overflow is fine, just wrap - { - int hash = 41; - // Suitable nullity checks etc, of course :) - {{#vars}} - if (this.{{name}} != null) - hash = hash * 59 + this.{{name}}.GetHashCode(); - {{/vars}} - return hash; - } + return this.PropertiesHash(); } #region Operators - public static bool operator ==({{classname}} left, {{classname}} right) { return Equals(left, right); @@ -136,9 +99,7 @@ namespace {{packageName}}.Models { return !Equals(left, right); } - #endregion Operators - } {{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache new file mode 100644 index 000000000000..5267cce16e12 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file From e30e1d9a9ece606c691338e56038efcf7748e9ce Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 17 May 2016 13:01:16 +0200 Subject: [PATCH 07/64] RequestExceptions utility class template for NancyFx Fixed package name to case-sensitive in GoClientOptionsTest, GoModelTest, LumenServerOptionsTest and SpringBootServerOptionsTest --- .../languages/NancyFXServerCodegen.java | 3 - .../nancyfx/requestExtensions.mustache | 153 ++++++++++++++++++ .../codegen/go/GoClientOptionsTest.java | 4 +- .../io/swagger/codegen/go/GoModelTest.java | 2 +- .../codegen/lumen/LumenServerOptionsTest.java | 2 +- .../SpringBootServerOptionsTest.java | 4 +- 6 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index a6a021407a46..bf0767d2b055 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -19,8 +19,6 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { protected Logger LOGGER = LoggerFactory.getLogger(NancyFXServerCodegen.class); public NancyFXServerCodegen() { - super(); - outputFolder = "generated-code" + File.separator + this.getName(); modelTemplateFiles.put("model.mustache", ".cs"); @@ -87,7 +85,6 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { public void processOpts() { super.processOpts(); - String packageFolder = sourceFolder + File.separator + packageName; apiPackage = packageName + ".Api"; modelPackage = packageName + ".Models"; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache new file mode 100644 index 000000000000..c4c86127b8fe --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache @@ -0,0 +1,153 @@ + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using Nancy; +using Sharpility.Base; +using Sharpility.Extensions; +using Sharpility.Util; + +namespace {{packageName}} +{ + internal static class RequestExtensions + { + private static readonly IDictionary> Parsers = CreateParsers(); + + internal static TParam QueryParam(this Request source, string name) + { + Preconditions.IsNotNull(source, () => new NullReferenceException("source")); + return QueryParam(source, name, default(TParam), useDefault: false); + } + + internal static TParam QueryParam(this Request source, string name, TParam defaultValue) + { + Preconditions.IsNotNull(source, () => new NullReferenceException("source")); + return QueryParam(source, name, default(TParam), useDefault: true); + } + + private static TParam QueryParam(Request request, string name, TParam defaultValue, bool useDefault) + { + var parameterType = typeof (TParam); + var nullable = default(TParam) == null; + var parser = Parsers.GetIfPresent(parameterType); + if (parser == null) + { + return TryParseUsingDynamic(request, name, defaultValue); + } + string value = request.Query[name]; + if (string.IsNullOrEmpty(value)) + { + Preconditions.Evaluate(nullable || (defaultValue != null && useDefault), () => + new ArgumentException(Strings.Format("Query: '{0}' value was not specified", name))); + return defaultValue; + } + var result = parser(Parameter.Of(name, value)); + try + { + return (TParam) result; + } + catch (InvalidCastException) + { + throw new InvalidOperationException(Strings.Format( + "Unexpected result type: '{0}' for query: '{1}' expected: '{2}'", + result.GetType(), name, parameterType)); + } + } + + private static TParam TryParseUsingDynamic(Request request, string name, TParam defaultValue) + { + string value = request.Query[name]; + try + { + TParam result = request.Query[name]; + return result != null ? result : defaultValue; + } + catch (Exception) + { + throw new InvalidOperationException(Strings.Format("Query: '{0}' value: '{1}' could not be parsed. " + + "Expected type: '{2}' is not supported", + name, value, typeof(TParam))); + } + } + + private static IDictionary> CreateParsers() + { + var parsers = ImmutableDictionary.CreateBuilder>(); + parsers.Put(typeof(bool), SafeParse(bool.Parse)); + parsers.Put(typeof(bool?), SafeParse(bool.Parse)); + parsers.Put(typeof(byte), SafeParse(byte.Parse)); + parsers.Put(typeof(sbyte?), SafeParse(sbyte.Parse)); + parsers.Put(typeof(short), SafeParse(short.Parse)); + parsers.Put(typeof(short?), SafeParse(short.Parse)); + parsers.Put(typeof(ushort), SafeParse(ushort.Parse)); + parsers.Put(typeof(ushort?), SafeParse(ushort.Parse)); + parsers.Put(typeof(int), SafeParse(int.Parse)); + parsers.Put(typeof(int?), SafeParse(int.Parse)); + parsers.Put(typeof(uint), SafeParse(uint.Parse)); + parsers.Put(typeof(uint?), SafeParse(uint.Parse)); + parsers.Put(typeof(long), SafeParse(long.Parse)); + parsers.Put(typeof(long?), SafeParse(long.Parse)); + parsers.Put(typeof(ulong), SafeParse(ulong.Parse)); + parsers.Put(typeof(ulong?), SafeParse(ulong.Parse)); + parsers.Put(typeof(float), SafeParse(float.Parse)); + parsers.Put(typeof(float?), SafeParse(float.Parse)); + parsers.Put(typeof(double), SafeParse(double.Parse)); + parsers.Put(typeof(double?), SafeParse(double.Parse)); + parsers.Put(typeof(decimal), SafeParse(decimal.Parse)); + parsers.Put(typeof(decimal?), SafeParse(decimal.Parse)); + parsers.Put(typeof(DateTime), SafeParse(DateTime.Parse)); + parsers.Put(typeof(DateTime?), SafeParse(DateTime.Parse)); + parsers.Put(typeof(TimeSpan), SafeParse(TimeSpan.Parse)); + parsers.Put(typeof(TimeSpan?), SafeParse(TimeSpan.Parse)); + return parsers.ToImmutableDictionary(); + } + + private static Func SafeParse(Func parse) + { + return parameter => + { + try + { + return parse(parameter.Value); + } + catch (OverflowException) + { + throw ParameterOutOfRange(parameter, typeof (short)); + } + catch (FormatException) + { + throw InvalidParameterFormat(parameter, typeof (short)); + } + }; + } + + private static ArgumentException ParameterOutOfRange(Parameter parameter, Type type) + { + return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", + parameter.Name, parameter.Value, type)); + } + + private static ArgumentException InvalidParameterFormat(Parameter parameter, Type type) + { + return new ArgumentException(Strings.Format("Query '{0}' value: '{1}' format is invalid for: '{2}'", + parameter.Name, parameter.Value, type)); + } + + private class Parameter + { + internal string Name { get; private set; } + internal string Value { get; private set; } + + private Parameter(string name, string value) + { + Name = name; + Value = value; + } + + internal static Parameter Of(string name, string value) + { + return new Parameter(name, value); + } + } + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoClientOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoClientOptionsTest.java index 528666c58e52..5baf4f9eb1cd 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoClientOptionsTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoClientOptionsTest.java @@ -1,4 +1,4 @@ -package io.swagger.codegen.Go; +package io.swagger.codegen.go; import io.swagger.codegen.AbstractOptionsTest; import io.swagger.codegen.CodegenConfig; @@ -29,7 +29,7 @@ public class GoClientOptionsTest extends AbstractOptionsTest { clientCodegen.setPackageVersion(GoClientOptionsProvider.PACKAGE_VERSION_VALUE); times = 1; clientCodegen.setPackageName(GoClientOptionsProvider.PACKAGE_NAME_VALUE); - times = 1; + times = 1; }}; } } diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoModelTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoModelTest.java index 83fa8d6437e4..ce9646398f08 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoModelTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/go/GoModelTest.java @@ -1,4 +1,4 @@ -package io.swagger.codegen.Go; +package io.swagger.codegen.go; import io.swagger.codegen.CodegenModel; import io.swagger.codegen.CodegenProperty; diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java index 71d9b3942f19..dcb89d263cc6 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lumen/LumenServerOptionsTest.java @@ -1,4 +1,4 @@ -package io.swagger.codegen.slim; +package io.swagger.codegen.lumen; import io.swagger.codegen.AbstractOptionsTest; import io.swagger.codegen.CodegenConfig; diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/springboot/SpringBootServerOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/springboot/SpringBootServerOptionsTest.java index a7ecdd9d9744..7228f119711e 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/springboot/SpringBootServerOptionsTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/springboot/SpringBootServerOptionsTest.java @@ -1,4 +1,4 @@ -package io.swagger.codegen.springBoot; +package io.swagger.codegen.springboot; import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.java.JavaClientOptionsTest; @@ -54,7 +54,7 @@ public class SpringBootServerOptionsTest extends JavaClientOptionsTest { times = 1; clientCodegen.setBasePackage(SpringBootServerOptionsProvider.BASE_PACKAGE_VALUE); times = 1; - + }}; } } From 1a670391ed93f16379a505b97aa7f1acc87c9864 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Tue, 17 May 2016 15:33:36 +0200 Subject: [PATCH 08/64] Respecting packageName option. --- .../codegen/languages/NancyFXServerCodegen.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 435e4fe38df4..f6e0f35833eb 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -12,7 +12,6 @@ import java.util.Arrays; public class NancyFXServerCodegen extends AbstractCSharpCodegen { - protected String sourceFolder = "src" + File.separator + packageName; protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}"; @SuppressWarnings("hiding") @@ -88,24 +87,29 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { apiPackage = packageName + ".Api"; modelPackage = packageName + ".Models"; - supportingFiles.add(new SupportingFile("ApiException.mustache", sourceFolder, "ApiException.cs")); - supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder, "packages.config")); + supportingFiles.add(new SupportingFile("ApiException.mustache", sourceFolder(), "ApiException.cs")); + supportingFiles.add(new SupportingFile("RequestExtensions.mustache", sourceFolder(), "RequestExtensions.cs")); + supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder(), "packages.config")); if (optionalProjectFileFlag) { supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); - supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder, packageName + ".csproj")); + supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder(), packageName + ".csproj")); } additionalProperties.put("packageGuid", packageGuid); } + private String sourceFolder() { + return "src" + File.separator + packageName; + } + @Override public String apiFileFolder() { - return outputFolder + File.separator + sourceFolder + File.separator + "Api"; + return outputFolder + File.separator + sourceFolder() + File.separator + "Api"; } @Override public String modelFileFolder() { - return outputFolder + File.separator + sourceFolder + File.separator + "Models"; + return outputFolder + File.separator + sourceFolder() + File.separator + "Models"; } @Override From 123a44125736edbea2875342acbdf84ecbdbacb4 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Wed, 18 May 2016 14:23:17 +0200 Subject: [PATCH 09/64] NancyFX: - Utility methods for obtaining value from header and path parameter added to requestExtensions.mustache template - Added support of parsing arrays (IEnumerable, ICollection, IList, List, ISet, Set, HashSet) for query, header and path parameters --- .../nancyfx/requestExtensions.mustache | 256 ++++++++++++++++-- 1 file changed, 240 insertions(+), 16 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache index c4c86127b8fe..d3ef4828b9c4 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using Nancy; using Sharpility.Base; using Sharpility.Extensions; @@ -15,26 +16,77 @@ namespace {{packageName}} internal static TParam QueryParam(this Request source, string name) { - Preconditions.IsNotNull(source, () => new NullReferenceException("source")); return QueryParam(source, name, default(TParam), useDefault: false); } internal static TParam QueryParam(this Request source, string name, TParam defaultValue) { - Preconditions.IsNotNull(source, () => new NullReferenceException("source")); - return QueryParam(source, name, default(TParam), useDefault: true); + return QueryParam(source, name, defaultValue, useDefault: true); } - private static TParam QueryParam(Request request, string name, TParam defaultValue, bool useDefault) + internal static THeader HeaderValue(this Request source, string name) { - var parameterType = typeof (TParam); - var nullable = default(TParam) == null; - var parser = Parsers.GetIfPresent(parameterType); + return HeaderValue(source, name, default(THeader), useDefault: false); + } + + internal static THeader HeaderValue(this Request source, string name, THeader defaultValue) + { + return HeaderValue(source, name, defaultValue, useDefault: true); + } + + internal static TPathParam PathParam(dynamic parameters, string name) + { + return PathParam(parameters, name, default(TPathParam), useDefault: false); + } + + internal static TPathParam PathParam(dynamic parameters, string name, TPathParam defaultValue) + { + return PathParam(parameters, name, defaultValue, useDefault: true); + } + + private static TParam QueryParam(Request source, string name, TParam defaultValue, bool useDefault) + { + Preconditions.IsNotNull(source, () => new NullReferenceException("source")); + var valueType = typeof(TParam); + var parser = Parsers.GetIfPresent(valueType); if (parser == null) { - return TryParseUsingDynamic(request, name, defaultValue); + return TryParseUsingDynamic(source.Query, name, defaultValue); } - string value = request.Query[name]; + string value = source.Query[name]; + return ValueOf(name, value, defaultValue, useDefault, parser); + } + + private static THeader HeaderValue(Request source, string name, THeader defaultValue, bool useDefault) + { + Preconditions.IsNotNull(source, () => new NullReferenceException("source")); + var valueType = typeof(THeader); + var values = source.Headers[name]; + var parser = Parsers.GetIfPresent(valueType); + var value = values != null ? string.Join(",", values) : null; + Preconditions.IsNotNull(parser, () => new InvalidOperationException( + Strings.Format("Header: '{0}' value: '{1}' could not be parsed. Expected type: '{2}' is not supported", + name, value, valueType))); + return ValueOf(name, value, defaultValue, useDefault, parser); + + } + + private static TPathParam PathParam(dynamic parameters, string name, TPathParam defaultValue, bool useDefault) + { + var valueType = typeof(TPathParam); + var parser = Parsers.GetIfPresent(valueType); + if (parser == null) + { + return TryParseUsingDynamic(parameters, name, defaultValue); + } + string value = parameters[name]; + return ValueOf(name, value, defaultValue, useDefault, parser); + } + + private static TValue ValueOf(string name, string value, TValue defaultValue, bool useDefault, Func parser) + { + var valueType = typeof(TValue); + var nullable = default(TValue) == null; if (string.IsNullOrEmpty(value)) { Preconditions.Evaluate(nullable || (defaultValue != null && useDefault), () => @@ -44,35 +96,36 @@ namespace {{packageName}} var result = parser(Parameter.Of(name, value)); try { - return (TParam) result; + return (TValue)result; } catch (InvalidCastException) { throw new InvalidOperationException(Strings.Format( "Unexpected result type: '{0}' for query: '{1}' expected: '{2}'", - result.GetType(), name, parameterType)); + result.GetType(), name, valueType)); } } - private static TParam TryParseUsingDynamic(Request request, string name, TParam defaultValue) + private static TValue TryParseUsingDynamic(dynamic parameters, string name, TValue defaultValue) { - string value = request.Query[name]; + string value = parameters[name]; try { - TParam result = request.Query[name]; + TValue result = parameters[name]; return result != null ? result : defaultValue; } catch (Exception) { - throw new InvalidOperationException(Strings.Format("Query: '{0}' value: '{1}' could not be parsed. " + + throw new InvalidOperationException(Strings.Format("Parameter: '{0}' value: '{1}' could not be parsed. " + "Expected type: '{2}' is not supported", - name, value, typeof(TParam))); + name, value, typeof(TValue))); } } private static IDictionary> CreateParsers() { var parsers = ImmutableDictionary.CreateBuilder>(); + parsers.Put(typeof(string), value => value); parsers.Put(typeof(bool), SafeParse(bool.Parse)); parsers.Put(typeof(bool?), SafeParse(bool.Parse)); parsers.Put(typeof(byte), SafeParse(byte.Parse)); @@ -99,6 +152,109 @@ namespace {{packageName}} parsers.Put(typeof(DateTime?), SafeParse(DateTime.Parse)); parsers.Put(typeof(TimeSpan), SafeParse(TimeSpan.Parse)); parsers.Put(typeof(TimeSpan?), SafeParse(TimeSpan.Parse)); + + parsers.Put(typeof(IEnumerable), value => value); + parsers.Put(typeof(ICollection), value => value); + parsers.Put(typeof(IList), value => value); + parsers.Put(typeof(List), value => value); + parsers.Put(typeof(ISet), value => value); + parsers.Put(typeof(HashSet), value => value); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(bool.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(bool.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(bool.Parse)); + parsers.Put(typeof(List), ListParse(bool.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(bool.Parse)); + parsers.Put(typeof(HashSet), SetParse(bool.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(byte.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(byte.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(byte.Parse)); + parsers.Put(typeof(List), ListParse(byte.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(byte.Parse)); + parsers.Put(typeof(HashSet), SetParse(byte.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(sbyte.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(sbyte.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(sbyte.Parse)); + parsers.Put(typeof(List), ListParse(sbyte.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(sbyte.Parse)); + parsers.Put(typeof(HashSet), SetParse(sbyte.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(short.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(short.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(short.Parse)); + parsers.Put(typeof(List), ListParse(short.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(short.Parse)); + parsers.Put(typeof(HashSet), SetParse(short.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(ushort.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(ushort.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(ushort.Parse)); + parsers.Put(typeof(List), ListParse(ushort.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(ushort.Parse)); + parsers.Put(typeof(HashSet), SetParse(ushort.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(int.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(int.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(int.Parse)); + parsers.Put(typeof(List), ListParse(int.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(int.Parse)); + parsers.Put(typeof(HashSet), SetParse(int.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(uint.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(uint.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(uint.Parse)); + parsers.Put(typeof(List), ListParse(uint.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(uint.Parse)); + parsers.Put(typeof(HashSet), SetParse(uint.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(long.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(long.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(long.Parse)); + parsers.Put(typeof(List), ListParse(long.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(long.Parse)); + parsers.Put(typeof(HashSet), SetParse(long.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(ulong.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(ulong.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(ulong.Parse)); + parsers.Put(typeof(List), ListParse(ulong.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(ulong.Parse)); + parsers.Put(typeof(HashSet), SetParse(ulong.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(float.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(float.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(float.Parse)); + parsers.Put(typeof(List), ListParse(float.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(float.Parse)); + parsers.Put(typeof(HashSet), SetParse(float.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(double.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(double.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(double.Parse)); + parsers.Put(typeof(List), ListParse(double.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(double.Parse)); + parsers.Put(typeof(HashSet), SetParse(double.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(decimal.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(decimal.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(decimal.Parse)); + parsers.Put(typeof(List), ListParse(decimal.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(decimal.Parse)); + parsers.Put(typeof(HashSet), SetParse(decimal.Parse)); + + + parsers.Put(typeof(IEnumerable), ImmutableListParse(DateTime.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(DateTime.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(DateTime.Parse)); + parsers.Put(typeof(List), ListParse(DateTime.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(DateTime.Parse)); + parsers.Put(typeof(HashSet), SetParse(DateTime.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(TimeSpan.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(TimeSpan.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(TimeSpan.Parse)); + parsers.Put(typeof(List), ListParse(TimeSpan.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(TimeSpan.Parse)); + parsers.Put(typeof(HashSet), SetParse(TimeSpan.Parse)); + return parsers.ToImmutableDictionary(); } @@ -121,6 +277,74 @@ namespace {{packageName}} }; } + private static Func ListParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return new List(); + } + var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToList(); + return results; + }; + } + + private static Func ImmutableListParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return Lists.EmptyList(); + } + var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToImmutableList(); + return results; + }; + } + + private static Func SetParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return new HashSet(); + } + var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToSet(); + return results; + }; + } + + private static Func ImmutableSetParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return Sets.EmptySet(); + } + var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToImmutableHashSet(); + return results; + }; + } + private static ArgumentException ParameterOutOfRange(Parameter parameter, Type type) { return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", From 806e22deb58db67c9bcf2cfc8846f91911b3e1a3 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Wed, 18 May 2016 14:54:40 +0200 Subject: [PATCH 10/64] NancyFx: Template for immutable model classes with builders --- .../src/main/resources/nancyfx/model.mustache | 122 +++++++++--------- 1 file changed, 64 insertions(+), 58 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index ab15150cad8f..036e423a628e 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -8,88 +8,43 @@ using Sharpility.Extensions; {{#model}} namespace {{packageName}}.Models { - /// - /// {{description}} - /// public class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { - /// - /// Initializes a new instance of the class. - /// -{{#vars}} /// {{#description}}{{description}}{{/description}}{{^description}}{{name}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}. -{{/vars}} - public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) - { - {{#vars}}{{#required}}// to ensure "{{name}}" is required (not null) - if ({{name}} == null) - { - throw new InvalidDataException("{{name}} is a required property for {{classname}} and cannot be null"); - } - else - { - this.{{name}} = {{name}}; - } - {{/required}}{{/vars}}{{#vars}}{{^required}}{{#defaultValue}}// use default value if no "{{name}}" provided - if ({{name}} == null) - { - this.{{name}} = {{{defaultValue}}}; - } - else - { - this.{{name}} = {{name}}; - } - {{/defaultValue}}{{^defaultValue}}this.{{name}} = {{name}}; - {{/defaultValue}}{{/required}}{{/vars}} - } - {{#vars}} - /// - /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}} - /// {{#description}} - /// {{{description}}}{{/description}} - public {{{datatype}}} {{name}} { get; set; } - + public {{{datatype}}} {{name}} { get; private set; } {{/vars}} - /// - /// Returns the string presentation of the object - /// - /// String presentation of the object + public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) + { + {{#vars}} + this.{{name}} = {{name}}; + {{/vars}} + } + + public static {{classname}}Builder Builder() { + return new {{classname}}Builder(); + } + public override string ToString() { return this.PropertiesToString(); } - /// - /// Returns true if objects are equal - /// - /// Object to be compared - /// Boolean public override bool Equals(object obj) { return this.EqualsByProperties(obj); } - /// - /// Returns true if {{classname}} instances are equal - /// - /// Instance of {{classname}} to be compared - /// Boolean public bool Equals({{classname}} other) { return this.Equals((object) other); } - /// - /// Gets the hash code - /// - /// Hash code public override int GetHashCode() { return this.PropertiesHash(); } - #region Operators public static bool operator ==({{classname}} left, {{classname}} right) { return Equals(left, right); @@ -99,7 +54,58 @@ namespace {{packageName}}.Models { return !Equals(left, right); } - #endregion Operators + + public sealed class {{classname}}Builder + { + {{#vars}} + private {{{datatype}}} _{{name}}; + {{/vars}} + + internal {{classname}}Builder() + { + SetupDefaults(); + } + + private void SetupDefaults() + { + {{#vars}} + {{^required}} + {{#defaultValue}} + _{{name}} = {{{defaultValue}}}; + {{/defaultValue}} + {{/^required}} + {{/vars}} + } + + {{#vars}} + public {{classname}}Builder {{name}}({{{datatype}}} value) + { + _{{name}} = value; + return this; + } + + {{/vars}} + + public {{classname}} Build() + { + Validate(); + return new {{classname}}( + {{#vars}} + {{name}}: _{{name}}{{#hasMore}},{{/hasMore}} + {{/vars}} + ); + } + + private void Validate() + { + {{#vars}}{{#required}} + if ({{name}} == null) + { + throw new ArgumentException("{{name}} is a required property for {{classname}} and cannot be null"); + } + {{/required}}{{/vars}} + } + } } {{/model}} {{/models}} From cdb9ab826e94f1fb705ab03c5287121e18c20a64 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Wed, 18 May 2016 14:59:16 +0200 Subject: [PATCH 11/64] Fix of model template. --- .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 036e423a628e..bfbdc13e63f2 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -73,7 +73,7 @@ namespace {{packageName}}.Models {{#defaultValue}} _{{name}} = {{{defaultValue}}}; {{/defaultValue}} - {{/^required}} + {{/required}} {{/vars}} } From 6564df79de90411ffb10392c7a55ec4c9015e38b Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Wed, 18 May 2016 15:03:47 +0200 Subject: [PATCH 12/64] NancyFx: With() method added for model classes --- .../src/main/resources/nancyfx/model.mustache | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index bfbdc13e63f2..757310bd2165 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -8,7 +8,7 @@ using Sharpility.Extensions; {{#model}} namespace {{packageName}}.Models { - public class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}} public {{{datatype}}} {{name}} { get; private set; } @@ -21,10 +21,19 @@ namespace {{packageName}}.Models {{/vars}} } - public static {{classname}}Builder Builder() { + public static {{classname}}Builder Builder() + { return new {{classname}}Builder(); } + public {{classname}}Builder With() + { + return Builder() + {{#vars}} + .{{name}}({{name}}) + {{/vars}}; + } + public override string ToString() { return this.PropertiesToString(); From dba662da59a047f862734274bc516ce64d11b776 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Wed, 18 May 2016 15:09:39 +0200 Subject: [PATCH 13/64] Code formatting. --- .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 757310bd2165..5d0b6cca24b2 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -30,8 +30,8 @@ namespace {{packageName}}.Models { return Builder() {{#vars}} - .{{name}}({{name}}) - {{/vars}}; + .{{name}}({{name}}) +{{/vars}} ; } public override string ToString() From f5f5a359e0d7beb76ac56ad4213b8cbdbbefe35a Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Thu, 19 May 2016 08:59:29 +0200 Subject: [PATCH 14/64] Fix of model builder validation method. --- .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 5d0b6cca24b2..1ee08ce7d701 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -108,7 +108,7 @@ namespace {{packageName}}.Models private void Validate() { {{#vars}}{{#required}} - if ({{name}} == null) + if ({{_name}} == null) { throw new ArgumentException("{{name}} is a required property for {{classname}} and cannot be null"); } From be44df44a5f7479ea374635210d9c3d69f5bd0c1 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Thu, 19 May 2016 09:08:02 +0200 Subject: [PATCH 15/64] Fix of model builder validation method. --- .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 1ee08ce7d701..e0a965b6c9e7 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -108,7 +108,7 @@ namespace {{packageName}}.Models private void Validate() { {{#vars}}{{#required}} - if ({{_name}} == null) + if (_{{name}} == null) { throw new ArgumentException("{{name}} is a required property for {{classname}} and cannot be null"); } From 8f2523c4480870171b7a7d4511ce2fb6be309e86 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Thu, 19 May 2016 14:41:47 +0200 Subject: [PATCH 16/64] Generation of enum types for parameters and properties. --- .../languages/NancyFXServerCodegen.java | 26 ++++++++++++++++--- .../resources/nancyfx/ApiException.mustache | 2 +- .../src/main/resources/nancyfx/api.mustache | 7 +++-- .../main/resources/nancyfx/innerEnum.mustache | 1 + .../src/main/resources/nancyfx/model.mustache | 9 +++++-- 5 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index f6e0f35833eb..b426ea6d07c4 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -84,8 +84,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { public void processOpts() { super.processOpts(); - apiPackage = packageName + ".Api"; - modelPackage = packageName + ".Models"; + apiPackage = packageName + ".Module"; + modelPackage = packageName + ".Model"; supportingFiles.add(new SupportingFile("ApiException.mustache", sourceFolder(), "ApiException.cs")); supportingFiles.add(new SupportingFile("RequestExtensions.mustache", sourceFolder(), "RequestExtensions.cs")); @@ -104,12 +104,12 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { @Override public String apiFileFolder() { - return outputFolder + File.separator + sourceFolder() + File.separator + "Api"; + return outputFolder + File.separator + sourceFolder() + File.separator + "Module"; } @Override public String modelFileFolder() { - return outputFolder + File.separator + sourceFolder() + File.separator + "Models"; + return outputFolder + File.separator + sourceFolder() + File.separator + "Model"; } @Override @@ -128,4 +128,22 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { // Converts, for example, PUT to HttpPut for controller attributes operation.httpMethod = operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); } + + @Override + public String toEnumVarName(String name, String datatype) { + String enumName = sanitizeName(name); + + enumName = enumName.replaceFirst("^_", ""); + enumName = enumName.replaceFirst("_$", ""); + + enumName = camelize(enumName); + + LOGGER.info("toEnumVarName = " + enumName); + + if (enumName.matches("\\d.*")) { // starts with number + return "_" + enumName; + } else { + return enumName; + } + } } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache index 6bc23093a873..ce6787e2d7b0 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache @@ -1,6 +1,6 @@ using System; -namespace {{packageName}}.Api +namespace {{packageName}}.Module { /// /// API Exception diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 3c4ba5309b0d..6360602423c1 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -2,10 +2,13 @@ using Nancy; using Nancy.ModelBinding; using System.Collections.Generic; using Sharpility.Net; -using {{packageName}}.Models; +using {{packageName}}.Model; -namespace {{packageName}}.Api +namespace {{packageName}}.Module { {{#operations}} + {{#operation}}{{#allParams}}{{#isEnum}} + {{>innerEnum}} + {{/isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache new file mode 100644 index 000000000000..e856bdbae0d2 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache @@ -0,0 +1 @@ +public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index e0a965b6c9e7..9f327cecdda1 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -6,11 +6,13 @@ using Sharpility.Extensions; {{#models}} {{#model}} -namespace {{packageName}}.Models +namespace {{packageName}}.Model { public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { - {{#vars}} + {{#vars}}{{#isEnum}} + {{>innerEnum}} + {{/isEnum}}{{/vars}}{{#vars}} public {{{datatype}}} {{name}} { get; private set; } {{/vars}} @@ -64,6 +66,9 @@ namespace {{packageName}}.Models return !Equals(left, right); } + /// + /// Builder of {{classname}} model + /// public sealed class {{classname}}Builder { {{#vars}} From e7781d0d9126b8b3dd0f88bd7d3bdae8879f9b14 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Thu, 19 May 2016 15:06:08 +0200 Subject: [PATCH 17/64] Handling enum properties and nullability. --- .../src/main/resources/nancyfx/api.mustache | 2 +- .../src/main/resources/nancyfx/bodyParam.mustache | 1 - .../src/main/resources/nancyfx/formParam.mustache | 1 - .../src/main/resources/nancyfx/headerParam.mustache | 1 - .../src/main/resources/nancyfx/model.mustache | 8 ++++---- .../src/main/resources/nancyfx/nullableDataType.mustache | 1 + .../src/main/resources/nancyfx/pathParam.mustache | 1 - .../src/main/resources/nancyfx/queryParam.mustache | 1 - 8 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 6360602423c1..0ef00cf111ce 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -36,7 +36,7 @@ namespace {{packageName}}.Module public interface {{classname}}Service { {{#operation}} - {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{&dataType}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{/operation}} } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache deleted file mode 100644 index 0d354f2365ed..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/bodyParam.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isBodyParam}}{{&dataType}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache deleted file mode 100644 index 1a15c1d76394..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/formParam.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isFormParam}}{{&dataType}} {{paramName}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache deleted file mode 100644 index 86bb66082301..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/headerParam.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isHeaderParam}}{{&dataType}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 9f327cecdda1..8510fe2e9616 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -13,10 +13,10 @@ namespace {{packageName}}.Model {{#vars}}{{#isEnum}} {{>innerEnum}} {{/isEnum}}{{/vars}}{{#vars}} - public {{{datatype}}} {{name}} { get; private set; } + public {{>nullableDataType}} {{name}} { get; private set; } {{/vars}} - public {{classname}}({{#vars}}{{{datatype}}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) + public {{classname}}({{#vars}}{{>nullableDataType}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) { {{#vars}} this.{{name}} = {{name}}; @@ -72,7 +72,7 @@ namespace {{packageName}}.Model public sealed class {{classname}}Builder { {{#vars}} - private {{{datatype}}} _{{name}}; + private {{>nullableDataType}} _{{name}}; {{/vars}} internal {{classname}}Builder() @@ -92,7 +92,7 @@ namespace {{packageName}}.Model } {{#vars}} - public {{classname}}Builder {{name}}({{{datatype}}} value) + public {{classname}}Builder {{name}}({{>nullableDataType}} value) { _{{name}} = value; return this; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache new file mode 100644 index 000000000000..c999b870119e --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache @@ -0,0 +1 @@ +{{&datatypeWithEnum}}{{#isEnum}}?{{/isEnum}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache deleted file mode 100644 index 5139812e1eff..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/pathParam.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isPathParam}}{{&dataType}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache deleted file mode 100644 index 8af670122a85..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/queryParam.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isQueryParam}}{{&dataType}} {{paramName}}{{/isQueryParam}} \ No newline at end of file From 0005faf77d70097c8c660a0141b95aaab8bf0ce2 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Fri, 20 May 2016 10:43:40 +0200 Subject: [PATCH 18/64] Handling collections of enumerables. --- .../src/main/resources/nancyfx/api.mustache | 6 +++--- .../src/main/resources/nancyfx/innerEnum.mustache | 2 +- .../src/main/resources/nancyfx/model.mustache | 11 ++++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 0ef00cf111ce..57c5e96b841a 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -6,9 +6,9 @@ using {{packageName}}.Model; namespace {{packageName}}.Module { {{#operations}} - {{#operation}}{{#allParams}}{{#isEnum}} - {{>innerEnum}} - {{/isEnum}}{{/allParams}}{{/operation}} + {{#operation}}{{#allParams}}{{#isEnum}}{{>innerEnum}} + {{/isEnum}}{{#items.isEnum}}{{#items}}{{>innerEnum}}{{/items}} + {{/items.isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache index e856bdbae0d2..19e4731f2cf4 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache @@ -1 +1 @@ -public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file +public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 8510fe2e9616..a8c6ed3f54cd 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -11,8 +11,9 @@ namespace {{packageName}}.Model public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}}{{#isEnum}} - {{>innerEnum}} - {{/isEnum}}{{/vars}}{{#vars}} + {{>innerEnum}}{{/isEnum}}{{#items.isEnum}} + {{#items}}{{>innerEnum}}{{/items}} + {{/items.isEnum}}{{/vars}}{{#vars}} public {{>nullableDataType}} {{name}} { get; private set; } {{/vars}} @@ -33,7 +34,7 @@ namespace {{packageName}}.Model return Builder() {{#vars}} .{{name}}({{name}}) -{{/vars}} ; +{{/vars}} ; } public override string ToString() @@ -56,12 +57,12 @@ namespace {{packageName}}.Model return this.PropertiesHash(); } - public static bool operator ==({{classname}} left, {{classname}} right) + public static bool operator == ({{classname}} left, {{classname}} right) { return Equals(left, right); } - public static bool operator !=({{classname}} left, {{classname}} right) + public static bool operator != ({{classname}} left, {{classname}} right) { return !Equals(left, right); } From eaddc18537364a165f20101550a380cc475df7c9 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Fri, 20 May 2016 14:22:48 +0200 Subject: [PATCH 19/64] Switching from custom exception to System.ArgumentException. --- .../languages/NancyFXServerCodegen.java | 1 - .../resources/nancyfx/ApiException.mustache | 49 ------------------- .../src/main/resources/nancyfx/api.mustache | 6 +-- .../src/main/resources/nancyfx/model.mustache | 9 ++-- .../nancyfx/requestExtensions.mustache | 1 - 5 files changed, 6 insertions(+), 60 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index b426ea6d07c4..37f3b66cdf36 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -87,7 +87,6 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { apiPackage = packageName + ".Module"; modelPackage = packageName + ".Model"; - supportingFiles.add(new SupportingFile("ApiException.mustache", sourceFolder(), "ApiException.cs")); supportingFiles.add(new SupportingFile("RequestExtensions.mustache", sourceFolder(), "RequestExtensions.cs")); supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder(), "packages.config")); diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache deleted file mode 100644 index ce6787e2d7b0..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/ApiException.mustache +++ /dev/null @@ -1,49 +0,0 @@ -using System; - -namespace {{packageName}}.Module -{ - /// - /// API Exception - /// - public class ApiException : Exception - { - /// - /// Gets or sets the error code (HTTP status code) - /// - /// The error code (HTTP status code). - public int ErrorCode { get; set; } - - /// - /// Gets or sets the error content (body json object) - /// - /// The error content (Http response body). - public {{#supportsAsync}}dynamic{{/supportsAsync}}{{^supportsAsync}}object{{/supportsAsync}} ErrorContent { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public ApiException() {} - - /// - /// Initializes a new instance of the class. - /// - /// HTTP status code. - /// Error message. - public ApiException(int errorCode, string message) : base(message) - { - this.ErrorCode = errorCode; - } - - /// - /// Initializes a new instance of the class. - /// - /// HTTP status code. - /// Error message. - /// Error content. - public ApiException(int errorCode, string message, {{#supportsAsync}}dynamic{{/supportsAsync}}{{^supportsAsync}}object{{/supportsAsync}} errorContent = null) : base(message) - { - this.ErrorCode = errorCode; - this.ErrorContent = errorContent; - } - } -} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 57c5e96b841a..2ce03220f7cf 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -1,3 +1,4 @@ +using System; using Nancy; using Nancy.ModelBinding; using System.Collections.Generic; @@ -7,8 +8,7 @@ using {{packageName}}.Model; namespace {{packageName}}.Module { {{#operations}} {{#operation}}{{#allParams}}{{#isEnum}}{{>innerEnum}} - {{/isEnum}}{{#items.isEnum}}{{#items}}{{>innerEnum}}{{/items}} - {{/items.isEnum}}{{/allParams}}{{/operation}} + {{/isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule { @@ -17,7 +17,7 @@ namespace {{packageName}}.Module {{httpMethod}}["{{path}}"] = parameters => { {{#allParams}}{{#required}} if (parameters.{{paramName}} == null) { - throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + throw new ArgumentException("Missing the required parameter '{{paramName}}' when calling {{operationId}}"); } {{/required}}{{/allParams}}{{#allParams}}{{#isBodyParam}} var {{paramName}} = this.Bind<{{&dataType}}>(); diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index a8c6ed3f54cd..d6b07417ecc9 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -9,13 +9,10 @@ using Sharpility.Extensions; namespace {{packageName}}.Model { public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> - { - {{#vars}}{{#isEnum}} + { {{#vars}}{{#isEnum}} {{>innerEnum}}{{/isEnum}}{{#items.isEnum}} - {{#items}}{{>innerEnum}}{{/items}} - {{/items.isEnum}}{{/vars}}{{#vars}} - public {{>nullableDataType}} {{name}} { get; private set; } - {{/vars}} + {{#items}}{{>innerEnum}}{{/items}}{{/items.isEnum}}{{/vars}}{{#vars}} + public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} public {{classname}}({{#vars}}{{>nullableDataType}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache index d3ef4828b9c4..3725af752304 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache @@ -1,4 +1,3 @@ - using System; using System.Collections.Generic; using System.Collections.Immutable; From f4c3b9ec9f21be6121a77dc699ca3598317829b9 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Fri, 20 May 2016 15:29:53 +0200 Subject: [PATCH 20/64] Fixed operation parameter input enums generation. --- .../swagger-codegen/src/main/resources/nancyfx/api.mustache | 3 +-- .../src/main/resources/nancyfx/innerApiEnum.mustache | 1 + .../nancyfx/{innerEnum.mustache => innerModelEnum.mustache} | 0 .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache rename modules/swagger-codegen/src/main/resources/nancyfx/{innerEnum.mustache => innerModelEnum.mustache} (100%) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 2ce03220f7cf..af38d53a4094 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -7,8 +7,7 @@ using {{packageName}}.Model; namespace {{packageName}}.Module { {{#operations}} - {{#operation}}{{#allParams}}{{#isEnum}}{{>innerEnum}} - {{/isEnum}}{{/allParams}}{{/operation}} + {{#operation}}{{#allParams}}{{#isEnum}}{{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache new file mode 100644 index 000000000000..dbc72cb97e01 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache @@ -0,0 +1 @@ +public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache similarity index 100% rename from modules/swagger-codegen/src/main/resources/nancyfx/innerEnum.mustache rename to modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index d6b07417ecc9..5e4003975b11 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -10,7 +10,7 @@ namespace {{packageName}}.Model { public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}}{{#isEnum}} - {{>innerEnum}}{{/isEnum}}{{#items.isEnum}} + {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} {{#items}}{{>innerEnum}}{{/items}}{{/items.isEnum}}{{/vars}}{{#vars}} public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} From e17b02183b5b67b7bbd8ef879210e6e31d8901a1 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Fri, 20 May 2016 15:56:35 +0200 Subject: [PATCH 21/64] Fix reference to subtemplate. --- .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 5e4003975b11..186d617b76ef 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.Model public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}}{{#isEnum}} {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} - {{#items}}{{>innerEnum}}{{/items}}{{/items.isEnum}}{{/vars}}{{#vars}} + {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}}{{#vars}} public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} public {{classname}}({{#vars}}{{>nullableDataType}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) From 36e94f7ed1dfdfe99f0061c0f79b48f1ad33c0e9 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 23 May 2016 13:40:12 +0200 Subject: [PATCH 22/64] Enumerations on api input. --- modules/swagger-codegen/src/main/resources/nancyfx/api.mustache | 2 +- .../src/main/resources/nancyfx/innerApiEnum.mustache | 2 +- .../src/main/resources/nancyfx/paramsList.mustache | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index af38d53a4094..8a35443f3d43 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -35,7 +35,7 @@ namespace {{packageName}}.Module public interface {{classname}}Service { {{#operation}} - {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{&dataType}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{>paramsList}}); {{/operation}} } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache index dbc72cb97e01..33e93bdd34b5 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache @@ -1 +1 @@ -public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file +public enum {{#datatypeWithEnum}}{{operationId}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache new file mode 100644 index 000000000000..75e21010c739 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache @@ -0,0 +1 @@ +{{#allParams}}{{#isEnum}}{{#datatypeWithEnum}}{{operationId}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{/isEnum}}{{^isEnum}}{{dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file From 9354fc8b0fdc6599566cc5c50f0358b8f53097c1 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 23 May 2016 13:56:28 +0200 Subject: [PATCH 23/64] Retrieving enum params from api request. --- modules/swagger-codegen/src/main/resources/nancyfx/api.mustache | 2 +- .../src/main/resources/nancyfx/innerApiEnum.mustache | 2 +- .../src/main/resources/nancyfx/innerApiEnumName.mustache | 1 + .../src/main/resources/nancyfx/paramsList.mustache | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnumName.mustache diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 8a35443f3d43..fdcd4ff7b9f9 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -20,7 +20,7 @@ namespace {{packageName}}.Module } {{/required}}{{/allParams}}{{#allParams}}{{#isBodyParam}} var {{paramName}} = this.Bind<{{&dataType}}>(); - {{/isBodyParam}}{{^isBodyParam}}{{&dataType}} {{paramName}} = parameters.{{paramName}}; + {{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{dataType}}{{/isEnum}} {{paramName}} = parameters.{{paramName}}; {{/isBodyParam}}{{/allParams}} {{#returnType}}return {{/returnType}}service.{{operationId}}( {{#allParams}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache index 33e93bdd34b5..1bf8ab2efa4d 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache @@ -1 +1 @@ -public enum {{#datatypeWithEnum}}{{operationId}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file +public enum {{>innerApiEnumName}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnumName.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnumName.mustache new file mode 100644 index 000000000000..f54069fb50c3 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnumName.mustache @@ -0,0 +1 @@ +{{#datatypeWithEnum}}{{operationId}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache index 75e21010c739..7317b4512512 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache @@ -1 +1 @@ -{{#allParams}}{{#isEnum}}{{#datatypeWithEnum}}{{operationId}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{/isEnum}}{{^isEnum}}{{dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file +{{#allParams}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file From 04af1cf2a75707aae51719ff712c371195169e89 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 23 May 2016 16:53:01 +0200 Subject: [PATCH 24/64] NancyFx: - Passing Nancy.Request to service interface - Generating AbstractService code - Removed null defaults from constructors in models - Fixed project namespace --- .../main/resources/nancyfx/Project.mustache | 2 +- .../src/main/resources/nancyfx/api.mustache | 55 +++++++++++-------- .../src/main/resources/nancyfx/model.mustache | 8 +-- .../resources/nancyfx/paramsList.mustache | 2 +- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index fb2a115d4df5..ae16f386e984 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -6,7 +6,7 @@ {{packageGuid}} Library Properties - {{packageTitle}} + {{packageName}} {{packageTitle}} {{^supportsUWP}} v4.5 diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index fdcd4ff7b9f9..9cba02edc3a5 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -2,31 +2,25 @@ using System; using Nancy; using Nancy.ModelBinding; using System.Collections.Generic; -using Sharpility.Net; -using {{packageName}}.Model; +using Sharpility.Base; +using {{packageName}}.Models; -namespace {{packageName}}.Module -{ {{#operations}} - {{#operation}}{{#allParams}}{{#isEnum}}{{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} - - public sealed class {{classname}}Module : NancyModule +namespace {{packageName}}.Api +{ +{{#operations}}{{#operation}}{{#allParams}}{{#isEnum}}{{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule { - public {{classname}}Module({{classname}}Service service) : base("") + public {{classname}}Module({{classname}}Service service) + :base("") { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => - { {{#allParams}}{{#required}} - if (parameters.{{paramName}} == null) { - throw new ArgumentException("Missing the required parameter '{{paramName}}' when calling {{operationId}}"); - } - {{/required}}{{/allParams}}{{#allParams}}{{#isBodyParam}} + { + {{#allParams}}{{#isBodyParam}} var {{paramName}} = this.Bind<{{&dataType}}>(); - {{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{dataType}}{{/isEnum}} {{paramName}} = parameters.{{paramName}}; - {{/isBodyParam}}{{/allParams}} - {{#returnType}}return {{/returnType}}service.{{operationId}}( - {{#allParams}} - {{paramName}}{{#hasMore}},{{/hasMore}} - {{/allParams}} - );{{^returnType}} + {{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{&dataType}}{{/isEnum}} {{paramName}} = parameters.{{paramName}};{{#hasMore}} + {{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}} + Preconditions.IsNotNull({{paramName}}, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + {{/required}}{{/allParams}} + {{#returnType}}return {{/returnType}}service.{{operationId}}(Request{{#allParams.0}}, {{/allParams.0}}{{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{^returnType}} return new Response { ContentType = "{{produces.0.mediaType}}"};{{/returnType}} }; {{/operation}} @@ -34,9 +28,24 @@ namespace {{packageName}}.Module } public interface {{classname}}Service - { {{#operation}} - {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{>paramsList}}); -{{/operation}} + { + {{#operation}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(Request request{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}} + + {{/hasMore}}{{/operation}} + } + + public abstract class Abstract{{classname}}Service: {{classname}}Service + { + {{#operation}}public {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(Request request{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) + { + {{#returnType}}return {{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + }{{#hasMore}} + + {{/hasMore}}{{/operation}} + + {{#operation}}protected abstract {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{>paramsList}});{{#hasMore}} + + {{/hasMore}}{{/operation}} } {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 186d617b76ef..b7972357c297 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -6,7 +6,7 @@ using Sharpility.Extensions; {{#models}} {{#model}} -namespace {{packageName}}.Model +namespace {{packageName}}.Models { public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}}{{#isEnum}} @@ -14,7 +14,7 @@ namespace {{packageName}}.Model {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}}{{#vars}} public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} - public {{classname}}({{#vars}}{{>nullableDataType}} {{name}} = null{{#hasMore}}, {{/hasMore}}{{/vars}}) + public {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) { {{#vars}} this.{{name}} = {{name}}; @@ -30,8 +30,8 @@ namespace {{packageName}}.Model { return Builder() {{#vars}} - .{{name}}({{name}}) -{{/vars}} ; + .{{name}}({{name}}){{#hasMore}} +{{/hasMore}}{{/vars}}; } public override string ToString() diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache index 7317b4512512..2883053e86b6 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache @@ -1 +1 @@ -{{#allParams}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file +{{#allParams}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{&dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file From 57aa6d01d23aa58b128d279f96a564cc6d5b7ee3 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 10:14:22 +0200 Subject: [PATCH 25/64] NancyFx: - Using virtual interface implementation in AbstractService - Fixed namespace for module classes - Using Parameters utility for parsing parameters in NancyModule - Excluding obj folder from csproj --- .../languages/NancyFXServerCodegen.java | 87 +++++------- .../main/resources/nancyfx/Project.mustache | 2 +- .../src/main/resources/nancyfx/api.mustache | 11 +- ...xtensions.mustache => parameters.mustache} | 125 ++++++------------ 4 files changed, 83 insertions(+), 142 deletions(-) rename modules/swagger-codegen/src/main/resources/nancyfx/{requestExtensions.mustache => parameters.mustache} (78%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 37f3b66cdf36..3bd66f560da9 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -1,6 +1,5 @@ package io.swagger.codegen.languages; -import io.swagger.codegen.CodegenConstants; import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenType; import io.swagger.codegen.SupportingFile; @@ -8,66 +7,45 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.util.Arrays; + +import static io.swagger.codegen.CodegenConstants.*; +import static io.swagger.codegen.CodegenType.SERVER; +import static java.util.Arrays.asList; +import static java.util.UUID.randomUUID; public class NancyFXServerCodegen extends AbstractCSharpCodegen { + private static final Logger log = LoggerFactory.getLogger(NancyFXServerCodegen.class); - protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase() + "}"; - - @SuppressWarnings("hiding") - protected Logger LOGGER = LoggerFactory.getLogger(NancyFXServerCodegen.class); + private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}"; public NancyFXServerCodegen() { - outputFolder = "generated-code" + File.separator + this.getName(); - + outputFolder = "generated-code" + File.separator + getName(); modelTemplateFiles.put("model.mustache", ".cs"); apiTemplateFiles.put("api.mustache", ".cs"); // contextually reserved words setReservedWordsLowerCase( - Arrays.asList("var", "async", "await", "dynamic", "yield") + asList("var", "async", "await", "dynamic", "yield") ); cliOptions.clear(); // CLI options - addOption(CodegenConstants.PACKAGE_NAME, - "C# package name (convention: Title.Case).", - this.packageName); - - addOption(CodegenConstants.PACKAGE_VERSION, - "C# package version.", - this.packageVersion); - - addOption(CodegenConstants.SOURCE_FOLDER, - CodegenConstants.SOURCE_FOLDER_DESC, - sourceFolder); + addOption(PACKAGE_NAME, "C# package name (convention: Title.Case).", packageName); + addOption(PACKAGE_VERSION, "C# package version.", packageVersion); + addOption(SOURCE_FOLDER, SOURCE_FOLDER_DESC, sourceFolder); // CLI Switches - addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, - CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC, - this.sortParamsByRequiredFlag); - - addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE, - CodegenConstants.OPTIONAL_PROJECT_FILE_DESC, - this.optionalProjectFileFlag); - - addSwitch(CodegenConstants.USE_DATETIME_OFFSET, - CodegenConstants.USE_DATETIME_OFFSET_DESC, - this.useDateTimeOffsetFlag); - - addSwitch(CodegenConstants.USE_COLLECTION, - CodegenConstants.USE_COLLECTION_DESC, - this.useCollection); - - addSwitch(CodegenConstants.RETURN_ICOLLECTION, - CodegenConstants.RETURN_ICOLLECTION_DESC, - this.returnICollection); + addSwitch(SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_BY_REQUIRED_FLAG_DESC, sortParamsByRequiredFlag); + addSwitch(OPTIONAL_PROJECT_FILE, OPTIONAL_PROJECT_FILE_DESC, optionalProjectFileFlag); + addSwitch(USE_DATETIME_OFFSET, USE_DATETIME_OFFSET_DESC, useDateTimeOffsetFlag); + addSwitch(USE_COLLECTION, USE_COLLECTION_DESC, useCollection); + addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection); } @Override public CodegenType getTag() { - return CodegenType.SERVER; + return SERVER; } @Override @@ -84,10 +62,10 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { public void processOpts() { super.processOpts(); - apiPackage = packageName + ".Module"; - modelPackage = packageName + ".Model"; + apiPackage = packageName + ".Modules"; + modelPackage = packageName + ".Models"; - supportingFiles.add(new SupportingFile("RequestExtensions.mustache", sourceFolder(), "RequestExtensions.cs")); + supportingFiles.add(new SupportingFile("parameters.mustache", sourceFile("Utils"), "Parameters.cs")); supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder(), "packages.config")); if (optionalProjectFileFlag) { @@ -101,14 +79,18 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { return "src" + File.separator + packageName; } + private String sourceFile(final String fileName) { + return sourceFolder() + File.separator + fileName; + } + @Override public String apiFileFolder() { - return outputFolder + File.separator + sourceFolder() + File.separator + "Module"; + return outputFolder + File.separator + sourceFolder() + File.separator + "Modules"; } @Override public String modelFileFolder() { - return outputFolder + File.separator + sourceFolder() + File.separator + "Model"; + return outputFolder + File.separator + sourceFolder() + File.separator + "Models"; } @Override @@ -120,7 +102,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { String original = operation.path; operation.path = operation.path.replace("?", "/"); if (!original.equals(operation.path)) { - LOGGER.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source."); + log.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source."); } } @@ -130,14 +112,11 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { @Override public String toEnumVarName(String name, String datatype) { - String enumName = sanitizeName(name); - - enumName = enumName.replaceFirst("^_", ""); - enumName = enumName.replaceFirst("_$", ""); - - enumName = camelize(enumName); - - LOGGER.info("toEnumVarName = " + enumName); + final String enumName = camelize( + sanitizeName(name) + .replaceFirst("^_", "") + .replaceFirst("_$", "")); + log.info("toEnumVarName = " + enumName); if (enumName.matches("\\d.*")) { // starts with number return "_" + enumName; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index ae16f386e984..8d1f652022da 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -83,7 +83,7 @@ - + diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 9cba02edc3a5..537f59000941 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -4,8 +4,9 @@ using Nancy.ModelBinding; using System.Collections.Generic; using Sharpility.Base; using {{packageName}}.Models; +using {{packageName}}.Utils; -namespace {{packageName}}.Api +namespace {{packageName}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}}{{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule { @@ -14,11 +15,9 @@ namespace {{packageName}}.Api { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => { - {{#allParams}}{{#isBodyParam}} - var {{paramName}} = this.Bind<{{&dataType}}>(); - {{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{&dataType}}{{/isEnum}} {{paramName}} = parameters.{{paramName}};{{#hasMore}} + {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}var{{/isEnum}} {{paramName}} = Parameters.ValueOf<{{&dataType}}>(parameters, "{{paramName}}");{{#hasMore}} {{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}} - Preconditions.IsNotNull({{paramName}}, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + Preconditions.IsNotNull({{paramName}}, "Required parameter: '{{paramName}}' is missing at '{{operationId}}'"); {{/required}}{{/allParams}} {{#returnType}}return {{/returnType}}service.{{operationId}}(Request{{#allParams.0}}, {{/allParams.0}}{{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{^returnType}} return new Response { ContentType = "{{produces.0.mediaType}}"};{{/returnType}} @@ -36,7 +35,7 @@ namespace {{packageName}}.Api public abstract class Abstract{{classname}}Service: {{classname}}Service { - {{#operation}}public {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(Request request{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) + {{#operation}}public virtual {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(Request request{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) { {{#returnType}}return {{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); }{{#hasMore}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache similarity index 78% rename from modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache rename to modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 3725af752304..a0b8e326cc8f 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/requestExtensions.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -1,3 +1,4 @@ + using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -7,91 +8,52 @@ using Sharpility.Base; using Sharpility.Extensions; using Sharpility.Util; -namespace {{packageName}} +namespace {{packageName}}.Utils { - internal static class RequestExtensions + internal static class Parameters { private static readonly IDictionary> Parsers = CreateParsers(); - internal static TParam QueryParam(this Request source, string name) + internal static TValue ValueOf(dynamic parameters, string name) { - return QueryParam(source, name, default(TParam), useDefault: false); - } - - internal static TParam QueryParam(this Request source, string name, TParam defaultValue) - { - return QueryParam(source, name, defaultValue, useDefault: true); - } - - internal static THeader HeaderValue(this Request source, string name) - { - return HeaderValue(source, name, default(THeader), useDefault: false); - } - - internal static THeader HeaderValue(this Request source, string name, THeader defaultValue) - { - return HeaderValue(source, name, defaultValue, useDefault: true); - } - - internal static TPathParam PathParam(dynamic parameters, string name) - { - return PathParam(parameters, name, default(TPathParam), useDefault: false); - } - - internal static TPathParam PathParam(dynamic parameters, string name, TPathParam defaultValue) - { - return PathParam(parameters, name, defaultValue, useDefault: true); - } - - private static TParam QueryParam(Request source, string name, TParam defaultValue, bool useDefault) - { - Preconditions.IsNotNull(source, () => new NullReferenceException("source")); - var valueType = typeof(TParam); - var parser = Parsers.GetIfPresent(valueType); - if (parser == null) - { - return TryParseUsingDynamic(source.Query, name, defaultValue); - } - string value = source.Query[name]; - return ValueOf(name, value, defaultValue, useDefault, parser); - } - - private static THeader HeaderValue(Request source, string name, THeader defaultValue, bool useDefault) - { - Preconditions.IsNotNull(source, () => new NullReferenceException("source")); - var valueType = typeof(THeader); - var values = source.Headers[name]; - var parser = Parsers.GetIfPresent(valueType); - var value = values != null ? string.Join(",", values) : null; - Preconditions.IsNotNull(parser, () => new InvalidOperationException( - Strings.Format("Header: '{0}' value: '{1}' could not be parsed. Expected type: '{2}' is not supported", - name, value, valueType))); - return ValueOf(name, value, defaultValue, useDefault, parser); - - } - - private static TPathParam PathParam(dynamic parameters, string name, TPathParam defaultValue, bool useDefault) - { - var valueType = typeof(TPathParam); - var parser = Parsers.GetIfPresent(valueType); - if (parser == null) - { - return TryParseUsingDynamic(parameters, name, defaultValue); - } + var valueType = typeof (TValue); + var isNullable = default(TValue) == null; string value = parameters[name]; - return ValueOf(name, value, defaultValue, useDefault, parser); + Preconditions.Evaluate(!string.IsNullOrEmpty(value) || isNullable, string.Format("Required parameter: '{0}' is missing", name)); + if (valueType.IsEnum) + { + return EnumValueOf(name, value); + } + return ValueOf(parameters, name, value, valueType); } - private static TValue ValueOf(string name, string value, TValue defaultValue, bool useDefault, Func parser) + private static TValue EnumValueOf(string name, string value) { - var valueType = typeof(TValue); - var nullable = default(TValue) == null; - if (string.IsNullOrEmpty(value)) + var values = Enum.GetValues(typeof(TValue)); + foreach (var entry in values) { - Preconditions.Evaluate(nullable || (defaultValue != null && useDefault), () => - new ArgumentException(Strings.Format("Query: '{0}' value was not specified", name))); - return defaultValue; + if (entry.ToString().EqualsIgnoreCases(value) + || ((int) entry).ToString().EqualsIgnoreCases(value)) + { + return (TValue) entry; + } } + throw new ArgumentException(string.Format("Parameter: '{0}' value: '{1}' is not supported. Expected one of: {2}", + name, value, value.ToComparable())); + } + + private static TValue ValueOf(dynamic parameters, string name, string value, Type valueType) + { + var parser = Parsers.GetIfPresent(valueType); + if (parser != null) + { + return ParseValueUsing(name, value, valueType, parser); + } + return DynamicValueOf(parameters, name); + } + + private static TValue ParseValueUsing(string name, string value, Type valueType, Func parser) + { var result = parser(Parameter.Of(name, value)); try { @@ -99,21 +61,22 @@ namespace {{packageName}} } catch (InvalidCastException) { - throw new InvalidOperationException(Strings.Format( - "Unexpected result type: '{0}' for query: '{1}' expected: '{2}'", - result.GetType(), name, valueType)); + throw new InvalidOperationException( + string.Format("Could not parse parameter: '{0}' with value: '{1}'. " + + "Received: '{2}', expected: '{3}'.", + name, value, result.GetType(), valueType)); } } - private static TValue TryParseUsingDynamic(dynamic parameters, string name, TValue defaultValue) + private static TValue DynamicValueOf(dynamic parameters, string name) { string value = parameters[name]; try { TValue result = parameters[name]; - return result != null ? result : defaultValue; + return result; } - catch (Exception) + catch (InvalidCastException) { throw new InvalidOperationException(Strings.Format("Parameter: '{0}' value: '{1}' could not be parsed. " + "Expected type: '{2}' is not supported", @@ -346,7 +309,7 @@ namespace {{packageName}} private static ArgumentException ParameterOutOfRange(Parameter parameter, Type type) { - return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", + return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", parameter.Name, parameter.Value, type)); } From c653aeec0bb643409b6f22f67927d8d428af9f7a Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 10:25:18 +0200 Subject: [PATCH 26/64] NancyFX: - Fixed parsing enum parameters in NancyModule --- .../swagger-codegen/src/main/resources/nancyfx/api.mustache | 5 +++-- .../src/main/resources/nancyfx/model.mustache | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 537f59000941..c70159701aa4 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -8,14 +8,15 @@ using {{packageName}}.Utils; namespace {{packageName}}.Modules { -{{#operations}}{{#operation}}{{#allParams}}{{#isEnum}}{{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} public sealed class {{classname}}Module : NancyModule +{{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} {{>innerApiEnum}}{{/isEnum}}{{/allParams}} +{{/operation}} public sealed class {{classname}}Module : NancyModule { public {{classname}}Module({{classname}}Service service) :base("") { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => { - {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}var{{/isEnum}} {{paramName}} = Parameters.ValueOf<{{&dataType}}>(parameters, "{{paramName}}");{{#hasMore}} + {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}var {{paramName}} = Parameters.ValueOf<{{>innerApiEnumName}}>(parameters, "{{paramName}}");{{/isEnum}}{{^isEnum}}var {{paramName}} = Parameters.ValueOf<{{&dataType}}>(parameters, "{{paramName}}");{{/isEnum}}{{#hasMore}} {{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}} Preconditions.IsNotNull({{paramName}}, "Required parameter: '{{paramName}}' is missing at '{{operationId}}'"); {{/required}}{{/allParams}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index b7972357c297..c2b7e7c43a3a 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -46,7 +46,7 @@ namespace {{packageName}}.Models public bool Equals({{classname}} other) { - return this.Equals((object) other); + return Equals((object) other); } public override int GetHashCode() From ba38a3b6cb26be9cbc3da1236f551dda99517521 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 10:32:09 +0200 Subject: [PATCH 27/64] NancyFx: - Removed "Enum" suffix of Enum class name --- .../io/swagger/codegen/languages/NancyFXServerCodegen.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 3bd66f560da9..df8d6c581a98 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -1,6 +1,7 @@ package io.swagger.codegen.languages; import io.swagger.codegen.CodegenOperation; +import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenType; import io.swagger.codegen.SupportingFile; import org.slf4j.Logger; @@ -124,4 +125,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { return enumName; } } + + @Override + public String toEnumName(CodegenProperty property) { + return sanitizeName(camelize(property.name)) ; + } } From 4b2e3a01f93e319874a4d3d45a3d47f533547e09 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Tue, 24 May 2016 11:31:27 +0200 Subject: [PATCH 28/64] Renaming request dispatcher to Nancy specific Module. --- .../codegen/languages/NancyFXServerCodegen.java | 8 ++++++++ .../src/main/resources/nancyfx/api.mustache | 10 +++++----- .../src/main/resources/nancyfx/listReturn.mustache | 4 ---- .../src/main/resources/nancyfx/mapReturn.mustache | 4 ---- .../src/main/resources/nancyfx/objectReturn.mustache | 4 ---- .../src/main/resources/nancyfx/tags.mustache | 1 - 6 files changed, 13 insertions(+), 18 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache delete mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index df8d6c581a98..c60764942f3b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -126,6 +126,14 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { } } + @Override + public String toApiName(String name) { + if (name.length() == 0) { + return "DefaultModule"; + } + return initialCaps(name) + "Module"; + } + @Override public String toEnumName(CodegenProperty property) { return sanitizeName(camelize(property.name)) ; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index c70159701aa4..ca2224eeba14 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -7,12 +7,12 @@ using {{packageName}}.Models; using {{packageName}}.Utils; namespace {{packageName}}.Modules -{ -{{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} {{>innerApiEnum}}{{/isEnum}}{{/allParams}} -{{/operation}} public sealed class {{classname}}Module : NancyModule +{ {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} + {{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} + + public sealed class {{classname}}Module : NancyModule { - public {{classname}}Module({{classname}}Service service) - :base("") + public {{classname}}Module({{classname}}Service service) : base("") { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache deleted file mode 100644 index d609e67148c2..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/listReturn.mustache +++ /dev/null @@ -1,4 +0,0 @@ - - var example = exampleJson != null - ? JsonConvert.DeserializeObject<{{returnContainer}}<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson) - : Enumerable.Empty<{{#returnType}}{{{returnType}}}{{/returnType}}>(); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache deleted file mode 100644 index 856fb1b3507c..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/mapReturn.mustache +++ /dev/null @@ -1,4 +0,0 @@ - - var example = exampleJson != null - ? JsonConvert.DeserializeObject>(exampleJson) - : new Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>(); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache deleted file mode 100644 index 4059a61ac0b8..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/objectReturn.mustache +++ /dev/null @@ -1,4 +0,0 @@ - - var example = exampleJson != null - ? JsonConvert.DeserializeObject<{{#returnType}}{{{returnType}}}{{/returnType}}>(exampleJson) - : default({{#returnType}}{{{returnType}}}{{/returnType}}); \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache deleted file mode 100644 index c97df19949e6..000000000000 --- a/modules/swagger-codegen/src/main/resources/nancyfx/tags.mustache +++ /dev/null @@ -1 +0,0 @@ -{{!TODO: Need iterable tags object...}}{{#tags}}, Tags = new[] { {{/tags}}"{{#tags}}{{tag}} {{/tags}}"{{#tags}} }{{/tags}} \ No newline at end of file From d0e3b5cc71c7fe9e39cff0caadb704e3b84c1a2c Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Tue, 24 May 2016 13:07:14 +0200 Subject: [PATCH 29/64] Moving enum definition of model lists outside class. --- .../src/main/resources/nancyfx/model.mustache | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index c2b7e7c43a3a..6a3e27de6572 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -7,11 +7,12 @@ using Sharpility.Extensions; {{#models}} {{#model}} namespace {{packageName}}.Models -{ +{ {{#vars}}{{#isEnum}} + {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} + {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} + public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> - { {{#vars}}{{#isEnum}} - {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} - {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}}{{#vars}} + { {{#vars}} public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} public {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) From cef6c9d8baacc242c9ac1d21bfcce6214beac5af Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 14:08:09 +0200 Subject: [PATCH 30/64] NancyFx: - Using NodaTime for date types --- .../languages/NancyFXServerCodegen.java | 20 +++++++++++++++++++ .../src/main/resources/nancyfx/api.mustache | 1 + .../src/main/resources/nancyfx/model.mustache | 1 + 3 files changed, 22 insertions(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index c60764942f3b..4ec80152e32e 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -1,13 +1,17 @@ package io.swagger.codegen.languages; +import com.google.common.collect.ImmutableMap; import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenType; import io.swagger.codegen.SupportingFile; +import io.swagger.models.properties.Property; +import io.swagger.models.properties.StringProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.Map; import static io.swagger.codegen.CodegenConstants.*; import static io.swagger.codegen.CodegenType.SERVER; @@ -42,6 +46,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { addSwitch(USE_DATETIME_OFFSET, USE_DATETIME_OFFSET_DESC, useDateTimeOffsetFlag); addSwitch(USE_COLLECTION, USE_COLLECTION_DESC, useCollection); addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection); + typeMapping.putAll(nodaTimeTypesMappings()); } @Override @@ -138,4 +143,19 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { public String toEnumName(CodegenProperty property) { return sanitizeName(camelize(property.name)) ; } + + @Override + public String getSwaggerType(Property property) { + if (property instanceof StringProperty && "time".equalsIgnoreCase(property.getFormat())) { + return "time"; + } + return super.getSwaggerType(property); + } + + private static Map nodaTimeTypesMappings() { + return ImmutableMap.of( + "time", "LocalTime?", + "date", "ZonedDateTime?", + "datetime", "ZonedDateTime?"); + } } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index ca2224eeba14..6c9eca1d0fd8 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -5,6 +5,7 @@ using System.Collections.Generic; using Sharpility.Base; using {{packageName}}.Models; using {{packageName}}.Utils; +using NodaTime; namespace {{packageName}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 6a3e27de6572..d6cf40c4d7a0 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using Sharpility.Extensions; +using NodaTime; {{#models}} {{#model}} From da3aa7214d24337451297b1a8cc6ab8d57fbd9dc Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 15:17:27 +0200 Subject: [PATCH 31/64] NancyFx: - Fixed Module classes naming (removed double 'Module' suffix) - Using partial classes for generated Nancy modules --- .../swagger/codegen/languages/NancyFXServerCodegen.java | 9 +++++++-- .../src/main/resources/nancyfx/api.mustache | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 4ec80152e32e..9437344b7392 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -134,9 +134,14 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { @Override public String toApiName(String name) { if (name.length() == 0) { - return "DefaultModule"; + return "Default"; } - return initialCaps(name) + "Module"; + return initialCaps(name); + } + + @Override + public String toApiFilename(String name) { + return super.toApiFilename(name) + "Module"; } @Override diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 6c9eca1d0fd8..5ef45be0410a 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} {{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} - public sealed class {{classname}}Module : NancyModule + public partial class {{classname}}Module : NancyModule { public {{classname}}Module({{classname}}Service service) : base("") { {{#operation}} From bc6fcbdc7b46b5b2d804fa8adde60f93313d2c8c Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 16:07:22 +0200 Subject: [PATCH 32/64] NancyFx: - Unnecessary dependencies removal - Nancy version update --- .../main/resources/nancyfx/Project.mustache | 24 ++----------------- .../nancyfx/packages.config.mustache | 7 +----- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index 8d1f652022da..6427c412e952 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -37,28 +37,8 @@ 4 - - ..\..\packages\Nancy.1.3.0\lib\net40\Nancy.dll - True - - - ..\..\packages\Nancy.Authentication.Token.1.3.0\lib\net40\Nancy.Authentication.Token.dll - True - - - ..\..\packages\Nancy.Hosting.Aspnet.1.3.0\lib\net40\Nancy.Hosting.Aspnet.dll - True - - - ..\..\packages\Nancy.Metadata.Modules.1.3.0\lib\net40\Nancy.Metadata.Modules.dll - True - - - ..\..\packages\Nancy.Serialization.JsonNet.1.3.0\lib\net40\Nancy.Serialization.JsonNet.dll - True - - - ..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\..\packages\Nancy.1.4.1\lib\net40\Nancy.dll True diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache index 5267cce16e12..6d8651cdcf40 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache @@ -1,11 +1,6 @@ - - - - - - + From bf68801295c86994ed8ad1ec4e7dc565fed3f9bb Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 24 May 2016 16:19:45 +0200 Subject: [PATCH 33/64] NancyFx: - Passing NancyContext to service instead of Request --- .../swagger-codegen/src/main/resources/nancyfx/api.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 5ef45be0410a..139149408c16 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -21,7 +21,7 @@ namespace {{packageName}}.Modules {{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}} Preconditions.IsNotNull({{paramName}}, "Required parameter: '{{paramName}}' is missing at '{{operationId}}'"); {{/required}}{{/allParams}} - {{#returnType}}return {{/returnType}}service.{{operationId}}(Request{{#allParams.0}}, {{/allParams.0}}{{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{^returnType}} + {{#returnType}}return {{/returnType}}service.{{operationId}}(Context{{#allParams.0}}, {{/allParams.0}}{{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{^returnType}} return new Response { ContentType = "{{produces.0.mediaType}}"};{{/returnType}} }; {{/operation}} @@ -30,14 +30,14 @@ namespace {{packageName}}.Modules public interface {{classname}}Service { - {{#operation}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(Request request{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}} + {{#operation}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}} {{/hasMore}}{{/operation}} } public abstract class Abstract{{classname}}Service: {{classname}}Service { - {{#operation}}public virtual {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(Request request{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) + {{#operation}}public virtual {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) { {{#returnType}}return {{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); }{{#hasMore}} From c59f2b03220885f8fde5a25d47c1d3e12a5410c5 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Wed, 25 May 2016 11:23:11 +0200 Subject: [PATCH 34/64] Versioning of generated model (namespace, base context). --- .../swagger/codegen/languages/NancyFXServerCodegen.java | 7 +++++++ .../src/main/resources/nancyfx/Project.mustache | 2 +- .../src/main/resources/nancyfx/api.mustache | 8 ++++---- .../src/main/resources/nancyfx/model.mustache | 2 +- .../src/main/resources/nancyfx/parameters.mustache | 3 +-- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 9437344b7392..ad04b76cb3eb 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -5,6 +5,7 @@ import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenType; import io.swagger.codegen.SupportingFile; +import io.swagger.models.Swagger; import io.swagger.models.properties.Property; import io.swagger.models.properties.StringProperty; import org.slf4j.Logger; @@ -144,6 +145,12 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { return super.toApiFilename(name) + "Module"; } + @Override + public void preprocessSwagger(Swagger swagger) { + additionalProperties.put("packageContext", sanitizeName(swagger.getBasePath())); + additionalProperties.put("baseContext", swagger.getBasePath()); + } + @Override public String toEnumName(CodegenProperty property) { return sanitizeName(camelize(property.name)) ; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index 6427c412e952..9962800b0cc8 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -6,7 +6,7 @@ {{packageGuid}} Library Properties - {{packageName}} + {{packageName}}.{{packageContext}} {{packageTitle}} {{^supportsUWP}} v4.5 diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 139149408c16..167408e8a365 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -3,17 +3,17 @@ using Nancy; using Nancy.ModelBinding; using System.Collections.Generic; using Sharpility.Base; -using {{packageName}}.Models; -using {{packageName}}.Utils; +using {{packageName}}.{{packageContext}}.Models; +using {{packageName}}.{{packageContext}}.Utils; using NodaTime; -namespace {{packageName}}.Modules +namespace {{packageName}}.{{packageContext}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} {{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} public partial class {{classname}}Module : NancyModule { - public {{classname}}Module({{classname}}Service service) : base("") + public {{classname}}Module({{classname}}Service service) : base("{{baseContext}}") { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index d6cf40c4d7a0..fbb08cec64c6 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -7,7 +7,7 @@ using NodaTime; {{#models}} {{#model}} -namespace {{packageName}}.Models +namespace {{packageName}}.{{packageContext}}.Models { {{#vars}}{{#isEnum}} {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index a0b8e326cc8f..32e615ec2469 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -1,4 +1,3 @@ - using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -8,7 +7,7 @@ using Sharpility.Base; using Sharpility.Extensions; using Sharpility.Util; -namespace {{packageName}}.Utils +namespace {{packageName}}.{{packageContext}}.Utils { internal static class Parameters { From a72640ce9c70bbdcf5131f02dce1092d772ca8b9 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 30 May 2016 10:33:22 +0200 Subject: [PATCH 35/64] NancyFx: - Sealed class for generated Modules - Empty constructor added to model classes - Code cleanup --- .../languages/NancyFXServerCodegen.java | 116 ++++++++++++------ .../src/main/resources/nancyfx/api.mustache | 2 +- .../src/main/resources/nancyfx/model.mustache | 6 + .../options/NancyFXServerOptionsProvider.java | 29 +++-- 4 files changed, 103 insertions(+), 50 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index ad04b76cb3eb..6fbb624374af 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -1,6 +1,24 @@ package io.swagger.codegen.languages; -import com.google.common.collect.ImmutableMap; +import static com.google.common.base.Strings.isNullOrEmpty; +import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE; +import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE_DESC; +import static io.swagger.codegen.CodegenConstants.PACKAGE_NAME; +import static io.swagger.codegen.CodegenConstants.PACKAGE_VERSION; +import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION; +import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION_DESC; +import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG; +import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC; +import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER; +import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER_DESC; +import static io.swagger.codegen.CodegenConstants.USE_COLLECTION; +import static io.swagger.codegen.CodegenConstants.USE_COLLECTION_DESC; +import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET; +import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET_DESC; +import static io.swagger.codegen.CodegenType.SERVER; +import static java.util.Arrays.asList; +import static java.util.UUID.randomUUID; +import static org.apache.commons.lang3.StringUtils.capitalize; import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenType; @@ -8,20 +26,26 @@ import io.swagger.codegen.SupportingFile; import io.swagger.models.Swagger; import io.swagger.models.properties.Property; import io.swagger.models.properties.StringProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.util.Map; +import java.util.Map.Entry; -import static io.swagger.codegen.CodegenConstants.*; -import static io.swagger.codegen.CodegenType.SERVER; -import static java.util.Arrays.asList; -import static java.util.UUID.randomUUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMap; public class NancyFXServerCodegen extends AbstractCSharpCodegen { private static final Logger log = LoggerFactory.getLogger(NancyFXServerCodegen.class); + private static final String API_NAMESPACE = "Modules"; + private static final String MODEL_NAMESPACE = "Models"; + + private static final Map> propertyToSwaggerTypeMapping = + createPropertyToSwaggerTypeMapping(); + private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}"; public NancyFXServerCodegen() { @@ -69,8 +93,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { public void processOpts() { super.processOpts(); - apiPackage = packageName + ".Modules"; - modelPackage = packageName + ".Models"; + apiPackage = isNullOrEmpty(packageName) ? API_NAMESPACE : packageName + "." + API_NAMESPACE; + modelPackage = isNullOrEmpty(packageName) ? MODEL_NAMESPACE : packageName + "." + MODEL_NAMESPACE; supportingFiles.add(new SupportingFile("parameters.mustache", sourceFile("Utils"), "Parameters.cs")); supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder(), "packages.config")); @@ -92,78 +116,94 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { @Override public String apiFileFolder() { - return outputFolder + File.separator + sourceFolder() + File.separator + "Modules"; + return outputFolder + File.separator + sourceFolder() + File.separator + API_NAMESPACE; } @Override public String modelFileFolder() { - return outputFolder + File.separator + sourceFolder() + File.separator + "Models"; + return outputFolder + File.separator + sourceFolder() + File.separator + MODEL_NAMESPACE; } @Override - protected void processOperation(CodegenOperation operation) { + protected void processOperation(final CodegenOperation operation) { super.processOperation(operation); - - // HACK: Unlikely in the wild, but we need to clean operation paths for MVC Routing - if (operation.path != null) { - String original = operation.path; + if (!isNullOrEmpty(operation.path) && operation.path.contains("?")) { operation.path = operation.path.replace("?", "/"); - if (!original.equals(operation.path)) { - log.warn("Normalized " + original + " to " + operation.path + ". Please verify generated source."); - } } - - // Converts, for example, PUT to HttpPut for controller attributes - operation.httpMethod = operation.httpMethod.substring(0, 1) + operation.httpMethod.substring(1).toLowerCase(); + if (!isNullOrEmpty(operation.httpMethod)) { + operation.httpMethod = capitalize(operation.httpMethod.toLowerCase()); + } } @Override - public String toEnumVarName(String name, String datatype) { + public String toEnumVarName(final String name, final String datatype) { final String enumName = camelize( sanitizeName(name) .replaceFirst("^_", "") .replaceFirst("_$", "")); - log.info("toEnumVarName = " + enumName); - - if (enumName.matches("\\d.*")) { // starts with number - return "_" + enumName; + final String result; + if (enumName.matches("\\d.*")) { + result = "_" + enumName; } else { - return enumName; + result = enumName; } + log.info(String.format("toEnumVarName('%s', %s) = '%s'", name, datatype, enumName)); + return result; } @Override - public String toApiName(String name) { - if (name.length() == 0) { - return "Default"; + public String toApiName(final String name) { + final String apiName; + if (isNullOrEmpty(name)) { + apiName = "Default"; + } else { + apiName = capitalize(name); } - return initialCaps(name); + log.info(String.format("toApiName('%s') = '%s'", name, apiName)); + return apiName; } @Override - public String toApiFilename(String name) { + public String toApiFilename(final String name) { return super.toApiFilename(name) + "Module"; } @Override - public void preprocessSwagger(Swagger swagger) { + public void preprocessSwagger(final Swagger swagger) { additionalProperties.put("packageContext", sanitizeName(swagger.getBasePath())); additionalProperties.put("baseContext", swagger.getBasePath()); } @Override - public String toEnumName(CodegenProperty property) { + public String toEnumName(final CodegenProperty property) { return sanitizeName(camelize(property.name)) ; } @Override - public String getSwaggerType(Property property) { - if (property instanceof StringProperty && "time".equalsIgnoreCase(property.getFormat())) { - return "time"; + public String getSwaggerType(final Property property) { + for (Entry> entry : propertyToSwaggerTypeMapping.entrySet()) { + if (entry.getValue().apply(property)) { + return entry.getKey(); + } } return super.getSwaggerType(property); } + private static Map> createPropertyToSwaggerTypeMapping() { + final ImmutableMap.Builder> mapping = ImmutableMap.builder(); + mapping.put("time", timeProperty()); + return mapping.build(); + } + + private static Predicate timeProperty() { + return new Predicate() { + @Override + public boolean apply(Property property) { + return property instanceof StringProperty && "time".equalsIgnoreCase(property.getFormat()); + } + }; + } + private static Map nodaTimeTypesMappings() { return ImmutableMap.of( "time", "LocalTime?", diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 167408e8a365..8e912f5ef17d 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.{{packageContext}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} {{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} - public partial class {{classname}}Module : NancyModule + public sealed class {{classname}}Module : NancyModule { public {{classname}}Module({{classname}}Service service) : base("{{baseContext}}") { {{#operation}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index fbb08cec64c6..fbb67988ed48 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -16,6 +16,12 @@ namespace {{packageName}}.{{packageContext}}.Models { {{#vars}} public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} + /// + /// Required by some serializers. + /// + [Obsolete] + public {{classname}}(){} + public {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) { {{#vars}} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java index e24df8847138..77a374f648ee 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/NancyFXServerOptionsProvider.java @@ -1,15 +1,22 @@ package io.swagger.codegen.options; -import com.google.common.collect.ImmutableMap; -import io.swagger.codegen.CodegenConstants; +import static io.swagger.codegen.CodegenConstants.PACKAGE_NAME; +import static io.swagger.codegen.CodegenConstants.PACKAGE_VERSION; +import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION; +import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG; +import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER; +import static io.swagger.codegen.CodegenConstants.USE_COLLECTION; +import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET; import java.util.Map; +import com.google.common.collect.ImmutableMap; + public class NancyFXServerOptionsProvider implements OptionsProvider { public static final String PACKAGE_NAME_VALUE = "swagger_server_nancyfx"; public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT"; public static final String SOURCE_FOLDER_VALUE = "src_nancyfx"; - + @Override public String getLanguage() { return "nancyfx"; @@ -17,14 +24,14 @@ public class NancyFXServerOptionsProvider implements OptionsProvider { @Override public Map createOptions() { - ImmutableMap.Builder builder = new ImmutableMap.Builder(); - return builder.put(CodegenConstants.PACKAGE_NAME, PACKAGE_NAME_VALUE) - .put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE) - .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE) - .put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true") - .put(CodegenConstants.USE_DATETIME_OFFSET, "true") - .put(CodegenConstants.USE_COLLECTION, "false") - .put(CodegenConstants.RETURN_ICOLLECTION, "false") + final ImmutableMap.Builder builder = ImmutableMap.builder(); + return builder.put(PACKAGE_NAME, PACKAGE_NAME_VALUE) + .put(PACKAGE_VERSION, PACKAGE_VERSION_VALUE) + .put(SOURCE_FOLDER, SOURCE_FOLDER_VALUE) + .put(SORT_PARAMS_BY_REQUIRED_FLAG, "true") + .put(USE_DATETIME_OFFSET, "true") + .put(USE_COLLECTION, "false") + .put(RETURN_ICOLLECTION, "false") .build(); } From 1d167b709d18081ad763f78de0e6b2a3fa563190 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 30 May 2016 11:21:21 +0200 Subject: [PATCH 36/64] NancyFx: - Including API docs --- .../main/resources/nancyfx/Project.mustache | 2 + .../src/main/resources/nancyfx/api.mustache | 21 ++++++++- .../resources/nancyfx/innerApiEnum.mustache | 5 +- .../src/main/resources/nancyfx/model.mustache | 47 +++++++++++++++++-- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index 9962800b0cc8..be880937bfd6 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -27,6 +27,7 @@ DEBUG;TRACE prompt 4 + bin\Debug\{{packageName}}.XML pdbonly @@ -35,6 +36,7 @@ TRACE prompt 4 + bin\Release\{{packageName}}.XML diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 8e912f5ef17d..e0357ecada2d 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -11,8 +11,15 @@ namespace {{packageName}}.{{packageContext}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} {{>innerApiEnum}}{{/isEnum}}{{/allParams}}{{/operation}} + /// + /// Module processing requests of {{classname}} domain. + /// public sealed class {{classname}}Module : NancyModule { + /// + /// Sets up HTTP methods mappings. + /// + /// Service handling requests public {{classname}}Module({{classname}}Service service) : base("{{baseContext}}") { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => @@ -28,13 +35,25 @@ namespace {{packageName}}.{{packageContext}}.Modules } } + /// + /// Service handling {{classname}} requests. + /// public interface {{classname}}Service { - {{#operation}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}} + {{#operation}}/// + /// {{notes}} + /// + /// Context of request + {{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}} + {{/allParams}}/// {{#returnType}}{{returnType}}{{/returnType}} + {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}} {{/hasMore}}{{/operation}} } + /// + /// Abstraction of {{classname}}Service. + /// public abstract class Abstract{{classname}}Service: {{classname}}Service { {{#operation}}public virtual {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}}) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache index 1bf8ab2efa4d..5a7a89aa5286 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerApiEnum.mustache @@ -1 +1,4 @@ -public enum {{>innerApiEnumName}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file +/// + /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} + /// + public enum {{>innerApiEnumName}} { {{#allowableValues}}{{#values}}{{&.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index fbb67988ed48..cf5091624d33 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -12,28 +12,45 @@ namespace {{packageName}}.{{packageContext}}.Models {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} + /// + /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} + /// public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}} - public {{>nullableDataType}} {{name}} { get; private set; }{{/vars}} + /// + /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + /// + public {{>nullableDataType}} {{name}} { get; private set; } +{{/vars}} /// - /// Required by some serializers. + /// Empty constructor required by some serializers. + /// Use {{classname}}.Builder() for instance creation instead. /// [Obsolete] - public {{classname}}(){} + public {{classname}}() {} - public {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) + private {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) { {{#vars}} this.{{name}} = {{name}}; {{/vars}} } + /// + /// Returns builder of {{classname}}. + /// + /// {{classname}}Builder public static {{classname}}Builder Builder() { return new {{classname}}Builder(); } + /// + /// Returns {{classname}}Builder with properties set. + /// Use it to change properties. + /// + /// {{classname}}Builder public {{classname}}Builder With() { return Builder() @@ -62,18 +79,30 @@ namespace {{packageName}}.{{packageContext}}.Models return this.PropertiesHash(); } + /// + /// Implementation of == operator for ({{classname}}. + /// + /// Compared ({{classname}} + /// Compared ({{classname}} + /// true if compared items are equals, false otherwise public static bool operator == ({{classname}} left, {{classname}} right) { return Equals(left, right); } + /// + /// Implementation of != operator for ({{classname}}. + /// + /// Compared ({{classname}} + /// Compared ({{classname}} + /// true if compared items are not equals, false otherwise public static bool operator != ({{classname}} left, {{classname}} right) { return !Equals(left, right); } /// - /// Builder of {{classname}} model + /// Builder of {{classname}}. /// public sealed class {{classname}}Builder { @@ -98,6 +127,10 @@ namespace {{packageName}}.{{packageContext}}.Models } {{#vars}} + /// + /// Sets value for {{classname}}.{{{name}}} property. + /// + /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} public {{classname}}Builder {{name}}({{>nullableDataType}} value) { _{{name}} = value; @@ -106,6 +139,10 @@ namespace {{packageName}}.{{packageContext}}.Models {{/vars}} + /// + /// Builds instance of {{classname}}. + /// + /// {{classname}} public {{classname}} Build() { Validate(); From ba26df95e217fd948571e900f360799138959c4b Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 30 May 2016 12:09:00 +0200 Subject: [PATCH 37/64] NancyFx: - Added generation of .nuspec file --- .../codegen/languages/NancyFXServerCodegen.java | 1 + .../src/main/resources/nancyfx/nuspec.mustache | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 6fbb624374af..1f5665ac952f 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -98,6 +98,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { supportingFiles.add(new SupportingFile("parameters.mustache", sourceFile("Utils"), "Parameters.cs")); supportingFiles.add(new SupportingFile("packages.config.mustache", sourceFolder(), "packages.config")); + supportingFiles.add(new SupportingFile("nuspec.mustache", sourceFolder(), packageName + ".nuspec")); if (optionalProjectFileFlag) { supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln")); diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache new file mode 100644 index 000000000000..2969443ab533 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache @@ -0,0 +1,12 @@ + + + + {{packageName}} + {{packageName}} + {{{version}}} + swagger-codegen + swagger-codegen + false + NancyFx {{packageName}} API + + \ No newline at end of file From c734a216af91d26f1be073603a9322f6730a73d5 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 30 May 2016 13:21:55 +0200 Subject: [PATCH 38/64] NancyFx: - Handling importMapping --- .../languages/NancyFXServerCodegen.java | 55 +++++++++++++++++++ .../src/main/resources/nancyfx/api.mustache | 2 + .../src/main/resources/nancyfx/model.mustache | 2 + .../main/resources/nancyfx/nuspec.mustache | 2 + .../nancyfx/packages.config.mustache | 3 + 5 files changed, 64 insertions(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 1f5665ac952f..4ff51e1ded5d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -28,6 +28,9 @@ import io.swagger.models.properties.Property; import io.swagger.models.properties.StringProperty; import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -36,6 +39,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; public class NancyFXServerCodegen extends AbstractCSharpCodegen { private static final Logger log = LoggerFactory.getLogger(NancyFXServerCodegen.class); @@ -48,6 +52,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}"; + private final Map dependencies = new HashMap<>(); + public NancyFXServerCodegen() { outputFolder = "generated-code" + File.separator + getName(); modelTemplateFiles.put("model.mustache", ".cs"); @@ -72,6 +78,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { addSwitch(USE_COLLECTION, USE_COLLECTION_DESC, useCollection); addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection); typeMapping.putAll(nodaTimeTypesMappings()); + + importMapping.clear(); } @Override @@ -105,6 +113,43 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder(), packageName + ".csproj")); } additionalProperties.put("packageGuid", packageGuid); + processImportMapping(); + setupDependencies(); + } + + private void processImportMapping() { + for (final Entry entry : ImmutableSet.copyOf(importMapping.entrySet())) { + final String model = entry.getKey(); + final String[] namespaceInfo = entry.getValue().split("\\s"); + final String namespace = namespaceInfo.length > 0 ? namespaceInfo[0].trim() : null; + final String assembly = namespaceInfo.length > 1 ? namespaceInfo[1].trim() : null; + final String assemblyVersion = namespaceInfo.length > 2 ? namespaceInfo[2].trim() : null; + final String assemblyFramework = namespaceInfo.length > 3 ? namespaceInfo[3].trim() : "net45"; + if (namespace == null) { + log.warn(String.format("Could not import: '%s' - invalid namespace: '%s'", model, entry.getValue())); + importMapping.remove(model); + } else { + log.info(String.format("Importing: '%s' from '%s' namespace.", model, namespace)); + importMapping.put(model, namespace); + } + if (assembly != null && assemblyVersion != null) { + log.info("Adding dependency: '%s', version: '%s', framework: '%s'", + assembly, assemblyVersion, assemblyVersion); + dependencies.put(assembly, new DependencyInfo(assemblyVersion, assemblyFramework)); + } + } + } + + private void setupDependencies() { + final List> listOfDependencies = new ArrayList<>(); + for (final Entry dependency : dependencies.entrySet()) { + final Map dependencyInfo = new HashMap<>(); + dependencyInfo.put("dependency", dependency.getKey()); + dependencyInfo.put("dependencyVersion", dependency.getValue().version); + dependencyInfo.put("dependencyFramework", dependency.getValue().framework); + listOfDependencies.add(dependencyInfo); + } + additionalProperties.put("dependencies", listOfDependencies); } private String sourceFolder() { @@ -211,4 +256,14 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { "date", "ZonedDateTime?", "datetime", "ZonedDateTime?"); } + + private class DependencyInfo { + private final String version; + private final String framework; + + private DependencyInfo(final String version, final String framework) { + this.version = version; + this.framework = framework; + } + } } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index e0357ecada2d..b6e1f316517f 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -6,6 +6,8 @@ using Sharpility.Base; using {{packageName}}.{{packageContext}}.Models; using {{packageName}}.{{packageContext}}.Utils; using NodaTime; +{{#imports}}using {{import}}; +{{/imports}} namespace {{packageName}}.{{packageContext}}.Modules { {{#operations}}{{#operation}}{{#allParams}}{{#isEnum}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index cf5091624d33..e199575a130c 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -4,6 +4,8 @@ using System.IO; using System.Text; using Sharpility.Extensions; using NodaTime; +{{#imports}}using {{import}}; +{{/imports}} {{#models}} {{#model}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache index 2969443ab533..71772df6d719 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache @@ -8,5 +8,7 @@ swagger-codegen false NancyFx {{packageName}} API + {{termsOfService}} + {{licenseUrl}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache index 6d8651cdcf40..55c32a09bdac 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache @@ -4,4 +4,7 @@ + {{#dependencies}} + + {{/dependencies}} \ No newline at end of file From c6d4df3e4134bfc014d3e445f31871e192574b67 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 30 May 2016 15:04:16 +0200 Subject: [PATCH 39/64] NancyFx: - Handling class name mapping --- .../languages/NancyFXServerCodegen.java | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 4ff51e1ded5d..649699d03efa 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -38,6 +38,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Predicate; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -53,6 +55,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}"; private final Map dependencies = new HashMap<>(); + private final BiMap modelNameMapping = HashBiMap.create(); public NancyFXServerCodegen() { outputFolder = "generated-code" + File.separator + getName(); @@ -121,20 +124,27 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { for (final Entry entry : ImmutableSet.copyOf(importMapping.entrySet())) { final String model = entry.getKey(); final String[] namespaceInfo = entry.getValue().split("\\s"); - final String namespace = namespaceInfo.length > 0 ? namespaceInfo[0].trim() : null; + final String[] namespace = (namespaceInfo.length > 0 ? namespaceInfo[0].trim() : "").split(":"); + final String namespaceName = namespace.length > 0 ? namespace[0].trim() : null; + final String modelClass = namespace.length > 1 ? namespace[1].trim() : null; final String assembly = namespaceInfo.length > 1 ? namespaceInfo[1].trim() : null; final String assemblyVersion = namespaceInfo.length > 2 ? namespaceInfo[2].trim() : null; final String assemblyFramework = namespaceInfo.length > 3 ? namespaceInfo[3].trim() : "net45"; - if (namespace == null) { + + if (isNullOrEmpty(model) || isNullOrEmpty(namespaceName)) { log.warn(String.format("Could not import: '%s' - invalid namespace: '%s'", model, entry.getValue())); importMapping.remove(model); } else { - log.info(String.format("Importing: '%s' from '%s' namespace.", model, namespace)); - importMapping.put(model, namespace); + log.info(String.format("Importing: '%s' from '%s' namespace.", model, namespaceName)); + importMapping.put(model, namespaceName); + } + if (!isNullOrEmpty(modelClass)) { + log.info(String.format("Mapping: '%s' class to '%s'", model, modelClass)); + modelNameMapping.put(model, modelClass); } if (assembly != null && assemblyVersion != null) { - log.info("Adding dependency: '%s', version: '%s', framework: '%s'", - assembly, assemblyVersion, assemblyVersion); + log.info(String.format("Adding dependency: '%s', version: '%s', framework: '%s'", + assembly, assemblyVersion, assemblyVersion)); dependencies.put(assembly, new DependencyInfo(assemblyVersion, assemblyFramework)); } } @@ -214,6 +224,29 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { return super.toApiFilename(name) + "Module"; } + @Override + public String toModelImport(final String name) { + final String result; + if (modelNameMapping.containsValue(name)) { + final String modelName = modelNameMapping.inverse().get(name); + result = importMapping.containsKey(modelName) ? + importMapping.get(modelName) : super.toModelImport(name); + } else if (importMapping.containsKey(name)) { + result = importMapping.get(name); + } else { + result = null; + } + log.info(String.format("toModelImport('%s') = '%s'", name, result)); + return result; + } + + @Override + public String toModelName(final String name) { + final String modelName = super.toModelName(name); + final String mappedModelName = modelNameMapping.get(modelName); + return isNullOrEmpty(mappedModelName) ? modelName: mappedModelName; + } + @Override public void preprocessSwagger(final Swagger swagger) { additionalProperties.put("packageContext", sanitizeName(swagger.getBasePath())); From 16200ae424a984aaf4c603593c3c95b63799f0b5 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Mon, 30 May 2016 15:49:37 +0200 Subject: [PATCH 40/64] NancyFx: - Mutable model generation for option -Dimmutable-false --- .../languages/NancyFXServerCodegen.java | 24 +++++-- .../resources/nancyfx/modelMutable.mustache | 72 +++++++++++++++++++ 2 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 649699d03efa..a908143bdb23 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -48,6 +48,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { private static final String API_NAMESPACE = "Modules"; private static final String MODEL_NAMESPACE = "Models"; + private static final String IMMUTABLE_OPTION = "immutable"; private static final Map> propertyToSwaggerTypeMapping = createPropertyToSwaggerTypeMapping(); @@ -59,7 +60,6 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { public NancyFXServerCodegen() { outputFolder = "generated-code" + File.separator + getName(); - modelTemplateFiles.put("model.mustache", ".cs"); apiTemplateFiles.put("api.mustache", ".cs"); // contextually reserved words @@ -80,6 +80,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { addSwitch(USE_DATETIME_OFFSET, USE_DATETIME_OFFSET_DESC, useDateTimeOffsetFlag); addSwitch(USE_COLLECTION, USE_COLLECTION_DESC, useCollection); addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection); + addSwitch(IMMUTABLE_OPTION, "Enabled by default. If disabled generates model classes with setters", true); typeMapping.putAll(nodaTimeTypesMappings()); importMapping.clear(); @@ -116,11 +117,24 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder(), packageName + ".csproj")); } additionalProperties.put("packageGuid", packageGuid); - processImportMapping(); - setupDependencies(); + + setupModelTemplate(); + processImportedMappings(); + appendDependencies(); } - private void processImportMapping() { + private void setupModelTemplate() { + final Object immutableOption = additionalProperties.get(IMMUTABLE_OPTION); + if (immutableOption != null && "false".equalsIgnoreCase(immutableOption.toString())) { + log.info("Using mutable model template"); + modelTemplateFiles.put("modelMutable.mustache", ".cs"); + } else { + log.info("Using immutable model template"); + modelTemplateFiles.put("model.mustache", ".cs"); + } + } + + private void processImportedMappings() { for (final Entry entry : ImmutableSet.copyOf(importMapping.entrySet())) { final String model = entry.getKey(); final String[] namespaceInfo = entry.getValue().split("\\s"); @@ -150,7 +164,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { } } - private void setupDependencies() { + private void appendDependencies() { final List> listOfDependencies = new ArrayList<>(); for (final Entry dependency : dependencies.entrySet()) { final Map dependencyInfo = new HashMap<>(); diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache new file mode 100644 index 000000000000..bcded25eec83 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Sharpility.Extensions; +using NodaTime; +{{#imports}}using {{import}}; +{{/imports}} + +{{#models}} +{{#model}} +namespace {{packageName}}.{{packageContext}}.Models +{ {{#vars}}{{#isEnum}} + {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} + {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} + + /// + /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} + /// + public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + { {{#vars}} + /// + /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + /// + public {{>nullableDataType}} {{name}} { get; set; } +{{/vars}} + + public override string ToString() + { + return this.PropertiesToString(); + } + + public override bool Equals(object obj) + { + return this.EqualsByProperties(obj); + } + + public bool Equals({{classname}} other) + { + return Equals((object) other); + } + + public override int GetHashCode() + { + return this.PropertiesHash(); + } + + /// + /// Implementation of == operator for ({{classname}}. + /// + /// Compared ({{classname}} + /// Compared ({{classname}} + /// true if compared items are equals, false otherwise + public static bool operator == ({{classname}} left, {{classname}} right) + { + return Equals(left, right); + } + + /// + /// Implementation of != operator for ({{classname}}. + /// + /// Compared ({{classname}} + /// Compared ({{classname}} + /// true if compared items are not equals, false otherwise + public static bool operator != ({{classname}} left, {{classname}} right) + { + return !Equals(left, right); + } + } +{{/model}} +{{/models}} +} From 849aa5064d754e41dc40b02675c0f63b8ac2c74b Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 31 May 2016 08:50:36 +0200 Subject: [PATCH 41/64] NancyFx: - Including dependencies in csproj --- .../src/main/resources/nancyfx/Project.mustache | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index be880937bfd6..e4f4f4c6bc0b 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -54,7 +54,12 @@ ..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True + {{#dependencies}} + + ..\..\packages\{{dependency}}.{{dependencyVersion}}\lib\{{dependencyFramework}}\{{dependency}}.dll + True + {{/dependencies}} From 30b7eb7854b63c2618b6bcfc1595e9b6a8aaa8e3 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Tue, 31 May 2016 09:01:26 +0200 Subject: [PATCH 42/64] NancyFx: - Omitting copyright and licenceurl tags i nuspec when not specified --- .../src/main/resources/nancyfx/nuspec.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache index 71772df6d719..bc7e4d8e8e78 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/nuspec.mustache @@ -7,8 +7,8 @@ swagger-codegen swagger-codegen false - NancyFx {{packageName}} API - {{termsOfService}} - {{licenseUrl}} + NancyFx {{packageName}} API{{#termsOfService}} + {{termsOfService}}{{/termsOfService}}{{#licenseUrl}} + {{licenseUrl}}{{/licenseUrl}} \ No newline at end of file From e1df89c8faa57dfd7273da706a3887d703f5fc06 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Tue, 31 May 2016 13:49:45 +0200 Subject: [PATCH 43/64] Formatting fix. --- .../src/main/resources/nancyfx/model.mustache | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index e199575a130c..5826bad368af 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -156,13 +156,11 @@ namespace {{packageName}}.{{packageContext}}.Models } private void Validate() - { - {{#vars}}{{#required}} + { {{#vars}}{{#required}} if (_{{name}} == null) { throw new ArgumentException("{{name}} is a required property for {{classname}} and cannot be null"); - } - {{/required}}{{/vars}} + } {{/required}}{{/vars}} } } } From fc9b4501fc91203cb67328a98b8e78de2cc2648d Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Wed, 1 Jun 2016 15:04:18 +0200 Subject: [PATCH 44/64] NancyFx: - Fixed inheritance support --- .../java/io/swagger/codegen/CodegenModel.java | 9 +- .../io/swagger/codegen/CodegenProperty.java | 22 ++++- .../languages/NancyFXServerCodegen.java | 89 ++++++++++++++++++- .../resources/nancyfx/innerModelEnum.mustache | 2 +- .../src/main/resources/nancyfx/model.mustache | 26 +++--- .../resources/nancyfx/modelMutable.mustache | 8 +- .../nancyfx/nullableDataType.mustache | 2 +- 7 files changed, 136 insertions(+), 22 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java index 438eb1912946..76fcbc3d21cd 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java @@ -20,6 +20,7 @@ public class CodegenModel { public List requiredVars = new ArrayList(); // a list of required properties public List optionalVars = new ArrayList(); // a list of optional properties public List allVars; + public List parentVars = new ArrayList<>(); public Map allowableValues; // Sorted sets of required parameters. @@ -27,7 +28,7 @@ public class CodegenModel { public Set allMandatory; public Set imports = new TreeSet(); - public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired; + public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired,hasChildrens; public ExternalDocs externalDocs; public Map vendorExtensions; @@ -109,6 +110,10 @@ public class CodegenModel { return false; if (externalDocs != null ? !externalDocs.equals(that.externalDocs) : that.externalDocs != null) return false; + if (!Objects.equals(hasChildrens, that.hasChildrens)) + return false; + if (!Objects.equals(parentVars, that.parentVars)) + return false; return vendorExtensions != null ? vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions == null; } @@ -145,6 +150,8 @@ public class CodegenModel { result = 31 * result + (isEnum != null ? isEnum.hashCode() : 0); result = 31 * result + (externalDocs != null ? externalDocs.hashCode() : 0); result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0); + result = 31 * result + Objects.hash(hasChildrens); + result = 31 * result + Objects.hash(parentVars); return result; } } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java index d58a1a81b1d3..558a280ca036 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java @@ -2,8 +2,9 @@ package io.swagger.codegen; import java.util.List; import java.util.Map; +import java.util.Objects; -public class CodegenProperty { +public class CodegenProperty implements Cloneable { public String baseName, complexType, getter, setter, description, datatype, datatypeWithEnum, name, min, max, defaultValue, defaultValueWithParam, baseType, containerType; @@ -43,6 +44,8 @@ public class CodegenProperty { public CodegenProperty items; public Map vendorExtensions; public Boolean hasValidation; // true if pattern, maximum, etc are set (only used in the mustache template) + public String parent; + public String parentClass; @Override public String toString() { @@ -105,6 +108,8 @@ public class CodegenProperty { result = prime * result + ((isDateTime == null) ? 0 : isDateTime.hashCode()); result = prime * result + ((isMapContainer == null) ? 0 : isMapContainer.hashCode()); result = prime * result + ((isListContainer == null) ? 0 : isListContainer.hashCode()); + result = prime * result + Objects.hashCode(parent); + result = prime * result + Objects.hashCode(parentClass); return result; } @@ -256,6 +261,21 @@ public class CodegenProperty { if (this.isMapContainer != other.isMapContainer && (this.isMapContainer == null || !this.isMapContainer.equals(other.isMapContainer))) { return false; } + if (!Objects.equals(this.parent, other.parent)) { + return false; + } + if (!Objects.equals(this.parentClass, other.parentClass)) { + return false; + } return true; } + + @Override + public CodegenProperty clone() { + try { + return (CodegenProperty) super.clone(); + } catch (CloneNotSupportedException e) { + throw new IllegalStateException(e); + } + } } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index a908143bdb23..9c7afce6d9e4 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -19,6 +19,7 @@ import static io.swagger.codegen.CodegenType.SERVER; import static java.util.Arrays.asList; import static java.util.UUID.randomUUID; import static org.apache.commons.lang3.StringUtils.capitalize; +import io.swagger.codegen.CodegenModel; import io.swagger.codegen.CodegenOperation; import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenType; @@ -29,19 +30,24 @@ import io.swagger.models.properties.StringProperty; import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Multimap; public class NancyFXServerCodegen extends AbstractCSharpCodegen { private static final Logger log = LoggerFactory.getLogger(NancyFXServerCodegen.class); @@ -56,6 +62,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}"; private final Map dependencies = new HashMap<>(); + private final Set parentModels = new HashSet<>(); + private final Multimap parentChildrens = ArrayListMultimap.create(); private final BiMap modelNameMapping = HashBiMap.create(); public NancyFXServerCodegen() { @@ -205,12 +213,89 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { } } + @Override + public Map postProcessAllModels(final Map models) { + final Map processed = super.postProcessAllModels(models); + postProcessParentModels(models); + return processed; + } + + private void postProcessParentModels(final Map models) { + log.info("Processing parents: " + parentModels); + for (final String parent : parentModels) { + final CodegenModel parentModel = modelByName(parent, models); + parentModel.hasChildrens = true; + final Collection childrens = parentChildrens.get(parent); + for (final CodegenModel child : childrens) { + processParentPropertiesInChildModel(parentModel, child); + } + } + } + + private CodegenModel modelByName(final String name, final Map models) { + final Object data = models.get(name); + if (data instanceof Map) { + final Map dataMap = (Map) data; + final Object dataModels = dataMap.get("models"); + if (dataModels instanceof List) { + final List dataModelsList = (List) dataModels; + for (final Object entry : dataModelsList) { + if (entry instanceof Map) { + final Map entryMap = (Map) entry; + final Object model = entryMap.get("model"); + if (model instanceof CodegenModel) { + return (CodegenModel) model; + } + } + } + } + } + return null; + } + + private void processParentPropertiesInChildModel(final CodegenModel parent, final CodegenModel child) { + final Map childPropertiesByName = new HashMap<>(child.vars.size()); + for (final CodegenProperty property : child.vars) { + childPropertiesByName.put(property.name, property); + } + CodegenProperty previousParentVar = null; + for (final CodegenProperty property : parent.vars) { + final CodegenProperty duplicatedByParent = childPropertiesByName.get(property.name); + if (duplicatedByParent != null) { + log.info(String.format("Property: '%s' in '%s' model is inherited from '%s'" , + property.name, child.classname, parent.classname)); + duplicatedByParent.parent = parent.name; + duplicatedByParent.parentClass = parent.classname; + + final CodegenProperty parentVar = duplicatedByParent.clone(); + parentVar.hasMore = false; + child.parentVars.add(parentVar); + if (previousParentVar != null) { + previousParentVar.hasMore = true; + } + previousParentVar = parentVar; + } + } + } + + @Override + public void postProcessModelProperty(final CodegenModel model, final CodegenProperty property) { + super.postProcessModelProperty(model, property); + if (!isNullOrEmpty(model.parent)) { + parentModels.add(model.parent); + if (!parentChildrens.containsEntry(model.parent, model)) { + parentChildrens.put(model.parent, model); + } + } + } + @Override public String toEnumVarName(final String name, final String datatype) { final String enumName = camelize( sanitizeName(name) .replaceFirst("^_", "") - .replaceFirst("_$", "")); + .replaceFirst("_$", "") + .replaceAll("-", "_")); final String result; if (enumName.matches("\\d.*")) { result = "_" + enumName; @@ -269,7 +354,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { @Override public String toEnumName(final CodegenProperty property) { - return sanitizeName(camelize(property.name)) ; + return sanitizeName(camelize(property.name)); } @Override diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache index 19e4731f2cf4..54d23b1d8d56 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache @@ -1 +1 @@ -public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file +public enum {{#parentClass}}{{parentClass}}{{/parentClass}}{{^parentClass}}{{classname}}{{/parentClass}}{{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index e199575a130c..409bd60641a2 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -10,40 +10,42 @@ using NodaTime; {{#models}} {{#model}} namespace {{packageName}}.{{packageContext}}.Models -{ {{#vars}}{{#isEnum}} - {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} +{ {{#vars}}{{#isEnum}}{{^parent}} + {{>innerModelEnum}}{{/parent}}{{/isEnum}}{{#items.isEnum}} {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} /// /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// - public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> - { {{#vars}} + public {{^hasChildrens}}sealed {{/hasChildrens}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + { {{#vars}}{{^parent}} /// /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} /// public {{>nullableDataType}} {{name}} { get; private set; } -{{/vars}} +{{/parent}}{{/vars}} /// /// Empty constructor required by some serializers. /// Use {{classname}}.Builder() for instance creation instead. /// [Obsolete] - public {{classname}}() {} - - private {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}) + public {{classname}}(){{#parent}} : base({{/parent}}{{#parentVars}}null{{#hasMore}}, {{/hasMore}}{{/parentVars}}{{#parent}}){{/parent}} { - {{#vars}} + } + + {{#hasChildrens}}protected{{/hasChildrens}}{{^hasChildrens}}private{{/hasChildrens}} {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}){{#parent}} : base({{#parentVars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}} + { + {{#vars}}{{^parent}} this.{{name}} = {{name}}; - {{/vars}} + {{/parent}}{{/vars}} } /// /// Returns builder of {{classname}}. /// /// {{classname}}Builder - public static {{classname}}Builder Builder() + public static {{#parent}}new {{/parent}}{{classname}}Builder Builder() { return new {{classname}}Builder(); } @@ -53,7 +55,7 @@ namespace {{packageName}}.{{packageContext}}.Models /// Use it to change properties. /// /// {{classname}}Builder - public {{classname}}Builder With() + public {{#parent}}new {{/parent}}{{classname}}Builder With() { return Builder() {{#vars}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache index bcded25eec83..038d4224eb1f 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache @@ -10,14 +10,14 @@ using NodaTime; {{#models}} {{#model}} namespace {{packageName}}.{{packageContext}}.Models -{ {{#vars}}{{#isEnum}} - {{>innerModelEnum}}{{/isEnum}}{{#items.isEnum}} +{ {{#vars}}{{#isEnum}}{{^parent}} + {{>innerModelEnum}}{{/parent}}{{/isEnum}}{{#items.isEnum}} {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} - /// +/// /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// - public sealed class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + public {{^hasChildrens}}sealed {{/hasChildrens}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}} /// /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache index c999b870119e..534590a7f896 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache @@ -1 +1 @@ -{{&datatypeWithEnum}}{{#isEnum}}?{{/isEnum}} \ No newline at end of file +{{#isEnum}}{{#parentClass}}{{parentClass}}{{/parentClass}}{{^parentClass}}{{classname}}{{/parentClass}}{{/isEnum}}{{&datatypeWithEnum}}{{#isEnum}}?{{/isEnum}} \ No newline at end of file From 1cfb3d1c9cdb3b1a417d24bea8755ed52b957be5 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 08:14:49 +0200 Subject: [PATCH 45/64] NancyFx: - Changed enum class name format - CodegenProperty parent and parentClass replaced by Booolen flag isInherited --- .../main/java/io/swagger/codegen/CodegenProperty.java | 11 +++-------- .../codegen/languages/NancyFXServerCodegen.java | 6 ++---- .../main/resources/nancyfx/innerModelEnum.mustache | 2 +- .../src/main/resources/nancyfx/model.mustache | 4 ++-- .../src/main/resources/nancyfx/modelMutable.mustache | 4 ++-- .../main/resources/nancyfx/nullableDataType.mustache | 2 +- 6 files changed, 11 insertions(+), 18 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java index 558a280ca036..eeef7777df2d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java @@ -44,8 +44,7 @@ public class CodegenProperty implements Cloneable { public CodegenProperty items; public Map vendorExtensions; public Boolean hasValidation; // true if pattern, maximum, etc are set (only used in the mustache template) - public String parent; - public String parentClass; + public Boolean isInherited; @Override public String toString() { @@ -108,8 +107,7 @@ public class CodegenProperty implements Cloneable { result = prime * result + ((isDateTime == null) ? 0 : isDateTime.hashCode()); result = prime * result + ((isMapContainer == null) ? 0 : isMapContainer.hashCode()); result = prime * result + ((isListContainer == null) ? 0 : isListContainer.hashCode()); - result = prime * result + Objects.hashCode(parent); - result = prime * result + Objects.hashCode(parentClass); + result = prime * result + Objects.hashCode(isInherited); return result; } @@ -261,10 +259,7 @@ public class CodegenProperty implements Cloneable { if (this.isMapContainer != other.isMapContainer && (this.isMapContainer == null || !this.isMapContainer.equals(other.isMapContainer))) { return false; } - if (!Objects.equals(this.parent, other.parent)) { - return false; - } - if (!Objects.equals(this.parentClass, other.parentClass)) { + if (!Objects.equals(this.isInherited, other.isInherited)) { return false; } return true; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 9c7afce6d9e4..b757ea0f12b7 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -264,9 +264,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { if (duplicatedByParent != null) { log.info(String.format("Property: '%s' in '%s' model is inherited from '%s'" , property.name, child.classname, parent.classname)); - duplicatedByParent.parent = parent.name; - duplicatedByParent.parentClass = parent.classname; - + duplicatedByParent.isInherited = true; final CodegenProperty parentVar = duplicatedByParent.clone(); parentVar.hasMore = false; child.parentVars.add(parentVar); @@ -354,7 +352,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { @Override public String toEnumName(final CodegenProperty property) { - return sanitizeName(camelize(property.name)); + return sanitizeName(camelize(property.name)) + "Enum"; } @Override diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache index 54d23b1d8d56..19e4731f2cf4 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerModelEnum.mustache @@ -1 +1 @@ -public enum {{#parentClass}}{{parentClass}}{{/parentClass}}{{^parentClass}}{{classname}}{{/parentClass}}{{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file +public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}}{{{name}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 9e53ea875eda..949a3db04917 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -18,12 +18,12 @@ namespace {{packageName}}.{{packageContext}}.Models /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// public {{^hasChildrens}}sealed {{/hasChildrens}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> - { {{#vars}}{{^parent}} + { {{#vars}}{{^isInherited}} /// /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} /// public {{>nullableDataType}} {{name}} { get; private set; } -{{/parent}}{{/vars}} +{{/isInherited}}{{/vars}} /// /// Empty constructor required by some serializers. diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache index 038d4224eb1f..3d03a8acfc29 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache @@ -18,12 +18,12 @@ namespace {{packageName}}.{{packageContext}}.Models /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// public {{^hasChildrens}}sealed {{/hasChildrens}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> - { {{#vars}} + { {{#vars}}{{^isInherited}} /// /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} /// public {{>nullableDataType}} {{name}} { get; set; } -{{/vars}} +{{/isInherited}}{{/vars}} public override string ToString() { diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache index 534590a7f896..c999b870119e 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/nullableDataType.mustache @@ -1 +1 @@ -{{#isEnum}}{{#parentClass}}{{parentClass}}{{/parentClass}}{{^parentClass}}{{classname}}{{/parentClass}}{{/isEnum}}{{&datatypeWithEnum}}{{#isEnum}}?{{/isEnum}} \ No newline at end of file +{{&datatypeWithEnum}}{{#isEnum}}?{{/isEnum}} \ No newline at end of file From da5804d583376773c9a186fe18cb00c3ce2172da Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 08:57:49 +0200 Subject: [PATCH 46/64] NancyFx: - Using nullable enum types in API --- modules/swagger-codegen/src/main/resources/nancyfx/api.mustache | 2 +- .../src/main/resources/nancyfx/paramsList.mustache | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index b6e1f316517f..7b20b10a0862 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -26,7 +26,7 @@ namespace {{packageName}}.{{packageContext}}.Modules { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => { - {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}var {{paramName}} = Parameters.ValueOf<{{>innerApiEnumName}}>(parameters, "{{paramName}}");{{/isEnum}}{{^isEnum}}var {{paramName}} = Parameters.ValueOf<{{&dataType}}>(parameters, "{{paramName}}");{{/isEnum}}{{#hasMore}} + {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}var {{paramName}} = Parameters.ValueOf<{{>innerApiEnumName}}?>(parameters, "{{paramName}}");{{/isEnum}}{{^isEnum}}var {{paramName}} = Parameters.ValueOf<{{&dataType}}>(parameters, "{{paramName}}");{{/isEnum}}{{#hasMore}} {{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}} Preconditions.IsNotNull({{paramName}}, "Required parameter: '{{paramName}}' is missing at '{{operationId}}'"); {{/required}}{{/allParams}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache index 2883053e86b6..a1c1d8fbaa10 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/paramsList.mustache @@ -1 +1 @@ -{{#allParams}}{{#isEnum}}{{>innerApiEnumName}}{{/isEnum}}{{^isEnum}}{{&dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file +{{#allParams}}{{#isEnum}}{{>innerApiEnumName}}?{{/isEnum}}{{^isEnum}}{{&dataType}}{{/isEnum}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} \ No newline at end of file From 0996f8c9309fb776e0675c49745c56f2180223c2 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 09:53:42 +0200 Subject: [PATCH 47/64] NancyFx: - Detailed exception of get parameter error --- .../main/resources/nancyfx/parameters.mustache | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 32e615ec2469..3d01f5bb2413 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -17,7 +17,7 @@ namespace {{packageName}}.{{packageContext}}.Utils { var valueType = typeof (TValue); var isNullable = default(TValue) == null; - string value = parameters[name]; + string value = RawValue(parameters, name); Preconditions.Evaluate(!string.IsNullOrEmpty(value) || isNullable, string.Format("Required parameter: '{0}' is missing", name)); if (valueType.IsEnum) { @@ -26,6 +26,18 @@ namespace {{packageName}}.{{packageContext}}.Utils return ValueOf(parameters, name, value, valueType); } + private static string RawValue(dynamic parameters, string name) + { + try + { + return parameters[name]; + } + catch (Exception e) + { + throw new InvalidOperationException(string.Format("Could not obtain value of '{0}' parameter", name), e); + } + } + private static TValue EnumValueOf(string name, string value) { var values = Enum.GetValues(typeof(TValue)); @@ -69,7 +81,7 @@ namespace {{packageName}}.{{packageContext}}.Utils private static TValue DynamicValueOf(dynamic parameters, string name) { - string value = parameters[name]; + string value = RawValue(parameters, name); try { TValue result = parameters[name]; From d201d6331cb58db7e77fddbc97d29c08fac89aad Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 10:52:21 +0200 Subject: [PATCH 48/64] NancyFx: - Details exception for error of dynamic value of parameter --- .../src/main/resources/nancyfx/parameters.mustache | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 3d01f5bb2413..593a117d0e70 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -93,6 +93,11 @@ namespace {{packageName}}.{{packageContext}}.Utils "Expected type: '{2}' is not supported", name, value, typeof(TValue))); } + catch (Exception e) + { + throw new InvalidOperationException(string.Format("Could not get '{0}' value of '{1}' type dynamicly", + name, typeof(TValue)), e); + } } private static IDictionary> CreateParsers() From 4c69e02a21b134f6f261b11a62266e93dcbb5c8c Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 11:00:16 +0200 Subject: [PATCH 49/64] NancyFx: - Fixed parsing nullable enums --- .../src/main/resources/nancyfx/parameters.mustache | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 593a117d0e70..4053744db40f 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -16,10 +16,11 @@ namespace {{packageName}}.{{packageContext}}.Utils internal static TValue ValueOf(dynamic parameters, string name) { var valueType = typeof (TValue); + var valueUnderlyingType = Nullable.GetUnderlyingType(valueType); var isNullable = default(TValue) == null; string value = RawValue(parameters, name); Preconditions.Evaluate(!string.IsNullOrEmpty(value) || isNullable, string.Format("Required parameter: '{0}' is missing", name)); - if (valueType.IsEnum) + if (valueType.IsEnum || (valueUnderlyingType != null && valueUnderlyingType.IsEnum)) { return EnumValueOf(name, value); } From d1cf803e49b7d96f48b8842af7ca5516109289e5 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 11:05:40 +0200 Subject: [PATCH 50/64] NancyFx: - Yet another fix for nullable enums parsing --- .../src/main/resources/nancyfx/parameters.mustache | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 4053744db40f..60dd6e068633 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -41,7 +41,9 @@ namespace {{packageName}}.{{packageContext}}.Utils private static TValue EnumValueOf(string name, string value) { - var values = Enum.GetValues(typeof(TValue)); + var valueType = typeof(TValue); + var enumType = valueType.IsEnum ? valueType : Nullable.GetUnderlyingType(valueType); + var values = Enum.GetValues(enumType); foreach (var entry in values) { if (entry.ToString().EqualsIgnoreCases(value) From a458e53e25cce23082b5b3845dd6ff3f8d00914e Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 11:14:05 +0200 Subject: [PATCH 51/64] NancyFx - Detailed exception of not expected parse error --- .../src/main/resources/nancyfx/parameters.mustache | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 60dd6e068633..5dfc253f3137 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -255,6 +255,11 @@ namespace {{packageName}}.{{packageContext}}.Utils { throw InvalidParameterFormat(parameter, typeof (short)); } + catch (Exception e) + { + throw new InvalidOperationException(Strings.Format("Unable to parse parameter: '{0}' with value: '{1}' to {2}", + parameter.Name, parameter.Value, typeof(T)), e); + } }; } From adb02a030f45d5680d308cfc13cb8e3a68c7e489 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 11:18:51 +0200 Subject: [PATCH 52/64] NancyFx: - Skipping parsing nulls of nullable types --- .../src/main/resources/nancyfx/parameters.mustache | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 5dfc253f3137..5f336b767668 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -20,6 +20,10 @@ namespace {{packageName}}.{{packageContext}}.Utils var isNullable = default(TValue) == null; string value = RawValue(parameters, name); Preconditions.Evaluate(!string.IsNullOrEmpty(value) || isNullable, string.Format("Required parameter: '{0}' is missing", name)); + if (value == null && isNullable) + { + return default(TValue); + } if (valueType.IsEnum || (valueUnderlyingType != null && valueUnderlyingType.IsEnum)) { return EnumValueOf(name, value); From 9c8373aea22dfe67ea13c9c041f5c0cea116bda4 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 11:53:25 +0200 Subject: [PATCH 53/64] NancyFx: - Fixed model template --- .../swagger-codegen/src/main/resources/nancyfx/model.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index 949a3db04917..c6fd17194517 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -36,9 +36,9 @@ namespace {{packageName}}.{{packageContext}}.Models {{#hasChildrens}}protected{{/hasChildrens}}{{^hasChildrens}}private{{/hasChildrens}} {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}){{#parent}} : base({{#parentVars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}} { - {{#vars}}{{^parent}} + {{#vars}}{{^isInherited}} this.{{name}} = {{name}}; - {{/parent}}{{/vars}} + {{/isInherited}}{{/vars}} } /// From 460f8130dbadd0517d380ae826f55f2e751ba3f8 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 13:12:16 +0200 Subject: [PATCH 54/64] NancyFx: - Fixed Query and Headers parameters parsing --- .../src/main/resources/nancyfx/api.mustache | 2 +- .../nancyfx/innerParameterType.mustache | 1 + .../innerParameterValueOfArgs.mustache | 1 + .../resources/nancyfx/parameters.mustache | 46 +++++++++++++++---- 4 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/innerParameterType.mustache create mode 100644 modules/swagger-codegen/src/main/resources/nancyfx/innerParameterValueOfArgs.mustache diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache index 7b20b10a0862..1e66c83c7693 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/api.mustache @@ -26,7 +26,7 @@ namespace {{packageName}}.{{packageContext}}.Modules { {{#operation}} {{httpMethod}}["{{path}}"] = parameters => { - {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}var {{paramName}} = Parameters.ValueOf<{{>innerApiEnumName}}?>(parameters, "{{paramName}}");{{/isEnum}}{{^isEnum}}var {{paramName}} = Parameters.ValueOf<{{&dataType}}>(parameters, "{{paramName}}");{{/isEnum}}{{#hasMore}} + {{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}var {{paramName}} = Parameters.ValueOf<{{>innerApiEnumName}}?>({{>innerParameterValueOfArgs}});{{/isEnum}}{{^isEnum}}var {{paramName}} = Parameters.ValueOf<{{&dataType}}>({{>innerParameterValueOfArgs}});{{/isEnum}}{{#hasMore}} {{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}} Preconditions.IsNotNull({{paramName}}, "Required parameter: '{{paramName}}' is missing at '{{operationId}}'"); {{/required}}{{/allParams}} diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerParameterType.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerParameterType.mustache new file mode 100644 index 000000000000..c9a8cb664495 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerParameterType.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}ParameterType.Query{{/isQueryParam}}{{#isPathParam}}ParameterType.Path{{/isPathParam}}{{#isHeaderParam}}ParameterType.Header{{/isHeaderParam}}{{^isQueryParam}}{{^isPathParam}}{{^isHeaderParam}}ParameterType.Undefined{{/isHeaderParam}}{{/isPathParam}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/innerParameterValueOfArgs.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/innerParameterValueOfArgs.mustache new file mode 100644 index 000000000000..2aca302eecf5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/nancyfx/innerParameterValueOfArgs.mustache @@ -0,0 +1 @@ +parameters, Context.Request, "{{paramName}}", {{>innerParameterType}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index 5f336b767668..ad0825e6ee76 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -13,12 +13,12 @@ namespace {{packageName}}.{{packageContext}}.Utils { private static readonly IDictionary> Parsers = CreateParsers(); - internal static TValue ValueOf(dynamic parameters, string name) + internal static TValue ValueOf(dynamic parameters, Request request, string name, ParameterType parameterType) { var valueType = typeof (TValue); var valueUnderlyingType = Nullable.GetUnderlyingType(valueType); var isNullable = default(TValue) == null; - string value = RawValue(parameters, name); + string value = RawValueOf(parameters, request, name, parameterType); Preconditions.Evaluate(!string.IsNullOrEmpty(value) || isNullable, string.Format("Required parameter: '{0}' is missing", name)); if (value == null && isNullable) { @@ -28,19 +28,31 @@ namespace {{packageName}}.{{packageContext}}.Utils { return EnumValueOf(name, value); } - return ValueOf(parameters, name, value, valueType); + return ValueOf(parameters, name, value, valueType, request, parameterType); } - private static string RawValue(dynamic parameters, string name) + private static string RawValueOf(dynamic parameters, Request request, string name, ParameterType parameterType) { try { - return parameters[name]; + switch (parameterType) + { + case ParameterType.Query: + string querValue = request.Query[name]; + return querValue; + case ParameterType.Path: + string pathValue = parameters[name]; + return pathValue; + case ParameterType.Header: + var headerValue = request.Headers[name]; + return headerValue != null ? string.Join(",", headerValue) : null; + } } catch (Exception e) { throw new InvalidOperationException(string.Format("Could not obtain value of '{0}' parameter", name), e); } + throw new InvalidOperationException(string.Format("Parameter with type: {0} is not supported", parameterType)); } private static TValue EnumValueOf(string name, string value) @@ -60,14 +72,22 @@ namespace {{packageName}}.{{packageContext}}.Utils name, value, value.ToComparable())); } - private static TValue ValueOf(dynamic parameters, string name, string value, Type valueType) + private static TValue ValueOf(dynamic parameters, string name, string value, Type valueType, Request request, ParameterType parameterType) { var parser = Parsers.GetIfPresent(valueType); if (parser != null) { return ParseValueUsing(name, value, valueType, parser); } - return DynamicValueOf(parameters, name); + if (parameterType == ParameterType.Path) + { + return DynamicValueOf(parameters, name); + } + if (parameterType == ParameterType.Query) + { + return DynamicValueOf(request.Query, name); + } + throw new InvalidOperationException(string.Format("Could not get value for {0} with type {1}", name, valueType)); } private static TValue ParseValueUsing(string name, string value, Type valueType, Func parser) @@ -88,7 +108,7 @@ namespace {{packageName}}.{{packageContext}}.Utils private static TValue DynamicValueOf(dynamic parameters, string name) { - string value = RawValue(parameters, name); + string value = parameters[name]; try { TValue result = parameters[name]; @@ -102,7 +122,7 @@ namespace {{packageName}}.{{packageContext}}.Utils } catch (Exception e) { - throw new InvalidOperationException(string.Format("Could not get '{0}' value of '{1}' type dynamicly", + throw new InvalidOperationException(string.Format("Could not get '{0}' value of '{1}' type dynamicly", name, typeof(TValue)), e); } } @@ -364,4 +384,12 @@ namespace {{packageName}}.{{packageContext}}.Utils } } } + + internal enum ParameterType + { + Undefined, + Query, + Path, + Header + } } \ No newline at end of file From 01145be00d50e1030fe25aa14796c8cab669230d Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 2 Jun 2016 16:06:47 +0200 Subject: [PATCH 55/64] NancyFx: - Moved model enum definitions to model class to avoid name duplications --- .../src/main/resources/nancyfx/model.mustache | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index c6fd17194517..e76319291d1a 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -10,10 +10,7 @@ using NodaTime; {{#models}} {{#model}} namespace {{packageName}}.{{packageContext}}.Models -{ {{#vars}}{{#isEnum}}{{^parent}} - {{>innerModelEnum}}{{/parent}}{{/isEnum}}{{#items.isEnum}} - {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} - +{ /// /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// @@ -165,6 +162,10 @@ namespace {{packageName}}.{{packageContext}}.Models } {{/required}}{{/vars}} } } + + {{#vars}}{{#isEnum}}{{^parent}} + {{>innerModelEnum}}{{/parent}}{{/isEnum}}{{#items.isEnum}} + {{#items}}{{>innerModelEnum}}{{/items}}{{/items.isEnum}}{{/vars}} } {{/model}} {{/models}} From e52f991d7246b5ee5ea47a8ff8dbdba8e99e6048 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Thu, 9 Jun 2016 12:58:58 +0200 Subject: [PATCH 56/64] Adding NodaTime types as primitives to keep them nullable. --- .../io/swagger/codegen/languages/NancyFXServerCodegen.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index b757ea0f12b7..213efa0fd280 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -90,6 +90,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection); addSwitch(IMMUTABLE_OPTION, "Enabled by default. If disabled generates model classes with setters", true); typeMapping.putAll(nodaTimeTypesMappings()); + languageSpecificPrimitives.addAll(nodaTimePrimitiveTypes()); importMapping.clear(); } @@ -387,6 +388,10 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { "datetime", "ZonedDateTime?"); } + private static Set nodaTimePrimitiveTypes() { + return ImmutableSet.of("LocalTime?", "ZonedDateTime?"); + } + private class DependencyInfo { private final String version; private final String framework; From e823c12dc0abf484ea587381ec835b7bee29fed8 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Thu, 9 Jun 2016 13:04:31 +0200 Subject: [PATCH 57/64] Rename inheritance property. --- .../swagger/codegen/languages/NancyFXServerCodegen.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index 213efa0fd280..ae9c6368d077 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -63,7 +63,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { private final Map dependencies = new HashMap<>(); private final Set parentModels = new HashSet<>(); - private final Multimap parentChildrens = ArrayListMultimap.create(); + private final Multimap children = ArrayListMultimap.create(); private final BiMap modelNameMapping = HashBiMap.create(); public NancyFXServerCodegen() { @@ -226,7 +226,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { for (final String parent : parentModels) { final CodegenModel parentModel = modelByName(parent, models); parentModel.hasChildrens = true; - final Collection childrens = parentChildrens.get(parent); + final Collection childrens = children.get(parent); for (final CodegenModel child : childrens) { processParentPropertiesInChildModel(parentModel, child); } @@ -282,8 +282,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { super.postProcessModelProperty(model, property); if (!isNullOrEmpty(model.parent)) { parentModels.add(model.parent); - if (!parentChildrens.containsEntry(model.parent, model)) { - parentChildrens.put(model.parent, model); + if (!children.containsEntry(model.parent, model)) { + children.put(model.parent, model); } } } From b604b1b80f4dfdca4c9ddaf193575f36ad41aece Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 9 Jun 2016 13:21:59 +0200 Subject: [PATCH 58/64] NancyFx: - Fixed error message for unsupported enum value - Fixed error message for Format and Overflow exceptions - Added support for ZonedDateTime and LocalTime in Parameters utility --- .../resources/nancyfx/parameters.mustache | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index ad0825e6ee76..c72432a9a729 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -15,7 +15,7 @@ namespace {{packageName}}.{{packageContext}}.Utils internal static TValue ValueOf(dynamic parameters, Request request, string name, ParameterType parameterType) { - var valueType = typeof (TValue); + var valueType = typeof(TValue); var valueUnderlyingType = Nullable.GetUnderlyingType(valueType); var isNullable = default(TValue) == null; string value = RawValueOf(parameters, request, name, parameterType); @@ -38,7 +38,7 @@ namespace {{packageName}}.{{packageContext}}.Utils switch (parameterType) { case ParameterType.Query: - string querValue = request.Query[name]; + string querValue = request.Query[name]; return querValue; case ParameterType.Path: string pathValue = parameters[name]; @@ -59,17 +59,19 @@ namespace {{packageName}}.{{packageContext}}.Utils { var valueType = typeof(TValue); var enumType = valueType.IsEnum ? valueType : Nullable.GetUnderlyingType(valueType); + Preconditions.IsNotNull(enumType, () => new InvalidOperationException( + string.Format("Could not parse parameter: '{0}' to enum. Type {1} is not enum", name, valueType))); var values = Enum.GetValues(enumType); foreach (var entry in values) { - if (entry.ToString().EqualsIgnoreCases(value) - || ((int) entry).ToString().EqualsIgnoreCases(value)) + if (entry.ToString().EqualsIgnoreCases(value) + || ((int)entry).ToString().EqualsIgnoreCases(value)) { - return (TValue) entry; - } + return (TValue)entry; + } } throw new ArgumentException(string.Format("Parameter: '{0}' value: '{1}' is not supported. Expected one of: {2}", - name, value, value.ToComparable())); + name, value, Strings.ToString(values))); } private static TValue ValueOf(dynamic parameters, string name, string value, Type valueType, Request request, ParameterType parameterType) @@ -101,7 +103,7 @@ namespace {{packageName}}.{{packageContext}}.Utils { throw new InvalidOperationException( string.Format("Could not parse parameter: '{0}' with value: '{1}'. " + - "Received: '{2}', expected: '{3}'.", + "Received: '{2}', expected: '{3}'.", name, value, result.GetType(), valueType)); } } @@ -122,7 +124,7 @@ namespace {{packageName}}.{{packageContext}}.Utils } catch (Exception e) { - throw new InvalidOperationException(string.Format("Could not get '{0}' value of '{1}' type dynamicly", + throw new InvalidOperationException(string.Format("Could not get '{0}' value of '{1}' type dynamicly", name, typeof(TValue)), e); } } @@ -157,6 +159,10 @@ namespace {{packageName}}.{{packageContext}}.Utils parsers.Put(typeof(DateTime?), SafeParse(DateTime.Parse)); parsers.Put(typeof(TimeSpan), SafeParse(TimeSpan.Parse)); parsers.Put(typeof(TimeSpan?), SafeParse(TimeSpan.Parse)); + parsers.Put(typeof(ZonedDateTime), SafeParse(ParseZonedDateTime)); + parsers.Put(typeof(ZonedDateTime?), SafeParse(ParseZonedDateTime)); + parsers.Put(typeof(LocalTime), SafeParse(ParseLocalTime)); + parsers.Put(typeof(LocalTime?), SafeParse(ParseLocalTime)); parsers.Put(typeof(IEnumerable), value => value); parsers.Put(typeof(ICollection), value => value); @@ -273,15 +279,15 @@ namespace {{packageName}}.{{packageContext}}.Utils } catch (OverflowException) { - throw ParameterOutOfRange(parameter, typeof (short)); + throw ParameterOutOfRange(parameter, typeof(T)); } catch (FormatException) { - throw InvalidParameterFormat(parameter, typeof (short)); + throw InvalidParameterFormat(parameter, typeof(T)); } catch (Exception e) { - throw new InvalidOperationException(Strings.Format("Unable to parse parameter: '{0}' with value: '{1}' to {2}", + throw new InvalidOperationException(Strings.Format("Unable to parse parameter: '{0}' with value: '{1}' to {2}", parameter.Name, parameter.Value, typeof(T)), e); } }; @@ -295,7 +301,7 @@ namespace {{packageName}}.{{packageContext}}.Utils { return new List(); } - var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) .Where(it => it != null) .Select(it => it.Trim()) .Select(itemParser) @@ -312,7 +318,7 @@ namespace {{packageName}}.{{packageContext}}.Utils { return Lists.EmptyList(); } - var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) .Where(it => it != null) .Select(it => it.Trim()) .Select(itemParser) @@ -329,7 +335,7 @@ namespace {{packageName}}.{{packageContext}}.Utils { return new HashSet(); } - var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) .Where(it => it != null) .Select(it => it.Trim()) .Select(itemParser) @@ -346,7 +352,7 @@ namespace {{packageName}}.{{packageContext}}.Utils { return Sets.EmptySet(); } - var results = parameter.Value.Split(new[] {','}, StringSplitOptions.None) + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) .Where(it => it != null) .Select(it => it.Trim()) .Select(itemParser) @@ -355,9 +361,20 @@ namespace {{packageName}}.{{packageContext}}.Utils }; } + private static ZonedDateTime ParseZonedDateTime(string value) + { + var dateTime = DateTime.Parse(value); + return new ZonedDateTime(Instant.FromDateTimeUtc(dateTime.ToUniversalTime()), DateTimeZone.Utc); + } + + private static LocalTime ParseLocalTime(string value) + { + return LocalTimePattern.ExtendedIsoPattern.Parse(value).Value; + } + private static ArgumentException ParameterOutOfRange(Parameter parameter, Type type) { - return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", + return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", parameter.Name, parameter.Value, type)); } From 33149c3a636aac2e4561b43317e72566e54da0f9 Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Thu, 9 Jun 2016 13:27:01 +0200 Subject: [PATCH 59/64] NancyFx: - Missing namespace import --- .../src/main/resources/nancyfx/parameters.mustache | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache index c72432a9a729..f9a55ba2b772 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/parameters.mustache @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Nancy; +using NodaTime; +using NodaTime.Text; using Sharpility.Base; using Sharpility.Extensions; using Sharpility.Util; From 38298c3709decc058bd7b76568710a292c9e5f2e Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Fri, 17 Jun 2016 09:35:53 +0200 Subject: [PATCH 60/64] NancyFx: - Sharpility version update --- .../src/main/resources/nancyfx/Project.mustache | 4 ++-- .../src/main/resources/nancyfx/packages.config.mustache | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache index e4f4f4c6bc0b..5b63a52feb2b 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/Project.mustache @@ -47,8 +47,8 @@ ..\..\packages\NodaTime.1.3.1\lib\net35-Client\NodaTime.dll True - - ..\..\packages\Sharpility.1.2.1\lib\net45\Sharpility.dll + + ..\..\packages\Sharpility.1.2.2\lib\net45\Sharpility.dll True diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache index 55c32a09bdac..58198276a425 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/packages.config.mustache @@ -2,7 +2,7 @@ - + {{#dependencies}} From 6404d47f9769a90547d7ef9362161896cd60f45e Mon Sep 17 00:00:00 2001 From: Jakub Malek Date: Fri, 17 Jun 2016 15:35:04 +0200 Subject: [PATCH 61/64] NancyFx: - Fixed typo --- .../main/java/io/swagger/codegen/CodegenModel.java | 6 +++--- .../codegen/languages/NancyFXServerCodegen.java | 12 ++++++------ .../src/main/resources/nancyfx/model.mustache | 4 ++-- .../src/main/resources/nancyfx/modelMutable.mustache | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java index a0e5d37d1278..d8205b6e7203 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java @@ -38,7 +38,7 @@ public class CodegenModel { public Set allMandatory; public Set imports = new TreeSet(); - public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired, isArrayModel, hasChildrens; + public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired, isArrayModel, hasChildren; public ExternalDocs externalDocs; public Map vendorExtensions; @@ -123,7 +123,7 @@ public class CodegenModel { return false; if (externalDocs != null ? !externalDocs.equals(that.externalDocs) : that.externalDocs != null) return false; - if (!Objects.equals(hasChildrens, that.hasChildrens)) + if (!Objects.equals(hasChildren, that.hasChildren)) return false; if (!Objects.equals(parentVars, that.parentVars)) return false; @@ -163,7 +163,7 @@ public class CodegenModel { result = 31 * result + (isEnum != null ? isEnum.hashCode() : 0); result = 31 * result + (externalDocs != null ? externalDocs.hashCode() : 0); result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0); - result = 31 * result + Objects.hash(hasChildrens); + result = 31 * result + Objects.hash(hasChildren); result = 31 * result + Objects.hash(parentVars); return result; } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java index ae9c6368d077..3eec3751364b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java @@ -63,7 +63,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { private final Map dependencies = new HashMap<>(); private final Set parentModels = new HashSet<>(); - private final Multimap children = ArrayListMultimap.create(); + private final Multimap childrenByParent = ArrayListMultimap.create(); private final BiMap modelNameMapping = HashBiMap.create(); public NancyFXServerCodegen() { @@ -225,9 +225,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { log.info("Processing parents: " + parentModels); for (final String parent : parentModels) { final CodegenModel parentModel = modelByName(parent, models); - parentModel.hasChildrens = true; - final Collection childrens = children.get(parent); - for (final CodegenModel child : childrens) { + parentModel.hasChildren = true; + final Collection childrenModels = childrenByParent.get(parent); + for (final CodegenModel child : childrenModels) { processParentPropertiesInChildModel(parentModel, child); } } @@ -282,8 +282,8 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen { super.postProcessModelProperty(model, property); if (!isNullOrEmpty(model.parent)) { parentModels.add(model.parent); - if (!children.containsEntry(model.parent, model)) { - children.put(model.parent, model); + if (!childrenByParent.containsEntry(model.parent, model)) { + childrenByParent.put(model.parent, model); } } } diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache index e76319291d1a..2313ae976f1e 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/model.mustache @@ -14,7 +14,7 @@ namespace {{packageName}}.{{packageContext}}.Models /// /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// - public {{^hasChildrens}}sealed {{/hasChildrens}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + public {{^hasChildren}}sealed {{/hasChildren}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}}{{^isInherited}} /// /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} @@ -31,7 +31,7 @@ namespace {{packageName}}.{{packageContext}}.Models { } - {{#hasChildrens}}protected{{/hasChildrens}}{{^hasChildrens}}private{{/hasChildrens}} {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}){{#parent}} : base({{#parentVars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}} + {{#hasChildren}}protected{{/hasChildren}}{{^hasChildren}}private{{/hasChildren}} {{classname}}({{#vars}}{{>nullableDataType}} {{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}){{#parent}} : base({{#parentVars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}} { {{#vars}}{{^isInherited}} this.{{name}} = {{name}}; diff --git a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache index 3d03a8acfc29..a9ef6c90bd33 100644 --- a/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache +++ b/modules/swagger-codegen/src/main/resources/nancyfx/modelMutable.mustache @@ -17,7 +17,7 @@ namespace {{packageName}}.{{packageContext}}.Models /// /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// - public {{^hasChildrens}}sealed {{/hasChildrens}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + public {{^hasChildren}}sealed {{/hasChildren}}class {{classname}}: {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> { {{#vars}}{{^isInherited}} /// /// {{^description}}{{{name}}}{{/description}}{{#description}}{{description}}{{/description}} From 0d9a490c17a2ab2f23deef075b6c2f550fd1f309 Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 20 Jun 2016 10:12:50 +0200 Subject: [PATCH 62/64] Petstore sample for NancyFX. --- .../server/petstore/nancyfx/IO.Swagger.sln | 25 ++ .../nancyfx/src/IO.Swagger/IO.Swagger.csproj | 66 +++ .../nancyfx/src/IO.Swagger/IO.Swagger.nuspec | 14 + .../nancyfx/src/IO.Swagger/Models/Category.cs | 165 +++++++ .../nancyfx/src/IO.Swagger/Models/Order.cs | 246 +++++++++++ .../nancyfx/src/IO.Swagger/Models/Pet.cs | 254 +++++++++++ .../nancyfx/src/IO.Swagger/Models/Tag.cs | 165 +++++++ .../nancyfx/src/IO.Swagger/Models/User.cs | 285 ++++++++++++ .../src/IO.Swagger/Modules/PetModule.cs | 229 ++++++++++ .../src/IO.Swagger/Modules/StoreModule.cs | 126 ++++++ .../src/IO.Swagger/Modules/UserModule.cs | 221 ++++++++++ .../src/IO.Swagger/Utils/Parameters.cs | 414 ++++++++++++++++++ .../nancyfx/src/IO.Swagger/packages.config | 7 + 13 files changed, 2217 insertions(+) create mode 100644 samples/server/petstore/nancyfx/IO.Swagger.sln create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.csproj create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.nuspec create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Models/Category.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Models/Order.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Models/Pet.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Models/Tag.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Models/User.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Modules/PetModule.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Modules/StoreModule.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Modules/UserModule.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/Utils/Parameters.cs create mode 100644 samples/server/petstore/nancyfx/src/IO.Swagger/packages.config diff --git a/samples/server/petstore/nancyfx/IO.Swagger.sln b/samples/server/petstore/nancyfx/IO.Swagger.sln new file mode 100644 index 000000000000..896f0bd86f63 --- /dev/null +++ b/samples/server/petstore/nancyfx/IO.Swagger.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +VisualStudioVersion = 12.0.0.0 +MinimumVisualStudioVersion = 10.0.0.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IO.Swagger", "src\IO.Swagger\IO.Swagger.csproj", "{1DE2DD8D-1AFB-4BC2-9FB5-04DE7DCA1353}" +EndProject +Global +GlobalSection(SolutionConfigurationPlatforms) = preSolution +Debug|Any CPU = Debug|Any CPU +Release|Any CPU = Release|Any CPU +EndGlobalSection +GlobalSection(ProjectConfigurationPlatforms) = postSolution +{1DE2DD8D-1AFB-4BC2-9FB5-04DE7DCA1353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{1DE2DD8D-1AFB-4BC2-9FB5-04DE7DCA1353}.Debug|Any CPU.Build.0 = Debug|Any CPU +{1DE2DD8D-1AFB-4BC2-9FB5-04DE7DCA1353}.Release|Any CPU.ActiveCfg = Release|Any CPU +{1DE2DD8D-1AFB-4BC2-9FB5-04DE7DCA1353}.Release|Any CPU.Build.0 = Release|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU +{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU +EndGlobalSection +GlobalSection(SolutionProperties) = preSolution +HideSolutionNode = FALSE +EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.csproj b/samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.csproj new file mode 100644 index 000000000000..46fb435d4192 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.csproj @@ -0,0 +1,66 @@ + + + + Debug + AnyCPU + {1DE2DD8D-1AFB-4BC2-9FB5-04DE7DCA1353} + Library + Properties + IO.Swagger.v2 + + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\IO.Swagger.XML + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\IO.Swagger.XML + + + + ..\..\packages\Nancy.1.4.1\lib\net40\Nancy.dll + True + + + ..\..\packages\NodaTime.1.3.1\lib\net35-Client\NodaTime.dll + True + + + ..\..\packages\Sharpility.1.2.1\lib\net45\Sharpility.dll + True + + + ..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + True + + + + + + + + + + + + + + + + + + diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.nuspec b/samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.nuspec new file mode 100644 index 000000000000..f6ab1af8e9b9 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/IO.Swagger.nuspec @@ -0,0 +1,14 @@ + + + + IO.Swagger + IO.Swagger + 1.0.0 + swagger-codegen + swagger-codegen + false + NancyFx IO.Swagger API + http://helloreverb.com/terms/ + http://www.apache.org/licenses/LICENSE-2.0.html + + \ No newline at end of file diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Category.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Category.cs new file mode 100644 index 000000000000..759bedd74a99 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Category.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Sharpility.Extensions; +using NodaTime; + +namespace IO.Swagger.v2.Models +{ + /// + /// Category + /// + public sealed class Category: IEquatable + { + /// + /// Id + /// + public long? Id { get; private set; } + + /// + /// Name + /// + public string Name { get; private set; } + + + /// + /// Empty constructor required by some serializers. + /// Use Category.Builder() for instance creation instead. + /// + [Obsolete] + public Category() + { + } + + private Category(long? Id, string Name) + { + + this.Id = Id; + + this.Name = Name; + + } + + /// + /// Returns builder of Category. + /// + /// CategoryBuilder + public static CategoryBuilder Builder() + { + return new CategoryBuilder(); + } + + /// + /// Returns CategoryBuilder with properties set. + /// Use it to change properties. + /// + /// CategoryBuilder + public CategoryBuilder With() + { + return Builder() + .Id(Id) + .Name(Name); + } + + public override string ToString() + { + return this.PropertiesToString(); + } + + public override bool Equals(object obj) + { + return this.EqualsByProperties(obj); + } + + public bool Equals(Category other) + { + return Equals((object) other); + } + + public override int GetHashCode() + { + return this.PropertiesHash(); + } + + /// + /// Implementation of == operator for (Category. + /// + /// Compared (Category + /// Compared (Category + /// true if compared items are equals, false otherwise + public static bool operator == (Category left, Category right) + { + return Equals(left, right); + } + + /// + /// Implementation of != operator for (Category. + /// + /// Compared (Category + /// Compared (Category + /// true if compared items are not equals, false otherwise + public static bool operator != (Category left, Category right) + { + return !Equals(left, right); + } + + /// + /// Builder of Category. + /// + public sealed class CategoryBuilder + { + private long? _Id; + private string _Name; + + internal CategoryBuilder() + { + SetupDefaults(); + } + + private void SetupDefaults() + { + } + + /// + /// Sets value for Category.Id property. + /// + /// Id + public CategoryBuilder Id(long? value) + { + _Id = value; + return this; + } + + /// + /// Sets value for Category.Name property. + /// + /// Name + public CategoryBuilder Name(string value) + { + _Name = value; + return this; + } + + + /// + /// Builds instance of Category. + /// + /// Category + public Category Build() + { + Validate(); + return new Category( + Id: _Id, + Name: _Name + ); + } + + private void Validate() + { + } + } + + + } +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Order.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Order.cs new file mode 100644 index 000000000000..22245ee5bfeb --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Order.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Sharpility.Extensions; +using NodaTime; + +namespace IO.Swagger.v2.Models +{ + /// + /// Order + /// + public sealed class Order: IEquatable + { + /// + /// Id + /// + public long? Id { get; private set; } + + /// + /// PetId + /// + public long? PetId { get; private set; } + + /// + /// Quantity + /// + public int? Quantity { get; private set; } + + /// + /// ShipDate + /// + public ZonedDateTime? ShipDate { get; private set; } + + /// + /// Order Status + /// + public StatusEnum? Status { get; private set; } + + /// + /// Complete + /// + public bool? Complete { get; private set; } + + + /// + /// Empty constructor required by some serializers. + /// Use Order.Builder() for instance creation instead. + /// + [Obsolete] + public Order() + { + } + + private Order(long? Id, long? PetId, int? Quantity, ZonedDateTime? ShipDate, StatusEnum? Status, bool? Complete) + { + + this.Id = Id; + + this.PetId = PetId; + + this.Quantity = Quantity; + + this.ShipDate = ShipDate; + + this.Status = Status; + + this.Complete = Complete; + + } + + /// + /// Returns builder of Order. + /// + /// OrderBuilder + public static OrderBuilder Builder() + { + return new OrderBuilder(); + } + + /// + /// Returns OrderBuilder with properties set. + /// Use it to change properties. + /// + /// OrderBuilder + public OrderBuilder With() + { + return Builder() + .Id(Id) + .PetId(PetId) + .Quantity(Quantity) + .ShipDate(ShipDate) + .Status(Status) + .Complete(Complete); + } + + public override string ToString() + { + return this.PropertiesToString(); + } + + public override bool Equals(object obj) + { + return this.EqualsByProperties(obj); + } + + public bool Equals(Order other) + { + return Equals((object) other); + } + + public override int GetHashCode() + { + return this.PropertiesHash(); + } + + /// + /// Implementation of == operator for (Order. + /// + /// Compared (Order + /// Compared (Order + /// true if compared items are equals, false otherwise + public static bool operator == (Order left, Order right) + { + return Equals(left, right); + } + + /// + /// Implementation of != operator for (Order. + /// + /// Compared (Order + /// Compared (Order + /// true if compared items are not equals, false otherwise + public static bool operator != (Order left, Order right) + { + return !Equals(left, right); + } + + /// + /// Builder of Order. + /// + public sealed class OrderBuilder + { + private long? _Id; + private long? _PetId; + private int? _Quantity; + private ZonedDateTime? _ShipDate; + private StatusEnum? _Status; + private bool? _Complete; + + internal OrderBuilder() + { + SetupDefaults(); + } + + private void SetupDefaults() + { + } + + /// + /// Sets value for Order.Id property. + /// + /// Id + public OrderBuilder Id(long? value) + { + _Id = value; + return this; + } + + /// + /// Sets value for Order.PetId property. + /// + /// PetId + public OrderBuilder PetId(long? value) + { + _PetId = value; + return this; + } + + /// + /// Sets value for Order.Quantity property. + /// + /// Quantity + public OrderBuilder Quantity(int? value) + { + _Quantity = value; + return this; + } + + /// + /// Sets value for Order.ShipDate property. + /// + /// ShipDate + public OrderBuilder ShipDate(ZonedDateTime? value) + { + _ShipDate = value; + return this; + } + + /// + /// Sets value for Order.Status property. + /// + /// Order Status + public OrderBuilder Status(StatusEnum? value) + { + _Status = value; + return this; + } + + /// + /// Sets value for Order.Complete property. + /// + /// Complete + public OrderBuilder Complete(bool? value) + { + _Complete = value; + return this; + } + + + /// + /// Builds instance of Order. + /// + /// Order + public Order Build() + { + Validate(); + return new Order( + Id: _Id, + PetId: _PetId, + Quantity: _Quantity, + ShipDate: _ShipDate, + Status: _Status, + Complete: _Complete + ); + } + + private void Validate() + { + } + } + + + public enum StatusEnum { Placed, Approved, Delivered }; + } +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Pet.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Pet.cs new file mode 100644 index 000000000000..aef03f6ba970 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Pet.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Sharpility.Extensions; +using NodaTime; + +namespace IO.Swagger.v2.Models +{ + /// + /// Pet + /// + public sealed class Pet: IEquatable + { + /// + /// Id + /// + public long? Id { get; private set; } + + /// + /// Category + /// + public Category Category { get; private set; } + + /// + /// Name + /// + public string Name { get; private set; } + + /// + /// PhotoUrls + /// + public List PhotoUrls { get; private set; } + + /// + /// Tags + /// + public List Tags { get; private set; } + + /// + /// pet status in the store + /// + public StatusEnum? Status { get; private set; } + + + /// + /// Empty constructor required by some serializers. + /// Use Pet.Builder() for instance creation instead. + /// + [Obsolete] + public Pet() + { + } + + private Pet(long? Id, Category Category, string Name, List PhotoUrls, List Tags, StatusEnum? Status) + { + + this.Id = Id; + + this.Category = Category; + + this.Name = Name; + + this.PhotoUrls = PhotoUrls; + + this.Tags = Tags; + + this.Status = Status; + + } + + /// + /// Returns builder of Pet. + /// + /// PetBuilder + public static PetBuilder Builder() + { + return new PetBuilder(); + } + + /// + /// Returns PetBuilder with properties set. + /// Use it to change properties. + /// + /// PetBuilder + public PetBuilder With() + { + return Builder() + .Id(Id) + .Category(Category) + .Name(Name) + .PhotoUrls(PhotoUrls) + .Tags(Tags) + .Status(Status); + } + + public override string ToString() + { + return this.PropertiesToString(); + } + + public override bool Equals(object obj) + { + return this.EqualsByProperties(obj); + } + + public bool Equals(Pet other) + { + return Equals((object) other); + } + + public override int GetHashCode() + { + return this.PropertiesHash(); + } + + /// + /// Implementation of == operator for (Pet. + /// + /// Compared (Pet + /// Compared (Pet + /// true if compared items are equals, false otherwise + public static bool operator == (Pet left, Pet right) + { + return Equals(left, right); + } + + /// + /// Implementation of != operator for (Pet. + /// + /// Compared (Pet + /// Compared (Pet + /// true if compared items are not equals, false otherwise + public static bool operator != (Pet left, Pet right) + { + return !Equals(left, right); + } + + /// + /// Builder of Pet. + /// + public sealed class PetBuilder + { + private long? _Id; + private Category _Category; + private string _Name; + private List _PhotoUrls; + private List _Tags; + private StatusEnum? _Status; + + internal PetBuilder() + { + SetupDefaults(); + } + + private void SetupDefaults() + { + } + + /// + /// Sets value for Pet.Id property. + /// + /// Id + public PetBuilder Id(long? value) + { + _Id = value; + return this; + } + + /// + /// Sets value for Pet.Category property. + /// + /// Category + public PetBuilder Category(Category value) + { + _Category = value; + return this; + } + + /// + /// Sets value for Pet.Name property. + /// + /// Name + public PetBuilder Name(string value) + { + _Name = value; + return this; + } + + /// + /// Sets value for Pet.PhotoUrls property. + /// + /// PhotoUrls + public PetBuilder PhotoUrls(List value) + { + _PhotoUrls = value; + return this; + } + + /// + /// Sets value for Pet.Tags property. + /// + /// Tags + public PetBuilder Tags(List value) + { + _Tags = value; + return this; + } + + /// + /// Sets value for Pet.Status property. + /// + /// pet status in the store + public PetBuilder Status(StatusEnum? value) + { + _Status = value; + return this; + } + + + /// + /// Builds instance of Pet. + /// + /// Pet + public Pet Build() + { + Validate(); + return new Pet( + Id: _Id, + Category: _Category, + Name: _Name, + PhotoUrls: _PhotoUrls, + Tags: _Tags, + Status: _Status + ); + } + + private void Validate() + { + if (_Name == null) + { + throw new ArgumentException("Name is a required property for Pet and cannot be null"); + } + if (_PhotoUrls == null) + { + throw new ArgumentException("PhotoUrls is a required property for Pet and cannot be null"); + } + } + } + + + public enum StatusEnum { Available, Pending, Sold }; + } +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Tag.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Tag.cs new file mode 100644 index 000000000000..36fd8204a8a8 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/Tag.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Sharpility.Extensions; +using NodaTime; + +namespace IO.Swagger.v2.Models +{ + /// + /// Tag + /// + public sealed class Tag: IEquatable + { + /// + /// Id + /// + public long? Id { get; private set; } + + /// + /// Name + /// + public string Name { get; private set; } + + + /// + /// Empty constructor required by some serializers. + /// Use Tag.Builder() for instance creation instead. + /// + [Obsolete] + public Tag() + { + } + + private Tag(long? Id, string Name) + { + + this.Id = Id; + + this.Name = Name; + + } + + /// + /// Returns builder of Tag. + /// + /// TagBuilder + public static TagBuilder Builder() + { + return new TagBuilder(); + } + + /// + /// Returns TagBuilder with properties set. + /// Use it to change properties. + /// + /// TagBuilder + public TagBuilder With() + { + return Builder() + .Id(Id) + .Name(Name); + } + + public override string ToString() + { + return this.PropertiesToString(); + } + + public override bool Equals(object obj) + { + return this.EqualsByProperties(obj); + } + + public bool Equals(Tag other) + { + return Equals((object) other); + } + + public override int GetHashCode() + { + return this.PropertiesHash(); + } + + /// + /// Implementation of == operator for (Tag. + /// + /// Compared (Tag + /// Compared (Tag + /// true if compared items are equals, false otherwise + public static bool operator == (Tag left, Tag right) + { + return Equals(left, right); + } + + /// + /// Implementation of != operator for (Tag. + /// + /// Compared (Tag + /// Compared (Tag + /// true if compared items are not equals, false otherwise + public static bool operator != (Tag left, Tag right) + { + return !Equals(left, right); + } + + /// + /// Builder of Tag. + /// + public sealed class TagBuilder + { + private long? _Id; + private string _Name; + + internal TagBuilder() + { + SetupDefaults(); + } + + private void SetupDefaults() + { + } + + /// + /// Sets value for Tag.Id property. + /// + /// Id + public TagBuilder Id(long? value) + { + _Id = value; + return this; + } + + /// + /// Sets value for Tag.Name property. + /// + /// Name + public TagBuilder Name(string value) + { + _Name = value; + return this; + } + + + /// + /// Builds instance of Tag. + /// + /// Tag + public Tag Build() + { + Validate(); + return new Tag( + Id: _Id, + Name: _Name + ); + } + + private void Validate() + { + } + } + + + } +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Models/User.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/User.cs new file mode 100644 index 000000000000..69d079ff42d2 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Models/User.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Sharpility.Extensions; +using NodaTime; + +namespace IO.Swagger.v2.Models +{ + /// + /// User + /// + public sealed class User: IEquatable + { + /// + /// Id + /// + public long? Id { get; private set; } + + /// + /// Username + /// + public string Username { get; private set; } + + /// + /// FirstName + /// + public string FirstName { get; private set; } + + /// + /// LastName + /// + public string LastName { get; private set; } + + /// + /// Email + /// + public string Email { get; private set; } + + /// + /// Password + /// + public string Password { get; private set; } + + /// + /// Phone + /// + public string Phone { get; private set; } + + /// + /// User Status + /// + public int? UserStatus { get; private set; } + + + /// + /// Empty constructor required by some serializers. + /// Use User.Builder() for instance creation instead. + /// + [Obsolete] + public User() + { + } + + private User(long? Id, string Username, string FirstName, string LastName, string Email, string Password, string Phone, int? UserStatus) + { + + this.Id = Id; + + this.Username = Username; + + this.FirstName = FirstName; + + this.LastName = LastName; + + this.Email = Email; + + this.Password = Password; + + this.Phone = Phone; + + this.UserStatus = UserStatus; + + } + + /// + /// Returns builder of User. + /// + /// UserBuilder + public static UserBuilder Builder() + { + return new UserBuilder(); + } + + /// + /// Returns UserBuilder with properties set. + /// Use it to change properties. + /// + /// UserBuilder + public UserBuilder With() + { + return Builder() + .Id(Id) + .Username(Username) + .FirstName(FirstName) + .LastName(LastName) + .Email(Email) + .Password(Password) + .Phone(Phone) + .UserStatus(UserStatus); + } + + public override string ToString() + { + return this.PropertiesToString(); + } + + public override bool Equals(object obj) + { + return this.EqualsByProperties(obj); + } + + public bool Equals(User other) + { + return Equals((object) other); + } + + public override int GetHashCode() + { + return this.PropertiesHash(); + } + + /// + /// Implementation of == operator for (User. + /// + /// Compared (User + /// Compared (User + /// true if compared items are equals, false otherwise + public static bool operator == (User left, User right) + { + return Equals(left, right); + } + + /// + /// Implementation of != operator for (User. + /// + /// Compared (User + /// Compared (User + /// true if compared items are not equals, false otherwise + public static bool operator != (User left, User right) + { + return !Equals(left, right); + } + + /// + /// Builder of User. + /// + public sealed class UserBuilder + { + private long? _Id; + private string _Username; + private string _FirstName; + private string _LastName; + private string _Email; + private string _Password; + private string _Phone; + private int? _UserStatus; + + internal UserBuilder() + { + SetupDefaults(); + } + + private void SetupDefaults() + { + } + + /// + /// Sets value for User.Id property. + /// + /// Id + public UserBuilder Id(long? value) + { + _Id = value; + return this; + } + + /// + /// Sets value for User.Username property. + /// + /// Username + public UserBuilder Username(string value) + { + _Username = value; + return this; + } + + /// + /// Sets value for User.FirstName property. + /// + /// FirstName + public UserBuilder FirstName(string value) + { + _FirstName = value; + return this; + } + + /// + /// Sets value for User.LastName property. + /// + /// LastName + public UserBuilder LastName(string value) + { + _LastName = value; + return this; + } + + /// + /// Sets value for User.Email property. + /// + /// Email + public UserBuilder Email(string value) + { + _Email = value; + return this; + } + + /// + /// Sets value for User.Password property. + /// + /// Password + public UserBuilder Password(string value) + { + _Password = value; + return this; + } + + /// + /// Sets value for User.Phone property. + /// + /// Phone + public UserBuilder Phone(string value) + { + _Phone = value; + return this; + } + + /// + /// Sets value for User.UserStatus property. + /// + /// User Status + public UserBuilder UserStatus(int? value) + { + _UserStatus = value; + return this; + } + + + /// + /// Builds instance of User. + /// + /// User + public User Build() + { + Validate(); + return new User( + Id: _Id, + Username: _Username, + FirstName: _FirstName, + LastName: _LastName, + Email: _Email, + Password: _Password, + Phone: _Phone, + UserStatus: _UserStatus + ); + } + + private void Validate() + { + } + } + + + } +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/PetModule.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/PetModule.cs new file mode 100644 index 000000000000..f3ab9ee2892c --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/PetModule.cs @@ -0,0 +1,229 @@ +using System; +using Nancy; +using Nancy.ModelBinding; +using System.Collections.Generic; +using Sharpility.Base; +using IO.Swagger.v2.Models; +using IO.Swagger.v2.Utils; +using NodaTime; + +namespace IO.Swagger.v2.Modules +{ + + /// + /// Module processing requests of Pet domain. + /// + public sealed class PetModule : NancyModule + { + /// + /// Sets up HTTP methods mappings. + /// + /// Service handling requests + public PetModule(PetService service) : base("/v2") + { + Post["/pet"] = parameters => + { + var body = this.Bind(); + service.AddPet(Context, body); + return new Response { ContentType = "application/json"}; + }; + + Delete["/pet/{petId}"] = parameters => + { + var petId = Parameters.ValueOf(parameters, Context.Request, "petId", ParameterType.Path); + var apiKey = Parameters.ValueOf(parameters, Context.Request, "apiKey", ParameterType.Header); + Preconditions.IsNotNull(petId, "Required parameter: 'petId' is missing at 'DeletePet'"); + + service.DeletePet(Context, petId, apiKey); + return new Response { ContentType = "application/json"}; + }; + + Get["/pet/findByStatus"] = parameters => + { + var status = Parameters.ValueOf>(parameters, Context.Request, "status", ParameterType.Query); + return service.FindPetsByStatus(Context, status); + }; + + Get["/pet/findByTags"] = parameters => + { + var tags = Parameters.ValueOf>(parameters, Context.Request, "tags", ParameterType.Query); + return service.FindPetsByTags(Context, tags); + }; + + Get["/pet/{petId}"] = parameters => + { + var petId = Parameters.ValueOf(parameters, Context.Request, "petId", ParameterType.Path); + Preconditions.IsNotNull(petId, "Required parameter: 'petId' is missing at 'GetPetById'"); + + return service.GetPetById(Context, petId); + }; + + Put["/pet"] = parameters => + { + var body = this.Bind(); + service.UpdatePet(Context, body); + return new Response { ContentType = "application/json"}; + }; + + Post["/pet/{petId}"] = parameters => + { + var petId = Parameters.ValueOf(parameters, Context.Request, "petId", ParameterType.Path); + var name = Parameters.ValueOf(parameters, Context.Request, "name", ParameterType.Undefined); + var status = Parameters.ValueOf(parameters, Context.Request, "status", ParameterType.Undefined); + Preconditions.IsNotNull(petId, "Required parameter: 'petId' is missing at 'UpdatePetWithForm'"); + + service.UpdatePetWithForm(Context, petId, name, status); + return new Response { ContentType = "application/json"}; + }; + + Post["/pet/{petId}/uploadImage"] = parameters => + { + var petId = Parameters.ValueOf(parameters, Context.Request, "petId", ParameterType.Path); + var additionalMetadata = Parameters.ValueOf(parameters, Context.Request, "additionalMetadata", ParameterType.Undefined); + var file = Parameters.ValueOf(parameters, Context.Request, "file", ParameterType.Undefined); + Preconditions.IsNotNull(petId, "Required parameter: 'petId' is missing at 'UploadFile'"); + + service.UploadFile(Context, petId, additionalMetadata, file); + return new Response { ContentType = "application/json"}; + }; + } + } + + /// + /// Service handling Pet requests. + /// + public interface PetService + { + /// + /// + /// + /// Context of request + /// Pet object that needs to be added to the store (optional) + /// + void AddPet(NancyContext context, Pet body); + + /// + /// + /// + /// Context of request + /// Pet id to delete + /// (optional) + /// + void DeletePet(NancyContext context, long? petId, string apiKey); + + /// + /// Multiple status values can be provided with comma seperated strings + /// + /// Context of request + /// Status values that need to be considered for filter (optional, default to available) + /// List<Pet> + List FindPetsByStatus(NancyContext context, List status); + + /// + /// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + /// + /// Context of request + /// Tags to filter by (optional) + /// List<Pet> + List FindPetsByTags(NancyContext context, List tags); + + /// + /// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + /// + /// Context of request + /// ID of pet that needs to be fetched + /// Pet + Pet GetPetById(NancyContext context, long? petId); + + /// + /// + /// + /// Context of request + /// Pet object that needs to be added to the store (optional) + /// + void UpdatePet(NancyContext context, Pet body); + + /// + /// + /// + /// Context of request + /// ID of pet that needs to be updated + /// Updated name of the pet (optional) + /// Updated status of the pet (optional) + /// + void UpdatePetWithForm(NancyContext context, string petId, string name, string status); + + /// + /// + /// + /// Context of request + /// ID of pet to update + /// Additional data to pass to server (optional) + /// file to upload (optional) + /// + void UploadFile(NancyContext context, long? petId, string additionalMetadata, System.IO.Stream file); + } + + /// + /// Abstraction of PetService. + /// + public abstract class AbstractPetService: PetService + { + public virtual void AddPet(NancyContext context, Pet body) + { + AddPet(body); + } + + public virtual void DeletePet(NancyContext context, long? petId, string apiKey) + { + DeletePet(petId, apiKey); + } + + public virtual List FindPetsByStatus(NancyContext context, List status) + { + return FindPetsByStatus(status); + } + + public virtual List FindPetsByTags(NancyContext context, List tags) + { + return FindPetsByTags(tags); + } + + public virtual Pet GetPetById(NancyContext context, long? petId) + { + return GetPetById(petId); + } + + public virtual void UpdatePet(NancyContext context, Pet body) + { + UpdatePet(body); + } + + public virtual void UpdatePetWithForm(NancyContext context, string petId, string name, string status) + { + UpdatePetWithForm(petId, name, status); + } + + public virtual void UploadFile(NancyContext context, long? petId, string additionalMetadata, System.IO.Stream file) + { + UploadFile(petId, additionalMetadata, file); + } + + protected abstract void AddPet(Pet body); + + protected abstract void DeletePet(long? petId, string apiKey); + + protected abstract List FindPetsByStatus(List status); + + protected abstract List FindPetsByTags(List tags); + + protected abstract Pet GetPetById(long? petId); + + protected abstract void UpdatePet(Pet body); + + protected abstract void UpdatePetWithForm(string petId, string name, string status); + + protected abstract void UploadFile(long? petId, string additionalMetadata, System.IO.Stream file); + } + +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/StoreModule.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/StoreModule.cs new file mode 100644 index 000000000000..06f397db4082 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/StoreModule.cs @@ -0,0 +1,126 @@ +using System; +using Nancy; +using Nancy.ModelBinding; +using System.Collections.Generic; +using Sharpility.Base; +using IO.Swagger.v2.Models; +using IO.Swagger.v2.Utils; +using NodaTime; + +namespace IO.Swagger.v2.Modules +{ + + /// + /// Module processing requests of Store domain. + /// + public sealed class StoreModule : NancyModule + { + /// + /// Sets up HTTP methods mappings. + /// + /// Service handling requests + public StoreModule(StoreService service) : base("/v2") + { + Delete["/store/order/{orderId}"] = parameters => + { + var orderId = Parameters.ValueOf(parameters, Context.Request, "orderId", ParameterType.Path); + Preconditions.IsNotNull(orderId, "Required parameter: 'orderId' is missing at 'DeleteOrder'"); + + service.DeleteOrder(Context, orderId); + return new Response { ContentType = "application/json"}; + }; + + Get["/store/inventory"] = parameters => + { + + return service.GetInventory(Context); + }; + + Get["/store/order/{orderId}"] = parameters => + { + var orderId = Parameters.ValueOf(parameters, Context.Request, "orderId", ParameterType.Path); + Preconditions.IsNotNull(orderId, "Required parameter: 'orderId' is missing at 'GetOrderById'"); + + return service.GetOrderById(Context, orderId); + }; + + Post["/store/order"] = parameters => + { + var body = this.Bind(); + return service.PlaceOrder(Context, body); + }; + } + } + + /// + /// Service handling Store requests. + /// + public interface StoreService + { + /// + /// For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + /// + /// Context of request + /// ID of the order that needs to be deleted + /// + void DeleteOrder(NancyContext context, string orderId); + + /// + /// Returns a map of status codes to quantities + /// + /// Context of request + /// Dictionary<string, int?> + Dictionary GetInventory(NancyContext context); + + /// + /// For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + /// + /// Context of request + /// ID of pet that needs to be fetched + /// Order + Order GetOrderById(NancyContext context, string orderId); + + /// + /// + /// + /// Context of request + /// order placed for purchasing the pet (optional) + /// Order + Order PlaceOrder(NancyContext context, Order body); + } + + /// + /// Abstraction of StoreService. + /// + public abstract class AbstractStoreService: StoreService + { + public virtual void DeleteOrder(NancyContext context, string orderId) + { + DeleteOrder(orderId); + } + + public virtual Dictionary GetInventory(NancyContext context) + { + return GetInventory(); + } + + public virtual Order GetOrderById(NancyContext context, string orderId) + { + return GetOrderById(orderId); + } + + public virtual Order PlaceOrder(NancyContext context, Order body) + { + return PlaceOrder(body); + } + + protected abstract void DeleteOrder(string orderId); + + protected abstract Dictionary GetInventory(); + + protected abstract Order GetOrderById(string orderId); + + protected abstract Order PlaceOrder(Order body); + } + +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/UserModule.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/UserModule.cs new file mode 100644 index 000000000000..8350479ef121 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Modules/UserModule.cs @@ -0,0 +1,221 @@ +using System; +using Nancy; +using Nancy.ModelBinding; +using System.Collections.Generic; +using Sharpility.Base; +using IO.Swagger.v2.Models; +using IO.Swagger.v2.Utils; +using NodaTime; + +namespace IO.Swagger.v2.Modules +{ + + /// + /// Module processing requests of User domain. + /// + public sealed class UserModule : NancyModule + { + /// + /// Sets up HTTP methods mappings. + /// + /// Service handling requests + public UserModule(UserService service) : base("/v2") + { + Post["/user"] = parameters => + { + var body = this.Bind(); + service.CreateUser(Context, body); + return new Response { ContentType = "application/json"}; + }; + + Post["/user/createWithArray"] = parameters => + { + var body = this.Bind>(); + service.CreateUsersWithArrayInput(Context, body); + return new Response { ContentType = "application/json"}; + }; + + Post["/user/createWithList"] = parameters => + { + var body = this.Bind>(); + service.CreateUsersWithListInput(Context, body); + return new Response { ContentType = "application/json"}; + }; + + Delete["/user/{username}"] = parameters => + { + var username = Parameters.ValueOf(parameters, Context.Request, "username", ParameterType.Path); + Preconditions.IsNotNull(username, "Required parameter: 'username' is missing at 'DeleteUser'"); + + service.DeleteUser(Context, username); + return new Response { ContentType = "application/json"}; + }; + + Get["/user/{username}"] = parameters => + { + var username = Parameters.ValueOf(parameters, Context.Request, "username", ParameterType.Path); + Preconditions.IsNotNull(username, "Required parameter: 'username' is missing at 'GetUserByName'"); + + return service.GetUserByName(Context, username); + }; + + Get["/user/login"] = parameters => + { + var username = Parameters.ValueOf(parameters, Context.Request, "username", ParameterType.Query); + var password = Parameters.ValueOf(parameters, Context.Request, "password", ParameterType.Query); + return service.LoginUser(Context, username, password); + }; + + Get["/user/logout"] = parameters => + { + + service.LogoutUser(Context); + return new Response { ContentType = "application/json"}; + }; + + Put["/user/{username}"] = parameters => + { + var username = Parameters.ValueOf(parameters, Context.Request, "username", ParameterType.Path); + var body = this.Bind(); + Preconditions.IsNotNull(username, "Required parameter: 'username' is missing at 'UpdateUser'"); + + service.UpdateUser(Context, username, body); + return new Response { ContentType = "application/json"}; + }; + } + } + + /// + /// Service handling User requests. + /// + public interface UserService + { + /// + /// This can only be done by the logged in user. + /// + /// Context of request + /// Created user object (optional) + /// + void CreateUser(NancyContext context, User body); + + /// + /// + /// + /// Context of request + /// List of user object (optional) + /// + void CreateUsersWithArrayInput(NancyContext context, List body); + + /// + /// + /// + /// Context of request + /// List of user object (optional) + /// + void CreateUsersWithListInput(NancyContext context, List body); + + /// + /// This can only be done by the logged in user. + /// + /// Context of request + /// The name that needs to be deleted + /// + void DeleteUser(NancyContext context, string username); + + /// + /// + /// + /// Context of request + /// The name that needs to be fetched. Use user1 for testing. + /// User + User GetUserByName(NancyContext context, string username); + + /// + /// + /// + /// Context of request + /// The user name for login (optional) + /// The password for login in clear text (optional) + /// string + string LoginUser(NancyContext context, string username, string password); + + /// + /// + /// + /// Context of request + /// + void LogoutUser(NancyContext context); + + /// + /// This can only be done by the logged in user. + /// + /// Context of request + /// name that need to be deleted + /// Updated user object (optional) + /// + void UpdateUser(NancyContext context, string username, User body); + } + + /// + /// Abstraction of UserService. + /// + public abstract class AbstractUserService: UserService + { + public virtual void CreateUser(NancyContext context, User body) + { + CreateUser(body); + } + + public virtual void CreateUsersWithArrayInput(NancyContext context, List body) + { + CreateUsersWithArrayInput(body); + } + + public virtual void CreateUsersWithListInput(NancyContext context, List body) + { + CreateUsersWithListInput(body); + } + + public virtual void DeleteUser(NancyContext context, string username) + { + DeleteUser(username); + } + + public virtual User GetUserByName(NancyContext context, string username) + { + return GetUserByName(username); + } + + public virtual string LoginUser(NancyContext context, string username, string password) + { + return LoginUser(username, password); + } + + public virtual void LogoutUser(NancyContext context) + { + LogoutUser(); + } + + public virtual void UpdateUser(NancyContext context, string username, User body) + { + UpdateUser(username, body); + } + + protected abstract void CreateUser(User body); + + protected abstract void CreateUsersWithArrayInput(List body); + + protected abstract void CreateUsersWithListInput(List body); + + protected abstract void DeleteUser(string username); + + protected abstract User GetUserByName(string username); + + protected abstract string LoginUser(string username, string password); + + protected abstract void LogoutUser(); + + protected abstract void UpdateUser(string username, User body); + } + +} diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/Utils/Parameters.cs b/samples/server/petstore/nancyfx/src/IO.Swagger/Utils/Parameters.cs new file mode 100644 index 000000000000..954683f095f5 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/Utils/Parameters.cs @@ -0,0 +1,414 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Nancy; +using NodaTime; +using NodaTime.Text; +using Sharpility.Base; +using Sharpility.Extensions; +using Sharpility.Util; + +namespace IO.Swagger.v2.Utils +{ + internal static class Parameters + { + private static readonly IDictionary> Parsers = CreateParsers(); + + internal static TValue ValueOf(dynamic parameters, Request request, string name, ParameterType parameterType) + { + var valueType = typeof(TValue); + var valueUnderlyingType = Nullable.GetUnderlyingType(valueType); + var isNullable = default(TValue) == null; + string value = RawValueOf(parameters, request, name, parameterType); + Preconditions.Evaluate(!string.IsNullOrEmpty(value) || isNullable, string.Format("Required parameter: '{0}' is missing", name)); + if (value == null && isNullable) + { + return default(TValue); + } + if (valueType.IsEnum || (valueUnderlyingType != null && valueUnderlyingType.IsEnum)) + { + return EnumValueOf(name, value); + } + return ValueOf(parameters, name, value, valueType, request, parameterType); + } + + private static string RawValueOf(dynamic parameters, Request request, string name, ParameterType parameterType) + { + try + { + switch (parameterType) + { + case ParameterType.Query: + string querValue = request.Query[name]; + return querValue; + case ParameterType.Path: + string pathValue = parameters[name]; + return pathValue; + case ParameterType.Header: + var headerValue = request.Headers[name]; + return headerValue != null ? string.Join(",", headerValue) : null; + } + } + catch (Exception e) + { + throw new InvalidOperationException(string.Format("Could not obtain value of '{0}' parameter", name), e); + } + throw new InvalidOperationException(string.Format("Parameter with type: {0} is not supported", parameterType)); + } + + private static TValue EnumValueOf(string name, string value) + { + var valueType = typeof(TValue); + var enumType = valueType.IsEnum ? valueType : Nullable.GetUnderlyingType(valueType); + Preconditions.IsNotNull(enumType, () => new InvalidOperationException( + string.Format("Could not parse parameter: '{0}' to enum. Type {1} is not enum", name, valueType))); + var values = Enum.GetValues(enumType); + foreach (var entry in values) + { + if (entry.ToString().EqualsIgnoreCases(value) + || ((int)entry).ToString().EqualsIgnoreCases(value)) + { + return (TValue)entry; + } + } + throw new ArgumentException(string.Format("Parameter: '{0}' value: '{1}' is not supported. Expected one of: {2}", + name, value, Strings.ToString(values))); + } + + private static TValue ValueOf(dynamic parameters, string name, string value, Type valueType, Request request, ParameterType parameterType) + { + var parser = Parsers.GetIfPresent(valueType); + if (parser != null) + { + return ParseValueUsing(name, value, valueType, parser); + } + if (parameterType == ParameterType.Path) + { + return DynamicValueOf(parameters, name); + } + if (parameterType == ParameterType.Query) + { + return DynamicValueOf(request.Query, name); + } + throw new InvalidOperationException(string.Format("Could not get value for {0} with type {1}", name, valueType)); + } + + private static TValue ParseValueUsing(string name, string value, Type valueType, Func parser) + { + var result = parser(Parameter.Of(name, value)); + try + { + return (TValue)result; + } + catch (InvalidCastException) + { + throw new InvalidOperationException( + string.Format("Could not parse parameter: '{0}' with value: '{1}'. " + + "Received: '{2}', expected: '{3}'.", + name, value, result.GetType(), valueType)); + } + } + + private static TValue DynamicValueOf(dynamic parameters, string name) + { + string value = parameters[name]; + try + { + TValue result = parameters[name]; + return result; + } + catch (InvalidCastException) + { + throw new InvalidOperationException(Strings.Format("Parameter: '{0}' value: '{1}' could not be parsed. " + + "Expected type: '{2}' is not supported", + name, value, typeof(TValue))); + } + catch (Exception e) + { + throw new InvalidOperationException(string.Format("Could not get '{0}' value of '{1}' type dynamicly", + name, typeof(TValue)), e); + } + } + + private static IDictionary> CreateParsers() + { + var parsers = ImmutableDictionary.CreateBuilder>(); + parsers.Put(typeof(string), value => value); + parsers.Put(typeof(bool), SafeParse(bool.Parse)); + parsers.Put(typeof(bool?), SafeParse(bool.Parse)); + parsers.Put(typeof(byte), SafeParse(byte.Parse)); + parsers.Put(typeof(sbyte?), SafeParse(sbyte.Parse)); + parsers.Put(typeof(short), SafeParse(short.Parse)); + parsers.Put(typeof(short?), SafeParse(short.Parse)); + parsers.Put(typeof(ushort), SafeParse(ushort.Parse)); + parsers.Put(typeof(ushort?), SafeParse(ushort.Parse)); + parsers.Put(typeof(int), SafeParse(int.Parse)); + parsers.Put(typeof(int?), SafeParse(int.Parse)); + parsers.Put(typeof(uint), SafeParse(uint.Parse)); + parsers.Put(typeof(uint?), SafeParse(uint.Parse)); + parsers.Put(typeof(long), SafeParse(long.Parse)); + parsers.Put(typeof(long?), SafeParse(long.Parse)); + parsers.Put(typeof(ulong), SafeParse(ulong.Parse)); + parsers.Put(typeof(ulong?), SafeParse(ulong.Parse)); + parsers.Put(typeof(float), SafeParse(float.Parse)); + parsers.Put(typeof(float?), SafeParse(float.Parse)); + parsers.Put(typeof(double), SafeParse(double.Parse)); + parsers.Put(typeof(double?), SafeParse(double.Parse)); + parsers.Put(typeof(decimal), SafeParse(decimal.Parse)); + parsers.Put(typeof(decimal?), SafeParse(decimal.Parse)); + parsers.Put(typeof(DateTime), SafeParse(DateTime.Parse)); + parsers.Put(typeof(DateTime?), SafeParse(DateTime.Parse)); + parsers.Put(typeof(TimeSpan), SafeParse(TimeSpan.Parse)); + parsers.Put(typeof(TimeSpan?), SafeParse(TimeSpan.Parse)); + parsers.Put(typeof(ZonedDateTime), SafeParse(ParseZonedDateTime)); + parsers.Put(typeof(ZonedDateTime?), SafeParse(ParseZonedDateTime)); + parsers.Put(typeof(LocalTime), SafeParse(ParseLocalTime)); + parsers.Put(typeof(LocalTime?), SafeParse(ParseLocalTime)); + + parsers.Put(typeof(IEnumerable), value => value); + parsers.Put(typeof(ICollection), value => value); + parsers.Put(typeof(IList), value => value); + parsers.Put(typeof(List), value => value); + parsers.Put(typeof(ISet), value => value); + parsers.Put(typeof(HashSet), value => value); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(bool.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(bool.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(bool.Parse)); + parsers.Put(typeof(List), ListParse(bool.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(bool.Parse)); + parsers.Put(typeof(HashSet), SetParse(bool.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(byte.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(byte.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(byte.Parse)); + parsers.Put(typeof(List), ListParse(byte.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(byte.Parse)); + parsers.Put(typeof(HashSet), SetParse(byte.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(sbyte.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(sbyte.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(sbyte.Parse)); + parsers.Put(typeof(List), ListParse(sbyte.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(sbyte.Parse)); + parsers.Put(typeof(HashSet), SetParse(sbyte.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(short.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(short.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(short.Parse)); + parsers.Put(typeof(List), ListParse(short.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(short.Parse)); + parsers.Put(typeof(HashSet), SetParse(short.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(ushort.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(ushort.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(ushort.Parse)); + parsers.Put(typeof(List), ListParse(ushort.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(ushort.Parse)); + parsers.Put(typeof(HashSet), SetParse(ushort.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(int.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(int.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(int.Parse)); + parsers.Put(typeof(List), ListParse(int.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(int.Parse)); + parsers.Put(typeof(HashSet), SetParse(int.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(uint.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(uint.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(uint.Parse)); + parsers.Put(typeof(List), ListParse(uint.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(uint.Parse)); + parsers.Put(typeof(HashSet), SetParse(uint.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(long.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(long.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(long.Parse)); + parsers.Put(typeof(List), ListParse(long.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(long.Parse)); + parsers.Put(typeof(HashSet), SetParse(long.Parse)); + parsers.Put(typeof(IEnumerable), ImmutableListParse(ulong.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(ulong.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(ulong.Parse)); + parsers.Put(typeof(List), ListParse(ulong.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(ulong.Parse)); + parsers.Put(typeof(HashSet), SetParse(ulong.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(float.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(float.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(float.Parse)); + parsers.Put(typeof(List), ListParse(float.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(float.Parse)); + parsers.Put(typeof(HashSet), SetParse(float.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(double.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(double.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(double.Parse)); + parsers.Put(typeof(List), ListParse(double.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(double.Parse)); + parsers.Put(typeof(HashSet), SetParse(double.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(decimal.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(decimal.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(decimal.Parse)); + parsers.Put(typeof(List), ListParse(decimal.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(decimal.Parse)); + parsers.Put(typeof(HashSet), SetParse(decimal.Parse)); + + + parsers.Put(typeof(IEnumerable), ImmutableListParse(DateTime.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(DateTime.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(DateTime.Parse)); + parsers.Put(typeof(List), ListParse(DateTime.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(DateTime.Parse)); + parsers.Put(typeof(HashSet), SetParse(DateTime.Parse)); + + parsers.Put(typeof(IEnumerable), ImmutableListParse(TimeSpan.Parse)); + parsers.Put(typeof(ICollection), ImmutableListParse(TimeSpan.Parse)); + parsers.Put(typeof(IList), ImmutableListParse(TimeSpan.Parse)); + parsers.Put(typeof(List), ListParse(TimeSpan.Parse)); + parsers.Put(typeof(ISet), ImmutableSetParse(TimeSpan.Parse)); + parsers.Put(typeof(HashSet), SetParse(TimeSpan.Parse)); + + return parsers.ToImmutableDictionary(); + } + + private static Func SafeParse(Func parse) + { + return parameter => + { + try + { + return parse(parameter.Value); + } + catch (OverflowException) + { + throw ParameterOutOfRange(parameter, typeof(T)); + } + catch (FormatException) + { + throw InvalidParameterFormat(parameter, typeof(T)); + } + catch (Exception e) + { + throw new InvalidOperationException(Strings.Format("Unable to parse parameter: '{0}' with value: '{1}' to {2}", + parameter.Name, parameter.Value, typeof(T)), e); + } + }; + } + + private static Func ListParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return new List(); + } + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToList(); + return results; + }; + } + + private static Func ImmutableListParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return Lists.EmptyList(); + } + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToImmutableList(); + return results; + }; + } + + private static Func SetParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return new HashSet(); + } + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToSet(); + return results; + }; + } + + private static Func ImmutableSetParse(Func itemParser) + { + return parameter => + { + if (string.IsNullOrEmpty(parameter.Value)) + { + return Sets.EmptySet(); + } + var results = parameter.Value.Split(new[] { ',' }, StringSplitOptions.None) + .Where(it => it != null) + .Select(it => it.Trim()) + .Select(itemParser) + .ToImmutableHashSet(); + return results; + }; + } + + private static ZonedDateTime ParseZonedDateTime(string value) + { + var dateTime = DateTime.Parse(value); + return new ZonedDateTime(Instant.FromDateTimeUtc(dateTime.ToUniversalTime()), DateTimeZone.Utc); + } + + private static LocalTime ParseLocalTime(string value) + { + return LocalTimePattern.ExtendedIsoPattern.Parse(value).Value; + } + + private static ArgumentException ParameterOutOfRange(Parameter parameter, Type type) + { + return new ArgumentException(Strings.Format("Query: '{0}' value: '{1}' is out of range for: '{2}'", + parameter.Name, parameter.Value, type)); + } + + private static ArgumentException InvalidParameterFormat(Parameter parameter, Type type) + { + return new ArgumentException(Strings.Format("Query '{0}' value: '{1}' format is invalid for: '{2}'", + parameter.Name, parameter.Value, type)); + } + + private class Parameter + { + internal string Name { get; private set; } + internal string Value { get; private set; } + + private Parameter(string name, string value) + { + Name = name; + Value = value; + } + + internal static Parameter Of(string name, string value) + { + return new Parameter(name, value); + } + } + } + + internal enum ParameterType + { + Undefined, + Query, + Path, + Header + } +} \ No newline at end of file diff --git a/samples/server/petstore/nancyfx/src/IO.Swagger/packages.config b/samples/server/petstore/nancyfx/src/IO.Swagger/packages.config new file mode 100644 index 000000000000..6d8651cdcf40 --- /dev/null +++ b/samples/server/petstore/nancyfx/src/IO.Swagger/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 897cd5c2efbf706d49b3a25bbaadc4d670eb012f Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 20 Jun 2016 11:44:25 +0200 Subject: [PATCH 63/64] Updated readme section with enlisted companies using Swagger Codegen. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fb1d85012873..f8fe5df3ea94 100644 --- a/README.md +++ b/README.md @@ -711,6 +711,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you - [eureka](http://eure.jp/) - [everystory.us](http://everystory.us) - [Expected Behavior](http://www.expectedbehavior.com/) +- [Finder](http://en.finder.pl/) - [FH Münster - University of Applied Sciences](http://www.fh-muenster.de) - [GraphHopper](https://graphhopper.com/) - [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications) From 5b7ed41b1bcacc8170d5d20a6eb8aafc6edb968e Mon Sep 17 00:00:00 2001 From: Marcin Stefaniuk Date: Mon, 20 Jun 2016 15:41:53 +0200 Subject: [PATCH 64/64] Extended list of generators. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f8fe5df3ea94..13e8bf2ad0e8 100644 --- a/README.md +++ b/README.md @@ -474,6 +474,7 @@ JavaJerseyServerCodegen.java JavaResteasyServerCodegen.java JavascriptClientCodegen.java NodeJSServerCodegen.java +NancyFXServerCodegen ObjcClientCodegen.java PerlClientCodegen.java PhpClientCodegen.java @@ -777,6 +778,7 @@ Swaagger Codegen core team members are contributors who have been making signfic | Java Spring Boot | | | Java SpringMVC | @kolyjjj (2016/05/01) | | Java JAX-RS | | +| NancyFX | | | NodeJS | @kolyjjj (2016/05/01) | | PHP Lumen | @abcsum (2016/05/01) | | PHP Silex | |