in objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel/Persistence/ModelJson/ManifestPersistence.cs [239:432]
public async static Task<Model> ToData(CdmManifestDefinition instance, ResolveOptions resOpt, CopyOptions options)
{
var result = new Model()
{
Name = instance.ManifestName,
Description = instance.Explanation,
ModifiedTime = instance.LastFileModifiedTime,
LastChildFileModifiedTime = instance.LastChildFileModifiedTime,
LastFileStatusCheckTime = instance.LastFileStatusCheckTime,
DocumentVersion = instance.DocumentVersion
};
TraitToPropertyMap t2pm = new TraitToPropertyMap(instance);
CdmTraitReference isHiddenTrait = t2pm.FetchTraitReference("is.hidden");
if (isHiddenTrait != null)
{
result.IsHidden = true;
}
CdmTraitReference applicationTrait = t2pm.FetchTraitReference("is.managedBy");
if (applicationTrait != null)
{
result.Application = applicationTrait.Arguments.AllItems[0].Value as string;
}
CdmTraitReference versionTrait = t2pm.FetchTraitReference("is.modelConversion.modelVersion");
if (versionTrait != null)
{
result.Version = versionTrait.Arguments.AllItems[0].Value;
}
else
{
// version property is required. If it doesn't exist set default.
result.Version = "1.0";
}
CdmTraitReference cultureTrait = t2pm.FetchTraitReference("is.partition.culture");
if (cultureTrait != null)
{
result.Culture = cultureTrait.Arguments.AllItems[0].Value as string;
}
Dictionary<string, string> referenceEntityLocations = new Dictionary<string, string>();
Dictionary<string, string> referenceModels = new Dictionary<string, string>();
CdmTraitReference referenceModelsTrait = t2pm.FetchTraitReference("is.modelConversion.referenceModelMap");
if (referenceModelsTrait != null)
{
JArray refModels = referenceModelsTrait.Arguments[0].Value as JArray;
foreach (JObject referenceModel in refModels)
{
var referenceModelId = referenceModel["id"];
var referenceModelIdAsString = referenceModelId.ToString();
var referenceModelLocation = referenceModel["location"];
var referenceModelLocationAsString = referenceModelLocation.ToString();
referenceModels.Add(referenceModelIdAsString, referenceModelLocationAsString);
referenceEntityLocations.Add(referenceModelLocationAsString, referenceModelIdAsString);
}
}
Utils.ProcessTraitsAndAnnotationsToData(instance.Ctx, result, instance.ExhibitsTraits);
if (instance.Entities != null && instance.Entities.Count > 0)
{
List<Task> promises = new List<Task>();
var obtainedEntities = new ConcurrentBag<JToken>();
foreach (var entity in instance.Entities)
{
Task createdPromise = Task.Run(async () =>
{
dynamic element = null;
if (entity.ObjectType == CdmObjectType.LocalEntityDeclarationDef)
{
element = await LocalEntityDeclarationPersistence.ToData(
entity as CdmLocalEntityDeclarationDefinition,
instance,
resOpt,
options
);
}
else if (entity.ObjectType == CdmObjectType.ReferencedEntityDeclarationDef)
{
element = await ReferencedEntityDeclarationPersistence.ToData(
entity as CdmReferencedEntityDeclarationDefinition,
resOpt,
options
);
var location = instance.Ctx.Corpus.Storage.CorpusPathToAdapterPath(entity.EntityPath);
if (string.IsNullOrEmpty(location))
{
Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToData), instance.AtCorpusPath, CdmLogCode.ErrPersistModelJsonInvalidEntityPath);
element = null;
}
if (element is ReferenceEntity referenceEntity)
{
// path separator can differ depending on the adapter, cover the case where path uses '/' or '\'
int lastSlashLocation = location.LastIndexOf("/") > location.LastIndexOf("\\") ? location.LastIndexOf("/") : location.LastIndexOf("\\");
if (lastSlashLocation > 0)
location = location.Slice(0, lastSlashLocation);
if (referenceEntity.ModelId != null)
{
if (referenceModels.TryGetValue(referenceEntity.ModelId, out var savedLocation) && savedLocation != location)
{
Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToData), instance.AtCorpusPath, CdmLogCode.ErrPersistModelJsonModelIdDuplication);
element = null;
}
else if (savedLocation == null)
{
referenceModels[referenceEntity.ModelId] = location;
referenceEntityLocations[location] = referenceEntity.ModelId;
}
}
else if (referenceEntity.ModelId == null && referenceEntityLocations.ContainsKey(location))
{
referenceEntity.ModelId = referenceEntityLocations[location];
}
else
{
referenceEntity.ModelId = Guid.NewGuid().ToString();
referenceModels[referenceEntity.ModelId] = location;
referenceEntityLocations[location] = referenceEntity.ModelId;
}
}
}
if (element != null)
{
obtainedEntities.Add(JToken.FromObject(element));
}
else
{
Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToData), instance.AtCorpusPath, CdmLogCode.ErrPersistModelJsonEntityDeclarationConversionError, entity.EntityName);
}
});
try
{
// TODO: Currently function is synchronous. Remove next line to turn it asynchronous.
// Currently some functions called are not thread safe.
await createdPromise;
promises.Add(createdPromise);
}
catch (Exception ex)
{
Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToData), instance.AtCorpusPath, CdmLogCode.ErrPersistModelJsonEntityDeclarationConversionFailure, entity.EntityName, ex.Message);
}
}
await Task.WhenAll(promises);
result.Entities = obtainedEntities.ToList();
}
if (referenceModels.Count > 0)
{
result.ReferenceModels = new List<ReferenceModel>();
foreach (var referenceModel in referenceModels)
{
result.ReferenceModels.Add(new ReferenceModel()
{
Id = referenceModel.Key,
Location = referenceModel.Value
});
}
}
if (instance.Relationships != null && instance.Relationships.Count > 0)
{
result.Relationships = new List<SingleKeyRelationship>();
foreach (var cdmRelationship in instance.Relationships)
{
var relationship = await RelationshipPersistence.ToData(cdmRelationship, resOpt, options);
if (relationship != null)
{
result.Relationships.Add(relationship);
}
}
}
if (instance.Imports != null && instance.Imports.Count > 0)
{
result.Imports = new List<Import>();
foreach (var element in instance.Imports)
{
result.Imports.Add(CdmFolder.ImportPersistence.ToData(element, resOpt, options));
}
}
return result;
}