private AggregateFunctionContext CreateMemberContext(ClassMappingDescriptor descriptor, MemberMappingDescriptor member, FunctionMap functionMap)
        {
            Type implementationType = functionMap.GetTypeForFunction(member.AggregateMappingDescription.FunctionName);
            string functionObjectName = string.Format("_{0}_to_{1}_Fn_",
                member.AggregateMappingDescription.FunctionObject,
                member.Member);
            if (implementationType.IsGenericType)
            {
                if (member.IsArray || member.IsList)
                {
                    Type instanceType = member.IsArray ?
                        member.AggregateMappingDescription.TargetType.GetElementType() :
                        member.AggregateMappingDescription.TargetType.GetGenericArguments()[0];
                    implementationType = implementationType.MakeGenericType(instanceType);
                }
                else
                {
                    implementationType = implementationType.MakeGenericType(member.AggregateMappingDescription.TargetType);
                }
            }

            IAggregateFunctionCodeGenerator generator = GetGeneratorImpl(implementationType, member);

            return new AggregateFunctionContext(member,
                                descriptor,
                                implementationType,
                                functionObjectName,
                                generator);
        }
Ejemplo n.º 2
0
        public void AddMapping(ClassMappingDescriptor descriptor, CodeGeneratorContext context)
        {
            CodeMemberMethod methodAssembleFrom = m_generator.CreateTypeTransformationMethod(descriptor);

            m_assemblerClass.Members.Add(methodAssembleFrom);

            CodeMemberMethod methodAssemble = m_generator.CreateInPlaceTransformationMethod(descriptor);

            m_assemblerClass.Members.Add(methodAssemble);

            CodeMemberMethod methodAssembleValueType = m_generator.CreateInPlaceTransformationMethodForValueTypes(descriptor);

            m_assemblerClass.Members.Add(methodAssembleValueType);

            CodeMemberMethod methodToList = m_generator.CreateToListMethod(descriptor);

            m_assemblerClass.Members.Add(methodToList);

            CodeMemberMethod methodToArray = m_generator.CreateToArrayMethod(descriptor);

            m_assemblerClass.Members.Add(methodToArray);


            string interfaceType = string.Format("IAssembler<{0}, {1}>",
                                                 TypeHelper.GetTypeDefinition(descriptor.TargetType),
                                                 TypeHelper.GetTypeDefinition(descriptor.SourceType));

            m_assemblerClass.BaseTypes.Add(interfaceType);
            AddReferencedAssemblies(descriptor);
        }
        private static void CopyMemberDescriptors(ClassMappingDescriptor from, ClassMappingDescriptor to)
        {
            foreach (MemberMappingDescriptor fromMember in from.MemberDescriptors)
            {
                // check if the member mapping is overriden in the derived class - do
                // not copy in that case
                bool overriden = false;
                foreach (MemberMappingDescriptor derivedMember in to.MemberDescriptors)
                {
                    if (!fromMember.Member.Equals(derivedMember.Member))
                    {
                        continue;
                    }
                    overriden = true;
                    break;
                }
                if (overriden)
                {
                    continue;
                }

                MemberMappingDescriptor toMember = new MemberMappingDescriptor(fromMember);
                toMember.OwnerType = to.TargetType;

                // check if the member is visible in the derived type
                MemberInfo member = FindMember(to.TargetType, toMember.Member);
                if (member != null)
                {
                    to.MemberDescriptors.Add(toMember);
                }
            }
        }
Ejemplo n.º 4
0
        private static ClassMappingDescriptor CreateMapping(Type type)
        {
            ClassMappingDescriptor desc = new ClassMappingDescriptor();

            desc.TargetType = type;

            object[]          attrs = type.GetCustomAttributes(typeof(MapClassAttribute), false);
            MapClassAttribute attr  = (MapClassAttribute)attrs[0];               // todo: assert (should be exactly 1)

            desc.SourceType    = attr.SourceType;
            desc.MappingHelper = attr.Helper;
            if (desc.HasHelper)
            {
                desc.IsHelperStatic = desc.MappingHelper.Contains(".");                             // todo: smarter assumption
            }
            desc.MappingPreparer = attr.Preparer;
            if (desc.HasPreparer)
            {
                desc.IsPreparerStatic = desc.MappingPreparer.Contains(".");         // todo: smarter assumption
            }
            AddMemberDescriptors(desc);
            AddPreparerMethod(desc);
            AddHelperMethod(desc);
            return(desc);
        }
        private AggregateFunctionContext CreateMemberContext(ClassMappingDescriptor descriptor, MemberMappingDescriptor member, FunctionMap functionMap)
        {
            Type   implementationType = functionMap.GetTypeForFunction(member.AggregateMappingDescription.FunctionName);
            string functionObjectName = string.Format("_{0}_to_{1}_Fn_",
                                                      member.AggregateMappingDescription.FunctionObject,
                                                      member.Member);

            if (implementationType.IsGenericType)
            {
                if (member.IsArray || member.IsList)
                {
                    Type instanceType = member.IsArray ?
                                        member.AggregateMappingDescription.TargetType.GetElementType() :
                                        member.AggregateMappingDescription.TargetType.GetGenericArguments()[0];
                    implementationType = implementationType.MakeGenericType(instanceType);
                }
                else
                {
                    implementationType = implementationType.MakeGenericType(member.AggregateMappingDescription.TargetType);
                }
            }

            IAggregateFunctionCodeGenerator generator = GetGeneratorImpl(implementationType, member);

            return(new AggregateFunctionContext(member,
                                                descriptor,
                                                implementationType,
                                                functionObjectName,
                                                generator));
        }
