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); } } }
// PRIVATE METHODS ////////////////////////////////////////////////// #region Methods private Relationship GetRelationship() { var links = default(Links); var toOneResourceLinkage = default(ResourceIdentifier); var toOneResourceLinkagePresent = default(bool); var toManyResourceLinkage = default(List <ResourceIdentifier>); var toManyResourceLinkagePresent = default(bool); var meta = default(Meta); var domRelationshipNodes = this.Nodes(); foreach (var domRelationshipNode in domRelationshipNodes) { var domRelationshipNodeType = domRelationshipNode.NodeType; switch (domRelationshipNodeType) { case DomNodeType.Links: { var domLinks = (IDomLinks)domRelationshipNode; links = domLinks.Links; } break; case DomNodeType.Data: { toOneResourceLinkagePresent = true; var domDataNode = (DomData)domRelationshipNode; var domResourceIdentifierNode = domDataNode.Node; if (domResourceIdentifierNode != null) { var apiResourceIdentifier = GetApiResourceIdentifier(domResourceIdentifierNode); toOneResourceLinkage = apiResourceIdentifier; } } break; case DomNodeType.DataCollection: { toManyResourceLinkagePresent = true; var domDataCollectionNode = (DomDataCollection)domRelationshipNode; var domResourceIdentifierNodes = domDataCollectionNode.Nodes(); toManyResourceLinkage = domResourceIdentifierNodes.Select(GetApiResourceIdentifier) .ToList(); } break; case DomNodeType.Meta: { var domMeta = (IDomMeta)domRelationshipNode; meta = domMeta.Meta; } break; default: { var detail = InfrastructureErrorStrings.DomExceptionDetailNodeHasUnexpectedChildNode .FormatWith(this.NodeType, domRelationshipNodeType); throw new DomException(detail); } } } if (toOneResourceLinkagePresent && toManyResourceLinkagePresent) { var detail = InfrastructureErrorStrings.DomExceptionDetailNodeHasIncompatibleChildNodes .FormatWith(this.NodeType, DomNodeType.Data, DomNodeType.DataCollection); throw new DomException(detail); } // Create the concrete relationship object and initialize the data property if needed. Relationship relationship; if (toOneResourceLinkagePresent) { relationship = new ToOneRelationship { Data = toOneResourceLinkage }; } else if (toManyResourceLinkagePresent) { relationship = new ToManyRelationship { Data = toManyResourceLinkage }; } else { relationship = new Relationship(); } // Initialize remaining common relationship properties. relationship.Links = links; relationship.Meta = meta; return(relationship); }