Example #1
0
        public void Mapping_Fails_For_Duplicate_Projection()
        {
            MemberMappingDescriptor desc = new MemberMappingDescriptor();

            desc.OwnerType = typeof(AttributedUserDTO);
            desc.Type      = typeof(string);
            desc.Member    = "FullName";
            desc.IsArray   = false;
            desc.IsList    = false;
            try
            {
                List <ProjectionItem> items = new List <ProjectionItem>();
                items.Add(new ProjectionItem("source", "target_1"));
                items.Add(new ProjectionItem("source", "target_2"));
                ProjectionBuilder.Build(desc, items);
            }
            catch (OtisException e)
            {
                if (e.Message.Contains("Invalid projection 'source => target_2'. 'source' is already mapped to '\"target_1\"'"))
                {
                    return;                     // success
                }
            }
            Assert.Fail("Tested method didn't throw an exception!");
        }
        internal static ProjectionInfo BuildProjections(MemberMappingDescriptor desc, XmlNodeList projections)
        {
            if (projections.Count < 1)
                return new ProjectionInfo();

            List<ProjectionItem> projectionItems = new List<ProjectionItem>(3);

            foreach (XmlNode node in projections)
            {
                // no check for existance, that is done with schema
                string to = GetAttributeValue(node.Attributes["to"]);
                if (to == string.Empty)
                {
                    string message = ErrorBuilder.EmptyToAttributeInXmlError(desc, node.InnerXml);
                    throw new OtisException(message);
                }

                // if 'from' is missing, it is assumed to be same as 'to'
                string from = GetAttributeValue(node.Attributes["from"], to);

                projectionItems.Add(
                    new ProjectionItem(
                        ExpressionParser.NormalizeExpression(from),
                        ExpressionParser.NormalizeExpression(to)));
            }

            return ProjectionBuilder.Build(desc,projectionItems);
        }
Example #3
0
 public void Setup()
 {
     m_desc           = new MemberMappingDescriptor();
     m_desc.Member    = "Gender";
     m_desc.OwnerType = typeof(XmlUserDTO);
     m_desc.Type      = typeof(Gender);
 }
Example #4
0
        private static CodeStatement[] CreateProjectionMapping(MemberMappingDescriptor member)
        {
            StringBuilder snippet = new StringBuilder();

            snippet.AppendLine(string.Format("switch({0}) {{", UnwindExpression(member.Expression)));

            foreach (ProjectionItem item in member.Projections.Items)
            {
                string resultExpression;
                if (member.HasFormatting)
                {
                    resultExpression = string.Format("string.Format(\"{0}\", {1})", member.Format, item.To);
                }
                else
                {
                    resultExpression = item.To;
                }

                snippet.AppendLine(string.Format("	case {0}: target.{1} = {2}; break;", item.From, member.Member, resultExpression));
            }

            snippet.AppendLine("}");

            CodeStatementCollection coll = new CodeStatementCollection();

            coll.Add(new CodeSnippetExpression(snippet.ToString()));
            return(new CodeStatement[1] {
                coll[0]
            });
        }
Example #5
0
        private static CodeStatement[] CreateAssemblerMapping(MemberMappingDescriptor member)
        {
            string expression = UnwindExpression(member.Expression);

            if (member.Type.IsPrimitive)
            {
                return(new CodeStatement[]
                {
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("target." + member.Member),
                        new CodeSnippetExpression(expression))
                });
            }

            CodeMethodInvokeExpression transform = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),
                                                                                  "Transform",
                                                                                  new CodeVariableReferenceExpression("target." + member.Member),
                                                                                  new CodeArgumentReferenceExpression(expression)
                                                                                  );

            if (member.HasNullValue)
            {
                transform.Parameters.Add(new CodeSnippetExpression(member.NullValue.ToString()));
            }

            CodeStatement st = new CodeAssignStatement(
                new CodeVariableReferenceExpression("target." + member.Member),
                transform);

            return(new CodeStatement[] { st });
        }
Example #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!");
        }