Ejemplo n.º 6
0
        public void Collect_Fails_On_Noncollection_Target()
        {
            CollectFunction         fn     = new CollectFunction();
            MemberMappingDescriptor member = new MemberMappingDescriptor();

            member.OwnerType  = typeof(AttributedUserDTO);
            member.Type       = typeof(string);
            member.Member     = "FullName";
            member.IsArray    = false;
            member.IsList     = false;
            member.Expression = "sum:$Projects/Tasks";
            ClassMappingDescriptor desc = new ClassMappingDescriptor();

            desc.SourceType = typeof(User);

            AggregateFunctionContext ctxt = new AggregateFunctionContext(member, desc, null, "", null);

            try
            {
                fn.GetInitializationStatements(ctxt);
            }
            catch (OtisException e)
            {
                if (e.Message.Contains("Target member 'FullName' for 'collect' aggregate function must be an array or a collection"))
                {
                    return;                     // success
                }
            }
            Assert.Fail("Tested method didn't throw an exception!");
        }
        private ClassMappingDescriptor CreateClassDescriptor(XmlNode node)
        {
            ClassMappingDescriptor desc = new ClassMappingDescriptor();

            desc.TargetType = Type.GetType(node.Attributes["name"].Value);                 // must exist
            if (desc.TargetType == null)
            {
                throw new OtisException(String.Format("Target Type \"{0}\" cannot be found", node.Attributes["name"].Value));
            }
            // todo: check if types exist + test.
            desc.SourceType = Type.GetType(node.Attributes["source"].Value);               // must exist
            if (desc.SourceType == null)
            {
                throw new OtisException(String.Format("Source Type \"{0}\" cannot be found", node.Attributes["source"].Value));
            }
            desc.MappingHelper = GetAttributeValue(node.Attributes["helper"]);             // optional
            if (desc.HasHelper)
            {
                desc.IsHelperStatic = desc.MappingHelper.Contains(".");
            }
            desc.MappingPreparer = GetAttributeValue(node.Attributes["preparer"]);             // optional
            if (desc.HasPreparer)
            {
                desc.IsPreparerStatic = desc.MappingPreparer.Contains(".");
            }
            AddMemberDescriptors(desc, node);
            return(desc);
        }
Ejemplo n.º 8
0
        private static string GetPath(ClassMappingDescriptor descriptor, MemberMappingDescriptor member)
        {
            // todo: optimize - don't do this for every member, this is also done in AggregateFunctionContext ctor
            IList <AggregateExpressionPathItem> pathItems = ExpressionParser.BuildAggregatePathItem(descriptor, member);
            bool isLastItemCollection = pathItems[pathItems.Count - 1].IsCollection;

            string path = member.Expression;
            int    pos  = path.IndexOf(':');

            if (pos >= 0)
            {
                path = path.Substring(pos + 1);
            }

            if (!isLastItemCollection)
            {
                pos = path.LastIndexOf('/');
                if (pos >= 0)
                {
                    path = path.Substring(0, pos);
                }
            }

            return(path);
        }
Ejemplo n.º 9
0
        public static IList <AggregateExpressionPathItem> BuildAggregatePathItem(ClassMappingDescriptor descriptor, MemberMappingDescriptor member)
        {
            string firstPart  = member.AggregateMappingDescription.PathParts[0];
            string targetName = firstPart.StartsWith("$") ? "source" : "";
            List <AggregateExpressionPathItem> pathItems = new List <AggregateExpressionPathItem>(3);
            Type targetType = descriptor.SourceType;


            foreach (string pathPart in member.AggregateMappingDescription.PathParts)
            {
                if (pathPart.Contains("."))
                {
                    string[] subParts = pathPart.Split('.');
                    foreach (string subPart in subParts)
                    {
                        targetName = AddPathItems(member, pathItems, subPart, targetName, ref targetType);
                    }
                }
                else
                {
                    targetName = AddPathItems(member, pathItems, pathPart, targetName, ref targetType);
                }
            }
            return(pathItems);
        }
Ejemplo n.º 10
0
        public CodeMemberMethod CreateToListMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();

            CreateExplicitInterfaceMethod(descriptor, method, "ToList");
            method.ReturnType = new CodeTypeReference(string.Format("List<{0}>", TypeHelper.GetTypeDefinition(descriptor.TargetType)));

            method.Parameters.Add(new CodeParameterDeclarationExpression(string.Format("IEnumerable<{0}>", TypeHelper.GetTypeDefinition(descriptor.SourceType)), "source"));

            method.Statements.Add(Util.CreateNullHandlingStatement(false, true, true));

            string listType = string.Format("List<{0}>", TypeHelper.GetTypeDefinition(descriptor.TargetType));
            string listInit = string.Format("new {0}(10)", listType);

            method.Statements.Add(new CodeVariableDeclarationStatement(listType, "lst", new CodeSnippetExpression(listInit)));
            method.Statements.Add(new CodeVariableDeclarationStatement(GetInterfaceTypeName(descriptor), "_this", new CodeThisReferenceExpression()));

            string forEach =
                string.Format("foreach({0} srcItem in source){{ lst.Add(_this.AssembleFrom(srcItem)); }}", TypeHelper.GetTypeDefinition(descriptor.SourceType));

            method.Statements.Add(new CodeSnippetExpression(forEach));
            method.Statements.Add(Util.CreateReturnStatement("lst"));

            return(method);
        }
Ejemplo n.º 11
0
        private CodeStatement CreateInitializationStatement(ClassMappingDescriptor descriptor)
        {
            string format        = descriptor.TargetType.IsValueType ? "default ({0})" : "new {0}()";
            string createSnippet = string.Format(format, TypeHelper.GetTypeDefinition(descriptor.TargetType));

            return(new CodeVariableDeclarationStatement(descriptor.TargetType, "target",
                                                        new CodeSnippetExpression(createSnippet)));
        }
        private static CodeStatement[] CreateAggregateMappingStatements(ClassMappingDescriptor descriptor, ICollection<MemberMappingDescriptor> members, CodeGeneratorContext context)
        {
            /*if (!member.IsAggregateExpression)										  todo: remove
                throw new OtisException(string.Format("Expression '{0}' is not a aggregate expression", member.Expression)); */

            AggregateExpressionBuilder expBuilder = new AggregateExpressionBuilder(descriptor, members, context.FunctionMap);
            return expBuilder.GetStatements();
        }
        public CodeMemberMethod CreateInPlaceTransformationMethodForValueTypes(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = CreateInPlaceTransformationMethod(descriptor);
            method.Parameters[0].Direction = FieldDirection.Ref;
            method.Parameters[1].Direction = FieldDirection.Ref;

            return method;
        }
