Skip to content

Commit

Permalink
Pass around context SemanticSchemaField field when processing embedde…
Browse files Browse the repository at this point in the history
…d fields to prevent mapping to schema fields outside the 'scope' of this embedded field if they happen to have the same name.
  • Loading branch information
willprice76 committed Jul 25, 2016
1 parent d5a4e0c commit f1b7f3b
Showing 1 changed file with 24 additions and 22 deletions.
46 changes: 24 additions & 22 deletions Sdl.Web.Tridion/Mapping/DefaultModelBuilder.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private PageModel CreatePageModel(IPage page, Localization localization)
}


protected virtual ViewModel CreateViewModel(MappingData mappingData)
protected virtual ViewModel CreateViewModel(MappingData mappingData, SemanticSchemaField contextSchemaField = null)
{
Type modelType = mappingData.TargetType; // TODO: why is this not a separate parameter?

Expand Down Expand Up @@ -394,10 +394,11 @@ protected virtual ViewModel CreateViewModel(MappingData mappingData)
{
foreach (SemanticProperty info in propertySemantics[pi.Name])
{
IField field = GetFieldFromSemantics(mappingData, info);
SemanticSchemaField schemaField = null;
IField field = GetFieldFromSemantics(mappingData, info, contextSchemaField, out schemaField);
if (field != null)
{
pi.SetValue(model, MapFieldValues(field, propertyType, multival, mappingData));
pi.SetValue(model, MapFieldValues(field, propertyType, multival, mappingData, schemaField));
xpmPropertyMetadata.Add(pi.Name, GetFieldXPath(field));
break;
}
Expand Down Expand Up @@ -484,8 +485,9 @@ protected virtual ViewModel CreateViewModel(MappingData mappingData)
return filtered;
}

private static IField GetFieldFromSemantics(MappingData mapData, SemanticProperty info)
private static IField GetFieldFromSemantics(MappingData mapData, SemanticProperty info, SemanticSchemaField contextSchemaField, out SemanticSchemaField matchingField)
{
matchingField = null;
KeyValuePair<string, string>? entityData = GetEntityData(info.Prefix, mapData.TargetEntitiesByPrefix, mapData.ParentDefaultPrefix);
if (entityData != null)
{
Expand All @@ -499,8 +501,8 @@ private static IField GetFieldFromSemantics(MappingData mapData, SemanticPropert
if (entity != null && mapData.SemanticSchema!=null)
{
FieldSemantics fieldSemantics = new FieldSemantics(prefix, entity, property);
// locate semantic schema field
SemanticSchemaField matchingField = mapData.SemanticSchema.FindFieldBySemantics(fieldSemantics);
// locate semantic schema field (using current context embedded field if available)
matchingField = contextSchemaField!=null ? contextSchemaField.FindFieldBySemantics(fieldSemantics) : mapData.SemanticSchema.FindFieldBySemantics(fieldSemantics);
if (matchingField != null)
{
return ExtractMatchedField(matchingField, (matchingField.IsMetadata && mapData.Meta!=null) ? mapData.Meta : mapData.Content, mapData.EmbedLevel);
Expand Down Expand Up @@ -565,7 +567,7 @@ private static IList CreateGenericList(Type listItemType)
}


private object MapFieldValues(IField field, Type modelType, bool multival, MappingData mapData)
private object MapFieldValues(IField field, Type modelType, bool multival, MappingData mapData, SemanticSchemaField contextSchemaField = null)
{
try
{
Expand Down Expand Up @@ -604,7 +606,7 @@ private object MapFieldValues(IField field, Type modelType, bool multival, Mappi
case FieldType.Embedded:
foreach (IFieldSet value in field.EmbeddedValues)
{
mappedValues.Add(MapEmbeddedFields(value, modelType, mapData));
mappedValues.Add(MapEmbeddedFields(value, modelType, mapData, contextSchemaField));
}
break;

Expand Down Expand Up @@ -726,22 +728,22 @@ protected virtual object MapComponent(IComponent component, Type modelType, Loca
return ModelBuilderPipeline.CreateEntityModel(component, modelType, localization);
}

private ViewModel MapEmbeddedFields(IFieldSet embeddedFields, Type modelType, MappingData mapData)
private ViewModel MapEmbeddedFields(IFieldSet embeddedFields, Type modelType, MappingData mapData, SemanticSchemaField contextSchemaField)
{
MappingData embeddedMappingData = new MappingData
{
TargetType = modelType,
Content = embeddedFields,
Meta = null,
EntityNames = mapData.EntityNames, // TODO: should this not be re-determined for the embedded model type?
ParentDefaultPrefix = mapData.ParentDefaultPrefix,
TargetEntitiesByPrefix = mapData.TargetEntitiesByPrefix, // TODO: should this not be re-determined for the embedded model type?
SemanticSchema = mapData.SemanticSchema, // TODO: should this not be re-determined for the embedded model type?
EmbedLevel = mapData.EmbedLevel + 1,
Localization = mapData.Localization
};
MappingData embeddedMappingData = new MappingData
{
TargetType = modelType,
Content = embeddedFields,
Meta = null,
EntityNames = mapData.EntityNames, // TODO: should this not be re-determined for the embedded model type?
ParentDefaultPrefix = mapData.ParentDefaultPrefix,
TargetEntitiesByPrefix = mapData.TargetEntitiesByPrefix, // TODO: should this not be re-determined for the embedded model type?
SemanticSchema = mapData.SemanticSchema, // TODO: should this not be re-determined for the embedded model type?
EmbedLevel = mapData.EmbedLevel + 1,
Localization = mapData.Localization
};

return CreateViewModel(embeddedMappingData);
return CreateViewModel(embeddedMappingData, contextSchemaField);
}

protected Dictionary<string, string> GetAllFieldsAsDictionary(IComponent component)
Expand Down

0 comments on commit f1b7f3b

Please sign in to comment.