|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using bsn.GoldParser.Grammar;
using EntityMapper.Semantic;
using bsn.GoldParser.Semantic;
using System.CodeDom;
using System.IO;
using bsn.GoldParser.Parser;
namespace EntityMapper.CodeGen
{
public class EntityMapperGenerator
{
public string GrammarTable { get; set; }
public string NamespaceName { get; private set; }
public string ClassName { get; private set; }
public string MethodName { get; private set; }
public string SourceCode { get; private set; }
public Type FromType { get; private set; }
public Type ToType { get; private set; }
private CodeCompileUnit _compileunit;
private string _cuKey = null;
public EntityMapperGenerator(string className = "MapperUtility", string methodName = "MapEntity")
{
this.GrammarTable = "EntityTransformation.cgt";
this.NamespaceName = this.GetType().Namespace;
this.ClassName = className;
this.MethodName = methodName;
}
public void Parse(Type fromType, Type toType, string businessRules, string[] importedNamespaces)
{
string fullBusinessRules = string.Format("{0}|{1}|{2}", fromType.FullName, toType.FullName, businessRules);
string cuKey = Convert.ToBase64String(System.Security.Cryptography.HashAlgorithm.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(fullBusinessRules)));
if (_cuKey != cuKey)
{
this.FromType = fromType;
this.ToType = toType;
CompiledGrammar grammar = CompiledGrammar.Load(typeof(TokenBase), this.GrammarTable);
SemanticTypeActions<TokenBase> actions = new SemanticTypeActions<TokenBase>(grammar);
actions.Initialize(true);
SemanticProcessor<TokenBase> processor = new SemanticProcessor<TokenBase>(new StringReader(businessRules), actions);
ParseMessage parseMessage = processor.ParseAll();
if (parseMessage == ParseMessage.Accept)
{
var ctx = new ExecutionContext(GetClassTypeWrapper(ExecutionContext.FromParamName, ExecutionContext.ToParamName, importedNamespaces));
var stmts = processor.CurrentToken as Sequence<Statement>;
foreach (Statement stmt in stmts)
{
stmt.Execute(ctx);
}
_compileunit = ctx.TypeWrapper.CompileUnit;
SourceCode = CodeCompilerUtility.GenerateCSharpCode(_compileunit);
_cuKey = cuKey;
}
else
{
IToken token = processor.CurrentToken;
throw new ApplicationException(string.Format("{0} at line {1} and column {2}", parseMessage, token.Position.Line, token.Position.Column));
}
}
}
public Delegate GetDelegate(params string[] referencedAssemblies)
{
if (_cuKey == null || _compileunit == null)
{
throw new InvalidOperationException("Parse operation is not performed or succeeded!");
}
string typeName = this.NamespaceName + "." + this.ClassName;
Type delType = typeof(Action<,>).MakeGenericType(this.FromType, this.ToType);
//Get delegate from assembly produced from CodeDom compilation unit
var mapper = CodeCompilerUtility.GetDelegateFromCompileUnit(
_cuKey,
_compileunit,
referencedAssemblies,
typeName,
this.MethodName,
delType,
false);
return mapper;
}
private ClassTypeWrapper GetClassTypeWrapper(string fromParmName, string toParmName, string[] importedNamespaces)
{
var classWrapper = new ClassTypeWrapper(this.NamespaceName, this.ClassName, importedNamespaces);
classWrapper.AddMainMethod(new MapCodeMemberMethod().Create(this.FromType, this.ToType, this.MethodName, fromParmName, toParmName));
return classWrapper;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am always interested in finding innovative ways for building better applications and founded a technology company since 2003. Welcome to exchange any idea with you and if I am not too busy before deadline of projects, I will reply your emails. Also, if you willing to pay for consulting works and customized software development, you can leave me message.