예제 #1
0
        private static Link CreateResourceRelationshipLink(IHypermediaContext hypermediaContext,
                                                           IResourcePathContext resourcePathContext,
                                                           IResourceType resourceType,
                                                           object clrResource,
                                                           bool addRelationshipsPathSegment,
                                                           IRelationshipInfo relationship,
                                                           Meta apiRelationshipLinkMeta)
        {
            Contract.Requires(hypermediaContext != null);
            Contract.Requires(resourcePathContext != null);
            Contract.Requires(resourceType != null);
            Contract.Requires(clrResource != null);
            Contract.Requires(relationship != null);

            var clrResourceType         = resourceType.ClrType;
            var urlBuilderConfiguration = hypermediaContext.GetUrlBuilderConfiguration(clrResourceType);

            var apiId           = resourceType.GetApiId(clrResource);
            var apiResourcePath = resourcePathContext.GetResourceSelfPath(apiId);
            var apiRelationshipRelPathSegment = relationship.ApiRelPathSegment;
            var apiRelationshipLinkHRef       = UrlBuilder.Create(urlBuilderConfiguration)
                                                .Path(apiResourcePath)
                                                .Path(Keywords.Relationships, addRelationshipsPathSegment)
                                                .Path(apiRelationshipRelPathSegment)
                                                .Build();
            var apiRelationshipLink = new Link
            {
                HRef = apiRelationshipLinkHRef,
                Meta = apiRelationshipLinkMeta
            };

            return(apiRelationshipLink);
        }
예제 #2
0
        public bool TryGetRelationshipInfo(string rel, out IRelationshipInfo relationship)
        {
            Contract.Requires(String.IsNullOrWhiteSpace(rel) == false);

            relationship = this.Collection.SingleOrDefault(x => x.Rel == rel);
            return(relationship != null);
        }
        private static void AddPath(IResourceType resourceType, Type clrResourceType, string apiId, IRelationshipInfo nextRelationship, ref List <IHypermediaPath> resourceBasePath, ref ResourcePathMode resourcePathMode, ref IRelationshipInfo resourcePreviousRelationship)
        {
            Contract.Requires(resourceType != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(String.IsNullOrWhiteSpace(apiId) == false);
            Contract.Requires(nextRelationship != null);
            Contract.Requires(resourceBasePath != null);

            if (resourcePreviousRelationship == null)
            {
                var apiCollectionPathSegment = resourceType.HypermediaInfo.ApiCollectionPathSegment;
                var resourceHypermediaPath   = new ResourceHypermediaPath(clrResourceType, apiCollectionPathSegment, apiId);

                resourceBasePath.Add(resourceHypermediaPath);
                resourcePathMode             = ResourcePathMode.IncludeApiId;
                resourcePreviousRelationship = nextRelationship;
                return;
            }

            var previousRelationshipCardinality = resourcePreviousRelationship.ToCardinality;
            var apiRelationshipRelPathSegment   = resourcePreviousRelationship.ApiRelPathSegment;

            switch (previousRelationshipCardinality)
            {
            case RelationshipCardinality.ToOne:
            {
                var toOneResourceHypermediaPath = new ToOneResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment);

                resourceBasePath.Add(toOneResourceHypermediaPath);
                resourcePathMode = ResourcePathMode.IgnoreApiId;
            }
            break;

            case RelationshipCardinality.ToMany:
            {
                var toManyResourceHypermediaPath = new ToManyResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment, apiId);

                resourceBasePath.Add(toManyResourceHypermediaPath);
                resourcePathMode = ResourcePathMode.IncludeApiId;
            }
            break;

            default:
            {
                var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                             .FormatWith(typeof(RelationshipCardinality).Name, previousRelationshipCardinality);
                throw new InternalErrorException(detail);
            }
            }

            resourcePreviousRelationship = nextRelationship;
        }
예제 #4
0
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region Assert Methods
        public static void Equal(IRelationshipInfo expected, IRelationshipInfo actual)
        {
            if (expected == null)
            {
                Assert.Null(actual);
                return;
            }
            Assert.NotNull(actual);

            Assert.Equal(expected.Rel, actual.Rel);
            Assert.Equal(expected.ApiRelPathSegment, actual.ApiRelPathSegment);
            Assert.Equal(expected.ToCardinality, actual.ToCardinality);
            Assert.Equal(expected.ToClrType, actual.ToClrType);
            Assert.Equal(expected.ToCanonicalRelPathMode, actual.ToCanonicalRelPathMode);
        }