Example #7
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);
        }
        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 static CodeStatement[] CreateAssemblerMapping(MemberMappingDescriptor member)
        {
            string expression = UnwindExpression(member.Expression);

            if(member.Type.IsPrimitive)
            {
                return new CodeStatement[]
                    {
                        new CodeAssignStatement(
                            new CodeVariableReferenceExpression("target." + member.Member),
                            new CodeSnippetExpression(expression))
                    };
            }

            CodeMethodInvokeExpression transform = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),
                                                       "Transform",
                                                       new CodeVariableReferenceExpression("target." + member.Member),
                                                       new CodeArgumentReferenceExpression(expression)
                );
            if(member.HasNullValue)
            {
                transform.Parameters.Add(new CodeSnippetExpression(member.NullValue.ToString()));
            }

            CodeStatement st = new CodeAssignStatement(
                new CodeVariableReferenceExpression("target." + member.Member),
                transform);
            return new CodeStatement[] { st };
        }
        internal static ProjectionInfo BuildProjections(MemberMappingDescriptor desc, XmlNodeList projections)
        {
            if (projections.Count < 1)
            {
                return(new ProjectionInfo());
            }

            List <ProjectionItem> projectionItems = new List <ProjectionItem>(3);

            foreach (XmlNode node in projections)
            {
                // no check for existance, that is done with schema
                string to = GetAttributeValue(node.Attributes["to"]);
                if (to == string.Empty)
                {
                    string message = ErrorBuilder.EmptyToAttributeInXmlError(desc, node.InnerXml);
                    throw new OtisException(message);
                }

                // if 'from' is missing, it is assumed to be same as 'to'
                string from = GetAttributeValue(node.Attributes["from"], to);

                projectionItems.Add(
                    new ProjectionItem(
                        ExpressionParser.NormalizeExpression(from),
                        ExpressionParser.NormalizeExpression(to)));
            }

            return(ProjectionBuilder.Build(desc, projectionItems));
        }
        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);
        }
        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\""]);
        }
        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);
        }
        private Type GetSourceItemType(IList <AggregateExpressionPathItem> items, MemberMappingDescriptor member)
        {
            if (items == null || items.Count < 1)
            {
                string msg = ErrorBuilder.InvalidAggregatePathError(member);
                throw new OtisException(msg);
            }

            return(items[items.Count - 1].Type);
        }
Example #15
0
        private static string GetNullablePartsCheckExpression(MemberMappingDescriptor member)
        {
            StringBuilder sb = new StringBuilder(20);

            foreach (string nullablePart in member.NullableParts)
            {
                sb.Append(nullablePart.Replace("$", "source."));
                sb.Append(" == null || ");
            }
            return(sb.ToString(0, sb.Length - 4));
        }
        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);
        }
 internal static ProjectionInfo GetProjections(MemberMappingDescriptor desc, string projection)
 {
     string normalizedProjection = ExpressionParser.NormalizeExpression(projection);
     normalizedProjection = normalizedProjection.Trim(';', ' ');
     if (!ExpressionParser.IsProjectionExpression(normalizedProjection))
     {
         // use original string in message to make it easier to find the attribute
         string message = ErrorBuilder.InvalidProjectionStringError(desc, projection);
         throw new OtisException(message);
     }
     IList<ProjectionItem> projectionItems = SplitProjectionItems(normalizedProjection);
     return ProjectionBuilder.Build(desc, projectionItems);
 }
