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));
}