public void TestDomReadWriteResourceCreateWithPersonResource() { // Arrange var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes; var personResourceType = serviceModel.GetResourceType <Person>(); var personResourceIdentity = personResourceType.ResourceIdentityInfo; var personFirstNameAttribute = personResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Person>(x => x.FirstName)); var personLastNameAttribute = personResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Person>(x => x.LastName)); var personTwitterAttribute = personResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Person>(x => x.Twitter)); var expected = ApiSampleData.PersonResource; // Act var actual = DomReadWriteResource.Create( DomType.CreateFromResourceType(personResourceType), DomId.CreateFromApiResourceIdentity(personResourceType, expected), DomAttributes.Create( DomAttribute.CreateFromApiResource(personFirstNameAttribute, expected), DomAttribute.CreateFromApiResource(personLastNameAttribute, expected), DomAttribute.CreateFromApiResource(personTwitterAttribute, expected)), DomReadWriteRelationships.Create( DomReadWriteRelationship.Create(ApiSampleData.PersonToCommentsRel, DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.PersonToRelationshipsToCommentsHRef)), DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.PersonToCommentsHRef))))), DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.PersonHRef))), DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta)); this.OutputDomTree(actual); // Assert DomReadWriteResourceAssert.Equal(expected, actual); }
public void TestDomReadWriteResourceCreateWithCommentResource() { // Arrange var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes; var commentResourceType = serviceModel.GetResourceType <Comment>(); var commentResourceIdentity = commentResourceType.ResourceIdentityInfo; var commentBodyAttribute = commentResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Comment>(x => x.Body)); var expected = ApiSampleData.CommentResource; // Act var actual = DomReadWriteResource.Create( DomType.CreateFromResourceType(commentResourceType), DomId.CreateFromApiResourceIdentity(commentResourceType, expected), DomAttributes.Create( DomAttribute.CreateFromApiResource(commentBodyAttribute, expected)), DomReadWriteRelationships.Create( DomReadWriteRelationship.Create(ApiSampleData.CommentToAuthorRel, DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.CommentToRelationshipsToAuthorHRef)), DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.CommentToAuthorHRef))))), DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.CommentHRef))), DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta)); this.OutputDomTree(actual); // Assert DomReadWriteResourceAssert.Equal(expected, actual); }
public void TestDomReadWriteResourceCreateWithBlogResource() { // Arrange var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes; var blogResourceType = serviceModel.GetResourceType <Blog>(); var blogResourceIdentity = blogResourceType.ResourceIdentityInfo; var blogNameAttribute = blogResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Blog>(x => x.Name)); var expectedBlog = ApiSampleData.BlogResource; // Act var actual = DomReadWriteResource.Create( DomType.CreateFromResourceType(blogResourceType), DomId.CreateFromApiResourceIdentity(blogResourceType, expectedBlog), DomAttributes.Create( DomAttribute.CreateFromApiResource(blogNameAttribute, expectedBlog)), DomReadWriteRelationships.Create( DomReadWriteRelationship.Create(ApiSampleData.BlogToArticlesRel, DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.BlogToRelationshipsToArticlesHRef)), DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.BlogToArticlesHRef))))), DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.BlogHRef))), DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta)); this.OutputDomTree(actual); // Assert DomReadWriteResourceAssert.Equal(expectedBlog, actual); }
public void TestDomReadWriteResourceCreateWithArticleResourceWithResourceLinkage() { // Arrange var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes; var articleResourceType = serviceModel.GetResourceType <Article>(); var articleTitleAttribute = articleResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Article>(x => x.Title)); var commentResourceType = serviceModel.GetResourceType <Comment>(); var personResourceType = serviceModel.GetResourceType <Person>(); var expectedArticle = ApiSampleData.ArticleResourceWithResourceLinkage; var expectedAuthor = ApiSampleData.PersonResource; var expectedComment1 = ApiSampleData.CommentResource1; var expectedComment2 = ApiSampleData.CommentResource2; // Act var actual = DomReadWriteResource.Create( DomType.CreateFromResourceType(articleResourceType), DomId.CreateFromApiResourceIdentity(articleResourceType, expectedArticle), DomAttributes.Create( DomAttribute.CreateFromApiResource(articleTitleAttribute, expectedArticle)), DomReadWriteRelationships.Create( DomReadWriteRelationship.Create(ApiSampleData.ArticleToAuthorRel, DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleToRelationshipsToAuthorHRef)), DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.ArticleToAuthorHRef))), DomData.CreateFromResourceIdentifier( DomReadWriteResourceIdentifier.Create( DomType.CreateFromResourceType(personResourceType), DomId.CreateFromApiResourceIdentity(personResourceType, expectedAuthor)))), DomReadWriteRelationship.Create(ApiSampleData.ArticleToCommentsRel, DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleToRelationshipsToCommentsHRef)), DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.ArticleToCommentsHRef))), DomDataCollection.CreateFromResourceIdentifiers( DomReadWriteResourceIdentifier.Create( DomType.CreateFromResourceType(commentResourceType), DomId.CreateFromApiResourceIdentity(commentResourceType, expectedComment1)), DomReadWriteResourceIdentifier.Create( DomType.CreateFromResourceType(commentResourceType), DomId.CreateFromApiResourceIdentity(commentResourceType, expectedComment2))))), DomReadWriteLinks.Create( DomReadWriteLink.Create(Keywords.Canonical, DomHRef.Create(ApiSampleData.ArticleHRef)), DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleHRef))), DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta)); this.OutputDomTree(actual); // Assert DomReadWriteResourceAssert.Equal(expectedArticle, actual); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region Assert Methods public static void Equal(Relationships expected, DomReadWriteRelationships actual) { if (expected == null) { Assert.Null(actual); return; } Assert.NotNull(actual); Assert.Equal(DomNodeType.Relationships, actual.NodeType); var actualNodes = actual.Nodes() .ToList(); var actualDomRelationshipsCount = actualNodes.Count; Assert.Equal(expected.Count, actualDomRelationshipsCount); foreach (var expectedRelRelationshipPair in expected) { var expectedRel = expectedRelRelationshipPair.Key; var expectedRelationship = expectedRelRelationshipPair.Value; DomNode actualDomRelationshipNode = null; foreach (var actualNode in actualNodes) { var domRelationship = (IDomRelationship)actualNode; if (domRelationship.Rel != expectedRel) { continue; } actualDomRelationshipNode = actualNode; break; } Assert.NotNull(actualDomRelationshipNode); DomRelationshipAssert.Equal(expectedRel, expectedRelationship, actualDomRelationshipNode); } }
// INTERNAL CONSTRUCTORS //////////////////////////////////////////// #region Constructors internal RelationshipsCollectionBuilder(TParentBuilder parentBuilder, IServiceModel serviceModel, IReadOnlyCollection <IContainerNode <DomNodeType> > domContainerNodeCollection, IReadOnlyList <TResource> clrResourceCollection) { Contract.Requires(parentBuilder != null); Contract.Requires(serviceModel != null); Contract.Requires(domContainerNodeCollection != null); var domReadWriteRelationshipsCollectionCount = domContainerNodeCollection.Count; var clrResourceCollectionCount = clrResourceCollection.Count; if (clrResourceCollectionCount != domReadWriteRelationshipsCollectionCount) { var detail = ServerErrorStrings .InternalErrorExceptionDetailCollectionCountMismatch .FormatWith("DOM read-write relationships collection", domReadWriteRelationshipsCollectionCount, "CLR resource collection", clrResourceCollectionCount); throw new InternalErrorException(detail); } this.ParentBuilder = parentBuilder; this.ServiceModel = serviceModel; var resourceType = serviceModel.GetResourceType <TResource>(); this.ResourceType = resourceType; var domReadWriteRelationshipsCollection = domContainerNodeCollection .Select(x => x.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create())) .ToList(); this.DomReadWriteRelationshipsCollection = domReadWriteRelationshipsCollection; this.ClrResourceCollection = clrResourceCollection; }
// INTERNAL CONSTRUCTORS //////////////////////////////////////////// #region Constructors internal RelationshipsBuilder(TParentBuilder parentBuilder, IServiceModel serviceModel, IContainerNode <DomNodeType> domContainerNode, Type clrResourceType, object clrResource) { Contract.Requires(parentBuilder != null); Contract.Requires(serviceModel != null); Contract.Requires(domContainerNode != null); Contract.Requires(clrResourceType != null); Contract.Requires(clrResource != null); this.ParentBuilder = parentBuilder; this.ServiceModel = serviceModel; var resourceType = serviceModel.GetResourceType(clrResourceType); this.ResourceType = resourceType; var domReadWriteRelationships = domContainerNode.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create()); this.DomReadWriteRelationships = domReadWriteRelationships; this.ClrResource = clrResource; }
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); }
internal void TestDomReadWriteRelationshipsCreate(string name, Relationships expected, DomReadWriteRelationships actual) { // Arrange // Act this.Output.WriteLine("Test Name: {0}", name); this.Output.WriteLine(String.Empty); this.OutputDomTree(actual); // Assert DomReadWriteRelationshipsAssert.Equal(expected, actual); }
// INTERNAL CONSTRUCTORS //////////////////////////////////////////// #region Constructors internal RelationshipsCollectionBuilder(TParentBuilder parentBuilder, IServiceModel serviceModel, IReadOnlyCollection <IContainerNode <DomNodeType> > domContainerNodeCollection, Type clrResourceType, IReadOnlyList <object> clrResourceCollection) { Contract.Requires(parentBuilder != null); Contract.Requires(serviceModel != null); Contract.Requires(domContainerNodeCollection != null); Contract.Requires(clrResourceType != null); Contract.Requires(clrResourceCollection != null); this.ParentBuilder = parentBuilder; this.ServiceModel = serviceModel; var resourceType = serviceModel.GetResourceType(clrResourceType); this.ResourceType = resourceType; var domReadWriteRelationshipsCollection = domContainerNodeCollection .Select(x => x.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create())) .ToList(); this.DomReadWriteRelationshipsCollection = domReadWriteRelationshipsCollection; this.ClrResourceCollection = clrResourceCollection; }
// INTERNAL CONSTRUCTORS //////////////////////////////////////////// #region Constructors internal RelationshipsBuilder(TParentBuilder parentBuilder, IContainerNode <DomNodeType> domContainerNode, TResource clrResource) { Contract.Requires(parentBuilder != null); Contract.Requires(domContainerNode != null); Contract.Requires(clrResource != null); this.ParentBuilder = parentBuilder; var domReadWriteRelationships = domContainerNode.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create()); this.DomReadWriteRelationships = domReadWriteRelationships; this.ClrResource = clrResource; }
// PRIVATE METHODS ////////////////////////////////////////////////// #region Methods private void AddDomReadWriteRelationshipIfNeeded(ApiResourceLinkageKey apiResourceLinkageKey) { // Add DOM read/write relationship node if not already added. var fromApiResourceIdentifier = apiResourceLinkageKey.FromResourceIdentifier; var fromApiRel = apiResourceLinkageKey.FromRel; if (!this.DomReadWriteResourceDictionary.TryGetValue(fromApiResourceIdentifier, out var domResource)) { return; } var domReadWriteRelationships = (DomReadWriteRelationships)domResource.GetNode(DomNodeType.Relationships); // ReSharper disable once ConvertIfStatementToNullCoalescingExpression if (domReadWriteRelationships == null) { // Add DOM read/write relationships node domReadWriteRelationships = domResource.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create()); } var domReadWriteRelationshipExists = domReadWriteRelationships.Nodes() .Cast <IDomRelationship>() .Any(x => x.Rel == fromApiRel); if (domReadWriteRelationshipExists) { return; } // Add DOM read/write relationship node. domReadWriteRelationships.AddDomReadWriteRelationship(fromApiRel); }