forked from loafle/openapi-generator-original
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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<Reference Include="System.Xml"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs"/>
|
||||
<Compile Include="**\*.cs" Exclude="obj\**"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="packages.config"/>
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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<Type, Func<Parameter, object>> Parsers = CreateParsers();
|
||||
|
||||
internal static TParam QueryParam<TParam>(this Request source, string name)
|
||||
internal static TValue ValueOf<TValue>(dynamic parameters, string name)
|
||||
{
|
||||
return QueryParam(source, name, default(TParam), useDefault: false);
|
||||
}
|
||||
|
||||
internal static TParam QueryParam<TParam>(this Request source, string name, TParam defaultValue)
|
||||
{
|
||||
return QueryParam(source, name, defaultValue, useDefault: true);
|
||||
}
|
||||
|
||||
internal static THeader HeaderValue<THeader>(this Request source, string name)
|
||||
{
|
||||
return HeaderValue(source, name, default(THeader), useDefault: false);
|
||||
}
|
||||
|
||||
internal static THeader HeaderValue<THeader>(this Request source, string name, THeader defaultValue)
|
||||
{
|
||||
return HeaderValue(source, name, defaultValue, useDefault: true);
|
||||
}
|
||||
|
||||
internal static TPathParam PathParam<TPathParam>(dynamic parameters, string name)
|
||||
{
|
||||
return PathParam(parameters, name, default(TPathParam), useDefault: false);
|
||||
}
|
||||
|
||||
internal static TPathParam PathParam<TPathParam>(dynamic parameters, string name, TPathParam defaultValue)
|
||||
{
|
||||
return PathParam(parameters, name, defaultValue, useDefault: true);
|
||||
}
|
||||
|
||||
private static TParam QueryParam<TParam>(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<THeader>(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<TPathParam>(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<TValue>(name, value);
|
||||
}
|
||||
return ValueOf<TValue>(parameters, name, value, valueType);
|
||||
}
|
||||
|
||||
private static TValue ValueOf<TValue>(string name, string value, TValue defaultValue, bool useDefault, Func<Parameter, object> parser)
|
||||
private static TValue EnumValueOf<TValue>(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<TValue>(dynamic parameters, string name, string value, Type valueType)
|
||||
{
|
||||
var parser = Parsers.GetIfPresent(valueType);
|
||||
if (parser != null)
|
||||
{
|
||||
return ParseValueUsing<TValue>(name, value, valueType, parser);
|
||||
}
|
||||
return DynamicValueOf<TValue>(parameters, name);
|
||||
}
|
||||
|
||||
private static TValue ParseValueUsing<TValue>(string name, string value, Type valueType, Func<Parameter, object> 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<TValue>(dynamic parameters, string name, TValue defaultValue)
|
||||
private static TValue DynamicValueOf<TValue>(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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user