/// <summary> /// Build out the EDM model for the given RDM Model /// </summary> /// <remarks>This method is not thread safe.</remarks> /// <returns>The constructed EDM model</returns> public IEdmModel Build(RdmDataModel rdmModel, EdmModel edmModel) { try { this.rdmModel = rdmModel; this.edmModel = edmModel; edmModel.SetEdmReferences(CreateReferences()); // add each of the schema elements and register them in the environment // order the elements so that base classes are created before subclasses foreach (var item in TopologicalOrder.Sort(rdmModel.Items)) { var edmElement = CreateSchemaElement(item); if (edmElement is IEdmType edmType) { logger.LogInfo("adding type '{0}' to environment", item.Name); env.Register(item.Name, edmType); } } // add the members, properties, etc to the schema elements foreach (var item in rdmModel.Items) { var edmElement = BuildSchemaElement(item); } } finally { rdmModel = null; } return(edmModel); }
// public IEdmModel Transform(RdmDataModel model, IDictionary<string, RdmDataModel> referencedModels) // { // return TryTransform(model, referencedModels, out var result) ? result : default; // } public bool TryTransform(RdmDataModel model, IDictionary <string, RdmDataModel> referencedModels, out IEdmModel edmModel) { // The transformation essentially happens in the phases // 1) create the type environment with all external and pre-defined types // 2) add "stubs" for each defined type. these "stubs" have no properties or base types yet. // the EDM model elements are added to the environment and the resulting RDM model // 3) add the properties, base types etc. to the stubs // The three phases are necessary since the graph of types is potentially a circular graph. try { var sw = Stopwatch.StartNew(); // create the environment based on the RDM model's types var env = new TypeEnvironment(logger); // adds the dependencies to allow to resolve the imported types. env.AddReferences(model, referencedModels ?? new Dictionary <string, RdmDataModel>()); // create the model that is going to be filled on by the builder; var result = new EdmModel(); // build out the model types var builder = new ModelBuilder(logger, env); builder.Build(model, result); edmModel = result; logger.LogInfo("transformation time: {0}", sw.Elapsed); return(true); } catch (TransformationException ex) { logger.LogError(ex, "error transforming rsdl model {0}", model.Namespace.NamespaceName); edmModel = default; return(false); } }