Example #18
0
        public override IEnumerable <CodeStatement> GetInitializationStatements(AggregateFunctionContext context)
        {
            MemberMappingDescriptor member = context.Member;
            Type resultType;
            Type instanceType;
            bool isSimpleMapping = false;

            if (member.IsArray || member.IsList)
            {
                instanceType = member.IsArray ?
                               member.AggregateMappingDescription.TargetType.GetElementType() :
                               member.AggregateMappingDescription.TargetType.GetGenericArguments()[0];
                resultType = typeof(List <>).MakeGenericType(instanceType);

                if (!instanceType.IsPrimitive && instanceType != typeof(string))
                {
                    m_expression = string.Format("{{0}}.Add({0}.AssembleFrom({{1}}));", GetAssemblerName(context));
                }
                else
                {
                    m_expression    = "{0}.Add({1});";
                    isSimpleMapping = true;
                }
            }
            else
            {
                string msg = ErrorBuilder.CantAggregateOverNoncollectionError(member, "collect");
                throw new OtisException(msg);                 //todo: test
            }

            m_isArray = member.IsArray;
            List <CodeStatement> statements = new List <CodeStatement>();

            CodeExpression[] parameters = new CodeExpression[0];
            CodeStatement    st         = new CodeVariableDeclarationStatement(resultType,
                                                                               context.FunctionObjectName,
                                                                               new CodeObjectCreateExpression(resultType, parameters));

            statements.Add(st);

            if (!isSimpleMapping)
            {
                st = new CodeVariableDeclarationStatement(
                    string.Format("IAssembler<{0}, {1}>", TypeHelper.GetTypeDefinition(instanceType), TypeHelper.GetTypeDefinition(context.SourceItemType)),
                    GetAssemblerName(context),
                    new CodeSnippetExpression("this"));
                statements.Add(st);
            }

            return(statements);
        }
Example #19
0
        internal static ProjectionInfo GetProjections(MemberMappingDescriptor desc, string projection)
        {
            string normalizedProjection = ExpressionParser.NormalizeExpression(projection);

            normalizedProjection = normalizedProjection.Trim(';', ' ');
            if (!ExpressionParser.IsProjectionExpression(normalizedProjection))
            {
                // use original string in message to make it easier to find the attribute
                string message = ErrorBuilder.InvalidProjectionStringError(desc, projection);
                throw new OtisException(message);
            }
            IList <ProjectionItem> projectionItems = SplitProjectionItems(normalizedProjection);

            return(ProjectionBuilder.Build(desc, projectionItems));
        }
        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];
        }
Example #21
0
        private static CodeStatement[] CreateListMappingStatements(MemberMappingDescriptor member)
        {
            string expression = member.Expression.Replace("$", "source.");

            CodeStatement[] statements = new CodeStatement[1];

            CodeMethodInvokeExpression transform = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),
                                                                                  "TransformToList",
                                                                                  new CodeVariableReferenceExpression("target." + member.Member),
                                                                                  new CodeArgumentReferenceExpression(expression)
                                                                                  );

            statements[0] = new CodeExpressionStatement(transform);
            return(statements);
        }
        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];
        }
        private static CodeStatement[] CreateArrayMappingStatements(MemberMappingDescriptor member)
        {
            string expression = member.Expression.Replace("$", "source.");

            CodeStatement[] statements = new CodeStatement[1];

            statements[0] = new CodeAssignStatement(
                                new CodeVariableReferenceExpression("target." + member.Member),
                                new CodeMethodInvokeExpression(
                                    new CodeThisReferenceExpression(),
                                    "TransformToArray",
                                    new CodeVariableReferenceExpression("target." + member.Member),
                                    new CodeArgumentReferenceExpression(expression)
                                ));
            return statements;
        }
        private static string ExpandProjectionTarget(MemberMappingDescriptor desc, ProjectionItem projectionItem)
        {
            if (desc.Type == typeof(string))
                return ExpandString(projectionItem.To);

            if (desc.Type.IsEnum)
            {
                string expanded = ExpandEnum(desc.Type, projectionItem.To);
                if(expanded == "") // no match
                {
                    string error = ErrorBuilder.EnumValueDoesntExistError(desc, projectionItem);
                    throw new OtisException(error);
                }
                return expanded;
            }

            return projectionItem.To;
        }
