public static DataSourceSet FindFor(IChildMemberMappingData childMappingData)
        {
            var findContext      = new DataSourceFindContext(childMappingData);
            var validDataSources = EnumerateDataSources(findContext).ToArray();

            return(new DataSourceSet(findContext.MapperData, validDataSources));
        }
        private static IEnumerable <IDataSource> EnumerateDataSources(DataSourceFindContext context)
        {
            foreach (var finder in EnumerateFinders())
            {
                foreach (var dataSource in finder.FindFor(context))
                {
                    if (!dataSource.IsValid)
                    {
                        continue;
                    }

                    yield return(dataSource);

                    if (!dataSource.IsConditional)
                    {
                        yield break;
                    }
                }

                if (context.StopFind)
                {
                    yield break;
                }
            }
        }
Exemple #3
0
        public IEnumerable <IDataSource> FindFor(DataSourceFindContext context)
        {
            if (context.MapperData.TargetMember.IsCustom)
            {
                yield break;
            }

            var matchingSourceMemberDataSource = GetSourceMemberDataSourceOrNull(context);
            var configuredDataSources          = context.ConfiguredDataSources;
            var targetMember = context.MapperData.TargetMember;

            if ((matchingSourceMemberDataSource == null) ||
                configuredDataSources.Any(cds => cds.IsSameAs(matchingSourceMemberDataSource)))
            {
                if (context.DataSourceIndex == 0)
                {
                    if (UseFallbackComplexTypeMappingDataSource(targetMember))
                    {
                        yield return(new ComplexTypeMappingDataSource(context.DataSourceIndex, context.ChildMappingData));
                    }
                }
                else if (configuredDataSources.Any() && configuredDataSources.Last().IsConditional)
                {
                    yield return(context.GetFallbackDataSource());
                }

                yield break;
            }

            if (matchingSourceMemberDataSource.SourceMember.IsSimple &&
                context.MapperData.MapperContext.UserConfigurations.HasConfiguredRootDataSources)
            {
                var updatedMapperData = new ChildMemberMapperData(
                    matchingSourceMemberDataSource.SourceMember,
                    targetMember,
                    context.MapperData.Parent);

                var configuredRootDataSources = context
                                                .MapperData
                                                .MapperContext
                                                .UserConfigurations
                                                .GetDataSources(updatedMapperData);

                foreach (var configuredRootDataSource in configuredRootDataSources)
                {
                    yield return(configuredRootDataSource);
                }
            }

            yield return(matchingSourceMemberDataSource);

            if (!targetMember.IsReadOnly &&
                matchingSourceMemberDataSource.IsConditional &&
                (matchingSourceMemberDataSource.IsValid || configuredDataSources.Any()))
            {
                yield return(context.GetFallbackDataSource());
            }
        }
Exemple #4
0
        public IEnumerable <IDataSource> FindFor(DataSourceFindContext context)
        {
            if (TryGetMetaMemberNameParts(context, out var memberNameParts) &&
                TryGetMetaMember(memberNameParts, context, out var metaMember))
            {
                var dataSource = metaMember.GetDataSource();

                yield return(context.GetFinalDataSource(dataSource));

                if (dataSource.IsConditional)
                {
                    yield return(context.GetFallbackDataSource());
                }
            }
        }
Exemple #5
0
        private static IDataSource GetSourceMemberDataSourceOrNull(DataSourceFindContext context)
        {
            var bestMatchingSourceMember = SourceMemberMatcher.GetMatchFor(
                context.ChildMappingData,
                out var contextMappingData);

            if (bestMatchingSourceMember == null)
            {
                return(null);
            }

            var sourceMemberDataSource = SourceMemberDataSource
                                         .For(bestMatchingSourceMember, contextMappingData.MapperData);

            return(context.GetFinalDataSource(sourceMemberDataSource, contextMappingData));
        }
Exemple #6
0
        private static bool UseMaptimeDataSources(
            DataSourceFindContext context,
            out IEnumerable <IDataSource> maptimeDataSources)
        {
            var applicableFactory = _mapTimeDataSourceFactories
                                    .FirstOrDefault(factory => factory.IsFor(context.MapperData));

            if (applicableFactory == null)
            {
                maptimeDataSources = null;
                return(false);
            }

            maptimeDataSources = applicableFactory.Create(context.ChildMappingData);
            return(true);
        }
Exemple #7
0
        public IEnumerable <IDataSource> FindFor(DataSourceFindContext context)
        {
            if (context.ConfiguredDataSources.None())
            {
                yield break;
            }

            foreach (var configuredDataSource in context.ConfiguredDataSources)
            {
                yield return(context.GetFinalDataSource(configuredDataSource));

                if (!configuredDataSource.IsConditional)
                {
                    yield break;
                }

                ++context.DataSourceIndex;
            }
        }
Exemple #8
0
        public IEnumerable <IDataSource> FindFor(DataSourceFindContext context)
        {
            if (!UseMaptimeDataSources(context, out var maptimeDataSources))
            {
                yield break;
            }

            context.StopFind = true;

            foreach (var maptimeDataSource in maptimeDataSources)
            {
                yield return(context.GetFinalDataSource(maptimeDataSource));

                if (maptimeDataSource.IsConditional)
                {
                    continue;
                }

                yield break;
            }

            yield return(context.GetFallbackDataSource());
        }
