private object SetHasOneRelationship(object entity, PropertyInfo[] entityProperties, HasOneAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships, List <DocumentData> included = null) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData) == false) { return(entity); } var rio = (ResourceIdentifierObject)relationshipData.ExposedData; var foreignKey = attr.IdentifiablePropertyName; var foreignKeyProperty = entityProperties.FirstOrDefault(p => p.Name == foreignKey); if (foreignKeyProperty == null && rio == null) { return(entity); } SetHasOneForeignKeyValue(entity, attr, foreignKeyProperty, rio); SetHasOneNavigationPropertyValue(entity, attr, rio, included); return(entity); }
/// <summary> /// Sets a HasOne relationship on a parsed entity. If present, also /// populates the foreign key. /// </summary> /// <param name="entity"></param> /// <param name="entityProperties"></param> /// <param name="attr"></param> /// <param name="relationshipData"></param> /// <returns></returns> private object SetHasOneRelationship(IIdentifiable entity, PropertyInfo[] entityProperties, HasOneAttribute attr, RelationshipEntry relationshipData) { var rio = (ResourceIdentifierObject)relationshipData.Data; var relatedId = rio?.Id ?? null; // this does not make sense in the following case: if we're setting the dependent of a one-to-one relationship, IdentifiablePropertyName should be null. var foreignKeyProperty = entityProperties.FirstOrDefault(p => p.Name == attr.IdentifiablePropertyName); if (foreignKeyProperty != null) { /// there is a FK from the current entity pointing to the related object, /// i.e. we're populating the relationship from the dependent side. SetForeignKey(entity, foreignKeyProperty, attr, relatedId); } SetNavigation(entity, attr, relatedId); /// depending on if this base parser is used client-side or server-side, /// different additional processing per field needs to be executed. AfterProcessField(entity, attr, relationshipData); return(entity); }
public RelationshipDictionaryTests() { FirstToOneAttr = new HasOneAttribute("firstToOne") { LeftType = typeof(Dummy), RightType = typeof(ToOne), PropertyInfo = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; SecondToOneAttr = new HasOneAttribute("secondToOne") { LeftType = typeof(Dummy), RightType = typeof(ToOne), PropertyInfo = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; ToManyAttr = new HasManyAttribute("toManies") { LeftType = typeof(Dummy), RightType = typeof(ToMany), PropertyInfo = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; Relationships.Add(FirstToOneAttr, FirstToOnesEntities); Relationships.Add(SecondToOneAttr, SecondToOnesEntities); Relationships.Add(ToManyAttr, ToManiesEntities); AllEntities = new HashSet <Dummy>(FirstToOnesEntities.Union(SecondToOnesEntities).Union(ToManiesEntities).Union(NoRelationshipsEntities)); }
/// <summary> /// Sets a HasOne relationship on a parsed resource. If present, also /// populates the foreign key. /// </summary> private void SetHasOneRelationship(IIdentifiable resource, PropertyInfo[] resourceProperties, HasOneAttribute attr, RelationshipEntry relationshipData) { var rio = (ResourceIdentifierObject)relationshipData.Data; var relatedId = rio?.Id; var relationshipType = relationshipData.SingleData == null ? attr.RightType : ResourceContextProvider.GetResourceContext(relationshipData.SingleData.Type).ResourceType; // this does not make sense in the following case: if we're setting the dependent of a one-to-one relationship, IdentifiablePropertyName should be null. var foreignKeyProperty = resourceProperties.FirstOrDefault(p => p.Name == attr.IdentifiablePropertyName); if (foreignKeyProperty != null) { // there is a FK from the current resource pointing to the related object, // i.e. we're populating the relationship from the dependent side. SetForeignKey(resource, foreignKeyProperty, attr, relatedId, relationshipType); } SetNavigation(resource, attr, relatedId, relationshipType); // depending on if this base parser is used client-side or server-side, // different additional processing per field needs to be executed. AfterProcessField(resource, attr, relationshipData); }
public RelationshipDictionaryTests() { _firstToOneAttr = new HasOneAttribute { PublicName = "firstToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; _secondToOneAttr = new HasOneAttribute { PublicName = "secondToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; _toManyAttr = new HasManyAttribute { PublicName = "toManies", LeftType = typeof(Dummy), RightType = typeof(ToMany), Property = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; _relationships.Add(_firstToOneAttr, _firstToOnesResources); _relationships.Add(_secondToOneAttr, _secondToOnesResources); _relationships.Add(_toManyAttr, _toManiesResources); _allResources = new HashSet <Dummy>(_firstToOnesResources.Union(_secondToOnesResources).Union(_toManiesResources).Union(_noRelationshipsResources)); }
public void HasOneAttribute_Equals_Returns_False_When_Different_Name() { var a = new HasOneAttribute("test"); var b = new HasOneAttribute("test2"); Assert.NotEqual(a, b); }
public void Applies_cascading_settings_for_relationship_links(LinkTypes linksInRelationshipAttribute, LinkTypes linksInResourceContext, LinkTypes linksInOptions, LinkTypes expected) { // Arrange var exampleResourceContext = new ResourceContext { PublicName = nameof(ExampleResource), ResourceType = typeof(ExampleResource), RelationshipLinks = linksInResourceContext }; var options = new JsonApiOptions { RelationshipLinks = linksInOptions }; var request = new JsonApiRequest(); var paginationContext = new PaginationContext(); var resourceGraph = new ResourceGraph(exampleResourceContext.AsArray()); var httpContextAccessor = new FakeHttpContextAccessor(); var linkGenerator = new FakeLinkGenerator(); var controllerResourceMapping = new FakeControllerResourceMapping(); var linkBuilder = new LinkBuilder(options, request, paginationContext, resourceGraph, httpContextAccessor, linkGenerator, controllerResourceMapping); var relationship = new HasOneAttribute { Links = linksInRelationshipAttribute }; // Act RelationshipLinks relationshipLinks = linkBuilder.GetRelationshipLinks(relationship, new ExampleResource()); // Assert if (expected == LinkTypes.None) { relationshipLinks.Should().BeNull(); } else { if (expected.HasFlag(LinkTypes.Self)) { relationshipLinks.Self.Should().NotBeNull(); } else { relationshipLinks.Self.Should().BeNull(); } if (expected.HasFlag(LinkTypes.Related)) { relationshipLinks.Related.Should().NotBeNull(); } else { relationshipLinks.Related.Should().BeNull(); } } }
public void HasOneAttribute_Equals_Returns_True_When_Same_Name() { var a = new HasOneAttribute("test"); var b = new HasOneAttribute("test"); Assert.Equal(a, b); }
private void SetHasOneForeignKeyValue(object entity, HasOneAttribute hasOneAttr, PropertyInfo foreignKeyProperty, ResourceIdentifierObject rio) { var foreignKeyPropertyValue = rio?.Id ?? null; if (foreignKeyProperty != null) { // in the case of the HasOne independent side of the relationship, we should still create the shell entity on the other side // we should not actually require the resource to have a foreign key (be the dependent side of the relationship) // e.g. PATCH /articles // {... { "relationships":{ "Owner": { "data": null } } } } bool foreignKeyPropertyIsNullableType = Nullable.GetUnderlyingType(foreignKeyProperty.PropertyType) != null || foreignKeyProperty.PropertyType == typeof(string); if (rio == null && !foreignKeyPropertyIsNullableType) { throw new JsonApiException(400, $"Cannot set required relationship identifier '{hasOneAttr.IdentifiablePropertyName}' to null because it is a non-nullable type."); } var convertedValue = TypeHelper.ConvertType(foreignKeyPropertyValue, foreignKeyProperty.PropertyType); /// todo: as a part of the process of decoupling JADNC (specifically /// through the decoupling IJsonApiContext), we now no longer need to /// store the updated relationship values in this property. For now /// just assigning null as value, will remove this property later as a whole. /// see #512 if (convertedValue == null) { _jsonApiContext.HasOneRelationshipPointers.Add(hasOneAttr, null); } } }
public RelationshipDictionaryTests() { FirstToOneAttr = new HasOneAttribute { PublicName = "firstToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; SecondToOneAttr = new HasOneAttribute { PublicName = "secondToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; ToManyAttr = new HasManyAttribute { PublicName = "toManies", LeftType = typeof(Dummy), RightType = typeof(ToMany), Property = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; Relationships.Add(FirstToOneAttr, FirstToOnesResources); Relationships.Add(SecondToOneAttr, SecondToOnesResources); Relationships.Add(ToManyAttr, ToManiesResources); AllResources = new HashSet <Dummy>(FirstToOnesResources.Union(SecondToOnesResources).Union(ToManiesResources).Union(NoRelationshipsResources)); }
public void BuildRelationshipLinks_GlobalResourceAndAttrConfiguration_ExpectedLinks(Link global, Link resource, Link relationship, object expectedSelfLink, object expectedRelatedLink) { // Arrange var config = GetConfiguration(relationshipLinks: global); var primaryResource = GetArticleResourceContext(relationshipLinks: resource); _provider.Setup(m => m.GetResourceContext(typeof(Article))).Returns(primaryResource); var builder = new LinkBuilder(config, GetRequestManager(), null, _provider.Object, _queryStringAccessor); var attr = new HasOneAttribute(links: relationship) { RightType = typeof(Author), PublicRelationshipName = "author" }; // Act var links = builder.GetRelationshipLinks(attr, new Article { Id = _baseId }); // Assert if (expectedSelfLink == null && expectedRelatedLink == null) { Assert.Null(links); } else { Assert.Equal(expectedSelfLink, links.Self); Assert.Equal(expectedRelatedLink, links.Related); } }
public RelationshipDictionaryTests() { FirstToOneAttr = new HasOneAttribute("first-to-one") { PrincipalType = typeof(Dummy), DependentType = typeof(ToOne), InternalRelationshipName = "FirstToOne" }; SecondToOneAttr = new HasOneAttribute("second-to-one") { PrincipalType = typeof(Dummy), DependentType = typeof(ToOne), InternalRelationshipName = "SecondToOne" }; ToManyAttr = new HasManyAttribute("to-manies") { PrincipalType = typeof(Dummy), DependentType = typeof(ToMany), InternalRelationshipName = "ToManies" }; Relationships.Add(FirstToOneAttr, FirstToOnesEntities); Relationships.Add(SecondToOneAttr, SecondToOnesEntities); Relationships.Add(ToManyAttr, ToManiesEntities); AllEntities = new HashSet <Dummy>(FirstToOnesEntities.Union(SecondToOnesEntities).Union(ToManiesEntities).Union(NoRelationshipsEntities)); }
public void HasManyAttribute_Does_Not_Equal_HasOneAttribute_With_Same_Name() { RelationshipAttribute a = new HasManyAttribute("test"); RelationshipAttribute b = new HasOneAttribute("test"); Assert.NotEqual(a, b); Assert.NotEqual(b, a); }
/// <summary> /// Builds a <see cref="ResourceIdentifierObject"/> for a HasOne relationship. /// </summary> private ResourceIdentifierObject GetRelatedResourceLinkageForHasOne(HasOneAttribute relationship, IIdentifiable resource) { var relatedResource = (IIdentifiable)relationship.GetValue(resource); if (relatedResource != null) { return(GetResourceIdentifier(relatedResource)); } return(null); }
/// <summary> /// Checks if the to-one relationship is required by checking if the foreign key is nullable. /// </summary> private bool IsRequiredToOneRelationship(HasOneAttribute attr, IIdentifiable entity) { var foreignKey = entity.GetType().GetProperty(attr.IdentifiablePropertyName); if (foreignKey != null && Nullable.GetUnderlyingType(foreignKey.PropertyType) == null) { return(true); } return(false); }
private object SetHasOneRelationship(object entity, PropertyInfo[] entityProperties, HasOneAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships, List <ResourceObject> included = null, List <string> includePaths = null) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData) == false) { return(entity); } var rio = (ResourceIdentifierObject)relationshipData.ExposedData; var foreignKey = attr.IdentifiablePropertyName; var foreignKeyProperty = entityProperties.FirstOrDefault(p => p.Name == foreignKey); if (foreignKeyProperty == null && rio == null) { return(entity); } SetHasOneForeignKeyValue(entity, attr, foreignKeyProperty, rio); SetHasOneNavigationPropertyValue(entity, attr, rio, included); // recursive call ... if (included != null) { var navigationPropertyValue = attr.GetValue(entity); var resourceGraphEntity = _jsonApiContext.ResourceGraph.GetContextEntity(attr.DependentType); if (navigationPropertyValue != null && resourceGraphEntity != null) { var includedResource = included.SingleOrDefault(r => r.Type == rio.Type && r.Id == rio.Id); if (includedResource != null) { var paths = includePaths?.Select(x => { var tmp = x.Split('.').ToList(); tmp.RemoveAt(0); return(string.Join(".", tmp)); }).ToList(); SetRelationships(navigationPropertyValue, resourceGraphEntity, includedResource.Relationships, included, paths); } } } return(entity); }
/// <summary> /// Sets the principal side of a HasOne relationship, which means no /// foreign key is involved /// </summary> private void SetNavigation(IIdentifiable entity, HasOneAttribute attr, string relatedId) { if (relatedId == null) { attr.SetValue(entity, null); } else { var relatedInstance = attr.RightType.New <IIdentifiable>(); relatedInstance.StringId = relatedId; attr.SetValue(entity, relatedInstance); } }
/// <summary> /// Sets the principal side of a HasOne relationship, which means no /// foreign key is involved /// </summary> private void SetNavigation(IIdentifiable entity, HasOneAttribute attr, string relatedId) { if (relatedId == null) { attr.SetValue(entity, null, _resourceFactory); } else { var relatedInstance = (IIdentifiable)_resourceFactory.CreateInstance(attr.RightType); relatedInstance.StringId = relatedId; attr.SetValue(entity, relatedInstance, _resourceFactory); } }
public void HasOneAttribute_Equals_Returns_True_When_Same_Name() { var attribute1 = new HasOneAttribute { PublicName = "test" }; var attribute2 = new HasOneAttribute { PublicName = "test" }; Assert.Equal(attribute1, attribute2); }
public void HasOneAttribute_Equals_Returns_False_When_Different_Name() { var attribute1 = new HasOneAttribute { PublicName = "test" }; var attribute2 = new HasOneAttribute { PublicName = "test2" }; Assert.NotEqual(attribute1, attribute2); }
/// <summary> /// Sets the principal side of a HasOne relationship, which means no /// foreign key is involved. /// </summary> private void SetNavigation(IIdentifiable resource, HasOneAttribute attr, string relatedId, Type relationshipType) { if (relatedId == null) { attr.SetValue(resource, null, ResourceFactory); } else { var relatedInstance = (IIdentifiable)ResourceFactory.CreateInstance(relationshipType); relatedInstance.StringId = relatedId; attr.SetValue(resource, relatedInstance, ResourceFactory); } }
public void HasManyAttribute_Does_Not_Equal_HasOneAttribute_With_Same_Name() { RelationshipAttribute attribute1 = new HasManyAttribute { PublicName = "test" }; RelationshipAttribute attribute2 = new HasOneAttribute { PublicName = "test" }; Assert.NotEqual(attribute1, attribute2); Assert.NotEqual(attribute2, attribute1); }
/// <summary> /// Sets the dependent side of a HasOne relationship, which means that a /// foreign key also will to be populated. /// </summary> private void SetForeignKey(IIdentifiable entity, PropertyInfo foreignKey, HasOneAttribute attr, string id) { bool foreignKeyPropertyIsNullableType = Nullable.GetUnderlyingType(foreignKey.PropertyType) != null || foreignKey.PropertyType == typeof(string); if (id == null && !foreignKeyPropertyIsNullableType) { // this happens when a non-optional relationship is deliberatedly set to null. // For a server deserializer, it should be mapped to a BadRequest HTTP error code. throw new FormatException($"Cannot set required relationship identifier '{attr.IdentifiablePropertyName}' to null because it is a non-nullable type."); } var convertedId = TypeHelper.ConvertType(id, foreignKey.PropertyType); foreignKey.SetValue(entity, convertedId); }
/// <summary> /// Builds a <see cref="ResourceIdentifierObject"/> for a HasOne relationship /// </summary> private ResourceIdentifierObject GetRelatedResourceLinkage(HasOneAttribute relationship, IIdentifiable entity) { var relatedEntity = (IIdentifiable)relationship.GetValue(entity); if (relatedEntity == null && IsRequiredToOneRelationship(relationship, entity)) { throw new NotSupportedException("Cannot serialize a required to one relationship that is not populated but was included in the set of relationships to be serialized."); } if (relatedEntity != null) { return(GetResourceIdentifier(relatedEntity)); } return(null); }
/// <summary> /// Sets a HasOne relationship on a parsed resource. /// </summary> private void SetHasOneRelationship(IIdentifiable resource, HasOneAttribute hasOneRelationship, RelationshipEntry relationshipData) { if (relationshipData.ManyData != null) { throw new JsonApiSerializationException("Expected single data element for to-one relationship.", $"Expected single data element for '{hasOneRelationship.PublicName}' relationship."); } var rightResource = CreateRightResource(hasOneRelationship, relationshipData.SingleData); hasOneRelationship.SetValue(resource, rightResource); // depending on if this base parser is used client-side or server-side, // different additional processing per field needs to be executed. AfterProcessField(resource, hasOneRelationship, relationshipData); }
private object SetHasOneRelationship(object entity, PropertyInfo[] entityProperties, HasOneAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData)) { var relationshipAttr = _jsonApiContext.RequestEntity.Relationships .SingleOrDefault(r => r.PublicRelationshipName == relationshipName); if (relationshipAttr == null) { throw new JsonApiException(400, $"{_jsonApiContext.RequestEntity.EntityName} does not contain a relationship '{relationshipName}'"); } var rio = (ResourceIdentifierObject)relationshipData.ExposedData; var foreignKey = attr.IdentifiablePropertyName; var entityProperty = entityProperties.FirstOrDefault(p => p.Name == foreignKey); if (entityProperty == null && rio != null) { throw new JsonApiException(400, $"{contextEntity.EntityType.Name} does not contain a foreign key property '{foreignKey}' for has one relationship '{attr.InternalRelationshipName}'"); } if (entityProperty != null) { // e.g. PATCH /articles // {... { "relationships":{ "Owner": { "data" :null } } } } if (rio == null && Nullable.GetUnderlyingType(entityProperty.PropertyType) == null) { throw new JsonApiException(400, $"Cannot set required relationship identifier '{attr.IdentifiablePropertyName}' to null."); } var newValue = rio?.Id ?? null; var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType); _jsonApiContext.RelationshipsToUpdate[relationshipAttr] = convertedValue; entityProperty.SetValue(entity, convertedValue); } } return(entity); }
private object SetHasOneRelationship(object entity, PropertyInfo[] entityProperties, HasOneAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships, List <ResourceObject> included = null) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData) == false) { return(entity); } var rio = (ResourceIdentifierObject)relationshipData.ExposedData; var foreignKey = attr.IdentifiablePropertyName; var foreignKeyProperty = entityProperties.FirstOrDefault(p => p.Name == foreignKey); if (foreignKeyProperty == null && rio == null) { return(entity); } SetHasOneForeignKeyValue(entity, attr, foreignKeyProperty, rio); SetHasOneNavigationPropertyValue(entity, attr, rio, included); // recursive call ... if (included != null) { var navigationPropertyValue = attr.GetValue(entity); var contextGraphEntity = _jsonApiContext.ContextGraph.GetContextEntity(attr.Type); if (navigationPropertyValue != null && contextGraphEntity != null) { var includedResource = included.SingleOrDefault(r => r.Type == rio.Type && r.Id == rio.Id); if (includedResource != null) { SetRelationships(navigationPropertyValue, contextGraphEntity, includedResource.Relationships, included); } } } return(entity); }
/// <summary> /// Sets the value of the navigation property for the related resource. /// If the resource has been included, all attributes will be set. /// If the resource has not been included, only the id will be set. /// </summary> private void SetHasOneNavigationPropertyValue(object entity, HasOneAttribute hasOneAttr, ResourceIdentifierObject rio, List <DocumentData> included) { // if the resource identifier is null, there should be no reason to instantiate an instance if (rio != null && rio.Id != null) { // we have now set the FK property on the resource, now we need to check to see if the // related entity was included in the payload and update its attributes var includedRelationshipObject = GetIncludedRelationship(rio, included, hasOneAttr); if (includedRelationshipObject != null) { hasOneAttr.SetValue(entity, includedRelationshipObject); } // we need to store the fact that this relationship was included in the payload // for EF, the repository will use these pointers to make ensure we don't try to // create resources if they already exist, we just need to create the relationship _jsonApiContext.HasOneRelationshipPointers.Add(hasOneAttr, includedRelationshipObject); } }
private object SetHasOneRelationship(object entity, PropertyInfo[] entityProperties, HasOneAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData)) { var relationshipAttr = _jsonApiContext.RequestEntity.Relationships .SingleOrDefault(r => r.PublicRelationshipName == relationshipName); if (relationshipAttr == null) { throw new JsonApiException(400, $"{_jsonApiContext.RequestEntity.EntityName} does not contain a relationship '{relationshipName}'"); } var rio = (ResourceIdentifierObject)relationshipData.ExposedData; if (rio == null) { return(entity); } var newValue = rio.Id; var foreignKey = attr.IdentifiablePropertyName; var entityProperty = entityProperties.FirstOrDefault(p => p.Name == foreignKey); if (entityProperty == null) { throw new JsonApiException(400, $"{contextEntity.EntityType.Name} does not contain a foreign key property '{foreignKey}' for has one relationship '{attr.InternalRelationshipName}'"); } var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType); _jsonApiContext.RelationshipsToUpdate[relationshipAttr] = convertedValue; entityProperty.SetValue(entity, convertedValue); } return(entity); }
private void SetHasOneForeignKeyValue(object entity, HasOneAttribute hasOneAttr, PropertyInfo foreignKeyProperty, ResourceIdentifierObject rio) { var foreignKeyPropertyValue = rio?.Id ?? null; if (foreignKeyProperty != null) { // in the case of the HasOne independent side of the relationship, we should still create the shell entity on the other side // we should not actually require the resource to have a foreign key (be the dependent side of the relationship) // e.g. PATCH /articles // {... { "relationships":{ "Owner": { "data": null } } } } if (rio == null && Nullable.GetUnderlyingType(foreignKeyProperty.PropertyType) == null) { throw new JsonApiException(400, $"Cannot set required relationship identifier '{hasOneAttr.IdentifiablePropertyName}' to null because it is a non-nullable type."); } var convertedValue = TypeHelper.ConvertType(foreignKeyPropertyValue, foreignKeyProperty.PropertyType); foreignKeyProperty.SetValue(entity, convertedValue); _jsonApiContext.RelationshipsToUpdate[hasOneAttr] = convertedValue; } }