protected virtual object CreateEntity(object sourceEntity, Type type, List<object> includes=null) { IComponent component = sourceEntity as IComponent; Dictionary<string, string> entityData; if (component == null && sourceEntity is IComponentPresentation) { var cp = (IComponentPresentation)sourceEntity; component = cp.Component; entityData = GetEntityData(cp); } else { entityData = GetEntityData(component); } if (component != null) { // get schema item id from tcmuri -> tcm:1-2-8 string[] uriParts = component.Schema.Id.Split('-'); long schemaId = Convert.ToInt64(uriParts[1]); MappingData mapData = new MappingData {SemanticSchema = SemanticMapping.GetSchema(schemaId.ToString(CultureInfo.InvariantCulture))}; // get schema entity names (indexed by vocabulary) mapData.EntityNames = mapData.SemanticSchema!=null ? mapData.SemanticSchema.GetEntityNames() : null; //TODO may need to merge with vocabs from embedded types mapData.TargetEntitiesByPrefix = GetEntityDataFromType(type); mapData.Content = component.Fields; mapData.Meta = component.MetadataFields; mapData.TargetType = type; mapData.SourceEntity = component; var model = CreateModelFromMapData(mapData); if (model is IEntity) { ((IEntity)model).EntityData = entityData; ((IEntity)model).Id = component.Id.Split('-')[1]; } if (model is MediaItem && component.Multimedia != null && component.Multimedia.Url != null) { ((MediaItem)model).Url = component.Multimedia.Url; ((MediaItem)model).FileName= component.Multimedia.FileName; ((MediaItem)model).FileSize = component.Multimedia.Size; ((MediaItem)model).MimeType = component.Multimedia.MimeType; } return model; } return null; }
private object GetMultiEmbedded(IField field, Type propertyType, bool multival, MappingData mapData) { MappingData embedMapData = new MappingData { TargetType = propertyType, Meta = null, EntityNames = mapData.EntityNames, ParentDefaultPrefix = mapData.ParentDefaultPrefix, TargetEntitiesByPrefix = mapData.TargetEntitiesByPrefix, SemanticSchema = mapData.SemanticSchema, EmbedLevel = mapData.EmbedLevel + 1 }; //This is a bit weird, but necessary as we cannot return List<object>, we need to get the right type var result = (IList)typeof(List<>).MakeGenericType(propertyType).GetConstructor(Type.EmptyTypes).Invoke(null); foreach (IFieldSet fields in field.EmbeddedValues) { embedMapData.Content = fields; var model = CreateModelFromMapData(embedMapData); if (model != null) { result.Add(model); } } return result.Count == 0 ? null : (multival ? result : result[0]); }
private object GetFieldValues(IField field, Type propertyType, bool multival, MappingData mapData) { switch (field.FieldType) { case (FieldType.Date): return GetDates(field, propertyType, multival); case (FieldType.Number): return GetNumbers(field, propertyType, multival); case (FieldType.MultiMediaLink): return GetMultiMediaLinks(field, propertyType, multival); case (FieldType.ComponentLink): return GetMultiComponentLinks(field, propertyType, multival); case (FieldType.Embedded): return GetMultiEmbedded(field, propertyType, multival, mapData); case (FieldType.Keyword): return GetMultiKeywords(field, propertyType, multival); case (FieldType.Xhtml): return GetMultiLineStrings(field, propertyType, multival); default: return GetStrings(field, propertyType, multival); } }
private static IField GetFieldFromSemantics(MappingData mapData, SemanticProperty info) { var entityData = GetEntityData(info.Prefix, mapData.TargetEntitiesByPrefix, mapData.ParentDefaultPrefix); if (entityData != null) { // determine field semantics var vocab = entityData.Value.Key; string prefix = SemanticMapping.GetPrefix(vocab); if (prefix != null && mapData.EntityNames!=null) { string property = info.PropertyName; string entity = mapData.EntityNames[vocab].FirstOrDefault(); if (entity != null && mapData.SemanticSchema!=null) { FieldSemantics fieldSemantics = new FieldSemantics(prefix, entity, property); // locate semantic schema field SemanticSchemaField matchingField = mapData.SemanticSchema.FindFieldBySemantics(fieldSemantics); if (matchingField != null) { return ExtractMatchedField(matchingField, (matchingField.IsMetadata && mapData.Meta!=null) ? mapData.Meta : mapData.Content, mapData.EmbedLevel); } } } } return null; }
protected virtual Dictionary<string, List<SemanticProperty>> FilterPropertySematicsByEntity(Dictionary<string, List<SemanticProperty>> semantics, MappingData mapData) { Dictionary<string, List<SemanticProperty>> filtered = new Dictionary<string, List<SemanticProperty>>(); foreach (var item in semantics) { filtered.Add(item.Key, new List<SemanticProperty>()); List<SemanticProperty> defaultProperties = new List<SemanticProperty>(); foreach (var prop in item.Value) { //Default prefix is always OK, but should be added last if (String.IsNullOrEmpty(prop.Prefix)) { defaultProperties.Add(prop); } else { //Filter out any properties belonging to other entities than the source entity var entityData = GetEntityData(prop.Prefix, mapData.TargetEntitiesByPrefix, mapData.ParentDefaultPrefix); if (entityData != null && mapData.EntityNames!=null) { if (mapData.EntityNames.Contains(entityData.Value.Key)) { if (mapData.EntityNames[entityData.Value.Key].First() == entityData.Value.Value) { filtered[item.Key].Add(prop); } } } } } filtered[item.Key].AddRange(defaultProperties); } return filtered; }
protected virtual object CreateModelFromMapData(MappingData mapData) { var model = Activator.CreateInstance(mapData.TargetType); Dictionary<string, string> propertyData = new Dictionary<string, string>(); var propertySemantics = FilterPropertySematicsByEntity(LoadPropertySemantics(mapData.TargetType),mapData); foreach (var pi in mapData.TargetType.GetProperties()) { bool multival = pi.PropertyType.IsGenericType && (pi.PropertyType.GetGenericTypeDefinition() == typeof(List<>)); Type propertyType = multival ? pi.PropertyType.GetGenericArguments()[0] : pi.PropertyType; if (propertySemantics.ContainsKey(pi.Name)) { foreach (var info in propertySemantics[pi.Name]) { IField field = GetFieldFromSemantics(mapData, info); if (field != null && (field.Values.Count > 0 || field.EmbeddedValues.Count > 0)) { pi.SetValue(model, GetFieldValues(field, propertyType, multival, mapData)); propertyData.Add(pi.Name, GetFieldXPath(field)); break; } //Special cases if (mapData.SourceEntity!=null) { bool processed = false; //Map the whole entity to an image property, or a resolved link to the entity to a Url field if (info.PropertyName == "_self") { if (propertyType == typeof(MediaItem) && mapData.SourceEntity.Multimedia != null) { pi.SetValue(model, GetMultiMediaLinks(new List<IComponent> { mapData.SourceEntity }, propertyType, multival)); processed = true; } else if (propertyType == typeof(Link) || propertyType == typeof(String)) { pi.SetValue(model, GetMultiComponentLinks(new List<IComponent> { mapData.SourceEntity }, propertyType, multival)); processed = true; } } //Map all fields into a single (Dictionary) property else if (info.PropertyName == "_all" && pi.PropertyType == typeof(Dictionary<string,string>)) { pi.SetValue(model, GetAllFieldsAsDictionary(mapData.SourceEntity)); processed = true; } if (processed) { break; } } } } } if (model is IEntity) { ((IEntity)model).PropertyData = propertyData; } return model; }