Ejemplo n.º 1
0
        public SingleResource CreateResourceRepresentation(object objectGraph, IResourceMapping resourceMapping, Context context)
        {
            var urlBuilder = new UrlBuilder
            {
                RoutePrefix = context.RoutePrefix
            };

            var result = new SingleResource();

            result.Id   = resourceMapping.IdGetter(objectGraph).ToString();
            result.Type = resourceMapping.ResourceType;

            result.Attributes = resourceMapping.PropertyGetters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value(objectGraph));

            if (resourceMapping.UrlTemplate != null)
            {
                result.Links = CreateLinks(resourceMapping, urlBuilder, result);
            }

            if (resourceMapping.Relationships.Any())
            {
                result.Relationships = CreateRelationships(objectGraph, result.Id, resourceMapping, context);
            }

            return(result);
        }
Ejemplo n.º 2
0
        public ILink RelationshipSelfLink(Context context, string resourceId, IResourceMapping resourceMapping, IRelationshipMapping linkMapping)
        {
            var selfLink     = FindResourceSelfLink(context, resourceId, resourceMapping).Href;
            var completeLink = $"{selfLink}/relationships/{linkMapping.RelationshipName}";

            return(new SimpleLink(new Uri(completeLink)));
        }
Ejemplo n.º 3
0
 public ILink RelationshipRelatedLink(Context context, string resourceId, IResourceMapping resourceMapping, IRelationshipMapping linkMapping)
 {
     var selfLink = FindResourceSelfLink(context, resourceId, resourceMapping).Href;
     var completeLink = $"{selfLink}/{linkMapping.RelationshipName}";
     return new SimpleLink(new Uri(completeLink));
    
 }
Ejemplo n.º 4
0
 public Delta(IConfiguration configuration)
 {
     _mapping             = configuration.GetMapping(typeof(T));
     ObjectPropertyValues = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
     CollectionDeltas     = new Dictionary <string, ICollectionDelta>();
     TopLevelMetaData     = null;
     ObjectMetaData       = null;
 }
Ejemplo n.º 5
0
 private static Dictionary <string, ILink> CreateLinks(IResourceMapping resourceMapping, Context context, SingleResource result)
 {
     return(new Dictionary <string, ILink>()
     {
         { SelfLinkKey, new SimpleLink {
               Href = context.GetFullyQualifiedUrl(resourceMapping.UrlTemplate.Replace(IdPlaceholder, result.Id))
           } }
     });
 }
Ejemplo n.º 6
0
        public List<SingleResource> CreateIncludedRepresentations(List<object> primaryResourceList, IResourceMapping resourceMapping, Context context)
        {
            var includedList = new List<SingleResource>();
            var alreadyVisitedObjects = new HashSet<object>(primaryResourceList);

            foreach (var resource in primaryResourceList)
                AppendIncludedRepresentationRecursive(resource, resourceMapping, includedList, alreadyVisitedObjects, context);

            return includedList;
        }
Ejemplo n.º 7
0
        public ISimpleLink FindResourceSelfLink(Context context, string resourceId, IResourceMapping resourceMapping)
        {
            var actions = descriptionProvider.From(resourceMapping.Controller);

            var action = actions.Single(a =>
                                        a.HttpMethod.Method == "GET" &&
                                        a.ParameterDescriptions.Count(p => p.Name == "id") == 1);

            var formattedUri = action.RelativePath.Replace("{id}", resourceId);

            return(new SimpleLink(new Uri(context.BaseUri, formattedUri)));
        }
Ejemplo n.º 8
0
        public ILink FindResourceSelfLink(Context context, string resourceId, IResourceMapping resourceMapping)
        {
            var actions = descriptionProvider.From(resourceMapping.Controller).Items;

            var action = actions.Single(a =>
                a.HttpMethod == "GET" &&
                a.ParameterDescriptions.Count(p => p.Name == "id") == 1);

            var values = new Dictionary<string, object>();
            values.Add("id", resourceId);

            return ToUrl(context, action, values);
        }