예제 #5
0
        public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo)
        {
            Member = member;

            MemberType = ReflectionHelper.GetMemberType(member);

            // Try to determine the RelationshipType
            if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect)
            {
                if (typeof(ICollection).IsAssignableFrom(MemberType))
                {
                    relationshipInfo.RelationType = RelationshipTypes.Many;
                }
                else
                {
                    relationshipInfo.RelationType = RelationshipTypes.One;
                }
            }

            // Try to determine the EntityType
            if (relationshipInfo.EntityType == null)
            {
                if (relationshipInfo.RelationType == RelationshipTypes.Many)
                {
                    if (MemberType.IsGenericType)
                    {
                        // Assume a Collection<T> or List<T> and return T
                        relationshipInfo.EntityType = MemberType.GetGenericArguments()[0];
                    }
                    else
                    {
                        throw new ArgumentException(string.Format(
                            "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.",
                            MemberType.Name));
                    }
                }
                else
                {
                    relationshipInfo.EntityType = MemberType;
                }
            }

            RelationshipInfo = relationshipInfo;



            Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name);
        }
예제 #6
0
        public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo)
        {
            Member = member;

            MemberType = ReflectionHelper.GetMemberType(member);

            // Try to determine the RelationshipType
            if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect)
            {
                if (typeof(ICollection).IsAssignableFrom(MemberType))
                {
                    relationshipInfo.RelationType = RelationshipTypes.Many;
                }
                else
                {
                    relationshipInfo.RelationType = RelationshipTypes.One;
                }
            }

            // Try to determine the EntityType
            if (relationshipInfo.EntityType == null)
            {
                if (relationshipInfo.RelationType == RelationshipTypes.Many)
                {
                    if (MemberType.IsGenericType)
                    {
                        // Assume a Collection<T> or List<T> and return T
                        relationshipInfo.EntityType = MemberType.GetGenericArguments()[0];
                    }
                    else
                    {
                        throw new ArgumentException(string.Format(
                                                        "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.",
                                                        MemberType.Name));
                    }
                }
                else
                {
                    relationshipInfo.EntityType = MemberType;
                }
            }

            RelationshipInfo = relationshipInfo;



            Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name);
        }
예제 #7
0
        private static Links CreateResourceRelationshipLinks(IHypermediaContext hypermediaContext,
                                                             IResourcePathContext resourcePathContext,
                                                             IResourceType resourceType,
                                                             object clrResource,
                                                             IRelationshipInfo relationship,
                                                             IRelationshipContext relationshipContext)
        {
            Contract.Requires(hypermediaContext != null);
            Contract.Requires(resourcePathContext != null);
            Contract.Requires(resourceType != null);
            Contract.Requires(clrResource != null);
            Contract.Requires(relationship != null);
            Contract.Requires(relationshipContext != null);

            var apiRelationshipHasLinks = relationshipContext.HasLinks();

            if (!apiRelationshipHasLinks)
            {
                return(null);
            }

            var links = relationshipContext.LinkContexts;
            var apiRelationshipRelToLinkDictionary = links
                                                     .Select(x =>
            {
                var rel        = x.Rel;
                var meta       = x.Meta;
                var isSelfLink = String.Compare(Keywords.Self, rel, StringComparison.Ordinal) == 0;
                var link       = CreateResourceRelationshipLink(hypermediaContext, resourcePathContext, resourceType, clrResource, isSelfLink, relationship, meta);
                return(new Tuple <string, Link>(rel, link));
            })
                                                     .ToDictionary(x => x.Item1, x => x.Item2);

            var apiRelationshipLinks = new Links(apiRelationshipRelToLinkDictionary);

            return(apiRelationshipLinks);
        }
