Esempio n. 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);
        }
        private static void ResolveResourceLink(IDomLink domLink,
                                                IHypermediaContext hypermediaContext,
                                                IHypermediaAssembler hypermediaAssembler,
                                                IResourcePathContext resourcePathContext,
                                                Type clrResourceType,
                                                object clrResource,
                                                DomReadWriteLinks domReadWriteLinks)
        {
            if (domLink.IsReadOnly)
            {
                return;
            }

            // Resolve read-write resource link
            var domReadWriteLink = (DomReadWriteLink)domLink;
            var apiLinkRel       = domReadWriteLink.Rel;

            var apiLinkMeta = default(Meta);
            var domLinkMeta = (IDomMeta)domReadWriteLink.GetNode(DomNodeType.Meta);

            if (domLinkMeta != null)
            {
                apiLinkMeta = domLinkMeta.Meta;
            }

            // Create link.
            var linkContext     = new LinkContext(apiLinkRel, apiLinkMeta);
            var apiResourceLink = hypermediaAssembler.CreateResourceLink(hypermediaContext, resourcePathContext, clrResourceType, clrResource, linkContext);

            // Replace the old DOM read-write link node with a new DOM read-only link created by the framework.
            var domReadOnlyLink = DomReadOnlyLink.Create(apiLinkRel, apiResourceLink);

            domReadWriteLinks.ReplaceNode(domReadWriteLink, domReadOnlyLink);
        }
        public Link CreateResourceLink(IHypermediaContext hypermediaContext, IResourcePathContext resourcePathContext, Type clrResourceType, object clrResource, ILinkContext linkContext)
        {
            Contract.Requires(hypermediaContext != null);
            Contract.Requires(resourcePathContext != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(clrResource != null);
            Contract.Requires(linkContext != null);

            var apiResourceLink = CreateStandardResourceLink(hypermediaContext, resourcePathContext, clrResourceType, clrResource, linkContext);

            if (apiResourceLink != null)
            {
                return(apiResourceLink);
            }

            var urlBuilderConfiguration        = hypermediaContext.GetUrlBuilderConfiguration(clrResourceType);
            var throwExceptionOnLinkBuildError = urlBuilderConfiguration.ThrowExceptionOnLinkBuildError;

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

            var apiRel = linkContext.Rel;
            var clrResourceTypeName = clrResourceType.Name;
            var detail = ServerErrorStrings.DocumentBuildExceptionDetailBuildNonStandardResourceLink
                         .FormatWith(apiRel, clrResourceTypeName);

            throw new DocumentBuildException(detail);
        }
Esempio n. 4
0
        public static IEnumerable <string> GetResourceSelfPath(this IResourcePathContext resourcePathContext, string apiId)
        {
            Contract.Requires(resourcePathContext != null);
            Contract.Requires(String.IsNullOrWhiteSpace(apiId) == false);

            var resourceSelfBasePath = resourcePathContext.ResourceSelfBasePath;
            var resourceSelfPathMode = resourcePathContext.ResourceSelfPathMode;
            var resourceSelfPath     = GetResourcePath(resourceSelfBasePath, resourceSelfPathMode, apiId);

            return(resourceSelfPath);
        }
        private void ResolveResourceRelationships(DomReadWriteResource domReadWriteResource,
                                                  IHypermediaContext hypermediaContext,
                                                  IHypermediaAssembler hypermediaAssembler,
                                                  IResourcePathContext resourcePathContext,
                                                  Type clrResourceType,
                                                  object clrResource)
        {
            var domRelationships = (IDomRelationships)domReadWriteResource.GetNode(DomNodeType.Relationships);

            if (domRelationships == null || domRelationships.IsReadOnly)
            {
                return;
            }

            var domReadWriteRelationships = (DomReadWriteRelationships)domRelationships;

            foreach (var domRelationship in domReadWriteRelationships.Nodes().Cast <IDomRelationship>())
            {
                this.ResolveResourceRelationship(domRelationship, hypermediaContext, hypermediaAssembler, resourcePathContext, clrResourceType, clrResource, domReadWriteRelationships);
            }
        }
        private static void ResolveResourceLinks(DomReadWriteResource domReadWriteResource,
                                                 IHypermediaContext hypermediaContext,
                                                 IHypermediaAssembler hypermediaAssembler,
                                                 IResourcePathContext resourcePathContext,
                                                 Type clrResourceType,
                                                 object clrResource)
        {
            var domLinks = (IDomLinks)domReadWriteResource.GetNode(DomNodeType.Links);

            if (domLinks == null || domLinks.IsReadOnly)
            {
                return;
            }

            var domReadWriteLinks = (DomReadWriteLinks)domLinks;

            foreach (var domLink in domReadWriteLinks.Nodes().Cast <IDomLink>())
            {
                ResolveResourceLink(domLink, hypermediaContext, hypermediaAssembler, resourcePathContext, clrResourceType, clrResource, domReadWriteLinks);
            }
        }
Esempio n. 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);
        }