Ejemplo n.º 9
0
        public ILink FindResourceSelfLink(Context context, string resourceId, IResourceMapping resourceMapping)
        {
            var actions = descriptionProvider.From(resourceMapping.Controller).Items;

            var action = actions.Single(a =>
                                        a.HttpMethod == "GET" &&
                                        a.ParameterDescriptions.Count(p => p.Name == "id") == 1);

            var values = new Dictionary <string, object>();

            values.Add("id", resourceId);

            return(ToUrl(context, action, values));
        }
Ejemplo n.º 10
0
        private List <SingleResource> AppendIncludedRepresentationRecursive(
            object resource,
            IResourceMapping resourceMapping,
            HashSet <SingleResourceIdentifier> alreadyVisitedObjects,
            Context context,
            string parentRelationshipPath = "")
        {
            var includedResources = new List <SingleResource>();

            foreach (var relationship in resourceMapping.Relationships)
            {
                if (relationship.InclusionRule == ResourceInclusionRules.ForceOmit)
                {
                    continue;
                }

                var    relatedResources = UnifyObjectsToList(relationship.RelatedResource(resource));
                string relationshipPath = BuildRelationshipPath(parentRelationshipPath, relationship);

                if (!context.IncludedResources.Any(x => x.Contains(relationshipPath)))
                {
                    continue;
                }

                foreach (var relatedResource in relatedResources)
                {
                    var relatedResourceId = new SingleResourceIdentifier
                    {
                        Id       = relationship.ResourceMapping.IdGetter(relatedResource).ToString(),
                        Type     = relationship.ResourceMapping.ResourceType,
                        MetaData = GetRelationshipMetadata(relatedResource)
                    };

                    if (alreadyVisitedObjects.Contains(relatedResourceId))
                    {
                        continue;
                    }

                    alreadyVisitedObjects.Add(relatedResourceId);
                    includedResources.Add(
                        CreateResourceRepresentation(relatedResource, relationship.ResourceMapping, context));

                    includedResources.AddRange(
                        AppendIncludedRepresentationRecursive(relatedResource, relationship.ResourceMapping, alreadyVisitedObjects, context, relationshipPath));
                }
            }

            return(includedResources);
        }
Ejemplo n.º 11
0
 public static void AppendIncludedRepresentationRecursive(object resource, IResourceMapping resourceMapping, List <SingleResource> includedList, HashSet <object> alreadyVisitedObjects, Context context)
 {
     resourceMapping.Relationships
     .Where(rm => rm.InclusionRule != ResourceInclusionRules.ForceOmit)
     .SelectMany(rm => UnifyObjectsToList(rm.RelatedResource(resource)), (rm, o) => new
     {
         Mapping = rm,
         RelatedResourceInstance = o,
     })
     .Where(x => !alreadyVisitedObjects.Contains(x.RelatedResourceInstance))
     .ToList()
     .ForEach(x =>
     {
         alreadyVisitedObjects.Add(x.RelatedResourceInstance);
         includedList.Add(CreateResourceRepresentation(x.RelatedResourceInstance, x.Mapping.ResourceMapping, context));
         AppendIncludedRepresentationRecursive(x.RelatedResourceInstance, x.Mapping.ResourceMapping, includedList, alreadyVisitedObjects, context);
     });
 }