Ejemplo n.º 14
0
        private static void CheckDescription <Target, Source>(ClassMappingDescriptor desc)
        {
            Assert.AreEqual(typeof(Target), desc.TargetType);
            Assert.AreEqual(typeof(Source), desc.SourceType);
            Assert.AreEqual("Otis.Tests.Util.Convert", desc.MappingHelper);

            Assert.AreEqual(8, desc.MemberDescriptors.Count);
            MemberMappingDescriptor member = null;

            member = Helpers.FindMember(desc.MemberDescriptors, "Id");
            Assert.AreEqual("$Id", member.Expression);
            Assert.AreEqual(null, member.NullValue);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(int), member.Type);

            member = Helpers.FindMember(desc.MemberDescriptors, "Age");
            Assert.AreEqual("$Age", member.Expression);
            Assert.AreEqual(null, member.NullValue);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(int), member.Type);

            member = Helpers.FindMember(desc.MemberDescriptors, "UserName");
            Assert.AreEqual("$UserName.ToUpper()", member.Expression);
            Assert.AreEqual("\"[unknown]\"", member.NullValue);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(string), member.Type);

            member = Helpers.FindMember(desc.MemberDescriptors, "FullName");
            Assert.AreEqual("$FirstName + \" \" + $LastName", member.Expression);
            Assert.AreEqual("\"MISSING_NAME_PART\"", member.NullValue);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(string), member.Type);

            member = Helpers.FindMember(desc.MemberDescriptors, "Title");
            Assert.AreEqual("\"Mr.\" + $FirstName + \" \" + $LastName", member.Expression);
            Assert.AreEqual(null, member.NullValue);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(string), member.Type);

            member = Helpers.FindMember(desc.MemberDescriptors, "ProjectCount");
            Assert.AreEqual("$Projects.Count", member.Expression);
            Assert.AreEqual(null, member.NullValue);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(int), member.Type);

            member = Helpers.FindMember(desc.MemberDescriptors, "Gender");
            Assert.AreEqual(2, member.Projections.Count);
            Assert.AreEqual("Otis.Tests.Gender.Male", member.Projections["\"M\""]);
            Assert.AreEqual("Otis.Tests.Gender.Female", member.Projections["\"W\""]);
            Assert.AreEqual(typeof(Target), member.OwnerType);
            Assert.AreEqual(typeof(Otis.Tests.Gender), member.Type);


            member = Helpers.FindMember(desc.MemberDescriptors, "GenderCode");
            Assert.AreEqual(2, member.Projections.Count);
            Assert.AreEqual("\"M\"", member.Projections["\"M\""]);
            Assert.AreEqual("\"W\"", member.Projections["\"W\""]);
        }
Ejemplo n.º 15
0
        private static CodeStatement[] CreateAggregateMappingStatements(ClassMappingDescriptor descriptor, ICollection <MemberMappingDescriptor> members, CodeGeneratorContext context)
        {
            /*if (!member.IsAggregateExpression)										  todo: remove
             *      throw new OtisException(string.Format("Expression '{0}' is not a aggregate expression", member.Expression)); */

            AggregateExpressionBuilder expBuilder = new AggregateExpressionBuilder(descriptor, members, context.FunctionMap);

            return(expBuilder.GetStatements());
        }
Ejemplo n.º 16
0
        public void Formatting_Is_Detected_In_Assembly_Mapping()
        {
            IMappingDescriptorProvider provider = ProviderFactory.FromType(typeof(UserDTO));
            ClassMappingDescriptor     desc     = provider.ClassDescriptors[0];
            MemberMappingDescriptor    member   = Helpers.FindMember(desc.MemberDescriptors, "BirthDay");

            Assert.IsTrue(member.HasFormatting);
            Assert.AreEqual("{0:D}", member.Format);
        }
        public AggregateExpressionBuilder(ClassMappingDescriptor descriptor, ICollection <MemberMappingDescriptor> members, FunctionMap functionMap)
        {
            m_contexts = new List <AggregateFunctionContext>(members.Count);

            foreach (MemberMappingDescriptor member in members)
            {
                m_contexts.Add(CreateMemberContext(descriptor, member, functionMap));
            }
        }
        public AggregateExpressionBuilder(ClassMappingDescriptor descriptor, ICollection<MemberMappingDescriptor> members, FunctionMap functionMap)
        {
            m_contexts = new List<AggregateFunctionContext>(members.Count);

            foreach (MemberMappingDescriptor member in members)
            {
                m_contexts.Add(CreateMemberContext(descriptor, member, functionMap));
            }
        }
Ejemplo n.º 19
0
        public void Read_Mapping_From_Xml()
        {
            IMappingDescriptorProvider provider = ProviderFactory.FromXmlFile("XmlMappings\\mappings.xml");

            Assert.AreEqual(2, provider.ClassDescriptors.Count);
            ClassMappingDescriptor desc = provider.ClassDescriptors[0];

            CheckDescription <XmlUserDTO, User>(desc);
        }
Ejemplo n.º 20
0
        public void Read_Mapping_From_Assembly()
        {
            IMappingDescriptorProvider provider = ProviderFactory.FromType(typeof(AttributedUserDTO));

            Assert.AreEqual(1, provider.ClassDescriptors.Count);
            ClassMappingDescriptor desc = provider.ClassDescriptors[0];

            CheckDescription <AttributedUserDTO, User>(desc);
        }