Esempio n. 8
0
        private static Link CreateStandardResourceLink(IHypermediaContext hypermediaContext, IResourcePathContext resourcePathContext, Type clrResourceType, object clrResource, ILinkContext linkContext)
        {
            Contract.Requires(hypermediaContext != null);
            Contract.Requires(resourcePathContext != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(clrResource != null);
            Contract.Requires(linkContext != null);

            var apiRel      = linkContext.Rel;
            var apiLinkMeta = linkContext.Meta;

            switch (apiRel)
            {
            case Keywords.Canonical:
            case Keywords.Self:
            {
                var urlBuilderConfiguration = hypermediaContext.GetUrlBuilderConfiguration(clrResourceType);

                var serviceModel = hypermediaContext.GetServiceModel();
                var resourceType = serviceModel.GetResourceType(clrResourceType);

                var isSelfLink = String.Compare(Keywords.Self, apiRel, StringComparison.Ordinal) == 0;

                var apiId           = resourceType.GetApiId(clrResource);
                var apiResourcePath = isSelfLink
                        ? resourcePathContext.GetResourceSelfPath(apiId)
                        : resourcePathContext.GetResourceCanonicalPath(apiId);
                var apiHRef = UrlBuilder.Create(urlBuilderConfiguration)
                              .Path(apiResourcePath)
                              .Build();
                var apiResourceLink = new Link
                {
                    HRef = apiHRef,
                    Meta = apiLinkMeta
                };
                return(apiResourceLink);
            }
            }

            return(null);
        }
Esempio n. 9
0
        public Relationship CreateResourceRelationship(IHypermediaContext hypermediaContext, IResourcePathContext resourcePathContext, Type clrResourceType, object clrResource, IRelationshipContext relationshipContext)
        {
            Contract.Requires(hypermediaContext != null);
            Contract.Requires(resourcePathContext != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(clrResource != null);
            Contract.Requires(relationshipContext != null);

            var apiRel = relationshipContext.Rel;

            var serviceModel = hypermediaContext.GetServiceModel();
            var resourceType = serviceModel.GetResourceType(clrResourceType);
            var relationship = resourceType.GetRelationshipInfo(apiRel);

            // Create the Links object of the relationship.
            var apiRelationshipLinks = CreateResourceRelationshipLinks(hypermediaContext, resourcePathContext, resourceType, clrResource, relationship, relationshipContext);

            // Create the relationship:
            var apiRelationship = CreateResourceRelationship(apiRelationshipLinks, resourceType, relationship, relationshipContext);

            return(apiRelationship);
        }
        private void ResolveResourceRelationship(IDomRelationship domRelationship,
                                                 IHypermediaContext hypermediaContext,
                                                 IHypermediaAssembler hypermediaAssembler,
                                                 IResourcePathContext resourcePathContext,
                                                 Type clrResourceType,
                                                 object clrResource,
                                                 DomReadWriteRelationships domReadWriteRelationships)
        {
            if (domRelationship.IsReadOnly)
            {
                return;
            }

            // Resolve read-write relationship
            var domReadWriteRelationship = (DomReadWriteRelationship)domRelationship;

            // .. Rel
            var apiRelationshipRel = domReadWriteRelationship.Rel;

            // .. Links
            var linkContexts         = new List <ILinkContext>();
            var domRelationshipLinks = (IDomLinks)domReadWriteRelationship.GetNode(DomNodeType.Links);

            if (domRelationshipLinks != null)
            {
                if (domRelationshipLinks.IsReadOnly)
                {
                    // A read-write relationship contains unexpected read-only relationship links.
                    var detail = ServerErrorStrings.DomExceptionDetailReadWriteNodeHasUnexpectedReadOnlyChildNode
                                 .FormatWith(DomNodeType.Relationship, DomNodeType.Links);
                    throw new DomException(detail);
                }

                var domReadWriteRelationshipLinks = (DomReadWriteLinks)domRelationshipLinks;
                foreach (var domLink in domReadWriteRelationshipLinks.Nodes().Cast <IDomLink>())
                {
                    if (domLink.IsReadOnly)
                    {
                        // A read-write relationship contains unexpected read-only relationship link.
                        var detail = ServerErrorStrings.DomExceptionDetailReadWriteNodeHasUnexpectedReadOnlyChildNode
                                     .FormatWith(DomNodeType.Relationship, DomNodeType.Link);
                        throw new DomException(detail);
                    }

                    // Resolve read-write relationship link
                    var domReadWriteLink = (DomReadWriteLink)domLink;
                    var apiLinkRel       = domReadWriteLink.Rel;

                    var apiLinkMeta = default(Meta);
                    var domMeta     = (IDomMeta)domReadWriteLink.GetNode(DomNodeType.Meta);
                    if (domMeta != null)
                    {
                        apiLinkMeta = domMeta.Meta;
                    }

                    var linkContext = new LinkContext(apiLinkRel, apiLinkMeta);
                    linkContexts.Add(linkContext);
                }
            }

            // .. Data
            var resourceType = this.ServiceModel.GetResourceType(clrResourceType);
            var fromApiResourceIdentifier = resourceType.GetApiResourceIdentifier(clrResource);

            var             resourceLinkageKey = new ResourceLinkageKey(fromApiResourceIdentifier, apiRelationshipRel);
            ResourceLinkage resourceLinkage;
            var             hasResourceLinkage = this.DocumentBuilderContext.TryGetResourceLinkage(resourceLinkageKey, out resourceLinkage);

            // .. Meta
            var apiRelationshipMeta = default(Meta);
            var domRelationshipMeta = (IDomMeta)domReadWriteRelationship.GetNode(DomNodeType.Meta);

            if (domRelationshipMeta != null)
            {
                apiRelationshipMeta = domRelationshipMeta.Meta;
            }

            // Create the correct relationship context based on resource linkage (if any).
            RelationshipContext relationshipContext;

            if (hasResourceLinkage)
            {
                var resourceLinkageType = resourceLinkage.Type;
                switch (resourceLinkageType)
                {
                case ResourceLinkageType.ToOneResourceLinkage:
                {
                    var toOneResourceLinkage = resourceLinkage.ToOneResourceLinkage;
                    relationshipContext = new ToOneRelationshipContext(apiRelationshipRel, linkContexts, toOneResourceLinkage, apiRelationshipMeta);
                }
                break;

                case ResourceLinkageType.ToManyResourceLinkage:
                {
                    var toManyResourceLinkage = resourceLinkage.ToManyResourceLinkage;
                    relationshipContext = new ToManyRelationshipContext(apiRelationshipRel, linkContexts, toManyResourceLinkage, apiRelationshipMeta);
                }
                break;

                default:
                {
                    var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                                 .FormatWith(typeof(ResourceLinkageType).Name, resourceLinkageType);
                    throw new InternalErrorException(detail);
                }
                }
            }
            else
            {
                relationshipContext = new RelationshipContext(apiRelationshipRel, linkContexts, apiRelationshipMeta);
            }

            // Create relationship.
            var apiResourceRelationship = hypermediaAssembler.CreateResourceRelationship(hypermediaContext, resourcePathContext, clrResourceType, clrResource, relationshipContext);

            // Replace the old DOM read-write relationship node with a new DOM read-only relationship created by the framework.
            var domReadOnlyRelationship = DomReadOnlyRelationship.Create(apiRelationshipRel, apiResourceRelationship);

            domReadWriteRelationships.ReplaceNode(domReadWriteRelationship, domReadOnlyRelationship);
        }
Esempio n. 11
0
        public static void SetResourcePathContext(this DomReadWriteResource domReadWriteResource, IResourcePathContext resourcePathContext)
        {
            Contract.Requires(domReadWriteResource != null);
            Contract.Requires(resourcePathContext != null);

            domReadWriteResource.SetSingleAttribute(ResourcePathContextNodeAttributeName, resourcePathContext);
        }