Example #25
0
        private static string AddPathItems(MemberMappingDescriptor member, List <AggregateExpressionPathItem> pathItems, string pathPart, string targetName, ref Type targetType)
        {
            targetType = GetTargetType(targetType, pathPart.Replace("$", ""));
            string objectName   = GetCollectionItemName(pathPart);
            bool   isCollection = IsCollection(targetType);

            if (isCollection)
            {
                pathItems.Add(new AggregateExpressionPathItem(ToInstanceType(member, targetType), objectName, targetName, pathPart, isCollection));
            }
            else
            {
                pathItems.Add(new AggregateExpressionPathItem(ToInstanceType(member, targetType), objectName, targetName, pathPart, isCollection));
            }
            targetType = ToInstanceType(member, targetType);
            targetName = objectName;
            return(targetName);
        }
        public void Nullable_parts_extraction()
        {
            MemberMappingDescriptor member = new MemberMappingDescriptor();

            member.Expression = "$FirstName";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);

            member.Expression = "$FirstName.ToUpper()";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);

            member.Expression = "$FirstName.ToUpper(true)";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);

            member.Expression = "$ToUpper()";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$ToUpper()", member.NullableParts[0]);

            member.Expression = "$ToUpper().ToLower()";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$ToUpper()", member.NullableParts[0]);

            member.Expression = "$ToUpper(true)";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$ToUpper(true)", member.NullableParts[0]);

            member.Expression = "$FirstName + $LastName";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(2, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);
            Assert.AreEqual("$LastName", member.NullableParts[1]);

            member.Expression = "tmp.GetSomeValue";
            Assert.IsFalse(member.HasNullableParts);
            Assert.AreEqual(0, member.NullableParts.Count);
        }
        public void Nullable_parts_extraction()
        {
            MemberMappingDescriptor member = new MemberMappingDescriptor();

            member.Expression = "$FirstName";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);

            member.Expression = "$FirstName.ToUpper()";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);

            member.Expression = "$FirstName.ToUpper(true)";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);

            member.Expression = "$ToUpper()";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$ToUpper()", member.NullableParts[0]);

            member.Expression = "$ToUpper().ToLower()";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$ToUpper()", member.NullableParts[0]);

            member.Expression = "$ToUpper(true)";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(1, member.NullableParts.Count);
            Assert.AreEqual("$ToUpper(true)", member.NullableParts[0]);

            member.Expression = "$FirstName + $LastName";
            Assert.IsTrue(member.HasNullableParts);
            Assert.AreEqual(2, member.NullableParts.Count);
            Assert.AreEqual("$FirstName", member.NullableParts[0]);
            Assert.AreEqual("$LastName", member.NullableParts[1]);

            member.Expression = "tmp.GetSomeValue";
            Assert.IsFalse(member.HasNullableParts);
            Assert.AreEqual(0, member.NullableParts.Count);
        }
Example #28
0
        public static ProjectionInfo Build(MemberMappingDescriptor desc, IList <ProjectionItem> projectionItems)
        {
            ProjectionInfo projectionInfo = new ProjectionInfo();

            foreach (ProjectionItem projectionItem in projectionItems)
            {
                string from = projectionItem.From;
                if (projectionInfo.ContainsKey(from))
                {
                    string error = ErrorBuilder.DuplicateProjectionError(desc, projectionItem, projectionInfo[from]);
                    throw new OtisException(error);
                }

                string expandedTo = ExpandProjectionTarget(desc, projectionItem);
                projectionInfo[from] = expandedTo;
            }

            return(projectionInfo);
        }
        public static ProjectionInfo Build(MemberMappingDescriptor desc, IList<ProjectionItem> projectionItems)
        {
            ProjectionInfo projectionInfo = new ProjectionInfo();

            foreach (ProjectionItem projectionItem in projectionItems)
            {
                string from = projectionItem.From;
                if(projectionInfo.ContainsKey(from))
                {
                    string error = ErrorBuilder.DuplicateProjectionError(desc, projectionItem, projectionInfo[from]);
                    throw new OtisException(error);
                }

                string expandedTo = ExpandProjectionTarget(desc, projectionItem);
                projectionInfo[from] = expandedTo;
            }

            return projectionInfo;
        }
Example #30
0
        private static Type ToInstanceType(MemberMappingDescriptor member, Type type)
        {
            if (type.IsArray)
            {
                return(type.GetElementType());
            }
            if (typeof(System.Collections.ICollection).IsAssignableFrom(type))
            {
                string msg = ErrorBuilder.CantAggregateOverUntypedCollections(member);
                throw new OtisException(msg);
            }

            if (type.GetInterface(typeof(ICollection <>).FullName) != null)           // generic collection
            {
                return(type.GetGenericArguments()[0]);
            }

            // simple type
            return(type);
        }
