private Dtmi ValidateAndCreateDtmi(string dtmi)
 {
     try
     {
         Dtmi dt = new Dtmi(dtmi);
         return(dt);
     }
     catch (Exception e)
     {
         return(null);
     }
 }
        public Task Run(Interactive p)
        {
            if (ModelId == null)
            {
                Log.Error("Please specify a valid model id");
                return(Task.FromResult <object>(null));
            }
            try
            {
                Dtmi modelId = new Dtmi(ModelId);

                if (p.Models.TryGetValue(modelId, out DTInterfaceInfo dti))
                {
                    Log.Ok("Inherited interfaces:");
                    foreach (DTInterfaceInfo parent in dti.Extends)
                    {
                        Log.Ok($"    {parent.Id}");
                    }
                    Dictionary <string, DTContentInfo> contents = dti.Contents;
                    Log.Alert($"  Properties:");
                    var props = contents
                                .Where(p => p.Value.EntityKind == DTEntityKind.Property)
                                .Select(p => p.Value);
                    foreach (DTPropertyInfo pi in props)
                    {
                        pi.Schema.DisplayName.TryGetValue("en", out string displayName);
                        Log.Out($"    {pi.Name}: {displayName ?? pi.Schema.ToString()}");
                    }
                    Log.Out($"  Relationships:", ConsoleColor.DarkMagenta);
                    var rels = contents
                               .Where(p => p.Value.EntityKind == DTEntityKind.Relationship)
                               .Select(p => p.Value);
                    foreach (DTRelationshipInfo ri in rels)
                    {
                        string target = "<any_type>";
                        if (ri.Target != null)
                        {
                            target = ri.Target.ToString();
                        }
                        Log.Out($"    {ri.Name} -> {target}");
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error($"{ModelId} is not a valid dtmi");
            }

            return(Task.FromResult <object>(null));
        }
        public Task Run(Interactive p)
        {
            if (ModelId == null)
            {
                Log.Error("Please specify a valid model id");
                return(Task.FromResult <object>(null));
            }
            try
            {
                Dtmi modelId = new Dtmi(ModelId);

                if (p.Models.TryGetValue(modelId, out DTInterfaceInfo @interface))
                {
                    Console.WriteLine(@interface.GetJsonLdText());
                }
            }
            catch (Exception e)
            {
                Log.Error($"{ModelId} is not a valid dtmi");
            }

            return(Task.FromResult <object>(null));
        }
Exemple #4
0
        private static Dtmi DefiningModel(string item, DTInterfaceInfo ifInfo)
        {
            // must be depth first
            Dtmi result = null;

            foreach (DTInterfaceInfo parent in ifInfo.Extends)
            {
                result = DefiningModel(item, parent);
                if (result != null)
                {
                    return(result);
                }
            }
            // Only check if defined locally after all super classes have been checked
            foreach (DTContentInfo ci in ifInfo.Contents.Values)
            {
                if (ci.Name == item)
                {
                    return(ifInfo.Id);
                }
            }
            // This should really never happen
            return(null);
        }
        public Task Run(Interactive p)
        {
            if (FirstModelId == null || SecondModelId == null)
            {
                Log.Error("Please specify two valid model ids as parameters");
                return(Task.FromResult <object>(null));
            }

            bool firstValid  = false;
            bool secondValid = false;

            Dtmi            first  = ValidateAndCreateDtmi(FirstModelId);
            Dtmi            second = ValidateAndCreateDtmi(SecondModelId);
            DTInterfaceInfo dt1    = null;
            DTInterfaceInfo dt2    = null;

            if (first != null && p.Models.TryGetValue(first, out dt1))
            {
                firstValid = true;
            }
            if (second != null && p.Models.TryGetValue(second, out dt2))
            {
                secondValid = true;
            }

            if (firstValid == false || secondValid == false)
            {
                if (first == null)
                {
                    Log.Error($"First model not a valid dtmi");
                }
                if (first != null && firstValid == false)
                {
                    Log.Error($"First model not found in loaded models");
                }
                if (second == null)
                {
                    Log.Error($"Second model not a valid dtmi");
                }
                if (second != null && secondValid == false)
                {
                    Log.Error($"Second model not found in loaded models");
                }
                return(Task.FromResult <object>(null));
            }

            SortedDictionary <string, DTContentInfo> con1 = dt1.Contents;
            SortedDictionary <string, DTContentInfo> con2 = dt2.Contents;

            var props1 = con1
                         .Where(p => p.Value.EntityKind == DTEntityKind.Property)
                         .Select(p => p.Value as DTPropertyInfo);

            var props2 = con2
                         .Where(p => p.Value.EntityKind == DTEntityKind.Property)
                         .Select(p => p.Value as DTPropertyInfo);

            IEnumerable <DTPropertyInfo> duplicates = props1.Intersect(props2, new DTPropertyInfoComparer());
            IEnumerable <DTPropertyInfo> diff1      = props1.Except(props2, new DTPropertyInfoComparer());
            IEnumerable <DTPropertyInfo> diff2      = props2.Except(props1, new DTPropertyInfoComparer());

            Log.Alert("Common Properties (comparing name and schema, ignoring explicit ids)");
            Console.WriteLine(listFormatBoth, "Property Name", "Schema");
            Console.WriteLine(listFormatBoth, "-------------", "------");
            foreach (var pi in duplicates)
            {
                Console.WriteLine(listFormatBoth, pi.Name, pi.Schema);
            }

            Console.WriteLine();
            PrintDifference(dt1, diff1);
            Console.WriteLine();
            PrintDifference(dt2, diff2);

            var rels1 = con1
                        .Where(p => p.Value.EntityKind == DTEntityKind.Relationship)
                        .Select(p => p.Value as DTRelationshipInfo);

            var rels2 = con2
                        .Where(p => p.Value.EntityKind == DTEntityKind.Relationship)
                        .Select(p => p.Value as DTRelationshipInfo);

            IEnumerable <DTRelationshipInfo> dupRels   = rels1.Intersect(rels2, new DTRelationshipInfoComparer());
            IEnumerable <DTRelationshipInfo> diffRels1 = rels1.Except(rels2, new DTRelationshipInfoComparer());
            IEnumerable <DTRelationshipInfo> diffRels2 = rels2.Except(rels1, new DTRelationshipInfoComparer());

            Console.WriteLine();
            Log.Alert("Common Relationships (comparing name and target - not checking properties, ignoring explicit ids)");
            Console.WriteLine(listFormatBoth, "Relationship Name", "Target");
            Console.WriteLine(listFormatBoth, "-----------------", "------");
            foreach (var pi in dupRels)
            {
                string target = "<any>";
                if (pi.Target != null)
                {
                    target = pi.Target.ToString();
                }
                Console.WriteLine(listFormatBoth, pi.Name, target);
            }

            Console.WriteLine();
            PrintDifference(dt1, diffRels1);
            Console.WriteLine();
            PrintDifference(dt2, diffRels2);

            return(Task.FromResult <object>(null));
        }
Exemple #6
0
        private static void CreateCustomEntity(CdmCorpusDefinition cdmCorpus, CdmManifestDefinition manifestAbstract,
                                               CdmFolderDefinition localRoot, DTInterfaceInfo info)
        {
            string EntityName          = info.Id.ToString();
            string convertedEntityName = EntityName.Replace(':', '_');

            convertedEntityName = convertedEntityName.Replace(';', '-');

            // Create an entity - CustomAccount which has a relationship with the entity CustomPerson
            // Create the entity definition instance
            var entity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, convertedEntityName, false);
            // Add type attributes to the entity instance
            var entityAttributeId = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"$dtId", "identifiedBy", "entityId");

            entity.Attributes.Add(entityAttributeId);
            //var entityAttributeName = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"${convertedEntityName}Name", "hasA", "name");
            //entity.Attributes.Add(entityAttributeName);

            var timestamp = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, "$timestamp", "hasA", "dateTime");

            entity.Attributes.Add(timestamp);

            // Add properties to the entity instance
            entity.DisplayName = info.DisplayName.FirstOrDefault().Value;
            entity.Version     = "0.0.1";
            entity.Description = info.Description.FirstOrDefault().Value;
            // Create the document which contains the entity
            var entityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{convertedEntityName}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            entityDoc.Imports.Add(FoundationJsonPath);
            entityDoc.Definitions.Add(entity);

            foreach (KeyValuePair <string, DTContentInfo> kvp in info.Contents)
            {
                if (kvp.Value.EntityKind == DTEntityKind.Property)
                {
                    DTPropertyInfo pi  = kvp.Value as DTPropertyInfo;
                    Dtmi           def = DefiningModel(pi.Name, info);
                    if (def == info.Id)
                    {
                        Log.Out($"{info.Id}: Adding locally defined property {pi.Name}");

                        string type = "";
                        if (pi.Schema != null)
                        {
                            switch (pi.Schema.EntityKind)
                            {
                            case DTEntityKind.String: type = "string"; break;

                            case DTEntityKind.Float: type = "float"; break;

                            case DTEntityKind.Double: type = "double"; break;

                            case DTEntityKind.Boolean: type = "boolean"; break;

                            case DTEntityKind.Integer: type = "integer"; break;

                            case DTEntityKind.DateTime: type = "dateTime"; break;

                            default: break;
                            }
                        }
                        if (type != "")
                        {
                            var prop = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, pi.Name, "hasA", type);
                            entity.Attributes.Add(prop);
                        }
                    }
                    else
                    {
                        Log.Alert($"{info.Id}: Ignored property {pi.Name} because it is defined in \n{def}");
                    }
                }
            }



            // Handle inheritance
            if (info.Extends.Count > 0)
            {
                foreach (DTInterfaceInfo parent in info.Extends)
                {
                    string pEntityName          = parent.Id.ToString();
                    string pConvertedEntityName = pEntityName.Replace(':', '_');
                    pConvertedEntityName = pConvertedEntityName.Replace(';', '-');
                    entity.ExtendsEntity = cdmCorpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, pConvertedEntityName, true);
                    entityDoc.Imports.Add($"{pConvertedEntityName}.cdm.json");
                }
            }

            // Handle references
            foreach (KeyValuePair <string, DTContentInfo> kvp in info.Contents)
            {
                if (kvp.Value.EntityKind == DTEntityKind.Relationship)
                {
                    DTRelationshipInfo ri = kvp.Value as DTRelationshipInfo;
                    Dtmi def = DefiningModel(ri.Name, info);
                    if (def == info.Id)
                    {
                        string pEntityName          = string.Format("{0}_{1}", def.AbsoluteUri.Substring(0, def.AbsoluteUri.IndexOf(";")), ri.Name.ToString());
                        string pConvertedEntityName = pEntityName.Replace(':', '_');
                        pConvertedEntityName = pConvertedEntityName.Replace(';', '-');
                        Log.Out($"{info.Id}: Adding locally defined relationship {ri.Name}");
                        var attributeExplanation = $"{ri.Name}: {ri.Description.Values.FirstOrDefault()}";
                        var t = kvp.Value;
                        CreateRelatedCustomEntity(cdmCorpus, manifestAbstract, localRoot, ri.Properties, pConvertedEntityName, ri.Name);
                        // You can all CreateSimpleAttributeForRelationshipBetweenTwoEntities() instead, but CreateAttributeForRelationshipBetweenTwoEntities() can show
                        // more details of how to use resolution guidance to customize your data
                        var refAttribute = CreateAttributeForRelationshipBetweenTwoEntities(cdmCorpus, convertedEntityName, pConvertedEntityName, attributeExplanation);
                        entity.Attributes.Add(refAttribute);
                        // Add an import to the foundations doc so the traits about partitons will resolve nicely
                        entityDoc.Imports.Add(FoundationJsonPath);
                        // the CustomAccount entity has a relationship with the CustomPerson entity, this relationship is defined from its attribute with traits,
                        // the import to the entity reference CustomPerson's doc is required
                        entityDoc.Imports.Add($"{pConvertedEntityName}.cdm.json");
                    }
                    else
                    {
                        Log.Alert($"{info.Id}: Ignored property {ri.Name} because it is defined in \n{def}");
                    }
                }
            }

            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(entityDoc, entityDoc.Name);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(entity);
        }