Ejemplo n.º 12
0
        public override void WriteResponseHeaders(OutputFormatterWriteContext context)
        {
            base.WriteResponseHeaders(context);
            this.configuration.OverrideResponseHeaders(new OverrideResponseHeadersContext()
            {
                HttpContext = context.HttpContext,
                Type        = context.ObjectType,
                Value       = context.Object
            });

            IResourceMapping mapping = this.configuration.GetMapping(context.ObjectType);

            if (mapping != null &&
                !string.IsNullOrEmpty(mapping.OutputContentType))
            {
                context.HttpContext.Response.ContentType = mapping.OutputContentType;
            }
        }
 public void AppendIncludedRepresentationRecursive(object resource, IResourceMapping resourceMapping, List<SingleResource> includedList, HashSet<object> alreadyVisitedObjects, Context context)
 {
     resourceMapping.Relationships
         .Where(rm => rm.InclusionRule != ResourceInclusionRules.ForceOmit)
         .SelectMany(rm => UnifyObjectsToList(rm.RelatedResource(resource)), (rm, o) => new
         {
             Mapping = rm,
             RelatedResourceInstance = o,
         })
         .Where(x => !alreadyVisitedObjects.Contains(x.RelatedResourceInstance))
         .ToList()
         .ForEach(x =>
         {
             alreadyVisitedObjects.Add(x.RelatedResourceInstance);
             includedList.Add(CreateResourceRepresentation(x.RelatedResourceInstance, x.Mapping.ResourceMapping, context, true, resource.GetType()));
             AppendIncludedRepresentationRecursive(x.RelatedResourceInstance, x.Mapping.ResourceMapping, includedList, alreadyVisitedObjects, context);
         });
 }
        private IDictionary <string, object> GenerateAttributes(object instance, IResourceMapping mapping)
        {
            var attributeNames = mapping.GetAttributeNames().ToList();

            if (!attributeNames.Any())
            {
                return(null);
            }

            var attributes = new Dictionary <string, object>();

            foreach (var attributeName in attributeNames)
            {
                var value = mapping.GetAttributeValue(instance, attributeName);
                attributes.Add(attributeName, value);
            }

            return(attributes);
        }
Ejemplo n.º 15
0
        private List<SingleResource> AppendIncludedRepresentationRecursive(
            object resource, 
            IResourceMapping resourceMapping, 
            HashSet<object> alreadyVisitedObjects, 
            Context context,
            string parentRelationshipPath = "")
        {
            var includedResources = new List<SingleResource>();

            foreach(var relationship in resourceMapping.Relationships)
            {
                if (relationship.InclusionRule == ResourceInclusionRules.ForceOmit)
                {
                    continue;
                }

                var relatedResources = UnifyObjectsToList(relationship.RelatedResource(resource));
                string relationshipPath = BuildRelationshipPath(parentRelationshipPath, relationship);

                if (!context.IncludedResources.Any(x => x.Contains(relationshipPath)))
                {
                    continue;
                }
                
                foreach (var relatedResource in relatedResources)
                {
                    if (alreadyVisitedObjects.Contains(relatedResource))
                    {
                        continue;
                    }

                    alreadyVisitedObjects.Add(relatedResource);
                    includedResources.Add(
                        CreateResourceRepresentation(relatedResource, relationship.ResourceMapping, context));

                    includedResources.AddRange(
                        AppendIncludedRepresentationRecursive(relatedResource, relationship.ResourceMapping, alreadyVisitedObjects, context, relationshipPath));
                }
            }

            return includedResources;
        }
        public List<SingleResource> CreateIncludedRepresentations(List<object> primaryResourceList, IResourceMapping resourceMapping, Context context)
        {
            var includedList = new List<SingleResource>();
            var alreadyVisitedObjects = new HashSet<object>(primaryResourceList);
            foreach (var resource in primaryResourceList)
            {
                try
                {
                    _parentId = resourceMapping.IdGetter(resource).ToString();
                }
                catch (Exception)
                {
                    _parentId = string.Empty;
                }

                AppendIncludedRepresentationRecursive(resource, resourceMapping, includedList, alreadyVisitedObjects, context);
            }

            return includedList;
        }
