예제 #1
0
        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));
        }
예제 #2
0
        static void RunOptions(Options opts)
        {
            Log.Ok("Simple DTDL Validator");

            if (opts.Interactive == true)
            {
                Log.Alert("Entering interactive mode");
                Interactive.Interactive i = new Interactive.Interactive();
                return;
            }

            DirectoryInfo dinfo = null;

            try
            {
                dinfo = new DirectoryInfo(opts.Directory);
            } catch (Exception e)
            {
                Log.Error($"Error accessing the target directory '{opts.Directory}': \n{e.Message}");
                return;
            }
            Log.Alert($"Validating *.{opts.Extension} files in folder '{dinfo.FullName}'.\nRecursive is set to {opts.Recursive}\n");
            if (dinfo.Exists == false)
            {
                Log.Error($"Specified directory '{opts.Directory}' does not exist: Exiting...");
                return;
            }
            else
            {
                SearchOption searchOpt = opts.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
                var          files     = dinfo.EnumerateFiles($"*.{opts.Extension}", searchOpt);
                if (files.Count() == 0)
                {
                    Log.Alert("No matching files found. Exiting.");
                    return;
                }
                Dictionary <FileInfo, string> modelDict = new Dictionary <FileInfo, string>();
                int    count    = 0;
                string lastFile = "<none>";
                try
                {
                    foreach (FileInfo fi in files)
                    {
                        StreamReader r    = new StreamReader(fi.FullName);
                        string       dtdl = r.ReadToEnd(); r.Close();
                        modelDict.Add(fi, dtdl);
                        lastFile = fi.FullName;
                        count++;
                    }
                } catch (Exception e)
                {
                    Log.Error($"Could not read files. \nLast file read: {lastFile}\nError: \n{e.Message}");
                    return;
                }
                Log.Ok($"Read {count} files from specified directory");
                int errJson = 0;
                foreach (FileInfo fi in modelDict.Keys)
                {
                    modelDict.TryGetValue(fi, out string dtdl);
                    try
                    {
                        JsonDocument.Parse(dtdl);
                    } catch (Exception e)
                    {
                        Log.Error($"Invalid json found in file {fi.FullName}.\nJson parser error \n{e.Message}");
                        errJson++;
                    }
                }
                if (errJson > 0)
                {
                    Log.Error($"\nFound  {errJson} Json parsing errors");
                    return;
                }
                Log.Ok($"Validated JSON for all files - now validating DTDL");
                List <string> modelList = modelDict.Values.ToList <string>();
                ModelParser   parser    = new ModelParser();
                parser.DtmiResolver = Resolver;
                try
                {
                    IReadOnlyDictionary <Dtmi, DTEntityInfo> om = parser.ParseAsync(modelList).GetAwaiter().GetResult();
                    Log.Out("");
                    Log.Ok($"**********************************************");
                    Log.Ok($"** Validated all files - Your DTDL is valid **");
                    Log.Ok($"**********************************************");
                    Log.Out($"Found a total of {om.Keys.Count()} entities");
                }
                catch (ParsingException pe)
                {
                    Log.Error($"*** Error parsing models");
                    int derrcount = 1;
                    foreach (ParsingError err in pe.Errors)
                    {
                        Log.Error($"Error {derrcount}:");
                        Log.Error($"{err.Message}");
                        Log.Error($"Primary ID: {err.PrimaryID}");
                        Log.Error($"Secondary ID: {err.SecondaryID}");
                        Log.Error($"Property: {err.Property}\n");
                        derrcount++;
                    }
                    return;
                }
                catch (ResolutionException rex)
                {
                    Log.Error("Could not resolve required references");
                }
            }
        }
예제 #3
0
        public async Task Run(Interactive p)
        {
            List <string> modelTexts = new List <string>();

            foreach (string fileName in FileNames)
            {
                string directoryName = Path.GetDirectoryName(fileName);
                if (string.IsNullOrWhiteSpace(directoryName))
                {
                    directoryName = ".";
                }

                string[] expandedFileNames = Directory.GetFiles(directoryName, Path.GetFileName(fileName));
                foreach (string expandedFileName in expandedFileNames)
                {
                    modelTexts.Add(File.ReadAllText(expandedFileName));
                    Console.WriteLine($"Loaded {expandedFileName}");
                }
            }

            // Parse the models.
            // The set of entities returned from ParseAsync includes entities loaded by the resolver.
            Console.WriteLine();
            try
            {
                (IReadOnlyDictionary <Dtmi, DTEntityInfo> entities, IEnumerable <DTInterfaceInfo> resolvedInterfaces) = await p.DTDLParser.ParseAsync(modelTexts);

                foreach (Dtmi entityDtmi in entities.Keys)
                {
                    Log.Ok($"Parsed {entityDtmi.AbsoluteUri}");
                }

                // Store only the newly loaded interfaces.
                // Because the entities returned from ParseAsync contains
                // more than just interfaces and also any entities loaded by the resolver:
                // - Filter to just interfaces
                // - Exclude interfaces that were loaded by the resolver.
                // The above seems reasonable for a client to do, since the parser
                // doesn't/shouldn't know these details.
                Console.WriteLine();
                IEnumerable <DTInterfaceInfo> interfaces = from entity in entities.Values
                                                           where entity.EntityKind == DTEntityKind.Interface
                                                           select entity as DTInterfaceInfo;
                interfaces = interfaces.Except(resolvedInterfaces, new DTInterfaceInfoComparer());
                foreach (DTInterfaceInfo @interface in interfaces)
                {
                    p.Models.Add(@interface.Id, @interface);
                    Console.WriteLine($"Stored {@interface.Id.AbsoluteUri}");
                }
            }
            catch (ParsingException pe)
            {
                Log.Error($"*** Error parsing models");
                int derrcount = 1;
                foreach (ParsingError err in pe.Errors)
                {
                    Log.Error($"Error {derrcount}:");
                    Log.Error($"{err.Message}");
                    Log.Error($"Primary ID: {err.PrimaryID}");
                    Log.Error($"Secondary ID: {err.SecondaryID}");
                    Log.Error($"Property: {err.Property}\n");
                    derrcount++;
                }
            }
        }
예제 #4
0
        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));
        }