-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from CodeFactoryLLC/StandardNDF
nuget release
- Loading branch information
Showing
20 changed files
with
1,123 additions
and
26 deletions.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
src/Standard/NDF/CodeFactory.Automation.Standard.NDF.Logic/AddMissingMembersNDF.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using CodeFactory.WinVs; | ||
using CodeFactory.WinVs.Models.CSharp; | ||
using CodeFactory.WinVs.Models.CSharp.Builder; | ||
|
||
namespace CodeFactory.Automation.Standard.NDF.Logic | ||
{ | ||
/// <summary> | ||
/// Logic for adding missing members. | ||
/// </summary> | ||
public static class AddMissingMembers | ||
{ | ||
/// <summary> | ||
/// Name of the Microsoft logging library. | ||
/// </summary> | ||
public const string MicrosoftLoggingNamespace = "Microsoft.Extensions.Logging"; | ||
|
||
/// <summary> | ||
/// Name of the NDF namespace. | ||
/// </summary> | ||
public const string NDFNamespace = "CodeFactory.NDF"; | ||
|
||
/// <summary> | ||
/// Add missing interface members | ||
/// </summary> | ||
/// <param name="source">The CodeFactory automation for Visual Studio Windows</param> | ||
/// <param name="sourceCode">Source code model to be updated with add members in the target class.</param> | ||
/// <param name="updateClass">Class model to add missing members to.</param> | ||
/// <param name="supportsLogging">Flag that determines if logging is enabled.</param> | ||
/// <param name="loggerFieldName">Optional, the name of the field to use for logging.</param> | ||
/// <returns></returns> | ||
public static async Task<CsClass> AddMissingMembersStandardNDFAsync(this IVsActions source, CsSource sourceCode, | ||
CsClass updateClass, bool supportsLogging, string loggerFieldName = "_logger") | ||
{ | ||
//Bounds checks to make sure all data needed is provided. | ||
if (sourceCode == null) | ||
throw new CodeFactoryException( | ||
"Visual Studio automation for CodeFactory was not provided cannot add missing members."); | ||
|
||
if (sourceCode == null) | ||
throw new CodeFactoryException("No source code was provided, cannot add the missing members."); | ||
|
||
if (updateClass == null) | ||
throw new CodeFactoryException( | ||
"No target class to add missing members was provided, cannot add the missing members."); | ||
|
||
//Get the missing members to be added | ||
var missingMembers = updateClass.GetMissingInterfaceMembers(); | ||
|
||
//If no missing members are found just return the current class. | ||
if (!missingMembers.Any()) return updateClass; | ||
|
||
//Creating the source code manager for the class. | ||
var manager = new SourceClassManager(sourceCode, updateClass, source); | ||
manager.LoadNamespaceManager(); | ||
|
||
|
||
//Creating the blocks to be used for code generation | ||
ILoggerBlock loggerBlock = supportsLogging ? new LoggerBlockNDF(loggerFieldName) : null; | ||
|
||
var boundsChecks = new IBoundsCheckBlock[] | ||
{ | ||
new BoundsCheckBlockStringNDF(true, loggerBlock), | ||
new BoundsCheckBlockNullNDF(true, loggerBlock) | ||
}; | ||
|
||
var catchBlocks = new ICatchBlock[] | ||
{ | ||
new CatchBlockManagedExceptionNDF(loggerBlock), | ||
new CatchBlockExceptionNDF(loggerBlock) | ||
}; | ||
|
||
ITryBlock tryBlock = new TryBlockStandard(loggerBlock, catchBlocks); | ||
|
||
if(supportsLogging) await manager.UsingStatementAddAsync(MicrosoftLoggingNamespace); | ||
await manager.UsingStatementAddAsync(NDFNamespace); | ||
|
||
//Creating the builders to generate code by member type. | ||
IMethodBuilder methodBuilder = new MethodBuilderStandard(loggerBlock, boundsChecks, tryBlock); | ||
IPropertyBuilder propertyBuilder = new PropertyBuilderStandard(); | ||
IEventBuilder eventBuilder = new EventBuilderStandard(); | ||
|
||
//Process all missing properties. | ||
var missingProperties = missingMembers.Where(m => m.MemberType == CsMemberType.Property).Cast<CsProperty>() | ||
.ToList(); | ||
|
||
foreach (var missingProperty in missingProperties) | ||
{ | ||
var propertySyntax = await propertyBuilder.BuildPropertyAsync(missingProperty, manager, 2); | ||
|
||
if(propertySyntax == null) continue; | ||
|
||
await manager.PropertiesAddAfterAsync(propertySyntax); | ||
|
||
} | ||
|
||
//Process all missing methods. | ||
var missingMethods = missingMembers.Where(m => m.MemberType == CsMemberType.Method).Cast<CsMethod>() | ||
.ToList(); | ||
|
||
foreach (var missingMethod in missingMethods) | ||
{ | ||
var methodSyntax = await methodBuilder.BuildMethodAsync(missingMethod, manager, 2); | ||
|
||
if(methodSyntax == null) continue; | ||
|
||
await manager.MethodsAddAfterAsync(methodSyntax); | ||
} | ||
|
||
//Process all missing events. | ||
var missingEvents = missingMembers.Where(m => m.MemberType == CsMemberType.Event).Cast<CsEvent>() | ||
.ToList(); | ||
|
||
foreach (var missingEvent in missingEvents) | ||
{ | ||
var eventSyntax = await eventBuilder.BuildEventAsync(missingEvent, manager, 2); | ||
|
||
if(eventSyntax == null) continue; | ||
|
||
await manager.EventsAddAfterAsync(eventSyntax); | ||
} | ||
|
||
return manager.Container; | ||
} | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
src/Standard/NDF/CodeFactory.Automation.Standard.NDF.Logic/AspNetConstants.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace CodeFactory.Automation.Standard.NDF.Logic | ||
{ | ||
/// <summary> | ||
/// Data class that holds constants used in AspNet Delivery. | ||
/// </summary> | ||
public static class AspNetConstants | ||
{ | ||
/// <summary> | ||
/// The name of the filed that holds the logger | ||
/// </summary> | ||
public const string FieldNameLogger = "_logger"; | ||
|
||
/// <summary> | ||
/// The full name of the library for logging. | ||
/// </summary> | ||
public const string MicrosoftExtensionLibraryForLoggingName = "Microsoft.Extensions.Logging.Abstractions"; | ||
|
||
/// <summary> | ||
/// Library name for the Microsoft Logger abstractions library. | ||
/// </summary> | ||
public const string MicrosoftLoggerLibraryName = "Microsoft.Extensions.Logging.Abstractions"; | ||
|
||
/// <summary> | ||
/// The default namespace for the Microsoft extensions logger implementation | ||
/// </summary> | ||
public const string MicrosoftLoggerNamespace = "Microsoft.Extensions.Logging"; | ||
|
||
/// <summary> | ||
/// The name of the interface for the Microsoft extensions logger. | ||
/// </summary> | ||
public const string MicrosoftLoggerInterfaceName = "ILogger"; | ||
|
||
/// <summary> | ||
/// The fully qualified name of the a aspnet core controller. | ||
/// </summary> | ||
public const string ControllerBaseName = "Microsoft.AspNetCore.Mvc.ControllerBase"; | ||
|
||
/// <summary> | ||
/// The full namespace for the mvc namespace. | ||
/// </summary> | ||
public const string MvcNamespace = "Microsoft.AspNetCore.Mvc"; | ||
|
||
/// <summary> | ||
/// Name for the abstract classes that support action result. | ||
/// </summary> | ||
public const string ActionResultClassName = "ActionResult"; | ||
|
||
/// <summary> | ||
/// Name of the interface for action results. | ||
/// </summary> | ||
public const string ActionResultInterfaceName = "IActionResult"; | ||
|
||
/// <summary> | ||
/// Namespace for tasks | ||
/// </summary> | ||
public const string SystemThreadingTasksNamespace = "System.Threading.Tasks"; | ||
|
||
/// <summary> | ||
/// Class name for the Task class. | ||
/// </summary> | ||
public const string TaskClassName = "Task"; | ||
|
||
/// <summary> | ||
/// Namespace for dependency injection. | ||
/// </summary> | ||
public const string DependencyInjectionAbstractions = "Microsoft.Extensions.DependencyInjection.Abstractions"; | ||
|
||
/// <summary> | ||
/// Namespace for configuration. | ||
/// </summary> | ||
public const string ConfigurationAbstractions = "Microsoft.Extensions.Configuration.Abstractions"; | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
src/Standard/NDF/CodeFactory.Automation.Standard.NDF.Logic/BoundsCheckBlockNullNDF.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using CodeFactory.WinVs.Models.CSharp; | ||
using CodeFactory.WinVs.Models.CSharp.Builder; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace CodeFactory.Automation.Standard.NDF.Logic | ||
{ | ||
/// <summary> | ||
/// Null bounds check that support NDF logging and exceptions. | ||
/// </summary> | ||
internal class BoundsCheckBlockNullNDF:BaseBoundsCheckBlock | ||
{ | ||
/// <summary>Initializes the base class for the bounds check.</summary> | ||
/// <param name="ignoreWhenDefaultValueIsSet">Flag that determines if the bounds checking should be ignored if a default value is set.</param> | ||
/// <param name="loggerBlock">Logger block used with bounds check logic.</param> | ||
public BoundsCheckBlockNullNDF(bool ignoreWhenDefaultValueIsSet, ILoggerBlock loggerBlock) : base(nameof(BoundsCheckBlockNullNDF), ignoreWhenDefaultValueIsSet, loggerBlock) | ||
{ | ||
//Intentionally blank | ||
} | ||
|
||
/// <summary> | ||
/// Generates the bounds check syntax if the parameter meets the criteria for a bounds check. | ||
/// </summary> | ||
/// <param name="sourceMethod">The target method the parameter belongs to.</param> | ||
/// <param name="checkParameter">The parameter to build the bounds check for.</param> | ||
/// <returns>Returns a tuple that contains a boolean that determines if the bounds check syntax was created for the parameter.</returns> | ||
public override (bool hasBoundsCheck, string boundsCheckSyntax) GenerateBoundsCheck(CsMethod sourceMethod, CsParameter checkParameter) | ||
{ | ||
//bounds check to make sure we have parameter data. | ||
if (checkParameter == null) return (false, null); | ||
|
||
if(checkParameter.ParameterType.IsValueType) return (false, null); | ||
|
||
if(checkParameter.HasDefaultValue) return (false, null); | ||
|
||
SourceFormatter formatter = new SourceFormatter(); | ||
|
||
formatter.AppendCodeLine(0,$"if ({checkParameter.Name} == null)"); | ||
formatter.AppendCodeLine(0,"{"); | ||
if (LoggerBlock != null) | ||
{ | ||
var errorMessage = $"$\"The parameter {{nameof({checkParameter.Name})}} was not provided. Will raise an argument exception\""; | ||
formatter.AppendCodeLine(1,LoggerBlock.GenerateLogging(LogLevel.Error, errorMessage,true)); | ||
formatter.AppendCodeLine(1, LoggerBlock.GenerateExitLogging(LogLevel.Error,sourceMethod.Name)); | ||
} | ||
formatter.AppendCodeLine(1,$"throw new ArgumentNullException(nameof({checkParameter.Name}));"); | ||
formatter.AppendCodeLine(0,"}"); | ||
|
||
return (true,formatter.ReturnSource()); | ||
} | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
src/Standard/NDF/CodeFactory.Automation.Standard.NDF.Logic/BoundsCheckBlockStringNDF.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using CodeFactory.WinVs.Models.CSharp; | ||
using CodeFactory.WinVs.Models.CSharp.Builder; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace CodeFactory.Automation.Standard.NDF.Logic | ||
{ | ||
/// <summary> | ||
/// String bounds check that supports NDF logging and exception management. | ||
/// </summary> | ||
public class BoundsCheckBlockStringNDF:BaseBoundsCheckBlock | ||
{ | ||
/// <summary>Initializes the base class for the bounds check.</summary> | ||
/// <param name="ignoreWhenDefaultValueIsSet">Flag that determines if the bounds checking should be ignored if a default value is set.</param> | ||
/// <param name="loggerBlock">Logger block used with bounds check logic.</param> | ||
public BoundsCheckBlockStringNDF(bool ignoreWhenDefaultValueIsSet, ILoggerBlock loggerBlock) : base(nameof(BoundsCheckBlockStringNDF), ignoreWhenDefaultValueIsSet, loggerBlock) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Generates the bounds check syntax if the parameter meets the criteria for a bounds check. | ||
/// </summary> | ||
/// <param name="sourceMethod">The target method the parameter belongs to.</param> | ||
/// <param name="checkParameter">The parameter to build the bounds check for.</param> | ||
/// <returns>Returns a tuple that contains a boolean that determines if the bounds check syntax was created for the parameter.</returns> | ||
public override (bool hasBoundsCheck, string boundsCheckSyntax) GenerateBoundsCheck(CsMethod sourceMethod, CsParameter checkParameter) | ||
{ | ||
//bounds check to make sure we have parameter data. | ||
if (checkParameter == null) return (false, null); | ||
|
||
if(!(checkParameter.ParameterType.Namespace == "System" & checkParameter.ParameterType.Name == "String")) return (false, null); | ||
|
||
if(checkParameter.HasDefaultValue) return (false, null); | ||
|
||
SourceFormatter formatter = new SourceFormatter(); | ||
|
||
formatter.AppendCodeLine(0,$"if (string.IsNullOrEmpty({checkParameter.Name}))"); | ||
formatter.AppendCodeLine(0,"{"); | ||
if (LoggerBlock != null) | ||
{ | ||
var errorMessage = | ||
$"$\"The parameter {{nameof({checkParameter.Name})}} was not provided. Will raise an argument exception\""; | ||
formatter.AppendCodeLine(1,LoggerBlock.GenerateLogging(LogLevel.Error, errorMessage,true)); | ||
formatter.AppendCodeLine(1, LoggerBlock.GenerateExitLogging(LogLevel.Error,sourceMethod.Name)); | ||
} | ||
formatter.AppendCodeLine(1,$"throw new ArgumentException(nameof({checkParameter.Name}));"); | ||
formatter.AppendCodeLine(0,"}"); | ||
|
||
return (true,formatter.ReturnSource()); | ||
} | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
src/Standard/NDF/CodeFactory.Automation.Standard.NDF.Logic/CatchBlockDBUpdateExceptionNDF.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using CodeFactory.WinVs.Models.CSharp.Builder; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace CodeFactory.Automation.Standard.NDF.Logic | ||
{ | ||
/// <summary> | ||
/// CodeBlock that builds a catch block for DBUpdateException and returns a NDF managed exception. | ||
/// </summary> | ||
public class CatchBlockDBUpdateExceptionNDF:BaseCatchBlock | ||
{ | ||
|
||
/// <summary> | ||
/// Creates a instances of the <see cref="CatchBlockDBUpdateExceptionNDF"/> | ||
/// </summary> | ||
/// <param name="loggerBlock">Optional, logger block to use for logging in the catch block.</param> | ||
public CatchBlockDBUpdateExceptionNDF(ILoggerBlock loggerBlock = null) : base(loggerBlock) | ||
{ | ||
//intentionally bank | ||
} | ||
|
||
/// <summary>Builds the catch block</summary> | ||
/// <param name="syntax">Syntax to be injected into the catch block, optional parameter.</param> | ||
/// <param name="multipleSyntax">Multiple syntax statements has been provided to be used by the catch block,optional parameter.</param> | ||
/// <param name="memberName">Optional parameter that determines the target member the catch block is implemented in.</param> | ||
/// <returns>Returns the generated catch block</returns> | ||
protected override string BuildCatchBlock(string syntax = null, IEnumerable<NamedSyntax> multipleSyntax = null, string memberName = null) | ||
{ | ||
SourceFormatter formatter = new SourceFormatter(); | ||
|
||
formatter.AppendCodeLine(0,"catch (DbUpdateException updateDataException)"); | ||
formatter.AppendCodeLine(0,"{"); | ||
formatter.AppendCodeLine(1, "var sqlError = updateDataException.InnerException as SqlException;"); | ||
formatter.AppendCodeLine(1); | ||
formatter.AppendCodeLine(1,"if (sqlError == null)"); | ||
formatter.AppendCodeLine(1,"{"); | ||
if (LoggerBlock != null) | ||
{ | ||
formatter.AppendCodeLine(2, LoggerBlock.GenerateLogging(LogLevel.Error, "The following database error occurred.",false,"updateDataException")); | ||
formatter.AppendCodeLine(2, LoggerBlock.GenerateExitLogging(LogLevel.Error, memberName)); | ||
} | ||
formatter.AppendCodeLine(2, "throw new DataException();"); | ||
formatter.AppendCodeLine(1,"}"); | ||
|
||
|
||
if (LoggerBlock != null) | ||
{ | ||
formatter.AppendCodeLine(1, LoggerBlock.GenerateLogging(LogLevel.Error, "The following SQL exception occurred.",false, "sqlError")); | ||
formatter.AppendCodeLine(1, LoggerBlock.GenerateExitLogging(LogLevel.Error, memberName)); | ||
} | ||
formatter.AppendCodeLine(1,"sqlError.ThrowManagedException();"); | ||
formatter.AppendCodeLine(0,"}"); | ||
|
||
return formatter.ReturnSource(); | ||
} | ||
} | ||
} |
Oops, something went wrong.