Skip to content

Commit

Permalink
Merge pull request #243 from NSwag/TemplateFactory
Browse files Browse the repository at this point in the history
Template factory
  • Loading branch information
RicoSuter authored Aug 18, 2016
2 parents 7445528 + a5eff69 commit 37a99ac
Show file tree
Hide file tree
Showing 74 changed files with 1,426 additions and 1,426 deletions.
4 changes: 2 additions & 2 deletions src/NSwag.AspNet.Owin/NSwag.AspNet.Owin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NJsonSchema, Version=3.3.6061.16591, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\packages\NJsonSchema.3.3.6061.16591\lib\net45\NJsonSchema.dll</HintPath>
<Reference Include="NJsonSchema, Version=4.0.6074.30968, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\packages\NJsonSchema.4.0.6074.30968\lib\net45\NJsonSchema.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
Expand Down
7 changes: 5 additions & 2 deletions src/NSwag.AspNet.Owin/SwaggerMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Owin;
using NSwag.CodeGeneration.SwaggerGenerators;
using NSwag.CodeGeneration.SwaggerGenerators.WebApi;

namespace NSwag.AspNet.Owin
Expand All @@ -21,13 +22,15 @@ internal class SwaggerMiddleware : OwinMiddleware
private readonly SwaggerOwinSettings _settings;
private readonly IEnumerable<Type> _controllerTypes;
private string _swaggerJson = null;
private readonly SwaggerJsonSchemaGenerator _schemaGenerator;

public SwaggerMiddleware(OwinMiddleware next, string path, IEnumerable<Type> controllerTypes, SwaggerOwinSettings settings)
public SwaggerMiddleware(OwinMiddleware next, string path, IEnumerable<Type> controllerTypes, SwaggerOwinSettings settings, SwaggerJsonSchemaGenerator schemaGenerator)
: base(next)
{
_path = path;
_controllerTypes = controllerTypes;
_settings = settings;
_schemaGenerator = schemaGenerator;
}