Ejemplo n.º 17
0
        public bool ValidateIncludedRelationshipPaths(string[] includedPaths)
        {
            foreach (var relationshipPath in includedPaths)
            {
                IResourceMapping currentMapping = this;

                var parts = relationshipPath.Split('.');
                foreach (var part in parts)
                {
                    var relationship = currentMapping.Relationships.SingleOrDefault(x => x.RelationshipName == part);
                    if (relationship == null)
                    {
                        return(false);
                    }

                    currentMapping = relationship.ResourceMapping;
                }
            }
            return(true);
        }
Ejemplo n.º 18
0
        public SingleResource CreateResourceRepresentation(
            object objectGraph,
            IResourceMapping resourceMapping,
            Context context)
        {
            var result = new SingleResource();

            result.Id         = resourceMapping.IdGetter(objectGraph).ToString();
            result.Type       = resourceMapping.ResourceType;
            result.Attributes = resourceMapping.GetAttributes(objectGraph, configuration.GetJsonSerializerSettings());
            result.Links      = GetObjectLinkData(objectGraph);
            result.Links.Add("self", linkBuilder.FindResourceSelfLink(context, result.Id, resourceMapping));
            result.MetaData = GetObjectMetadata(objectGraph);

            if (resourceMapping.Relationships.Any())
            {
                result.Relationships = CreateRelationships(objectGraph, result.Id, resourceMapping, context);
            }

            return(result);
        }
Ejemplo n.º 19
0
        public SingleResource CreateResourceRepresentation(
            object objectGraph,
            IResourceMapping resourceMapping,
            Context context)
        {
            var result = new SingleResource();

            result.Id         = resourceMapping.IdGetter(objectGraph).ToString();
            result.Type       = resourceMapping.ResourceType;
            result.Attributes = resourceMapping.GetAttributes(objectGraph);
            result.Links      = new Dictionary <string, ILink>()
            {
                { "self", linkBuilder.FindResourceSelfLink(context, result.Id, resourceMapping) }
            };

            if (resourceMapping.Relationships.Any())
            {
                result.Relationships = CreateRelationships(objectGraph, result.Id, resourceMapping, context);
            }

            return(result);
        }
Ejemplo n.º 20
0
        public SingleResource CreateResourceRepresentation(
            object objectGraph, 
            IResourceMapping resourceMapping, 
            Context context)
        {
            var result = new SingleResource();

            result.Id = resourceMapping.IdGetter(objectGraph).ToString();
            result.Type = resourceMapping.ResourceType;
            result.Attributes = resourceMapping.PropertyGetters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value(objectGraph));
            result.Links = new Dictionary<string, ILink>() { { "self", linkBuilder.FindResourceSelfLink(context, result.Id, resourceMapping) } };

            if (resourceMapping.Relationships.Any())
            {
                result.Relationships = CreateRelationships(objectGraph, result.Id, resourceMapping, context);
            }

            return result;
        }
Ejemplo n.º 21
0
 public ILink RelationshipSelfLink(Context context, string resourceId, IResourceMapping resourceMapping, IRelationshipMapping linkMapping)
 {
     return new SimpleLink(new Uri("http://example.com"));
 }
Ejemplo n.º 22
0
 public ILink FindResourceSelfLink(Context context, string id, IResourceMapping resourceMapping)
 {
     return new SimpleLink(new Uri("http://example.com"));
 }
Ejemplo n.º 23
0
 public ILink RelationshipSelfLink(Context context, string resourceId, IResourceMapping resourceMapping, IRelationshipMapping linkMapping)
 {
     return(new SimpleLink(new Uri("http://example.com")));
 }
Ejemplo n.º 24
0
 public ILink FindResourceSelfLink(Context context, string id, IResourceMapping resourceMapping)
 {
     return(new SimpleLink(new Uri("http://example.com")));
 }