Ejemplo n.º 21
0
        public CodeMemberMethod CreateInPlaceTransformationMethodForValueTypes(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = CreateInPlaceTransformationMethod(descriptor);

            method.Parameters[0].Direction = FieldDirection.Ref;
            method.Parameters[1].Direction = FieldDirection.Ref;

            return(method);
        }
        private void AddMemberDescriptors(ClassMappingDescriptor desc, XmlNode classNode)
        {
            XmlNodeList members = classNode.SelectNodes("default:member", m_nsMgr);

            foreach (XmlNode memberNode in members)
            {
                desc.MemberDescriptors.Add(CreateMemberDescriptor(desc, memberNode));
            }
            AddInheritanceMemberDescriptors(desc);
        }
        public CodeMemberMethod CreateInPlaceTransformationMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            CreateMethodCommons(method, "Assemble", descriptor);

            method.ReturnType = new CodeTypeReference(typeof(void));
            method.Parameters.Add(new CodeParameterDeclarationExpression(descriptor.TargetType, "target"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(descriptor.SourceType, "source"));

            return method;
        }
Ejemplo n.º 24
0
        public void Formatting_Is_Detected_In_Xml_Mapping()
        {
            IMappingDescriptorProvider provider = ProviderFactory.FromXmlFile("XmlMappings\\mappings.xml");

            Assert.AreEqual(2, provider.ClassDescriptors.Count);
            ClassMappingDescriptor  desc   = provider.ClassDescriptors[1];
            MemberMappingDescriptor member = Helpers.FindMember(desc.MemberDescriptors, "BirthDay");

            Assert.IsTrue(member.HasFormatting);
            Assert.AreEqual("{0:D}", member.Format);
        }
        public CodeMemberMethod CreateTypeTransformationMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Statements.Add(CreateInitializationStatement(descriptor));
            CreateMethodCommons(method, "AssembleFrom", descriptor);

            method.ReturnType = new CodeTypeReference(descriptor.TargetType);
            method.Parameters.Add(new CodeParameterDeclarationExpression(descriptor.SourceType, "source"));
            method.Statements.Add(Util.CreateReturnStatement("target"));

            return method;
        }
Ejemplo n.º 26
0
        public CodeMemberMethod CreateInPlaceTransformationMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();

            CreateMethodCommons(method, "Assemble", descriptor);

            method.ReturnType = new CodeTypeReference(typeof(void));
            method.Parameters.Add(new CodeParameterDeclarationExpression(descriptor.TargetType, "target"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(descriptor.SourceType, "source"));

            return(method);
        }
Ejemplo n.º 27
0
        private static void CreateExplicitInterfaceMethod(ClassMappingDescriptor descriptor, CodeMemberMethod method, string methodName)
        {
            method.Name = methodName;

            string interfaceType = GetInterfaceTypeName(descriptor);

            method.Attributes = MemberAttributes.Final;
            // interfaces are explicitly implemented which makes it possible to have multiple methods with
            // same name and same parameters in one class, e.g.
            // DTO1 AssembleFrom(Entity); -> implemented as: DTO1 IAssembler<DTO1, Entity>.AssembleFrom(Entity);
            // DTO2 AssembleFrom(Entity); -> implemented as: DTO2 IAssembler<DTO2, Entity>.AssembleFrom(Entity);
            method.PrivateImplementationType = new CodeTypeReference(interfaceType);
        }
Ejemplo n.º 28
0
        public CodeMemberMethod CreateTypeTransformationMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();

            method.Statements.Add(CreateInitializationStatement(descriptor));
            CreateMethodCommons(method, "AssembleFrom", descriptor);

            method.ReturnType = new CodeTypeReference(descriptor.TargetType);
            method.Parameters.Add(new CodeParameterDeclarationExpression(descriptor.SourceType, "source"));
            method.Statements.Add(Util.CreateReturnStatement("target"));

            return(method);
        }
        public CodeMemberMethod CreateToArrayMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            CreateExplicitInterfaceMethod(descriptor, method, "ToArray");
            method.ReturnType = new CodeTypeReference(string.Format("{0}[]", TypeHelper.GetTypeDefinition(descriptor.TargetType)));

            method.Parameters.Add(new CodeParameterDeclarationExpression(string.Format("IEnumerable<{0}>", TypeHelper.GetTypeDefinition(descriptor.SourceType)), "source"));

            method.Statements.Add(Util.CreateNullHandlingStatement(false, true, true));
            method.Statements.Add(new CodeVariableDeclarationStatement(GetInterfaceTypeName(descriptor), "_this", new CodeThisReferenceExpression()));
            method.Statements.Add(Util.CreateReturnStatement("_this.ToList(source).ToArray()"));

            return method;
        }
        public AggregateFunctionContext(MemberMappingDescriptor member,
                                        ClassMappingDescriptor descriptor,
                                        Type implementationType,
                                        string functionObjectName,
                                        IAggregateFunctionCodeGenerator generator)
        {
            m_member             = member;
            m_generator          = generator;
            m_functionObjectName = functionObjectName;
            m_implementationType = implementationType;
            m_descriptor         = descriptor;

            m_pathItems  = ExpressionParser.BuildAggregatePathItem(descriptor, member);
            m_sourceItem = m_pathItems[m_pathItems.Count - 1];
        }
Ejemplo n.º 31
0
        public CodeMemberMethod CreateToArrayMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();

            CreateExplicitInterfaceMethod(descriptor, method, "ToArray");
            method.ReturnType = new CodeTypeReference(string.Format("{0}[]", TypeHelper.GetTypeDefinition(descriptor.TargetType)));

            method.Parameters.Add(new CodeParameterDeclarationExpression(string.Format("IEnumerable<{0}>", TypeHelper.GetTypeDefinition(descriptor.SourceType)), "source"));

            method.Statements.Add(Util.CreateNullHandlingStatement(false, true, true));
            method.Statements.Add(new CodeVariableDeclarationStatement(GetInterfaceTypeName(descriptor), "_this", new CodeThisReferenceExpression()));
            method.Statements.Add(Util.CreateReturnStatement("_this.ToList(source).ToArray()"));

            return(method);
        }
        public AggregateFunctionContext(MemberMappingDescriptor member, 
            ClassMappingDescriptor descriptor,
            Type implementationType,
            string functionObjectName,
            IAggregateFunctionCodeGenerator generator)
        {
            m_member = member;
            m_generator = generator;
            m_functionObjectName = functionObjectName;
            m_implementationType = implementationType;
            m_descriptor = descriptor;

            m_pathItems = ExpressionParser.BuildAggregatePathItem(descriptor, member);
            m_sourceItem = m_pathItems[m_pathItems.Count - 1];
        }
