Exemplo n.º 1
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);
            }
            }
        }
        // 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);
        }