Ejemplo n.º 25
0
        public Changes <TResource> BuildChanges <TResource>(DocumentData data, IResourceMapping mapping)
        {
            var changes = new Changes <TResource>();

            if (data.Id.HasValue)
            {
                changes.AddChange(resource => mapping.SetId(resource, data.Id.Value));
            }

            if (data.Attributes != null)
            {
                foreach (var attribute in data.Attributes)
                {
                    var attributeType = mapping.GetAttributeType(attribute.Key);
                    if (attributeType == null)
                    {
                        continue;
                    }
                    var value = attribute.Value.ParseAs(attributeType, _jsonSerializer);
                    changes.AddChange(resource => mapping.SetAttributeValue(resource, attribute.Key, value));
                }
            }

            if (data.Relationships != null)
            {
                foreach (var relation in data.Relationships)
                {
                    var relationResourceType = mapping.GetResourceTypeOfRelation(relation.Key);
                    if (relationResourceType == null)
                    {
                        throw new JsonApiException(CausedBy.Client, $"Unknown relation {relation.Key}");
                    }
                    var relationResourceTypeName = GetResourceTypeName(relationResourceType);
                    if (mapping.IsHasManyRelation(relation.Key))
                    {
                        var relationData = relation.Value.Data.ParseAs <IEnumerable <RelationData> >(_jsonSerializer);
                        if (relationData != null)
                        {
                            if (relationData.Any(x => !x.Type.Equals(relationResourceTypeName)))
                            {
                                throw new JsonApiFormatException(CausedBy.Client, $"Not all relations specified for {relation.Key} are of the type {relationResourceTypeName}");
                            }
                            var relationIds = relationData.Select(x => x.Id);
                            changes.AddChange(resource => mapping.SetRelationValue(resource, relation.Key, relationIds));
                        }
                    }
                    else
                    {
                        var relationData = relation.Value.Data.ParseAs <RelationData>(_jsonSerializer);
                        if (relationData != null)
                        {
                            if (!relationData.Type.Equals(relationResourceTypeName))
                            {
                                throw new JsonApiFormatException(CausedBy.Client, $"Relation type specified for {relation.Key} must be {relationResourceTypeName} instead of {relationData.Type}");
                            }
                            var relationId = relationData.Id;
                            changes.AddChange(resource => mapping.SetRelationValue(resource, relation.Key, relationId));
                        }
                    }
                }
            }

            return(changes);
        }