Example #31
0
        private static string ExpandProjectionTarget(MemberMappingDescriptor desc, ProjectionItem projectionItem)
        {
            if (desc.Type == typeof(string))
            {
                return(ExpandString(projectionItem.To));
            }

            if (desc.Type.IsEnum)
            {
                string expanded = ExpandEnum(desc.Type, projectionItem.To);
                if (expanded == "")                // no match
                {
                    string error = ErrorBuilder.EnumValueDoesntExistError(desc, projectionItem);
                    throw new OtisException(error);
                }
                return(expanded);
            }

            return(projectionItem.To);
        }
 public void Mapping_Fails_For_Duplicate_Projection()
 {
     MemberMappingDescriptor desc = new MemberMappingDescriptor();
     desc.OwnerType = typeof(AttributedUserDTO);
     desc.Type = typeof(string);
     desc.Member = "FullName";
     desc.IsArray = false;
     desc.IsList = false;
     try
     {
         List<ProjectionItem> items = new List<ProjectionItem>();
         items.Add(new ProjectionItem("source", "target_1"));
         items.Add(new ProjectionItem("source", "target_2"));
         ProjectionBuilder.Build(desc, items);
     }
     catch (OtisException e)
     {
         if (e.Message.Contains("Invalid projection 'source => target_2'. 'source' is already mapped to '\"target_1\"'"))
             return; // success
     }
     Assert.Fail("Tested method didn't throw an exception!");
 }
Example #33
0
        private static CodeStatement[] CreateSimpleMapping(MemberMappingDescriptor member)
        {
            string expression = UnwindExpression(member.Expression);

            if (member.Type == typeof(string))
            {
                if (member.HasFormatting)
                {
                    expression = string.Format("string.Format(\"{0}\", {1})", member.Format, expression);
                }
                else
                {
                    expression = string.Format("({0}).ToString()", expression);
                }
            }

            CodeSnippetExpression exp = new CodeSnippetExpression(expression);
            CodeStatement         st  = new CodeAssignStatement(
                new CodeVariableReferenceExpression("target." + member.Member),
                exp);

            return(new CodeStatement[] { st });
        }
        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);
        }
Example #35
0
        public void Projection_Mapping_Fails_For_Nonexisting_Enum_Value()
        {
            MemberMappingDescriptor desc = new MemberMappingDescriptor();

            desc.OwnerType = typeof(AttributedUserDTO);
            desc.Type      = typeof(Gender);
            desc.Member    = "Gender";
            desc.IsArray   = false;
            desc.IsList    = false;
            try
            {
                List <ProjectionItem> items = new List <ProjectionItem>();
                items.Add(new ProjectionItem("X", "Undefined"));
                ProjectionBuilder.Build(desc, items);
            }
            catch (OtisException e)
            {
                if (e.Message.Contains("Invalid projection 'X => Undefined'. Value 'Undefined' is not defined in 'Otis.Tests.Gender' enumeration"))
                {
                    return;                     // success
                }
            }
            Assert.Fail("Tested method didn't throw an exception!");
        }
        private Type GetSourceItemType(IList<AggregateExpressionPathItem> items, MemberMappingDescriptor member)
        {
            if (items == null || items.Count < 1)
            {
                string msg = ErrorBuilder.InvalidAggregatePathError(member);
                throw new OtisException(msg);
            }

            return items[items.Count - 1].Type;
        }
        private static CodeStatement[] CreateSimpleMapping(MemberMappingDescriptor member)
        {
            string expression = UnwindExpression(member.Expression);
            if(member.Type == typeof(string))
            {
                if (member.HasFormatting)
                    expression = string.Format("string.Format(\"{0}\", {1})", member.Format, expression);
                else
                    expression = string.Format("({0}).ToString()", expression);
            }

            CodeSnippetExpression exp = new CodeSnippetExpression(expression);
            CodeStatement st = new CodeAssignStatement(
                new CodeVariableReferenceExpression("target." + member.Member),
                exp);
            return new CodeStatement[] { st };
        }
        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 IAggregateFunctionCodeGenerator GetGeneratorImpl(Type implementationType, MemberMappingDescriptor member)
        {
            Type[] interfaces = implementationType.GetInterfaces();
            foreach (Type itf in interfaces) // first check if it has its own implementation of IAggregateFunctionCodeGenerator
            {
                if (itf == typeof (IAggregateFunctionCodeGenerator))
                    return Activator.CreateInstance(implementationType, true) as IAggregateFunctionCodeGenerator;
            }

            foreach (Type itf in interfaces) // now check if it only implement IAggregateFunction
            {
                if (itf.IsGenericType && itf.GetGenericTypeDefinition() == typeof(IAggregateFunction<>))
                    return new DefaultAggregateFunctionCodeGenerator();
            }

            string msg = ErrorBuilder.InvalidAggregatePathError(member);
            throw new OtisException(msg); // test
        }
        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 string GetNullablePartsCheckExpression(MemberMappingDescriptor member)
 {
     StringBuilder sb = new StringBuilder(20);
     foreach (string nullablePart in member.NullableParts)
     {
         sb.Append(nullablePart.Replace("$", "source."));
         sb.Append(" == null || ");
     }
     return sb.ToString(0, sb.Length - 4);
 }
