Main files of nancyfx generator.

This commit is contained in:
Marcin Stefaniuk
2016-05-16 10:49:24 +02:00
parent 48fbaa793a
commit 496de14cff
16 changed files with 459 additions and 0 deletions

View File

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

View File

@@ -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

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{{packageGuid}}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>{{packageTitle}}</RootNamespace>
<AssemblyName>{{packageTitle}}</AssemblyName>
{{^supportsUWP}}
<TargetFrameworkVersion>{{targetFramework}}</TargetFrameworkVersion>
{{/supportsUWP}}
{{#supportsUWP}}
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
{{/supportsUWP}}
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs"/>
</ItemGroup>
<Import Project="$(MsBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -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

View File

@@ -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}}
/// <summary>
/// {{description}}
/// </summary>{{#description}}{{#basePath}}
[Route("{{basePath}}")]
{{/basePath}}[Description("{{description}}")]{{/description}}
public class {{classname}}Controller : Controller
{ {{#operation}}
/// <summary>
/// {{#summary}}{{summary}}{{/summary}}
/// </summary>
{{#notes}}/// <remarks>{{notes}}</remarks>{{/notes}}{{#allParams}}
/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}{{#responses}}
/// <response code="{{code}}">{{message}}</response>{{/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}}
}

View File

@@ -0,0 +1 @@
{{#isBodyParam}}[FromBody]{{&dataType}} {{paramName}}{{/isBodyParam}}

View File

@@ -0,0 +1 @@
{{#isFormParam}}[FromForm]{{&dataType}} {{paramName}}{{/isFormParam}}

View File

@@ -0,0 +1 @@
{{#isHeaderParam}}[FromHeader]{{&dataType}} {{paramName}}{{/isHeaderParam}}

View File

@@ -0,0 +1,4 @@
var example = exampleJson != null
? JsonConvert.DeserializeObject<{{returnContainer}}<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson)
: Enumerable.Empty<{{#returnType}}{{{returnType}}}{{/returnType}}>();

View File

@@ -0,0 +1,4 @@
var example = exampleJson != null
? JsonConvert.DeserializeObject<Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>>(exampleJson)
: new Dictionary<{{#returnType}}{{{returnType}}}{{/returnType}}>();

View File

@@ -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
{
/// <summary>
/// {{description}}
/// </summary>
public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>
{
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
/// </summary>
{{#vars}} /// <param name="{{name}}">{{#description}}{{description}}{{/description}}{{^description}}{{name}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}.</param>
{{/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}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
/// </summary>{{#description}}
/// <value>{{{description}}}</value>{{/description}}
public {{{datatype}}} {{name}} { get; set; }
{{/vars}}
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
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();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public {{#parent}} new {{/parent}}string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="obj">Object to be compared</param>
/// <returns>Boolean</returns>
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);
}
/// <summary>
/// Returns true if {{classname}} instances are equal
/// </summary>
/// <param name="other">Instance of {{classname}} to be compared</param>
/// <returns>Boolean</returns>
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}};
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
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}}
}

View File

@@ -0,0 +1,4 @@
var example = exampleJson != null
? JsonConvert.DeserializeObject<{{#returnType}}{{{returnType}}}{{/returnType}}>(exampleJson)
: default({{#returnType}}{{{returnType}}}{{/returnType}});

View File

@@ -0,0 +1 @@
{{#isPathParam}}[FromRoute]{{&dataType}} {{paramName}}{{/isPathParam}}

View File

@@ -0,0 +1 @@
{{#isQueryParam}}[FromQuery]{{&dataType}} {{paramName}}{{/isQueryParam}}

View File

@@ -0,0 +1 @@
{{!TODO: Need iterable tags object...}}{{#tags}}, Tags = new[] { {{/tags}}"{{#tags}}{{tag}} {{/tags}}"{{#tags}} }{{/tags}}

View File

@@ -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<String, String> createOptions() {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
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;
}
}