Ejemplo n.º 33
0
        public static CodeStatement[] CreateMappingStatements(ClassMappingDescriptor descriptor, CodeGeneratorContext context)
        {
            Dictionary <string, List <MemberMappingDescriptor> > aggregateGroups = new Dictionary <string, List <MemberMappingDescriptor> >();
            List <CodeStatement> statements = new List <CodeStatement>(20);

            foreach (MemberMappingDescriptor member in descriptor.MemberDescriptors)
            {
                if (member.IsAggregateExpression)
                {
                    // group all agregates by expression to avoid multiple traversals over same path
                    //string path = GetPath(member.Expression);
                    string path = GetPath(descriptor, member);
                    if (!aggregateGroups.ContainsKey(path))
                    {
                        aggregateGroups[path] = new List <MemberMappingDescriptor>(1);
                    }
                    aggregateGroups[path].Add(member);
                }
                else
                {
                    CodeStatement[] st = CreateNonAggregateMappingStatements(descriptor, member, context);
                    if (member.HasNullValue)
                    {
                        CodeStatement[] falseStatements = st;
                        CodeStatement[] trueStatements  = new CodeStatement[1];
                        trueStatements[0] = new CodeAssignStatement(
                            new CodeVariableReferenceExpression("target." + member.Member),
                            new CodeSnippetExpression(member.NullValue.ToString()));

                        string         checkExpression = GetNullablePartsCheckExpression(member);
                        CodeExpression ifExpression    = new CodeSnippetExpression(checkExpression);

                        st    = new CodeStatement[1];
                        st[0] = new CodeConditionStatement(ifExpression, trueStatements, falseStatements);
                    }
                    statements.AddRange(st);
                }
            }

            foreach (List <MemberMappingDescriptor> group in aggregateGroups.Values)
            {
                CodeStatement[] st = CreateAggregateMappingStatements(descriptor, group, context);
                statements.AddRange(st);
            }

            return(statements.ToArray());
        }
        public static CodeStatement[] CreateMappingStatements(ClassMappingDescriptor descriptor, CodeGeneratorContext context)
        {
            Dictionary<string, List<MemberMappingDescriptor>> aggregateGroups = new Dictionary<string, List<MemberMappingDescriptor>>();
            List<CodeStatement> statements = new List<CodeStatement>(20);
            foreach (MemberMappingDescriptor member in descriptor.MemberDescriptors)
            {
                if (member.IsAggregateExpression)
                {
                    // group all agregates by expression to avoid multiple traversals over same path
                    //string path = GetPath(member.Expression);
                    string path = GetPath(descriptor, member);
                    if(!aggregateGroups.ContainsKey(path))
                        aggregateGroups[path] = new List<MemberMappingDescriptor>(1);
                    aggregateGroups[path].Add(member);
                }
                else
                {
                    CodeStatement[] st = CreateNonAggregateMappingStatements(descriptor, member, context);
                    if(member.HasNullValue)
                    {
                        CodeStatement[] falseStatements = st;
                        CodeStatement[] trueStatements = new CodeStatement[1];
                        trueStatements[0] = new CodeAssignStatement(
                            new CodeVariableReferenceExpression("target." + member.Member),
                            new CodeSnippetExpression(member.NullValue.ToString()));

                        string checkExpression = GetNullablePartsCheckExpression(member);
                        CodeExpression ifExpression = new CodeSnippetExpression(checkExpression);

                        st = new CodeStatement[1];
                        st[0] = new CodeConditionStatement(ifExpression, trueStatements, falseStatements);
                    }
                    statements.AddRange(st);
                }
            }

            foreach (List<MemberMappingDescriptor> group in aggregateGroups.Values)
            {
                    CodeStatement[] st = CreateAggregateMappingStatements(descriptor, group, context);
                    statements.AddRange(st);
            }

            return statements.ToArray();
        }
        private void AddInheritanceMemberDescriptors(ClassMappingDescriptor currentClassDescriptor)
        {
            foreach (ClassMappingDescriptor desc in m_classDescriptors)
            {
                if (desc.TargetType.Equals(currentClassDescriptor.TargetType))
                {
                    continue;
                }

                if (desc.TargetType.IsAssignableFrom(currentClassDescriptor.TargetType))
                {
                    CopyMemberDescriptors(desc, currentClassDescriptor);
                }
                if (currentClassDescriptor.TargetType.IsAssignableFrom(desc.TargetType))
                {
                    CopyMemberDescriptors(currentClassDescriptor, desc);
                }
            }
        }