Ejemplo n.º 26
0
        public Dictionary<string, IRelationship> CreateRelationships(object objectGraph, string parentId, IResourceMapping resourceMapping, Context context)
        {
            var relationships = new Dictionary<string, IRelationship>();
            foreach (var linkMapping in resourceMapping.Relationships)
            {
                var relationshipName = linkMapping.RelationshipName;
                var rel = new Relationship();
                var relLinks = new RelationshipLinks();

                relLinks.Self = linkBuilder.RelationshipSelfLink(context, parentId, resourceMapping, linkMapping);
                relLinks.Related = linkBuilder.RelationshipRelatedLink(context, parentId, resourceMapping, linkMapping);

                if (!linkMapping.IsCollection)
                {
                    string relatedId = null;
                    object relatedInstance = null;
                    if (linkMapping.RelatedResource != null)
                    {
                        relatedInstance = linkMapping.RelatedResource(objectGraph);
                        if (relatedInstance != null)
                            relatedId = linkMapping.ResourceMapping.IdGetter(relatedInstance).ToString();
                    }
                    if (linkMapping.RelatedResourceId != null && relatedId == null)
                    {
                        var id = linkMapping.RelatedResourceId(objectGraph);
                        if (id != null)
                            relatedId = id.ToString();
                    }

                    if (linkMapping.InclusionRule != ResourceInclusionRules.ForceOmit)
                    {
                        // Generating resource linkage for to-one relationships
                        if (relatedInstance != null)
                            rel.Data = new SingleResourceIdentifier
                            {
                                Id = relatedId,
                                Type = configuration.GetMapping(relatedInstance.GetType()).ResourceType // This allows polymorphic (subtyped) resources to be fully represented
                            };
                        else if (relatedId == null || linkMapping.InclusionRule == ResourceInclusionRules.ForceInclude)
                            rel.Data = new NullResourceIdentifier(); // two-state null case, see NullResourceIdentifier summary
                    }
                }
                else
                {
                    IEnumerable relatedInstance = null;
                    if (linkMapping.RelatedResource != null)
                        relatedInstance = (IEnumerable)linkMapping.RelatedResource(objectGraph);

                    // Generating resource linkage for to-many relationships
                    if (linkMapping.InclusionRule == ResourceInclusionRules.ForceInclude && relatedInstance == null)
                        rel.Data = new MultipleResourceIdentifiers();
                    if (linkMapping.InclusionRule != ResourceInclusionRules.ForceOmit && relatedInstance != null)
                    {
                        var idGetter = linkMapping.ResourceMapping.IdGetter;
                        var identifiers = relatedInstance
                            .Cast<object>()
                            .Select(o => new SingleResourceIdentifier
                            {
                                Id = idGetter(o).ToString(),
                                Type = configuration.GetMapping(o.GetType()).ResourceType // This allows polymorphic (subtyped) resources to be fully represented
                            });
                        rel.Data = new MultipleResourceIdentifiers(identifiers);
                    }

                    // If data is present, count meta attribute is added for convenience
                    if (rel.Data != null)
                        rel.Meta = new Dictionary<string, string> { { MetaCountAttribute, ((MultipleResourceIdentifiers)rel.Data).Count.ToString() } };
                }

                if (relLinks.Self != null || relLinks.Related != null)
                    rel.Links = relLinks;

                if (rel.Data != null || rel.Links != null)
                    relationships.Add(relationshipName, rel);
            }
            return relationships.Any() ? relationships : null;
        }
Ejemplo n.º 27
0
        public List <SingleResource> CreateIncludedRepresentations(List <object> primaryResourceList, IResourceMapping resourceMapping, Context context)
        {
            var includedList = new List <SingleResource>();

            var primaryResourceIdentifiers = primaryResourceList.Select(x =>
            {
                var id = new SingleResourceIdentifier
                {
                    Id       = resourceMapping.IdGetter(x).ToString(),
                    Type     = resourceMapping.ResourceType,
                    MetaData = GetRelationshipMetadata(x)
                };

                return(id);
            });

            var alreadyVisitedObjects = new HashSet <SingleResourceIdentifier>(primaryResourceIdentifiers, new SingleResourceIdentifierComparer());

            foreach (var resource in primaryResourceList)
            {
                includedList.AddRange(
                    AppendIncludedRepresentationRecursive(
                        resource,
                        resourceMapping,
                        alreadyVisitedObjects,
                        context));
            }

            if (includedList.Any())
            {
                return(includedList);
            }
            return(null);
        }