Exemple #9
0
        private static bool TryGetMetaMemberNameParts(
            DataSourceFindContext context,
            out IList <string> memberNameParts)
        {
            memberNameParts = default(IList <string>);

            var targetMemberName         = context.MapperData.TargetMember.Name;
            var previousNamePartEndIndex = targetMemberName.Length;
            var currentMemberName        = string.Empty;
            var noMetaMemberAdded        = true;

            for (var i = previousNamePartEndIndex - 1; i >= 0; --i)
            {
                if (!char.IsUpper(targetMemberName[i]))
                {
                    continue;
                }

                if (memberNameParts == null)
                {
                    if (i == 0)
                    {
                        return(false);
                    }

                    memberNameParts = new List <string>();
                }

                var memberNamePart = targetMemberName.Substring(i, previousNamePartEndIndex - i);

                switch (memberNamePart)
                {
                case HasMetaMemberPart.Name:
                case FirstMetaMemberPart.Name:
                case LastMetaMemberPart.Name:
                case CountMetaMemberPart.Name:
                    if (currentMemberName.Length != 0)
                    {
                        memberNameParts.Add(GetFinalMemberName(currentMemberName, memberNamePart));
                        currentMemberName = string.Empty;
                    }

                    memberNameParts.Add(memberNamePart);
                    noMetaMemberAdded = false;
                    break;

                default:
                    currentMemberName = memberNamePart + currentMemberName;

                    if (currentMemberName.StartsWith(NumberOfMetaMemberPart.Name, Ordinal))
                    {
                        currentMemberName = currentMemberName.Substring(NumberOfMetaMemberPart.Name.Length);
                        memberNameParts.Add(currentMemberName);
                        memberNameParts.Add(NumberOfMetaMemberPart.Name);
                        currentMemberName = string.Empty;
                        noMetaMemberAdded = false;
                    }
                    break;
                }

                previousNamePartEndIndex = i;
            }

            if (noMetaMemberAdded)
            {
                return(false);
            }

            if (currentMemberName.Length == 0)
            {
                return(memberNameParts.Any());
            }

            memberNameParts.Add(GetFinalMemberName(
                                    currentMemberName,
                                    memberNameParts[memberNameParts.Count - 1]));

            return(memberNameParts.Any());
        }
Exemple #10
0
        private static bool TryGetMetaMember(
            IList <string> memberNameParts,
            DataSourceFindContext context,
            out MetaMemberPartBase metaMember)
        {
            var currentMappingData  = default(IObjectMappingData);
            var currentSourceMember = default(IQualifiedMember);
            var currentTargetMember = default(QualifiedMember);
            var currentMemberPart   = metaMember = default(MetaMemberPartBase);

            Func <IQualifiedMember, QualifiedMember, IObjectMappingData, DataSourceFindContext, IObjectMappingData> currentMappingDataFactory =
                (sm, tm, md, c) => c.ChildMappingData.Parent;

            for (var i = memberNameParts.Count - 1; i >= 0; --i)
            {
                var memberNamePart = memberNameParts[i];

                switch (memberNamePart)
                {
                case HasMetaMemberPart.Name:
                    if (HasMetaMemberPart.TryCreateFor(context.MapperData, ref currentMemberPart))
                    {
                        break;
                    }

                    return(false);

                case FirstMetaMemberPart.Name:
                    currentMemberPart = new FirstMetaMemberPart(context.MapperData);
                    break;

                case LastMetaMemberPart.Name:
                    currentMemberPart = new LastMetaMemberPart(context.MapperData);
                    break;

                case CountMetaMemberPart.Name:
                    if (CountMetaMemberPart.TryCreateFor(context.MapperData, ref currentMemberPart))
                    {
                        break;
                    }

                    return(false);

                case NumberOfMetaMemberPart.Name:
                    if (NumberOfMetaMemberPart.TryCreateFor(context.MapperData, ref currentMemberPart))
                    {
                        break;
                    }

                    return(false);

                default:
                    currentMappingData = currentMappingDataFactory.Invoke(
                        currentSourceMember,
                        currentTargetMember,
                        currentMappingData,
                        context);

                    var currentMapperData = currentMappingData.MapperData;

                    var matchingTargetMember = GlobalContext.Instance
                                               .MemberCache
                                               .GetTargetMembers(currentMapperData.TargetType)
                                               .FirstOrDefault(m => m.Name == memberNamePart);

                    if (matchingTargetMember == null)
                    {
                        matchingTargetMember = GlobalContext.Instance
                                               .MemberCache
                                               .GetSourceMembers(currentMapperData.SourceType)
                                               .FirstOrDefault(m => m.Name == memberNamePart);

                        if (matchingTargetMember == null)
                        {
                            return(false);
                        }
                    }

                    currentTargetMember = currentMapperData.TargetMember.Append(matchingTargetMember);

                    var childMemberMapperData = new ChildMemberMapperData(currentTargetMember, currentMapperData);

                    var memberMappingData = currentMappingData.GetChildMappingData(childMemberMapperData);

                    currentSourceMember = SourceMemberMatcher.GetMatchFor(
                        memberMappingData,
                        out _,
                        searchParentContexts: false);

                    if (currentSourceMember == null)
                    {
                        return(false);
                    }

                    currentMemberPart = new SourceMemberMetaMemberPart(
                        currentSourceMember,
                        currentMapperData,
                        isRootMemberPart: currentMemberPart == null);

                    currentMappingDataFactory = (sm, tm, md, c) =>
                    {
                        var mappingData = ObjectMappingDataFactory.ForChild(sm, tm, 0, md);

                        return(sm.IsEnumerable
                                ? ObjectMappingDataFactory.ForElement(mappingData)
                                : ObjectMappingDataFactory.ForChild(sm, tm, 0, md));
                    };

                    break;
                }

                if (metaMember == null)
                {
                    metaMember = currentMemberPart;
                    continue;
                }

                if (!metaMember.TrySetNextPart(currentMemberPart))
                {
                    return(false);
                }
            }

            return(true);
        }