Ejemplo n.º 36
0
        private static void AddMemberDescriptors(ClassMappingDescriptor desc)
        {
            FieldInfo[]    fields     = desc.TargetType.GetFields(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo[] properties = desc.TargetType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (FieldInfo field in fields)
            {
                if (field.IsDefined(typeof(MapAttribute), false))
                {
                    desc.MemberDescriptors.Add(CreateMemberMapping(desc, field));
                }
            }

            foreach (PropertyInfo property in properties)
            {
                if (property.IsDefined(typeof(MapAttribute), false))
                {
                    desc.MemberDescriptors.Add(CreateMemberMapping(desc, property));
                }
            }
        }
        public CodeMemberMethod CreateToListMethod(ClassMappingDescriptor descriptor)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            CreateExplicitInterfaceMethod(descriptor, method, "ToList");
            method.ReturnType = new CodeTypeReference(string.Format("List<{0}>", TypeHelper.GetTypeDefinition(descriptor.TargetType)));

            method.Parameters.Add(new CodeParameterDeclarationExpression(string.Format("IEnumerable<{0}>", TypeHelper.GetTypeDefinition(descriptor.SourceType)), "source"));

            method.Statements.Add(Util.CreateNullHandlingStatement(false, true, true));

            string listType = string.Format("List<{0}>", TypeHelper.GetTypeDefinition(descriptor.TargetType));
            string listInit = string.Format("new {0}(10)", listType);
            method.Statements.Add(new CodeVariableDeclarationStatement(listType, "lst", new CodeSnippetExpression(listInit)));
            method.Statements.Add(new CodeVariableDeclarationStatement(GetInterfaceTypeName(descriptor), "_this", new CodeThisReferenceExpression()));

            string forEach =
                string.Format("foreach({0} srcItem in source){{ lst.Add(_this.AssembleFrom(srcItem)); }}", TypeHelper.GetTypeDefinition(descriptor.SourceType));
            method.Statements.Add(new CodeSnippetExpression(forEach));
            method.Statements.Add(Util.CreateReturnStatement("lst"));

            return method;
        }
        private static void AddHelperMethod(ClassMappingDescriptor desc)
        {
            MethodInfo[] methods = desc.TargetType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

            foreach (MethodInfo method in methods)
                if (method.IsDefined(typeof(MappingHelperAttribute), false))
                {
                    if(desc.HasHelper)
                    {
                        string msg = string.Format(errDuplicateHelper, method.Name, TypeHelper.GetTypeDefinition(desc.TargetType), desc.MappingHelper);
                        throw new OtisException(msg);
                    }
                    if (!method.IsPublic)
                    {
                        string msg = string.Format(errHelperIsPrivate, method.Name, TypeHelper.GetTypeDefinition(desc.TargetType));
                        throw new OtisException(msg);
                    }

                    desc.MappingHelper = method.Name;
                    desc.IsHelperStatic = method.IsStatic;
                }
        }
        private MemberMappingDescriptor CreateMemberDescriptor(ClassMappingDescriptor classDesc, XmlNode node)
        {
            MemberMappingDescriptor desc = new MemberMappingDescriptor();

            desc.Member     = GetAttributeValue(node.Attributes["name"]);
            desc.Expression = GetAttributeValue(node.Attributes["expression"], "$" + desc.Member);
            desc.NullValue  = GetAttributeValue(node.Attributes["nullValue"]);
            desc.Format     = GetAttributeValue(node.Attributes["format"]);
            desc.OwnerType  = classDesc.TargetType;

            MemberInfo member = FindMember(classDesc.TargetType, desc.Member);

            if (member == null)
            {
                string msg = string.Format(Errors.MemberNotFound, desc.Member, TypeHelper.GetTypeDefinition(classDesc.TargetType));
                throw new OtisException(msg);
            }

            desc.Type = GetTargetType(member);

            if (desc.HasFormatting && desc.Type != typeof(string))
            {
                string msg = string.Format(Errors.FormattingAppliedOnNonStringMember,
                                           TypeHelper.GetTypeDefinition(classDesc.TargetType),
                                           desc.Member,
                                           TypeHelper.GetTypeDefinition(desc.Type));
                throw new OtisException(msg);
            }

            desc.IsArray = desc.Type.IsArray;
            desc.IsList  = (typeof(ICollection).IsAssignableFrom(desc.Type)) || desc.Type.GetInterface(typeof(ICollection <>).FullName) != null;

            XmlNodeList projections = node.SelectNodes("default:map", m_nsMgr);

            desc.Projections = BuildProjections(desc, projections);
            return(desc);
        }
Ejemplo n.º 40
0
        public void AddMapping(ClassMappingDescriptor descriptor, CodeGeneratorContext context)
        {
            CodeMemberMethod methodAssembleFrom = m_generator.CreateTypeTransformationMethod(descriptor);
            m_assemblerClass.Members.Add(methodAssembleFrom);

            CodeMemberMethod methodAssemble = m_generator.CreateInPlaceTransformationMethod(descriptor);
            m_assemblerClass.Members.Add(methodAssemble);

            CodeMemberMethod methodAssembleValueType = m_generator.CreateInPlaceTransformationMethodForValueTypes(descriptor);
            m_assemblerClass.Members.Add(methodAssembleValueType);

            CodeMemberMethod methodToList = m_generator.CreateToListMethod(descriptor);
            m_assemblerClass.Members.Add(methodToList);

            CodeMemberMethod methodToArray = m_generator.CreateToArrayMethod(descriptor);
            m_assemblerClass.Members.Add(methodToArray);

            string interfaceType = string.Format(	"IAssembler<{0}, {1}>",
                                                    TypeHelper.GetTypeDefinition(descriptor.TargetType),
                                                    TypeHelper.GetTypeDefinition(descriptor.SourceType));

            m_assemblerClass.BaseTypes.Add(interfaceType);
            AddReferencedAssemblies(descriptor);
        }
Ejemplo n.º 41
0
        private static CodeStatement[] CreateNonAggregateMappingStatements(ClassMappingDescriptor descriptor, MemberMappingDescriptor member, CodeGeneratorContext context)
        {
            if (member.Projections.Count > 0)
            {
                return(CreateProjectionMapping(member));
            }

            if (member.Type == typeof(string) || member.Type.IsPrimitive)
            {
                return(CreateSimpleMapping(member));
            }

            if (member.IsArray)
            {
                return(CreateArrayMappingStatements(member));
            }

            if (member.IsList)
            {
                return(CreateListMappingStatements(member));
            }

            return(CreateAssemblerMapping(member));
        }
