public Task <IResourceLinkage> Deserialize(JsonReader reader, string currentPath) { IResourceLinkage linkage; if (reader.TokenType == JsonToken.StartArray) { var array = JToken.ReadFrom(reader); var resourceIdentifiers = array.Select(t => ReadResourceIdentifier(t, currentPath)).ToArray(); linkage = new ToManyResourceLinkage(resourceIdentifiers); } else if (reader.TokenType == JsonToken.StartObject) { var obj = JToken.ReadFrom(reader); var resourceIdentifier = ReadResourceIdentifier(obj, currentPath); linkage = new ToOneResourceLinkage(resourceIdentifier); } else if (reader.TokenType == JsonToken.Null) { linkage = new ToOneResourceLinkage(null); } else { throw new DeserializationException("Invalid linkage for relationship", "Expected an array, object, or null for linkage, but got " + reader.TokenType, currentPath); } return(Task.FromResult(linkage)); }
public void Identifiers_is_correct_for_present_identifiers() { var mockIdentifier1 = new Mock <IResourceIdentifier>(MockBehavior.Strict); mockIdentifier1.Setup(i => i.Type).Returns("countries"); mockIdentifier1.Setup(i => i.Id).Returns("1000"); var mockIdentifier2 = new Mock <IResourceIdentifier>(MockBehavior.Strict); mockIdentifier2.Setup(i => i.Type).Returns("cities"); mockIdentifier2.Setup(i => i.Id).Returns("4000"); var linkage = new ToManyResourceLinkage(new [] { mockIdentifier1.Object, mockIdentifier2.Object }); linkage.Identifiers.Length.Should().Be(2); linkage.Identifiers[0].Type.Should().Be("countries"); linkage.Identifiers[0].Id.Should().Be("1000"); linkage.Identifiers[1].Type.Should().Be("cities"); linkage.Identifiers[1].Id.Should().Be("4000"); }
/// <summary> /// Creates a JSON API resource object from the given CLR object /// </summary> /// <param name="modelObject"></param> /// <param name="idDictionariesByType"></param> /// <param name="currentPath"></param> /// <param name="includePathExpressions"></param> /// <param name="linkBaseUrl"></param> /// <returns></returns> protected ResourceObject CreateResourceObject(object modelObject, IDictionary<string, IDictionary<string, ResourceObject>> idDictionariesByType, string currentPath, string[] includePathExpressions, string linkBaseUrl) { if (modelObject == null) return null; var modelObjectRuntimeType = modelObject.GetType(); var resourceTypeRegistration = _resourceTypeRegistry.GetRegistrationForType(modelObjectRuntimeType); var attributes = new Dictionary<string, JToken>(); var relationships = new Dictionary<string, IRelationshipObject>(); foreach (var attribute in resourceTypeRegistration.Attributes) { var propertyValue = attribute.GetValue(modelObject); attributes[attribute.JsonKey] = propertyValue; } foreach (var modelRelationship in resourceTypeRegistration.Relationships) { IResourceLinkage linkage = null; var childPath = currentPath == null ? modelRelationship.JsonKey : (currentPath + "." + modelRelationship.JsonKey); if (includePathExpressions != null && includePathExpressions.Any(e => PathExpressionMatchesCurrentPath(childPath, e))) { if (modelRelationship.IsToMany) { var propertyValue = (IEnumerable<object>)modelRelationship.Property.GetValue(modelObject); if (propertyValue != null) { var identifiers = new List<IResourceIdentifier>(); foreach (var relatedResource in propertyValue) { var identifier = GetResourceIdentifierForResource(relatedResource); identifiers.Add(identifier); IDictionary<string, ResourceObject> idDictionary; if (!idDictionariesByType.TryGetValue(identifier.Type, out idDictionary)) { idDictionary = new Dictionary<string, ResourceObject>(); idDictionariesByType[identifier.Type] = idDictionary; } ResourceObject relatedResourceObject; if (!idDictionary.TryGetValue(identifier.Id, out relatedResourceObject)) { relatedResourceObject = CreateResourceObject(relatedResource, idDictionariesByType, childPath, includePathExpressions, linkBaseUrl); idDictionary[identifier.Id] = relatedResourceObject; } } linkage = new ToManyResourceLinkage(identifiers.ToArray()); } } else { var relatedResource = modelRelationship.Property.GetValue(modelObject); if (relatedResource != null) { var identifier = GetResourceIdentifierForResource(relatedResource); IDictionary<string, ResourceObject> idDictionary; if (!idDictionariesByType.TryGetValue(identifier.Type, out idDictionary)) { idDictionary = new Dictionary<string, ResourceObject>(); idDictionariesByType[identifier.Type] = idDictionary; } ResourceObject relatedResourceObject; if (!idDictionary.TryGetValue(identifier.Id, out relatedResourceObject)) { relatedResourceObject = CreateResourceObject(relatedResource, idDictionariesByType, childPath, includePathExpressions, linkBaseUrl); idDictionary[identifier.Id] = relatedResourceObject; } linkage = new ToOneResourceLinkage(identifier); } else { linkage = new ToOneResourceLinkage(null); } } } var selfLink = _linkConventions.GetRelationshipLink(modelObject, _resourceTypeRegistry, modelRelationship, linkBaseUrl); var relatedResourceLink = _linkConventions.GetRelatedResourceLink(modelObject, _resourceTypeRegistry, modelRelationship, linkBaseUrl); relationships[modelRelationship.JsonKey] = new RelationshipObject(linkage, selfLink, relatedResourceLink); } var resourceId = resourceTypeRegistration.GetIdForResource(modelObject); return new ResourceObject(resourceTypeRegistration.ResourceTypeName, resourceId, attributes, relationships); }
public void Returns_corrent_LinkageToken_for_empty_identifiers() { var linkage = new ToManyResourceLinkage(new IResourceIdentifier[] { }); linkage.Identifiers.Length.Should().Be(0); }
public void Returns_corrent_LinkageToken_for_null_identifiers() { var linkage = new ToManyResourceLinkage(null); linkage.Identifiers.Length.Should().Be(0); }
/// <summary> /// Creates a JSON API resource object from the given CLR object /// </summary> /// <param name="modelObject"></param> /// <param name="idDictionariesByType"></param> /// <param name="currentPath"></param> /// <param name="includePathExpressions"></param> /// <param name="linkBaseUrl"></param> /// <param name="resourceObjectMetadata"></param> /// <returns></returns> protected ResourceObject CreateResourceObject(object modelObject, IDictionary <string, IDictionary <string, ResourceObject> > idDictionariesByType, string currentPath, string[] includePathExpressions, string linkBaseUrl, IDictionary <object, IMetadata> resourceObjectMetadata) { if (modelObject == null) { return(null); } var modelObjectRuntimeType = modelObject.GetType(); var resourceTypeRegistration = _resourceTypeRegistry.GetRegistrationForType(modelObjectRuntimeType); var attributes = new Dictionary <string, JToken>(); var relationships = new Dictionary <string, IRelationshipObject>(); foreach (var attribute in resourceTypeRegistration.Attributes) { var propertyValue = attribute.GetValue(modelObject); attributes[attribute.JsonKey] = propertyValue; } foreach (var modelRelationship in resourceTypeRegistration.Relationships) { IResourceLinkage linkage = null; var childPath = currentPath == null ? modelRelationship.JsonKey : (currentPath + "." + modelRelationship.JsonKey); if (includePathExpressions != null && includePathExpressions.Any(e => PathExpressionMatchesCurrentPath(childPath, e))) { if (modelRelationship.IsToMany) { var propertyValue = (IEnumerable <object>)modelRelationship.Property.GetValue(modelObject); if (propertyValue != null) { var identifiers = new List <IResourceIdentifier>(); foreach (var relatedResource in propertyValue) { var identifier = GetResourceIdentifierForResource(relatedResource); identifiers.Add(identifier); IDictionary <string, ResourceObject> idDictionary; if (!idDictionariesByType.TryGetValue(identifier.Type, out idDictionary)) { idDictionary = new Dictionary <string, ResourceObject>(); idDictionariesByType[identifier.Type] = idDictionary; } ResourceObject relatedResourceObject; if (!idDictionary.TryGetValue(identifier.Id, out relatedResourceObject)) { relatedResourceObject = CreateResourceObject(relatedResource, idDictionariesByType, childPath, includePathExpressions, linkBaseUrl, resourceObjectMetadata); idDictionary[identifier.Id] = relatedResourceObject; } } linkage = new ToManyResourceLinkage(identifiers.ToArray()); } } else { var relatedResource = modelRelationship.Property.GetValue(modelObject); if (relatedResource != null) { var identifier = GetResourceIdentifierForResource(relatedResource); IDictionary <string, ResourceObject> idDictionary; if (!idDictionariesByType.TryGetValue(identifier.Type, out idDictionary)) { idDictionary = new Dictionary <string, ResourceObject>(); idDictionariesByType[identifier.Type] = idDictionary; } ResourceObject relatedResourceObject; if (!idDictionary.TryGetValue(identifier.Id, out relatedResourceObject)) { relatedResourceObject = CreateResourceObject(relatedResource, idDictionariesByType, childPath, includePathExpressions, linkBaseUrl, resourceObjectMetadata); idDictionary[identifier.Id] = relatedResourceObject; } linkage = new ToOneResourceLinkage(identifier); } else { linkage = new ToOneResourceLinkage(null); } } } var selfLink = _linkConventions.GetRelationshipLink(modelObject, _resourceTypeRegistry, modelRelationship, linkBaseUrl); var relatedResourceLink = _linkConventions.GetRelatedResourceLink(modelObject, _resourceTypeRegistry, modelRelationship, linkBaseUrl); relationships[modelRelationship.JsonKey] = new RelationshipObject(linkage, selfLink, relatedResourceLink); } var resourceId = resourceTypeRegistration.GetIdForResource(modelObject); IMetadata thisResourceObjectsMetadata; if (resourceObjectMetadata != null) { resourceObjectMetadata.TryGetValue(modelObject, out thisResourceObjectsMetadata); } else { thisResourceObjectsMetadata = null; } return(new ResourceObject(resourceTypeRegistration.ResourceTypeName, resourceId, attributes, relationships, metadata: thisResourceObjectsMetadata)); }