Example #42
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));
        }
        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 IAggregateFunctionCodeGenerator GetGeneratorImpl(Type implementationType, MemberMappingDescriptor member)
        {
            Type[] interfaces = implementationType.GetInterfaces();
            foreach (Type itf in interfaces)             // first check if it has its own implementation of IAggregateFunctionCodeGenerator
            {
                if (itf == typeof(IAggregateFunctionCodeGenerator))
                {
                    return(Activator.CreateInstance(implementationType, true) as IAggregateFunctionCodeGenerator);
                }
            }

            foreach (Type itf in interfaces)             // now check if it only implement IAggregateFunction
            {
                if (itf.IsGenericType && itf.GetGenericTypeDefinition() == typeof(IAggregateFunction <>))
                {
                    return(new DefaultAggregateFunctionCodeGenerator());
                }
            }

            string msg = ErrorBuilder.InvalidAggregatePathError(member);

            throw new OtisException(msg);             // test
        }
 public void Projection_Mapping_Fails_For_Nonexisting_Enum_Value()
 {
     MemberMappingDescriptor desc = new MemberMappingDescriptor();
     desc.OwnerType = typeof(AttributedUserDTO);
     desc.Type = typeof(Gender);
     desc.Member = "Gender";
     desc.IsArray = false;
     desc.IsList = false;
     try
     {
         List<ProjectionItem> items = new List<ProjectionItem>();
         items.Add(new ProjectionItem("X", "Undefined"));
         ProjectionBuilder.Build(desc, items);
     }
     catch (OtisException e)
     {
         if (e.Message.Contains("Invalid projection 'X => Undefined'. Value 'Undefined' is not defined in 'Otis.Tests.Gender' enumeration"))
             return; // success
     }
     Assert.Fail("Tested method didn't throw an exception!");
 }
        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));
        }
 public void Setup()
 {
     m_desc = new MemberMappingDescriptor();
     m_desc.Member = "Gender";
     m_desc.OwnerType = typeof(XmlUserDTO);
     m_desc.Type = typeof(Gender);
 }
Example #48
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);
        }
Example #49
0
        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 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 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 CodeStatement[] CreateProjectionMapping(MemberMappingDescriptor member)
        {
            StringBuilder snippet = new StringBuilder();
            snippet.AppendLine(string.Format("switch({0}) {{", UnwindExpression(member.Expression)));

            foreach (ProjectionItem item in member.Projections.Items)
            {
                string resultExpression;
                if(member.HasFormatting)
                    resultExpression = string.Format("string.Format(\"{0}\", {1})", member.Format, item.To);
                else
                    resultExpression = item.To;

                snippet.AppendLine(string.Format("	case {0}: target.{1} = {2}; break;", item.From, member.Member, resultExpression));
            }

            snippet.AppendLine("}");

            CodeStatementCollection coll = new CodeStatementCollection();
            coll.Add(new CodeSnippetExpression(snippet.ToString()));
            return new CodeStatement[1] { coll[0] };
        }