Ejemplo n.º 28
0
        public static List <SingleResource> CreateIncludedRepresentations(List <object> primaryResourceList, IResourceMapping resourceMapping, Context context)
        {
            var includedList          = new List <SingleResource>();
            var alreadyVisitedObjects = new HashSet <object>(primaryResourceList);

            foreach (var resource in primaryResourceList)
            {
                AppendIncludedRepresentationRecursive(resource, resourceMapping, includedList, alreadyVisitedObjects, context);
            }

            return(includedList);
        }
        public SingleResource CreateResourceRepresentation(object objectGraph, IResourceMapping resourceMapping, Context context, bool isIncludedResource = false, Type ownerType = null)
        {
            var urlBuilder = new UrlBuilder
            {
                RoutePrefix = context.RoutePrefix
            };

            var result = new SingleResource();

            result.Id = resourceMapping.IdGetter(objectGraph).ToString();
            result.Type = resourceMapping.ResourceType;

            result.Attributes = resourceMapping.PropertyGetters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value(objectGraph));

            if (resourceMapping.UrlTemplate != null)
            {
                result.Links = CreateLinks(resourceMapping, urlBuilder, result, _parentId);
            }

            if (resourceMapping.Relationships.Any())
                result.Relationships = CreateRelationships(objectGraph, result.Id, resourceMapping, context, result.Type);

            if (resourceMapping.PipelineModule != null)
            {
                resourceMapping.PipelineModule.Run(resourceMapping.ResourceRepresentationType, result, isIncludedResource, resourceMapping.RequestedFields);
            }

            result.OwnerType = ownerType;

            return result;
        }
        private IDictionary <string, Relationship> GenerateRelationships(object instance, IResourceMapping mapping)
        {
            var relationNames = mapping.GetRelationNames().ToList();

            if (!relationNames.Any())
            {
                return(null);
            }

            var relationships = new Dictionary <string, Relationship>();

            foreach (var relationName in relationNames)
            {
                var relationTypeName = _configuration.ResourceConfigurations[mapping.GetResourceTypeOfRelation(relationName)]?.TypeName;
                if (relationTypeName == null)
                {
                    throw new JsonApiException(CausedBy.Server, $"Resource type for relation {relationName} is not configured");
                }

                var value = mapping.GetRelationValue(instance, relationName);
                if (value == null)
                {
                    return(null);
                }

                if (value is Guid)
                {
                    relationships.Add(relationName, new Relationship(relationTypeName, (Guid)value));
                }
                else if (value is IEnumerable <Guid> )
                {
                    relationships.Add(relationName, new Relationship(relationTypeName, (IEnumerable <Guid>)value));
                }
            }

            return(relationships);
        }
Ejemplo n.º 31
0
 public void AddMapping(IResourceMapping resourceMapping)
 {
     resourcesMappingsByResourceType[resourceMapping.ResourceType]       = resourceMapping;
     resourcesMappingsByType[resourceMapping.ResourceRepresentationType] = resourceMapping;
 }