Ejemplo n.º 42
0
        private static void AddHelperMethod(ClassMappingDescriptor desc)
        {
            MethodInfo[] methods = desc.TargetType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

            foreach (MethodInfo method in methods)
            {
                if (method.IsDefined(typeof(MappingHelperAttribute), false))
                {
                    if (desc.HasHelper)
                    {
                        string msg = string.Format(errDuplicateHelper, method.Name, TypeHelper.GetTypeDefinition(desc.TargetType), desc.MappingHelper);
                        throw new OtisException(msg);
                    }
                    if (!method.IsPublic)
                    {
                        string msg = string.Format(errHelperIsPrivate, method.Name, TypeHelper.GetTypeDefinition(desc.TargetType));
                        throw new OtisException(msg);
                    }

                    desc.MappingHelper  = method.Name;
                    desc.IsHelperStatic = method.IsStatic;
                }
            }
        }
        private static void CreateExplicitInterfaceMethod(ClassMappingDescriptor descriptor, CodeMemberMethod method, string methodName)
        {
            method.Name = methodName;

            string interfaceType = GetInterfaceTypeName(descriptor);

            method.Attributes = MemberAttributes.Final;
            // interfaces are explicitly implemented which makes it possible to have multiple methods with
            // same name and same parameters in one class, e.g.
            // DTO1 AssembleFrom(Entity); -> implemented as: DTO1 IAssembler<DTO1, Entity>.AssembleFrom(Entity);
            // DTO2 AssembleFrom(Entity); -> implemented as: DTO2 IAssembler<DTO2, Entity>.AssembleFrom(Entity);
            method.PrivateImplementationType = new CodeTypeReference(interfaceType);
        }
        private CodeMemberMethod CreateMethodCommons(CodeMemberMethod method, string methodName, ClassMappingDescriptor descriptor)
        {
            CreateExplicitInterfaceMethod(descriptor, method, methodName);

            if (descriptor.HasPreparer)
            {
                method.Statements.Add(CreatePreparerCall(descriptor));
            }

            CodeStatement[] statements = FunctionMappingGenerator.CreateMappingStatements(descriptor, m_context);
            method.Statements.AddRange(statements);

            if (descriptor.HasHelper)
            {
                method.Statements.Add(CreateHelperCall(descriptor));
            }

            return method;
        }
        private void AddInheritanceMemberDescriptors(ClassMappingDescriptor currentClassDescriptor)
        {
            foreach(ClassMappingDescriptor desc in m_classDescriptors)
            {
                if (desc.TargetType.Equals(currentClassDescriptor.TargetType)) continue;

                if (desc.TargetType.IsAssignableFrom(currentClassDescriptor.TargetType))
                {
                    CopyMemberDescriptors(desc, currentClassDescriptor);
                }
                if (currentClassDescriptor.TargetType.IsAssignableFrom(desc.TargetType))
                {
                    CopyMemberDescriptors(currentClassDescriptor, desc);
                }
            }
        }
        private static void CopyMemberDescriptors(ClassMappingDescriptor from, ClassMappingDescriptor to)
        {
            foreach(MemberMappingDescriptor fromMember in from.MemberDescriptors)
            {
                // check if the member mapping is overriden in the derived class - do
                // not copy in that case
                bool overriden = false;
                foreach(MemberMappingDescriptor derivedMember in to.MemberDescriptors)
                {
                    if (!fromMember.Member.Equals(derivedMember.Member)) continue;
                    overriden = true;
                    break;
                }
                if (overriden) continue;

                MemberMappingDescriptor toMember = new MemberMappingDescriptor(fromMember);
                toMember.OwnerType = to.TargetType;

                // check if the member is visible in the derived type
                MemberInfo member = FindMember(to.TargetType, toMember.Member);
                if (member != null)
                {
                    to.MemberDescriptors.Add(toMember);
                }
            }
        }
 private ClassMappingDescriptor CreateClassDescriptor(XmlNode node)
 {
     ClassMappingDescriptor desc = new ClassMappingDescriptor();
     desc.TargetType = Type.GetType(node.Attributes["name"].Value);	   // must exist
     if (desc.TargetType == null)
     {
         throw new OtisException(String.Format("Target Type \"{0}\" cannot be found", node.Attributes["name"].Value));
     }
     // todo: check if types exist + test.
     desc.SourceType = Type.GetType(node.Attributes["source"].Value);   // must exist
     if (desc.SourceType == null)
     {
         throw new OtisException(String.Format("Source Type \"{0}\" cannot be found", node.Attributes["source"].Value));
     }
     desc.MappingHelper = GetAttributeValue(node.Attributes["helper"]); // optional
     if (desc.HasHelper) desc.IsHelperStatic = desc.MappingHelper.Contains(".");
     desc.MappingPreparer = GetAttributeValue(node.Attributes["preparer"]); // optional
     if (desc.HasPreparer)
     desc.IsPreparerStatic = desc.MappingPreparer.Contains(".");
     AddMemberDescriptors(desc, node);
     return desc;
 }
 private void AddMemberDescriptors(ClassMappingDescriptor desc, XmlNode classNode)
 {
     XmlNodeList members = classNode.SelectNodes("default:member", m_nsMgr);
     foreach (XmlNode memberNode in members)
     {
         desc.MemberDescriptors.Add(CreateMemberDescriptor(desc, memberNode));
     }
     AddInheritanceMemberDescriptors(desc);
 }
        private static ClassMappingDescriptor CreateMapping(Type type)
        {
            ClassMappingDescriptor desc = new ClassMappingDescriptor();
            desc.TargetType = type;

            object[] attrs = type.GetCustomAttributes(typeof(MapClassAttribute), false);
            MapClassAttribute attr = (MapClassAttribute) attrs[0];   // todo: assert (should be exactly 1)

            desc.SourceType = attr.SourceType;
            desc.MappingHelper = attr.Helper;
            if (desc.HasHelper) desc.IsHelperStatic = desc.MappingHelper.Contains("."); // todo: smarter assumption
            desc.MappingPreparer = attr.Preparer;
            if (desc.HasPreparer)
            desc.IsPreparerStatic = desc.MappingPreparer.Contains("."); // todo: smarter assumption
            AddMemberDescriptors(desc);
            AddPreparerMethod(desc);
            AddHelperMethod(desc);
            return desc;
        }
 private static string GetInterfaceTypeName(ClassMappingDescriptor descriptor)
 {
     return string.Format("IAssembler<{0}, {1}>",
                          TypeHelper.GetTypeDefinition(descriptor.TargetType),
                          TypeHelper.GetTypeDefinition(descriptor.SourceType));
 }
        private static void AddMemberDescriptors(ClassMappingDescriptor desc)
        {
            FieldInfo[] fields = desc.TargetType.GetFields(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo[] properties = desc.TargetType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (FieldInfo field in fields)
                if (field.IsDefined(typeof(MapAttribute), false))
                    desc.MemberDescriptors.Add(CreateMemberMapping(desc, field));

            foreach (PropertyInfo property in properties)
                if (property.IsDefined(typeof(MapAttribute), false))
                    desc.MemberDescriptors.Add(CreateMemberMapping(desc, property));
        }
        private static MemberMappingDescriptor CreateMemberMapping(ClassMappingDescriptor classDesc, MemberInfo member)
        {
            MemberMappingDescriptor desc = new MemberMappingDescriptor();
            object[] attrs = member.GetCustomAttributes(typeof(MapAttribute), false);
            MapAttribute attr = (MapAttribute) attrs[0]; // todo: assert (should be exactly 1) + test

            desc.Member = member.Name;
            desc.Expression = attr.Expression ?? "$" + desc.Member;
            if (attr.NullValue is string)
                desc.NullValue = "\"" + attr.NullValue.ToString().Trim('"') + "\"";
            else if(attr.NullValue != null)
                desc.NullValue = attr.NullValue.ToString();
            else
                desc.NullValue = null;
            desc.Format = attr.Format;
            desc.OwnerType = classDesc.TargetType;

            if(member.MemberType == MemberTypes.Property)
            {
                PropertyInfo p = (PropertyInfo)member;
                desc.Type = p.PropertyType;
            }
            else
            {
                FieldInfo f = (FieldInfo)member;
                desc.Type = f.FieldType;
            }

            if(desc.HasFormatting && desc.Type != typeof(string))
            {
                string msg = string.Format(Errors.FormattingAppliedOnNonStringMember,
                                           TypeHelper.GetTypeDefinition(classDesc.TargetType),
                                           desc.Member,
                                     TypeHelper.GetTypeDefinition(desc.Type));
                throw new OtisException(msg);
            }

            if(desc.Type.IsArray)
            {
                desc.IsArray = true;
            }
            else if (typeof(ICollection).IsAssignableFrom(desc.Type)
                || desc.Type.GetInterface(typeof(ICollection<>).FullName) != null)
            {
                desc.IsList = true;
            }

            if(attr.HasProjection)
            {
                desc.Projections = GetProjections(desc, attr.Projection);
            }

            return desc;
        }
        private static CodeStatement[] CreateNonAggregateMappingStatements(ClassMappingDescriptor descriptor, MemberMappingDescriptor member, CodeGeneratorContext context)
        {
            if (member.Projections.Count > 0)
                return CreateProjectionMapping(member);

            if (member.Type == typeof(string) || member.Type.IsPrimitive)
                return CreateSimpleMapping(member);

            if (member.IsArray)
                return CreateArrayMappingStatements(member);

            if (member.IsList)
                return CreateListMappingStatements(member);

            return CreateAssemblerMapping(member);
        }
        private static string GetPath(ClassMappingDescriptor descriptor, MemberMappingDescriptor member)
        {
            // todo: optimize - don't do this for every member, this is also done in AggregateFunctionContext ctor
            IList<AggregateExpressionPathItem> pathItems = ExpressionParser.BuildAggregatePathItem(descriptor, member);
            bool isLastItemCollection = pathItems[pathItems.Count - 1].IsCollection;

            string path = member.Expression;
            int pos = path.IndexOf(':');

            if (pos >= 0)
                path = path.Substring(pos + 1);

            if (!isLastItemCollection)
            {
                pos = path.LastIndexOf('/');
                if (pos >= 0)
                    path = path.Substring(0, pos);
            }

            return path;
        }
 private void CheckDescriptor(ClassMappingDescriptor descriptor)
 {
     //throw new Exception("!");
 }
        private CodeStatement CreateInitializationStatement(ClassMappingDescriptor descriptor)
        {
            string format = descriptor.TargetType.IsValueType ? "default ({0})" : "new {0}()";
            string createSnippet = string.Format(format, TypeHelper.GetTypeDefinition(descriptor.TargetType));

            return new CodeVariableDeclarationStatement(descriptor.TargetType, "target",
                new CodeSnippetExpression(createSnippet));
        }
        private MemberMappingDescriptor CreateMemberDescriptor(ClassMappingDescriptor classDesc, XmlNode node)
        {
            MemberMappingDescriptor desc = new MemberMappingDescriptor();
            desc.Member = GetAttributeValue(node.Attributes["name"]);
            desc.Expression = GetAttributeValue(node.Attributes["expression"], "$" + desc.Member);
            desc.NullValue = GetAttributeValue(node.Attributes["nullValue"]);
            desc.Format = GetAttributeValue(node.Attributes["format"]);
            desc.OwnerType = classDesc.TargetType;

            MemberInfo member = FindMember(classDesc.TargetType, desc.Member);
            if(member == null)
            {
                string msg = string.Format(Errors.MemberNotFound, desc.Member, TypeHelper.GetTypeDefinition(classDesc.TargetType));
                throw new OtisException(msg);
            }

            desc.Type = GetTargetType(member);

            if(desc.HasFormatting && desc.Type != typeof(string))
            {
                string msg = string.Format(Errors.FormattingAppliedOnNonStringMember,
                                           TypeHelper.GetTypeDefinition(classDesc.TargetType),
                                           desc.Member,
                                     TypeHelper.GetTypeDefinition(desc.Type));
                throw new OtisException(msg);
            }

            desc.IsArray = desc.Type.IsArray;
            desc.IsList = (typeof (ICollection).IsAssignableFrom(desc.Type)) || desc.Type.GetInterface(typeof(ICollection<>).FullName) != null;

            XmlNodeList projections = node.SelectNodes("default:map", m_nsMgr);
            desc.Projections = BuildProjections(desc, projections);
            return desc;
        }
 private static CodeExpression CreatePreparerCall(ClassMappingDescriptor descriptor)
 {
     return CreateSupportFunctionCall(descriptor.MappingPreparer, descriptor.IsPreparerStatic);
 }
Ejemplo n.º 59
0
 private void AddReferencedAssemblies(ClassMappingDescriptor descriptor)
 {
     AddAssembliesForType(descriptor.TargetType);
     AddAssembliesForType(descriptor.SourceType);
 }