예제 #8
0
        private static Relationship CreateResourceRelationship(Links apiRelationshipLinks, IResourceType resourceType, IRelationshipInfo relationship, IRelationshipContext relationshipContext)
        {
            Contract.Requires(resourceType != null);
            Contract.Requires(relationship != null);
            Contract.Requires(relationshipContext != null);

            var apiRelationshipToCardinality = relationship.ToCardinality;
            var apiRelationshipMeta          = relationshipContext.Meta;
            var apiRelationshipType          = relationshipContext.GetRelationshipType();

            switch (apiRelationshipType)
            {
            case RelationshipType.Relationship:
            {
                var apiRelationship = new Relationship
                {
                    Links = apiRelationshipLinks,
                    Meta  = apiRelationshipMeta
                };
                return(apiRelationship);
            }

            case RelationshipType.ToOneRelationship:
            {
                if (apiRelationshipToCardinality != RelationshipCardinality.ToOne)
                {
                    var apiRel = relationshipContext.Rel;
                    var fromClrResourceTypeName = resourceType.ClrType.Name;
                    var toClrResourceTypeName   = relationship.ToClrType.Name;
                    var detail = ServerErrorStrings
                                 .DocumentBuildExceptionDetailBuildResourceRelationshipCardinalityMismatch
                                 .FormatWith(apiRel, fromClrResourceTypeName, toClrResourceTypeName, RelationshipCardinality.ToOne, apiRelationshipToCardinality);
                    throw new DocumentBuildException(detail);
                }

                var apiToOneResourceLinkage = relationshipContext.GetToOneResourceLinkage();
                var apiRelationship         = new ToOneRelationship
                {
                    Links = apiRelationshipLinks,
                    Data  = apiToOneResourceLinkage,
                    Meta  = apiRelationshipMeta
                };
                return(apiRelationship);
            }

            case RelationshipType.ToManyRelationship:
            {
                if (apiRelationshipToCardinality != RelationshipCardinality.ToMany)
                {
                    var apiRel = relationshipContext.Rel;
                    var fromClrResourceTypeName = resourceType.ClrType.Name;
                    var toClrResourceTypeName   = relationship.ToClrType.Name;
                    var detail = ServerErrorStrings
                                 .DocumentBuildExceptionDetailBuildResourceRelationshipCardinalityMismatch
                                 .FormatWith(apiRel, fromClrResourceTypeName, toClrResourceTypeName, RelationshipCardinality.ToMany, apiRelationshipToCardinality);
                    throw new DocumentBuildException(detail);
                }

                var apiToManyResourceLinkage = relationshipContext.GetToManyResourceLinkage()
                                               .SafeToList();
                var apiRelationship = new ToManyRelationship
                {
                    Links = apiRelationshipLinks,
                    Data  = apiToManyResourceLinkage,
                    Meta  = apiRelationshipMeta
                };
                return(apiRelationship);
            }

            default:
            {
                var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                             .FormatWith(typeof(RelationshipType).Name, apiRelationshipType);
                throw new InternalErrorException(detail);
            }
            }
        }
예제 #9
0
        public void TestResourceTypeGetRelationshipInfo(string name, bool relationshipExists, IResourceType resourceType, string rel, IRelationshipInfo expected)
        {
            this.Output.WriteLine("Test Name: {0}", name);
            this.Output.WriteLine(String.Empty);

            // Arrange

            // Act
            if (!relationshipExists)
            {
                Assert.Throws <ServiceModelException>(() => resourceType.GetRelationshipInfo(rel));
                return;
            }
            var actual = resourceType.GetRelationshipInfo(rel);

            // Assert
            RelationshipInfoAssert.Equal(expected, actual);
        }
예제 #10
0
        public void TestResourceTypeTryGetRelationshipInfo(string name, bool attributeExists, IResourceType resourceType, string clrPropertyName, IRelationshipInfo expected)
        {
            this.Output.WriteLine("Test Name: {0}", name);
            this.Output.WriteLine(String.Empty);

            // Arrange

            // Act
            IRelationshipInfo actual;
            var actualExists = resourceType.TryGetRelationshipInfo(clrPropertyName, out actual);

            // Assert
            if (!attributeExists)
            {
                Assert.False(actualExists);
                Assert.Null(actual);
                return;
            }

            Assert.True(actualExists);
            Assert.NotNull(actual);
            RelationshipInfoAssert.Equal(expected, actual);
        }
예제 #11
0
        public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo)
        {
            Member = member;

            MemberType = ReflectionHelper.GetMemberType(member);

            // Try to determine the RelationshipType
            if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect)
            {
				if (member.MemberType == MemberTypes.Field && MemberType == typeof(object))
				{
					// Handles dynamic member fields that are lazy loaded
					var prop = DataHelper.FindPropertyForBackingField(member.ReflectedType, member);
					if (prop != null)
					{
						if (typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.ReturnType))
							relationshipInfo.RelationType = RelationshipTypes.Many;
						else
							relationshipInfo.RelationType = RelationshipTypes.One;
					}
				}
				else
				{
					if (typeof(System.Collections.IEnumerable).IsAssignableFrom(MemberType))
						relationshipInfo.RelationType = RelationshipTypes.Many;
					else
						relationshipInfo.RelationType = RelationshipTypes.One;
				}
            }

            // Try to determine the EntityType
            if (relationshipInfo.EntityType == null)
            {
                if (relationshipInfo.RelationType == RelationshipTypes.Many)
                {
                    if (MemberType.IsGenericType)
                    {
                        // Assume a Collection<T> or List<T> and return T
                        relationshipInfo.EntityType = MemberType.GetGenericArguments()[0];
                    }
					else if (MemberType == typeof(object))
					{
						relationshipInfo.EntityType = typeof(object);
					}
					else
					{
						throw new ArgumentException(string.Format(
							"The DataMapper could not determine the RelationshipAttribute EntityType for {0}.",
							MemberType.Name));
					}
                }
                else
                {
                    relationshipInfo.EntityType = MemberType;
                }
            }

            RelationshipInfo = relationshipInfo;



            Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name);
        }