Ejemplo n.º 32
0
        public static Dictionary <string, IRelationship> CreateRelationships(object objectGraph, string parentId, IResourceMapping resourceMapping, Context context)
        {
            var relationships = new Dictionary <string, IRelationship>();

            foreach (var linkMapping in resourceMapping.Relationships)
            {
                var relationshipName = linkMapping.RelationshipName;
                var rel      = new Relationship();
                var relLinks = new RelationshipLinks();

                // Generating "self" link
                if (linkMapping.SelfUrlTemplate != null)
                {
                    relLinks.Self = GetUrlFromTemplate(context, linkMapping.SelfUrlTemplate, parentId);
                }

                if (!linkMapping.IsCollection)
                {
                    string relatedId       = null;
                    object relatedInstance = null;
                    if (linkMapping.RelatedResource != null)
                    {
                        relatedInstance = linkMapping.RelatedResource(objectGraph);
                        if (relatedInstance != null)
                        {
                            relatedId = linkMapping.ResourceMapping.IdGetter(relatedInstance).ToString();
                        }
                    }
                    if (linkMapping.RelatedResourceId != null && relatedId == null)
                    {
                        var id = linkMapping.RelatedResourceId(objectGraph);
                        if (id != null)
                        {
                            relatedId = id.ToString();
                        }
                    }

                    // Generating "related" link for to-one relationships
                    if (linkMapping.RelatedUrlTemplate != null && relatedId != null)
                    {
                        relLinks.Related = GetUrlFromTemplate(context, linkMapping.RelatedUrlTemplate, parentId, relatedId.ToString());
                    }


                    if (linkMapping.InclusionRule != ResourceInclusionRules.ForceOmit)
                    {
                        // Generating resource linkage for to-one relationships
                        if (relatedInstance != null)
                        {
                            rel.Data = new SingleResourceIdentifier
                            {
                                Id   = relatedId,
                                Type = context.Configuration.GetMapping(relatedInstance.GetType()).ResourceType // This allows polymorphic (subtyped) resources to be fully represented
                            }
                        }
                        ;
                        else if (relatedId == null || linkMapping.InclusionRule == ResourceInclusionRules.ForceInclude)
                        {
                            rel.Data = new NullResourceIdentifier(); // two-state null case, see NullResourceIdentifier summary
                        }
                    }
                }
                else
                {
                    // Generating "related" link for to-many relationships
                    if (linkMapping.RelatedUrlTemplate != null)
                    {
                        relLinks.Related = GetUrlFromTemplate(context, linkMapping.RelatedUrlTemplate, parentId);
                    }

                    IEnumerable relatedInstance = null;
                    if (linkMapping.RelatedResource != null)
                    {
                        relatedInstance = (IEnumerable)linkMapping.RelatedResource(objectGraph);
                    }

                    // Generating resource linkage for to-many relationships
                    if (linkMapping.InclusionRule == ResourceInclusionRules.ForceInclude && relatedInstance == null)
                    {
                        rel.Data = new MultipleResourceIdentifiers();
                    }
                    if (linkMapping.InclusionRule != ResourceInclusionRules.ForceOmit && relatedInstance != null)
                    {
                        var idGetter    = linkMapping.ResourceMapping.IdGetter;
                        var identifiers = relatedInstance
                                          .Cast <object>()
                                          .Select(o => new SingleResourceIdentifier
                        {
                            Id   = idGetter(o).ToString(),
                            Type = context.Configuration.GetMapping(o.GetType()).ResourceType     // This allows polymorphic (subtyped) resources to be fully represented
                        });
                        rel.Data = new MultipleResourceIdentifiers(identifiers);
                    }

                    // If data is present, count meta attribute is added for convenience
                    if (rel.Data != null)
                    {
                        rel.Meta = new Dictionary <string, string> {
                            { MetaCountAttribute, ((MultipleResourceIdentifiers)rel.Data).Count.ToString() }
                        }
                    }
                    ;
                }

                if (relLinks.Self != null || relLinks.Related != null)
                {
                    rel.Links = relLinks;
                }

                if (rel.Data != null || rel.Links != null)
                {
                    relationships.Add(relationshipName, rel);
                }
            }
            return(relationships.Any() ? relationships : null);
        }
 private static Dictionary<string, ILink> CreateLinks(IResourceMapping resourceMapping, UrlBuilder urlBuilder, SingleResource result, string parentId = null)
 {
     return new Dictionary<string, ILink>() { { SelfLinkKey, new SimpleLink { Href = urlBuilder.GetFullyQualifiedUrl(resourceMapping.UrlTemplate.Replace(TypePlaceholder, result.Type).Replace(IdPlaceholder, result.Id).Replace(ParentIdPlaceholder, parentId)) } } };
 }
 public void AddMapping(IResourceMapping resourceMapping)
 {
     resourcesMappingsByResourceType[resourceMapping.ResourceType] = resourceMapping;
     resourcesMappingsByType[resourceMapping.ResourceRepresentationType] = resourceMapping;
 }
Ejemplo n.º 35
0
        public SingleResource CreateResourceRepresentation(object objectGraph, IResourceMapping resourceMapping, Context context)
        {
            var urlBuilder = new UrlBuilder
            {
                RoutePrefix = context.RoutePrefix
            };

            var result = new SingleResource();

            result.Id = resourceMapping.IdGetter(objectGraph).ToString();
            result.Type = resourceMapping.ResourceType;

            result.Attributes = resourceMapping.PropertyGetters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value(objectGraph));

            if (resourceMapping.UrlTemplate != null)
                result.Links = CreateLinks(resourceMapping, urlBuilder, result);

            if (resourceMapping.Relationships.Any())
                result.Relationships = CreateRelationships(objectGraph, result.Id, resourceMapping, context);

            return result;
        }