public override async Task Invoke(IOwinContext context)
Expand All @@ -50,7 +53,7 @@ private string GenerateSwagger(IOwinContext context)
{
if (_swaggerJson == null)
{
var generator = new WebApiToSwaggerGenerator(_settings);
var generator = new WebApiToSwaggerGenerator(_settings, _schemaGenerator);
var service = generator.GenerateForControllers(_controllerTypes);

foreach (var processor in _settings.DocumentProcessors)
Expand Down
9 changes: 6 additions & 3 deletions src/NSwag.AspNet.Owin/SwaggerUiExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.Owin.Extensions;
using Microsoft.Owin.FileSystems;
using Microsoft.Owin.StaticFiles;
using NSwag.CodeGeneration.SwaggerGenerators;
using NSwag.CodeGeneration.SwaggerGenerators.WebApi;
using Owin;

Expand Down Expand Up @@ -88,21 +89,23 @@ public static IAppBuilder UseSwaggerUi(
SwaggerUiOwinSettings settings)
{
var controllerTypes = webApiAssemblies.SelectMany(WebApiToSwaggerGenerator.GetControllerClasses);
return app.UseSwaggerUi(controllerTypes, settings);
return app.UseSwaggerUi(controllerTypes, settings, new SwaggerJsonSchemaGenerator(settings));
}

/// <summary>Addes the Swagger generator and Swagger UI to the OWIN pipeline.</summary>
/// <param name="app">The app.</param>
/// <param name="controllerTypes">The Web API controller types.</param>
/// <param name="settings">The Swagger generator settings.</param>
/// <param name="schemaGenerator">The schema generator.</param>
/// <returns>The app builder.</returns>
public static IAppBuilder UseSwaggerUi(
this IAppBuilder app,
IEnumerable<Type> controllerTypes,
SwaggerUiOwinSettings settings)
SwaggerUiOwinSettings settings,
SwaggerJsonSchemaGenerator schemaGenerator)
{
app.Use<RedirectMiddleware>(settings.SwaggerUiRoute, settings.SwaggerUiRoute + "/index.html?url=" + Uri.EscapeDataString(settings.SwaggerRoute));
app.Use<SwaggerMiddleware>(settings.SwaggerRoute, controllerTypes, settings);
app.Use<SwaggerMiddleware>(settings.SwaggerRoute, controllerTypes, settings, schemaGenerator);
app.Use<SwaggerUiIndexMiddleware>(settings.SwaggerUiRoute + "/index.html", settings);
app.UseFileServer(new FileServerOptions
{
Expand Down
2 changes: 1 addition & 1 deletion src/NSwag.AspNet.Owin/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NJsonSchema" publicKeyToken="c2f9c3bdfae56102" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.6061.16591" newVersion="3.3.6061.16591" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6074.30968" newVersion="4.0.6074.30968" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
Expand Down
2 changes: 1 addition & 1 deletion src/NSwag.AspNet.Owin/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="NJsonSchema" version="3.3.6061.16591" targetFramework="net45" />
<package id="NJsonSchema" version="4.0.6074.30968" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>
8 changes: 5 additions & 3 deletions src/NSwag.AspNetCore/SwaggerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,23 @@ public static IApplicationBuilder UseSwaggerUi(
SwaggerUiOwinSettings settings)
{
var controllerTypes = webApiAssemblies.SelectMany(WebApiToSwaggerGenerator.GetControllerClasses);
return app.UseSwaggerUi(controllerTypes, settings);
return app.UseSwaggerUi(controllerTypes, settings, new ReferencedJsonSchemaGenerator(settings));
}

/// <summary>Addes the Swagger generator and Swagger UI to the OWIN pipeline.</summary>
/// <param name="app">The app.</param>
/// <param name="controllerTypes">The Web API controller types.</param>
/// <param name="settings">The Swagger generator settings.</param>
/// <param name="schemaGenerator">The schema generator.</param>
/// <returns>The app builder.</returns>
public static IApplicationBuilder UseSwaggerUi(
this IApplicationBuilder app,
IEnumerable<Type> controllerTypes,
SwaggerUiOwinSettings settings)
SwaggerUiOwinSettings settings,
ReferencedJsonSchemaGenerator schemaGenerator)
{
app.UseMiddleware<RedirectMiddleware>(settings.SwaggerUiRoute, settings.SwaggerUiRoute + "/index.html?url=" + Uri.EscapeDataString(settings.SwaggerRoute));
app.UseMiddleware<SwaggerMiddleware>(settings.SwaggerRoute, controllerTypes, settings);
app.UseMiddleware<SwaggerMiddleware>(settings.SwaggerRoute, controllerTypes, settings, schemaGenerator);
app.UseMiddleware<SwaggerUiIndexMiddleware>(settings.SwaggerUiRoute + "/index.html", settings);
app.UseFileServer(new FileServerOptions
{
Expand Down
6 changes: 4 additions & 2 deletions src/NSwag.AspNetCore/SwaggerMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ internal class SwaggerMiddleware
private readonly IEnumerable<Type> _controllerTypes;
private string _swaggerJson = null;
private readonly SwaggerOwinSettings _settings;
private readonly ReferencedJsonSchemaGenerator _schemaGenerator;

public SwaggerMiddleware(RequestDelegate nextDelegate, string path, IEnumerable<Type> controllerTypes, SwaggerOwinSettings settings)
public SwaggerMiddleware(RequestDelegate nextDelegate, string path, IEnumerable<Type> controllerTypes, SwaggerOwinSettings settings, ReferencedJsonSchemaGenerator schemaGenerator)
{
_nextDelegate = nextDelegate;
_path = path;
_controllerTypes = controllerTypes;
_settings = settings;
_schemaGenerator = schemaGenerator;
}

public async Task Invoke(HttpContext context)
Expand All @@ -51,7 +53,7 @@ private string GenerateSwagger(HttpContext context)
{
if (_swaggerJson == null)
{
var generator = new WebApiToSwaggerGenerator(_settings);
var generator = new WebApiToSwaggerGenerator(_settings, _schemaGenerator);
var service = generator.GenerateForControllers(_controllerTypes);

foreach (var processor in _settings.DocumentProcessors)
Expand Down
5 changes: 3 additions & 2 deletions src/NSwag.AssemblyLoader/NSwag.AssemblyLoader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NJsonSchema, Version=3.3.6061.16591, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\packages\NJsonSchema.3.3.6061.16591\lib\net45\NJsonSchema.dll</HintPath>
<Reference Include="NJsonSchema, Version=4.0.6074.30968, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\packages\NJsonSchema.4.0.6074.30968\lib\net45\NJsonSchema.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
Expand All @@ -61,6 +61,7 @@
<Compile Include="SwaggerGenerators\AssemblyTypeToSwaggerGeneratorSettings.cs" />
<Compile Include="SwaggerGenerators\WebApi\WebApiAssemblyToSwaggerGenerator.cs" />
<Compile Include="SwaggerGenerators\WebApi\WebApiAssemblyToSwaggerGeneratorSettings.cs" />
<Compile Include="Utilities\PathUtilities.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NSwag.CodeGeneration\NSwag.CodeGeneration.csproj">
Expand Down
5 changes: 4 additions & 1 deletion src/NSwag.AssemblyLoader/SwaggerGenerators/AssemblyLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ protected void RegisterReferencePaths(IEnumerable<string> referencePaths)
foreach (var path in referencePaths.Where(p => !string.IsNullOrWhiteSpace(p)))
allReferencePaths.AddRange(GetAllDirectories(path));

// Add path to nswag directory
allReferencePaths.Add(Path.GetDirectoryName(typeof(AssemblyLoader).Assembly.CodeBase.Replace("file:///", string.Empty)));

domain.AssemblyResolve += (sender, args) =>
{
foreach (var path in allReferencePaths)
{
var assemblyName = args.Name.Substring(0, args.Name.IndexOf(",", StringComparison.InvariantCulture)) + ".dll";
var assemblyName = args.Name.Substring(0, args.Name.IndexOf(",", StringComparison.InvariantCulture)) + ".dll";
var files = Directory.GetFiles(path, assemblyName, SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Channels;
using Newtonsoft.Json;
using NJsonSchema;
using NJsonSchema.Generation;
Expand Down Expand Up @@ -58,15 +59,17 @@ internal string FromAssemblyType(string[] classNames, string settingsData)
var settings = JsonConvert.DeserializeObject<AssemblyTypeToSwaggerGeneratorSettings>(settingsData);
RegisterReferencePaths(settings.ReferencePaths);

var generator = new JsonSchemaGenerator(settings);
var resolver = new SchemaResolver();
var service = new SwaggerService();

var generator = new JsonSchemaGenerator(settings);
var schemaResolver = new SchemaResolver();
var schemaDefinitionAppender = new SwaggerServiceSchemaDefinitionAppender(service, settings.TypeNameGenerator);

var assembly = Assembly.LoadFrom(settings.AssemblyPath);
foreach (var className in classNames)
{
var type = assembly.GetType(className);
var schema = generator.Generate(type, resolver);
var schema = generator.Generate(type, schemaResolver, schemaDefinitionAppender);
service.Definitions[type.Name] = schema;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Reflection;
using Newtonsoft.Json;
using NSwag.CodeGeneration.Infrastructure;
using NSwag.CodeGeneration.Utilities;

namespace NSwag.CodeGeneration.SwaggerGenerators.WebApi
{
Expand Down Expand Up @@ -107,7 +108,9 @@ private IEnumerable<Type> GetControllerTypes(IEnumerable<string> controllerClass
if (settings.AssemblyPaths == null || settings.AssemblyPaths.Length == 0)
throw new InvalidOperationException("No assembly paths have been provided.");

var assemblies = settings.AssemblyPaths.Select(path => Assembly.LoadFrom(path)).ToArray();
var assemblies = PathUtilities.ExpandFileWildcards(settings.AssemblyPaths)
.Select(path => Assembly.LoadFrom(path)).ToArray();

var controllerTypes = new List<Type>();
foreach (var className in controllerClassNames)
{
Expand All @@ -124,7 +127,7 @@ internal string[] GetControllerClasses(string[] assemblyPaths, IEnumerable<strin
{
RegisterReferencePaths(referencePaths);

return assemblyPaths
return PathUtilities.ExpandFileWildcards(assemblyPaths)
.Select(Assembly.LoadFrom)
.SelectMany(WebApiToSwaggerGenerator.GetControllerClasses)
.Select(t => t.FullName)
Expand Down
134 changes: 134 additions & 0 deletions src/NSwag.AssemblyLoader/Utilities/PathUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//-----------------------------------------------------------------------
// <copyright file="PathUtilities.cs" company="NSwag">
// Copyright (c) Rico Suter. All rights reserved.
// </copyright>
// <license>https://github.com/NSwag/NSwag/blob/master/LICENSE.md</license>
// <author>Rico Suter, mail@rsuter.com</author>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace NSwag.CodeGeneration.Utilities
{
/// <summary>Provides file path utility methods.</summary>
public static class PathUtilities
{
// TODO: Move to MyToolkit

/// <summary>Expands the given wildcards (** or *) in the path.</summary>
/// <param name="path">The file path with wildcards.</param>
/// <returns>All expanded file paths.</returns>
public static IEnumerable<string> ExpandFileWildcards(string path)
{
return ExpandFileWildcards(new[] { path });
}

/// <summary>Expands the given wildcards (** or *) in the paths.</summary>
/// <param name="paths">The files path with wildcards.</param>
/// <returns>All expanded file paths.</returns>
public static IEnumerable<string> ExpandFileWildcards(IEnumerable<string> paths)
{
var allFiles = new List<string>();
foreach (var path in paths)
{
if (path.Contains("*"))
{
var starIndex = path.IndexOf("*", StringComparison.InvariantCulture);

var rootIndex = path.Substring(0, starIndex).LastIndexOf("\\", StringComparison.InvariantCulture);
if (rootIndex == -1)
rootIndex = path.Substring(0, starIndex).LastIndexOf("/", StringComparison.InvariantCulture);

var rootPath = rootIndex >= 0 ? path.Substring(0, rootIndex + 1) : Directory.GetCurrentDirectory();
var files = Directory.GetFiles(rootPath, "*", SearchOption.AllDirectories);

var regex = new Regex(
"^" +
Regex.Escape(path//.Substring(rootIndex + 1)
.Replace("**/", "__starstar__")
.Replace("**\\", "__starstar__")
.Replace("/", "__del__")
.Replace("\\", "__del__")
.Replace("*", "__star__"))
.Replace("__del__", "([\\\\/])")
.Replace("__starstar__", "((.*?)[/\\\\])")
.Replace("__star__", "([^\\/]*?)") + "$");

allFiles.AddRange(files
.Where(f => regex.Match(f).Success)
.Select(Path.GetFullPath));
}
else
allFiles.Add(path);
}

return allFiles.Distinct();
}

/// <summary>Converts a relative path to an absolute path.</summary>
/// <param name="relativePath">The relative path.</param>
/// <param name="relativeTo">The current directory.</param>
/// <returns>The absolute path.</returns>
public static string MakeAbsolutePath(string relativePath, string relativeTo)
{
var absolutePath = Path.Combine(relativePath, relativeTo);
return Path.GetFullPath(new Uri(absolutePath).LocalPath);
}

/// <summary>Converts an absolute path to a relative path if possible.</summary>
/// <param name="absolutePath">The absolute path.</param>
/// <param name="relativeTo">The current directory.</param>
/// <returns>The relative path.</returns>
/// <exception cref="ArgumentException">The path of the two files doesn't have any common base.</exception>
public static string MakeRelativePath(string absolutePath, string relativeTo)
{
string[] absParts = absolutePath.Split(System.IO.Path.DirectorySeparatorChar);
string[] relParts = relativeTo.Split(System.IO.Path.DirectorySeparatorChar);

// Get the shortest of the two paths
int len = absParts.Length < relParts.Length ? absParts.Length : relParts.Length;

// Use to determine where in the loop we exited
int lastCommonRoot = -1;
int index;

// Find common root
for (index = 0; index < len; index++)
{
if (absParts[index].Equals(relParts[index], StringComparison.OrdinalIgnoreCase))
lastCommonRoot = index;
else
break;
}

// If we didn't find a common prefix then throw
if (lastCommonRoot == -1)
return absolutePath;

// Build up the relative path
var relativePath = new StringBuilder();

// Add on the ..
for (index = lastCommonRoot + 1; index < relParts.Length; index++)
{
relativePath.Append("..");
relativePath.Append(System.IO.Path.DirectorySeparatorChar);
}

// Add on the folders
for (index = lastCommonRoot + 1; index < absParts.Length - 1; index++)
{
relativePath.Append(absParts[index]);
relativePath.Append(System.IO.Path.DirectorySeparatorChar);
}
relativePath.Append(absParts[absParts.Length - 1]);

return relativePath.ToString();
}
}
}
2 changes: 1 addition & 1 deletion src/NSwag.AssemblyLoader/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NJsonSchema" publicKeyToken="c2f9c3bdfae56102" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.6061.16591" newVersion="3.3.6061.16591" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6074.30968" newVersion="4.0.6074.30968" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
Expand Down
Loading

0 comments on commit 37a99ac

Please sign in to comment.