예제 #12
0
        public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo)
        {
            Member = member;

            MemberType = ReflectionHelper.GetMemberType(member);

            // Try to determine the RelationshipType
            if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect)
            {
                if (member.MemberType == MemberTypes.Field && MemberType == typeof(object))
                {
                    // Handles dynamic member fields that are lazy loaded
                    var prop = DataHelper.FindPropertyForBackingField(member.ReflectedType, member);
                    if (prop != null)
                    {
                        if (typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.ReturnType))
                        {
                            relationshipInfo.RelationType = RelationshipTypes.Many;
                        }
                        else
                        {
                            relationshipInfo.RelationType = RelationshipTypes.One;
                        }
                    }
                }
                else
                {
                    if (typeof(System.Collections.IEnumerable).IsAssignableFrom(MemberType))
                    {
                        relationshipInfo.RelationType = RelationshipTypes.Many;
                    }
                    else
                    {
                        relationshipInfo.RelationType = RelationshipTypes.One;
                    }
                }
            }

            // Try to determine the EntityType
            if (relationshipInfo.EntityType == null)
            {
                if (relationshipInfo.RelationType == RelationshipTypes.Many)
                {
                    if (MemberType.IsGenericType)
                    {
                        // Assume a Collection<T> or List<T> and return T
                        relationshipInfo.EntityType = MemberType.GetGenericArguments()[0];
                    }
                    else if (MemberType == typeof(object))
                    {
                        relationshipInfo.EntityType = typeof(object);
                    }
                    else
                    {
                        throw new ArgumentException(string.Format(
                                                        "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.",
                                                        MemberType.Name));
                    }
                }
                else
                {
                    relationshipInfo.EntityType = MemberType;
                }
            }

            RelationshipInfo = relationshipInfo;



            Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name);
        }
        private static Tuple <ICollection <IHypermediaPath>, ResourcePathMode> CreateResourcePathParts(Type clrResourceType, IResourceType resourceType, ICollection <IHypermediaPath> resourceBasePath, IRelationshipInfo resourcePreviousRelationship)
        {
            Contract.Requires(clrResourceType != null);
            Contract.Requires(resourceType != null);

            ResourcePathMode resourcePathMode;

            if (resourcePreviousRelationship == null)
            {
                var apiCollectionPathSegment = resourceType.HypermediaInfo.ApiCollectionPathSegment;

                var hypermediaPath = default(IHypermediaPath);
                if (!resourceType.IsSingleton())
                {
                    hypermediaPath   = new ResourceCollectionHypermediaPath(clrResourceType, apiCollectionPathSegment);
                    resourcePathMode = ResourcePathMode.IncludeApiId;
                }
                else
                {
                    hypermediaPath   = new SingletonHypermediaPath(clrResourceType, apiCollectionPathSegment);
                    resourcePathMode = ResourcePathMode.IgnoreApiId;
                }

                resourceBasePath.Add(hypermediaPath);
            }
            else
            {
                var previousRelationshipCardinality = resourcePreviousRelationship.ToCardinality;
                var apiRelationshipRelPathSegment   = resourcePreviousRelationship.ApiRelPathSegment;
                switch (previousRelationshipCardinality)
                {
                case RelationshipCardinality.ToOne:
                {
                    var toOneResourceHypermediaPath = new ToOneResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment);
                    resourceBasePath.Add(toOneResourceHypermediaPath);
                    resourcePathMode = ResourcePathMode.IgnoreApiId;
                }
                break;

                case RelationshipCardinality.ToMany:
                {
                    var toManyResourceHypermediaPath = new ToManyResourceCollectionHypermediaPath(clrResourceType, apiRelationshipRelPathSegment);
                    resourceBasePath.Add(toManyResourceHypermediaPath);
                    resourcePathMode = ResourcePathMode.IncludeApiId;
                }
                break;

                default:
                {
                    var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                                 .FormatWith(typeof(RelationshipCardinality).Name, previousRelationshipCardinality);
                    throw new InternalErrorException(detail);
                }
                }
            }

            var resourcePathParts = new Tuple <ICollection <IHypermediaPath>, ResourcePathMode>(resourceBasePath, resourcePathMode);

            return(resourcePathParts);
        }
예제 #14
0
 public bool TryGetRelationshipInfo(string rel, out IRelationshipInfo relationshipInfo)
 {
     relationshipInfo = null;
     return(this.RelationshipsInfo != null && this.RelationshipsInfo.TryGetRelationshipInfo(rel, out relationshipInfo));
 }